verify_em_child.diff
application/octet-stream
Filename: verify_em_child.diff
Type: application/octet-stream
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/equivclass.c | 30 | 0 |
| src/backend/optimizer/path/pathkeys.c | 5 | 0 |
| src/backend/optimizer/plan/createplan.c | 25 | 19 |
| src/include/optimizer/paths.h | 1 | 0 |
diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index 5ace28eab0..7212f2d3bc 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -675,7 +675,10 @@ get_eclass_for_sort_expr(PlannerInfo *root,
*/
if (cur_em->em_is_child &&
!bms_equal(cur_em->em_relids, rel))
+ {
+ verify_em_child(root, cur_em);
continue;
+ }
/*
* If below an outer join, don't match constants: they're not as
@@ -2002,7 +2005,10 @@ exprs_known_equal(PlannerInfo *root, Node *item1, Node *item2)
EquivalenceMember *em = (EquivalenceMember *) lfirst(lc2);
if (em->em_is_child)
+ {
+ verify_em_child(root, em);
continue; /* ignore children here */
+ }
if (equal(item1, em->em_expr))
item1member = true;
else if (equal(item2, em->em_expr))
@@ -2059,7 +2065,10 @@ match_eclasses_to_foreign_key_col(PlannerInfo *root,
Var *var;
if (em->em_is_child)
+ {
+ verify_em_child(root, em);
continue; /* ignore children here */
+ }
/* EM must be a Var, possibly with RelabelType */
var = (Var *) em->em_expr;
@@ -2286,7 +2295,10 @@ generate_implied_equalities_for_column(PlannerInfo *root,
RestrictInfo *rinfo;
if (other_em->em_is_child)
+ {
+ verify_em_child(root, other_em);
continue; /* ignore children here */
+ }
/* Make sure it'll be a join to a different rel */
if (other_em == cur_em ||
@@ -2386,6 +2398,21 @@ have_relevant_eclass_joinclause(PlannerInfo *root,
return false;
}
+void
+verify_em_child(PlannerInfo *root, EquivalenceMember *em)
+{
+ int relid;
+ Assert(em->em_is_child);
+
+ relid = -1;
+ while ((relid = bms_next_member(em->em_relids, relid)) >= 0)
+ {
+ if (root->simple_rel_array[relid]->reloptkind == RELOPT_BASEREL)
+ elog(WARNING, "child EquivalenceMember skipped: %s", nodeToString(em->em_expr));
+ }
+}
+
+
/*
* has_relevant_eclass_joinclause
@@ -2476,7 +2503,10 @@ eclass_useful_for_merging(PlannerInfo *root,
EquivalenceMember *cur_em = (EquivalenceMember *) lfirst(lc);
if (cur_em->em_is_child)
+ {
+ verify_em_child(root, cur_em);
continue; /* ignore children here */
+ }
if (!bms_overlap(cur_em->em_relids, relids))
return true;
diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c
index ec66cb9c3c..27bff4a56d 100644
--- a/src/backend/optimizer/path/pathkeys.c
+++ b/src/backend/optimizer/path/pathkeys.c
@@ -717,7 +717,10 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
ListCell *k;
if (sub_member->em_is_child)
+ {
+ verify_em_child(rel->subroot, sub_member);
continue; /* ignore children here */
+ }
foreach(k, subquery_tlist)
{
@@ -1179,6 +1182,8 @@ select_outer_pathkeys_for_merge(PlannerInfo *root,
if (!em->em_is_const && !em->em_is_child &&
!bms_overlap(em->em_relids, joinrel->relids))
score++;
+ else if (em->em_is_child)
+ verify_em_child(root, em);
}
ecs[necs] = oeclass;
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 28c4b53fea..56a7c69775 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -237,7 +237,7 @@ static MergeJoin *make_mergejoin(List *tlist,
static Sort *make_sort(Plan *lefttree, int numCols,
AttrNumber *sortColIdx, Oid *sortOperators,
Oid *collations, bool *nullsFirst);
-static Plan *prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
+static Plan *prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
Relids relids,
const AttrNumber *reqColIdx,
bool adjust_tlist_in_place,
@@ -246,10 +246,10 @@ static Plan *prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
Oid **p_sortOperators,
Oid **p_collations,
bool **p_nullsFirst);
-static EquivalenceMember *find_ec_member_for_tle(EquivalenceClass *ec,
+static EquivalenceMember *find_ec_member_for_tle(PlannerInfo *root,EquivalenceClass *ec,
TargetEntry *tle,
Relids relids);
-static Sort *make_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
+static Sort *make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
Relids relids);
static Sort *make_sort_from_groupcols(List *groupcls,
AttrNumber *grpColIdx,
@@ -266,7 +266,7 @@ static Group *make_group(List *tlist, List *qual, int numGroupCols,
AttrNumber *grpColIdx, Oid *grpOperators,
Plan *lefttree);
static Unique *make_unique_from_sortclauses(Plan *lefttree, List *distinctList);
-static Unique *make_unique_from_pathkeys(Plan *lefttree,
+static Unique *make_unique_from_pathkeys(PlannerInfo *root, Plan *lefttree,
List *pathkeys, int numCols);
static Gather *make_gather(List *qptlist, List *qpqual,
int nworkers, int rescan_param, bool single_copy, Plan *subplan);
@@ -1147,7 +1147,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path)
plan->righttree = NULL;
/* Compute sort column info, and adjust MergeAppend's tlist as needed */
- (void) prepare_sort_from_pathkeys(plan, pathkeys,
+ (void) prepare_sort_from_pathkeys(root, plan, pathkeys,
best_path->path.parent->relids,
NULL,
true,
@@ -1177,7 +1177,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path)
subplan = create_plan_recurse(root, subpath, CP_EXACT_TLIST);
/* Compute sort column info, and adjust subplan's tlist as needed */
- subplan = prepare_sort_from_pathkeys(subplan, pathkeys,
+ subplan = prepare_sort_from_pathkeys(root, subplan, pathkeys,
subpath->parent->relids,
node->sortColIdx,
false,
@@ -1606,7 +1606,7 @@ create_gather_merge_plan(PlannerInfo *root, GatherMergePath *best_path)
Assert(pathkeys != NIL);
/* Compute sort column info, and adjust subplan's tlist as needed */
- subplan = prepare_sort_from_pathkeys(subplan, pathkeys,
+ subplan = prepare_sort_from_pathkeys(root, subplan, pathkeys,
best_path->subpath->parent->relids,
gm_plan->sortColIdx,
false,
@@ -1788,7 +1788,7 @@ create_sort_plan(PlannerInfo *root, SortPath *best_path, int flags)
* relids. Thus, if this sort path is based on a child relation, we must
* pass its relids.
*/
- plan = make_sort_from_pathkeys(subplan, best_path->path.pathkeys,
+ plan = make_sort_from_pathkeys(root, subplan, best_path->path.pathkeys,
IS_OTHER_REL(best_path->subpath->parent) ?
best_path->path.parent->relids : NULL);
@@ -1853,7 +1853,7 @@ create_upper_unique_plan(PlannerInfo *root, UpperUniquePath *best_path, int flag
subplan = create_plan_recurse(root, best_path->subpath,
flags | CP_LABEL_TLIST);
- plan = make_unique_from_pathkeys(subplan,
+ plan = make_unique_from_pathkeys(root, subplan,
best_path->path.pathkeys,
best_path->numkeys);
@@ -3879,7 +3879,7 @@ create_mergejoin_plan(PlannerInfo *root,
if (best_path->outersortkeys)
{
Relids outer_relids = outer_path->parent->relids;
- Sort *sort = make_sort_from_pathkeys(outer_plan,
+ Sort *sort = make_sort_from_pathkeys(root, outer_plan,
best_path->outersortkeys,
outer_relids);
@@ -3893,7 +3893,7 @@ create_mergejoin_plan(PlannerInfo *root,
if (best_path->innersortkeys)
{
Relids inner_relids = inner_path->parent->relids;
- Sort *sort = make_sort_from_pathkeys(inner_plan,
+ Sort *sort = make_sort_from_pathkeys(root, inner_plan,
best_path->innersortkeys,
inner_relids);
@@ -5604,7 +5604,7 @@ make_sort(Plan *lefttree, int numCols,
* or a Result stacked atop lefttree).
*/
static Plan *
-prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
+prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
Relids relids,
const AttrNumber *reqColIdx,
bool adjust_tlist_in_place,
@@ -5671,7 +5671,7 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
tle = get_tle_by_resno(tlist, reqColIdx[numsortkeys]);
if (tle)
{
- em = find_ec_member_for_tle(ec, tle, relids);
+ em = find_ec_member_for_tle(root, ec, tle, relids);
if (em)
{
/* found expr at right place in tlist */
@@ -5702,7 +5702,7 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
foreach(j, tlist)
{
tle = (TargetEntry *) lfirst(j);
- em = find_ec_member_for_tle(ec, tle, relids);
+ em = find_ec_member_for_tle(root, ec, tle, relids);
if (em)
{
/* found expr already in tlist */
@@ -5745,7 +5745,10 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
*/
if (em->em_is_child &&
!bms_is_subset(em->em_relids, relids))
+ {
+ verify_em_child(root, em);
continue;
+ }
sortexpr = em->em_expr;
exprvars = pull_var_clause((Node *) sortexpr,
@@ -5831,7 +5834,7 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
* Child EC members are ignored unless they belong to given 'relids'.
*/
static EquivalenceMember *
-find_ec_member_for_tle(EquivalenceClass *ec,
+find_ec_member_for_tle(PlannerInfo *root, EquivalenceClass *ec,
TargetEntry *tle,
Relids relids)
{
@@ -5860,7 +5863,10 @@ find_ec_member_for_tle(EquivalenceClass *ec,
*/
if (em->em_is_child &&
!bms_is_subset(em->em_relids, relids))
+ {
+ verify_em_child(root, em);
continue;
+ }
/* Match if same expression (after stripping relabel) */
emexpr = em->em_expr;
@@ -5883,7 +5889,7 @@ find_ec_member_for_tle(EquivalenceClass *ec,
* 'relids' is the set of relations required by prepare_sort_from_pathkeys()
*/
static Sort *
-make_sort_from_pathkeys(Plan *lefttree, List *pathkeys, Relids relids)
+make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys, Relids relids)
{
int numsortkeys;
AttrNumber *sortColIdx;
@@ -5892,7 +5898,7 @@ make_sort_from_pathkeys(Plan *lefttree, List *pathkeys, Relids relids)
bool *nullsFirst;
/* Compute sort column info, and adjust lefttree as needed */
- lefttree = prepare_sort_from_pathkeys(lefttree, pathkeys,
+ lefttree = prepare_sort_from_pathkeys(root, lefttree, pathkeys,
relids,
NULL,
false,
@@ -6204,7 +6210,7 @@ make_unique_from_sortclauses(Plan *lefttree, List *distinctList)
* as above, but use pathkeys to identify the sort columns and semantics
*/
static Unique *
-make_unique_from_pathkeys(Plan *lefttree, List *pathkeys, int numCols)
+make_unique_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys, int numCols)
{
Unique *node = makeNode(Unique);
Plan *plan = &node->plan;
@@ -6265,7 +6271,7 @@ make_unique_from_pathkeys(Plan *lefttree, List *pathkeys, int numCols)
foreach(j, plan->targetlist)
{
tle = (TargetEntry *) lfirst(j);
- em = find_ec_member_for_tle(ec, tle, NULL);
+ em = find_ec_member_for_tle(root, ec, tle, NULL);
if (em)
{
/* found expr already in tlist */
diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h
index cafde307ad..a3f34a5c8c 100644
--- a/src/include/optimizer/paths.h
+++ b/src/include/optimizer/paths.h
@@ -169,6 +169,7 @@ extern List *generate_implied_equalities_for_column(PlannerInfo *root,
Relids prohibited_rels);
extern bool have_relevant_eclass_joinclause(PlannerInfo *root,
RelOptInfo *rel1, RelOptInfo *rel2);
+extern void verify_em_child(PlannerInfo *root, EquivalenceMember *em);
extern bool has_relevant_eclass_joinclause(PlannerInfo *root,
RelOptInfo *rel1);
extern bool eclass_useful_for_merging(PlannerInfo *root,