mirror of
https://github.com/postgres/postgres.git
synced 2025-11-19 13:42:17 +03:00
Re-allow planner to use Merge Append to efficiently implement UNION.
This reverts commit7204f35919, thus restoring66c0185a3(Allow planner to use Merge Append to efficiently implement UNION) as well as the follow-on commitsd5d2205c8,3b1a7eb28,7487044d6. Per further discussion on pgsql-release, we wish to ship beta1 with this feature, and patch the bug that was found just before wrap, rather than shipping beta1 with the feature reverted.
This commit is contained in:
@@ -2633,9 +2633,8 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
Assert(root->plan_params == NIL);
|
||||
|
||||
/* Generate a subroot and Paths for the subquery */
|
||||
rel->subroot = subquery_planner(root->glob, subquery,
|
||||
root,
|
||||
false, tuple_fraction);
|
||||
rel->subroot = subquery_planner(root->glob, subquery, root, false,
|
||||
tuple_fraction, NULL);
|
||||
|
||||
/* Isolate the params needed by this specific subplan */
|
||||
rel->subplan_params = root->plan_params;
|
||||
|
||||
@@ -2882,6 +2882,67 @@ add_child_join_rel_equivalences(PlannerInfo *root,
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
}
|
||||
|
||||
/*
|
||||
* add_setop_child_rel_equivalences
|
||||
* Add equivalence members for each non-resjunk target in 'child_tlist'
|
||||
* to the EquivalenceClass in the corresponding setop_pathkey's pk_eclass.
|
||||
*
|
||||
* 'root' is the PlannerInfo belonging to the top-level set operation.
|
||||
* 'child_rel' is the RelOptInfo of the child relation we're adding
|
||||
* EquivalenceMembers for.
|
||||
* 'child_tlist' is the target list for the setop child relation. The target
|
||||
* list expressions are what we add as EquivalenceMembers.
|
||||
* 'setop_pathkeys' is a list of PathKeys which must contain an entry for each
|
||||
* non-resjunk target in 'child_tlist'.
|
||||
*/
|
||||
void
|
||||
add_setop_child_rel_equivalences(PlannerInfo *root, RelOptInfo *child_rel,
|
||||
List *child_tlist, List *setop_pathkeys)
|
||||
{
|
||||
ListCell *lc;
|
||||
ListCell *lc2 = list_head(setop_pathkeys);
|
||||
|
||||
foreach(lc, child_tlist)
|
||||
{
|
||||
TargetEntry *tle = lfirst_node(TargetEntry, lc);
|
||||
EquivalenceMember *parent_em;
|
||||
PathKey *pk;
|
||||
|
||||
if (tle->resjunk)
|
||||
continue;
|
||||
|
||||
if (lc2 == NULL)
|
||||
elog(ERROR, "too few pathkeys for set operation");
|
||||
|
||||
pk = lfirst_node(PathKey, lc2);
|
||||
parent_em = linitial(pk->pk_eclass->ec_members);
|
||||
|
||||
/*
|
||||
* We can safely pass the parent member as the first member in the
|
||||
* ec_members list as this is added first in generate_union_paths,
|
||||
* likewise, the JoinDomain can be that of the initial member of the
|
||||
* Pathkey's EquivalenceClass.
|
||||
*/
|
||||
add_eq_member(pk->pk_eclass,
|
||||
tle->expr,
|
||||
child_rel->relids,
|
||||
parent_em->em_jdomain,
|
||||
parent_em,
|
||||
exprType((Node *) tle->expr));
|
||||
|
||||
lc2 = lnext(setop_pathkeys, lc2);
|
||||
}
|
||||
|
||||
/*
|
||||
* transformSetOperationStmt() ensures that the targetlist never contains
|
||||
* any resjunk columns, so all eclasses that exist in 'root' must have
|
||||
* received a new member in the loop above. Add them to the child_rel's
|
||||
* eclass_indexes.
|
||||
*/
|
||||
child_rel->eclass_indexes = bms_add_range(child_rel->eclass_indexes, 0,
|
||||
list_length(root->eq_classes) - 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* generate_implied_equalities_for_column
|
||||
|
||||
@@ -2191,6 +2191,22 @@ pathkeys_useful_for_grouping(PlannerInfo *root, List *pathkeys)
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* pathkeys_useful_for_setop
|
||||
* Count the number of leading common pathkeys root's 'setop_pathkeys' in
|
||||
* 'pathkeys'.
|
||||
*/
|
||||
static int
|
||||
pathkeys_useful_for_setop(PlannerInfo *root, List *pathkeys)
|
||||
{
|
||||
int n_common_pathkeys;
|
||||
|
||||
(void) pathkeys_count_contained_in(root->setop_pathkeys, pathkeys,
|
||||
&n_common_pathkeys);
|
||||
|
||||
return n_common_pathkeys;
|
||||
}
|
||||
|
||||
/*
|
||||
* truncate_useless_pathkeys
|
||||
* Shorten the given pathkey list to just the useful pathkeys.
|
||||
@@ -2208,6 +2224,9 @@ truncate_useless_pathkeys(PlannerInfo *root,
|
||||
if (nuseful2 > nuseful)
|
||||
nuseful = nuseful2;
|
||||
nuseful2 = pathkeys_useful_for_grouping(root, pathkeys);
|
||||
if (nuseful2 > nuseful)
|
||||
nuseful = nuseful2;
|
||||
nuseful2 = pathkeys_useful_for_setop(root, pathkeys);
|
||||
if (nuseful2 > nuseful)
|
||||
nuseful = nuseful2;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user