diff-v34-v35.txt
text/plain
Filename: diff-v34-v35.txt
Type: text/plain
Part: 0
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index dbf92c9b7ca..adcf6417468 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -7829,11 +7829,11 @@ EquivalenceMember *
find_em_for_rel(PlannerInfo *root, EquivalenceClass *ec, RelOptInfo *rel)
{
PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private;
- EquivalenceAllMemberIterator it;
+ EquivalenceMemberIterator it;
EquivalenceMember *em;
- setup_eclass_all_member_iterator_for_relids(&it, root, ec, rel->relids);
- while ((em = eclass_all_member_iterator_for_relids_next(&it)) != NULL)
+ setup_eclass_member_iterator_with_children(&it, root, ec, rel->relids);
+ while ((em = eclass_member_iterator_next(&it)) != NULL)
{
/*
* Note we require !bms_is_empty, else we'd accept constant
@@ -7845,7 +7845,7 @@ find_em_for_rel(PlannerInfo *root, EquivalenceClass *ec, RelOptInfo *rel)
is_foreign_expr(root, rel, em->em_expr))
return em;
}
- dispose_eclass_all_member_iterator_for_relids(&it);
+ dispose_eclass_member_iterator(&it);
return NULL;
}
diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index c6ecfb874c8..1ffd2ce0a04 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -38,10 +38,10 @@ static EquivalenceMember *make_eq_member(EquivalenceClass *ec,
JoinDomain *jdomain,
EquivalenceMember *parent,
Oid datatype);
-static EquivalenceMember *add_parent_eq_member(EquivalenceClass *ec,
- Expr *expr, Relids relids,
- JoinDomain *jdomain,
- Oid datatype);
+static EquivalenceMember *add_eq_member(EquivalenceClass *ec,
+ Expr *expr, Relids relids,
+ JoinDomain *jdomain,
+ Oid datatype);
static void add_eq_source(PlannerInfo *root, EquivalenceClass *ec,
RestrictInfo *rinfo);
static void add_eq_derive(PlannerInfo *root, EquivalenceClass *ec,
@@ -76,7 +76,7 @@ static bool reconsider_outer_join_clause(PlannerInfo *root,
static bool reconsider_full_join_clause(PlannerInfo *root,
OuterJoinClauseInfo *ojcinfo);
static JoinDomain *find_join_domain(PlannerInfo *root, Relids relids);
-static void add_eclass_child_members_to_iterator(EquivalenceAllMemberIterator *it,
+static void add_eclass_child_members_to_iterator(EquivalenceMemberIterator *it,
PlannerInfo *root,
EquivalenceClass *ec,
RelOptInfo *child_rel);
@@ -280,7 +280,8 @@ process_equivalence(PlannerInfo *root,
{
EquivalenceMember *cur_em = (EquivalenceMember *) lfirst(lc2);
- Assert(!cur_em->em_is_child); /* no children yet */
+ /* Child members should not exist in ec_members */
+ Assert(!cur_em->em_is_child);
/*
* Match constants only within the same JoinDomain (see
@@ -388,8 +389,8 @@ process_equivalence(PlannerInfo *root,
else if (ec1)
{
/* Case 3: add item2 to ec1 */
- em2 = add_parent_eq_member(ec1, item2, item2_relids,
- jdomain, item2_type);
+ em2 = add_eq_member(ec1, item2, item2_relids,
+ jdomain, item2_type);
ec1->ec_min_security = Min(ec1->ec_min_security,
restrictinfo->security_level);
ec1->ec_max_security = Max(ec1->ec_max_security,
@@ -406,8 +407,8 @@ process_equivalence(PlannerInfo *root,
else if (ec2)
{
/* Case 3: add item1 to ec2 */
- em1 = add_parent_eq_member(ec2, item1, item1_relids,
- jdomain, item1_type);
+ em1 = add_eq_member(ec2, item1, item1_relids,
+ jdomain, item1_type);
ec2->ec_min_security = Min(ec2->ec_min_security,
restrictinfo->security_level);
ec2->ec_max_security = Max(ec2->ec_max_security,
@@ -439,10 +440,10 @@ process_equivalence(PlannerInfo *root,
ec->ec_min_security = restrictinfo->security_level;
ec->ec_max_security = restrictinfo->security_level;
ec->ec_merged = NULL;
- em1 = add_parent_eq_member(ec, item1, item1_relids,
- jdomain, item1_type);
- em2 = add_parent_eq_member(ec, item2, item2_relids,
- jdomain, item2_type);
+ em1 = add_eq_member(ec, item1, item1_relids,
+ jdomain, item1_type);
+ em2 = add_eq_member(ec, item2, item2_relids,
+ jdomain, item2_type);
root->eq_classes = lappend(root->eq_classes, ec);
@@ -576,7 +577,7 @@ make_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids,
}
/*
- * add_parent_eq_member - build a new parent EquivalenceMember and add it to an EC
+ * add_eq_member - build a new parent EquivalenceMember and add it to an EC
*
* Note: We don't have a function to add a child member like
* add_child_eq_member() because how to do it depends on the relations they
@@ -585,8 +586,8 @@ make_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids,
* to see how to add child members.
*/
static EquivalenceMember *
-add_parent_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids,
- JoinDomain *jdomain, Oid datatype)
+add_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids,
+ JoinDomain *jdomain, Oid datatype)
{
EquivalenceMember *em = make_eq_member(ec, expr, relids, jdomain,
NULL, datatype);
@@ -821,7 +822,7 @@ get_eclass_for_sort_expr(PlannerInfo *root,
foreach(lc1, root->eq_classes)
{
EquivalenceClass *cur_ec = (EquivalenceClass *) lfirst(lc1);
- EquivalenceAllMemberIterator it;
+ EquivalenceMemberIterator it;
EquivalenceMember *cur_em;
/*
@@ -837,8 +838,8 @@ get_eclass_for_sort_expr(PlannerInfo *root,
if (!equal(opfamilies, cur_ec->ec_opfamilies))
continue;
- setup_eclass_all_member_iterator_for_relids(&it, root, cur_ec, rel);
- while ((cur_em = eclass_all_member_iterator_for_relids_next(&it)) != NULL)
+ setup_eclass_member_iterator_with_children(&it, root, cur_ec, rel);
+ while ((cur_em = eclass_member_iterator_next(&it)) != NULL)
{
/*
* Ignore child members unless they match the request.
@@ -858,7 +859,7 @@ get_eclass_for_sort_expr(PlannerInfo *root,
equal(expr, cur_em->em_expr))
return cur_ec; /* Match! */
}
- dispose_eclass_all_member_iterator_for_relids(&it);
+ dispose_eclass_member_iterator(&it);
}
/* No match; does caller want a NULL result? */
@@ -895,14 +896,14 @@ get_eclass_for_sort_expr(PlannerInfo *root,
*/
expr_relids = pull_varnos(root, (Node *) expr);
- newem = add_parent_eq_member(newec, copyObject(expr), expr_relids,
- jdomain, opcintype);
+ newem = add_eq_member(newec, copyObject(expr), expr_relids,
+ jdomain, opcintype);
/*
- * add_parent_eq_member doesn't check for volatile functions,
- * set-returning functions, aggregates, or window functions, but such
- * could appear in sort expressions; so we have to check whether its
- * const-marking was correct.
+ * add_eq_member doesn't check for volatile functions, set-returning
+ * functions, aggregates, or window functions, but such could appear in
+ * sort expressions; so we have to check whether its const-marking was
+ * correct.
*/
if (newec->ec_has_const)
{
@@ -970,15 +971,15 @@ find_ec_member_matching_expr(PlannerInfo *root, EquivalenceClass *ec,
Expr *expr,
Relids relids)
{
- EquivalenceAllMemberIterator it;
+ EquivalenceMemberIterator it;
EquivalenceMember *em;
/* We ignore binary-compatible relabeling on both ends */
while (expr && IsA(expr, RelabelType))
expr = ((RelabelType *) expr)->arg;
- setup_eclass_all_member_iterator_for_relids(&it, root, ec, relids);
- while ((em = eclass_all_member_iterator_for_relids_next(&it)) != NULL)
+ setup_eclass_member_iterator_with_children(&it, root, ec, relids);
+ while ((em = eclass_member_iterator_next(&it)) != NULL)
{
Expr *emexpr;
@@ -1006,7 +1007,7 @@ find_ec_member_matching_expr(PlannerInfo *root, EquivalenceClass *ec,
if (equal(emexpr, expr))
return em;
}
- dispose_eclass_all_member_iterator_for_relids(&it);
+ dispose_eclass_member_iterator(&it);
return NULL;
}
@@ -1049,7 +1050,7 @@ find_computable_ec_member(PlannerInfo *root,
bool require_parallel_safe)
{
List *exprvars;
- EquivalenceAllMemberIterator it;
+ EquivalenceMemberIterator it;
EquivalenceMember *em;
/*
@@ -1064,8 +1065,8 @@ find_computable_ec_member(PlannerInfo *root,
PVC_INCLUDE_PLACEHOLDERS |
PVC_INCLUDE_CONVERTROWTYPES);
- setup_eclass_all_member_iterator_for_relids(&it, root, ec, relids);
- while ((em = eclass_all_member_iterator_for_relids_next(&it)) != NULL)
+ setup_eclass_member_iterator_with_children(&it, root, ec, relids);
+ while ((em = eclass_member_iterator_next(&it)) != NULL)
{
List *emvars;
ListCell *lc2;
@@ -1110,7 +1111,7 @@ find_computable_ec_member(PlannerInfo *root,
return em; /* found usable expression */
}
- dispose_eclass_all_member_iterator_for_relids(&it);
+ dispose_eclass_member_iterator(&it);
return NULL;
}
@@ -1373,7 +1374,8 @@ generate_base_implied_equalities_const(PlannerInfo *root,
Oid eq_op;
RestrictInfo *rinfo;
- Assert(!cur_em->em_is_child); /* no children yet */
+ Assert(!cur_em->em_is_child); /* Child members should not exist in
+ * ec_members */
if (cur_em == const_em)
continue;
eq_op = select_equality_operator(ec,
@@ -1443,7 +1445,8 @@ generate_base_implied_equalities_no_const(PlannerInfo *root,
EquivalenceMember *cur_em = (EquivalenceMember *) lfirst(lc);
int relid;
- Assert(!cur_em->em_is_child); /* no children yet */
+ Assert(!cur_em->em_is_child); /* Child members should not exist in
+ * ec_members */
if (!bms_get_singleton_member(cur_em->em_relids, &relid))
continue;
Assert(relid < root->simple_rel_array_size);
@@ -1777,7 +1780,7 @@ generate_join_implied_equalities_normal(PlannerInfo *root,
List *new_members = NIL;
List *outer_members = NIL;
List *inner_members = NIL;
- EquivalenceAllMemberIterator it;
+ EquivalenceMemberIterator it;
EquivalenceMember *cur_em;
/*
@@ -1789,8 +1792,8 @@ generate_join_implied_equalities_normal(PlannerInfo *root,
* as well as to at least one input member, plus enforce at least one
* outer-rel member equal to at least one inner-rel member.
*/
- setup_eclass_all_member_iterator_for_relids(&it, root, ec, join_relids);
- while ((cur_em = eclass_all_member_iterator_for_relids_next(&it)) != NULL)
+ setup_eclass_member_iterator_with_children(&it, root, ec, join_relids);
+ while ((cur_em = eclass_member_iterator_next(&it)) != NULL)
{
/*
* We don't need to check explicitly for child EC members. This test
@@ -1807,7 +1810,7 @@ generate_join_implied_equalities_normal(PlannerInfo *root,
else
new_members = lappend(new_members, cur_em);
}
- dispose_eclass_all_member_iterator_for_relids(&it);
+ dispose_eclass_member_iterator(&it);
/*
* First, select the joinclause if needed. We can equate any one outer
@@ -2406,7 +2409,8 @@ reconsider_outer_join_clause(PlannerInfo *root, OuterJoinClauseInfo *ojcinfo,
{
EquivalenceMember *cur_em = (EquivalenceMember *) lfirst(lc2);
- Assert(!cur_em->em_is_child); /* no children yet */
+ Assert(!cur_em->em_is_child); /* Child members should not exist
+ * in ec_members */
if (equal(outervar, cur_em->em_expr))
{
match = true;
@@ -2533,7 +2537,8 @@ reconsider_full_join_clause(PlannerInfo *root, OuterJoinClauseInfo *ojcinfo)
foreach(lc2, cur_ec->ec_members)
{
coal_em = (EquivalenceMember *) lfirst(lc2);
- Assert(!coal_em->em_is_child); /* no children yet */
+ Assert(!coal_em->em_is_child); /* Child members should not exist
+ * in ec_members */
if (IsA(coal_em->em_expr, CoalesceExpr))
{
CoalesceExpr *cexpr = (CoalesceExpr *) coal_em->em_expr;
@@ -2630,7 +2635,6 @@ reconsider_full_join_clause(PlannerInfo *root, OuterJoinClauseInfo *ojcinfo)
if (matchleft && matchright)
{
cur_ec->ec_members = list_delete_nth_cell(cur_ec->ec_members, coal_idx);
- Assert(!bms_is_empty(coal_em->em_relids));
return true;
}
@@ -2752,8 +2756,8 @@ exprs_known_equal(PlannerInfo *root, Node *item1, Node *item2, Oid opfamily)
{
EquivalenceMember *em = (EquivalenceMember *) lfirst(lc2);
- /* Child members should not exist in ec_members */
- Assert(!em->em_is_child);
+ Assert(!em->em_is_child); /* Child members should not exist in
+ * ec_members */
if (equal(item1, em->em_expr))
item1member = true;
else if (equal(item2, em->em_expr))
@@ -2957,16 +2961,8 @@ add_child_rel_equivalences(PlannerInfo *root,
if (cur_em->em_is_const)
continue; /* ignore consts here */
- /*
- * We consider only original EC members here, not
- * already-transformed child members. Otherwise, if some original
- * member expression references more than one appendrel, we'd get
- * an O(N^2) explosion of useless derived expressions for
- * combinations of children. (But add_child_join_rel_equivalences
- * may add targeted combinations for partitionwise-join purposes.)
- */
- Assert(!cur_em->em_is_child); /* Child members should not exist
- * in ec_members */
+ /* Child members should not exist in ec_members */
+ Assert(!cur_em->em_is_child);
/*
* Consider only members that reference and can be computed at
@@ -3045,7 +3041,6 @@ add_child_join_rel_equivalences(PlannerInfo *root,
Relids child_relids = child_joinrel->relids;
Bitmapset *matching_ecs;
MemoryContext oldcontext;
- ListCell *lc;
int i;
Assert(IS_JOIN_REL(child_joinrel) && IS_JOIN_REL(parent_joinrel));
@@ -3067,6 +3062,7 @@ add_child_join_rel_equivalences(PlannerInfo *root,
while ((i = bms_next_member(matching_ecs, i)) >= 0)
{
EquivalenceClass *cur_ec = (EquivalenceClass *) list_nth(root->eq_classes, i);
+ ListCell *lc;
/*
* If this EC contains a volatile expression, then generating child
@@ -3086,12 +3082,8 @@ add_child_join_rel_equivalences(PlannerInfo *root,
if (cur_em->em_is_const)
continue; /* ignore consts here */
- /*
- * We consider only original EC members here, not
- * already-transformed child members.
- */
- Assert(!cur_em->em_is_child); /* Child members should not exist
- * in ec_members */
+ /* Child members should not exist in ec_members */
+ Assert(!cur_em->em_is_child);
/*
* We may ignore expressions that reference a single baserel,
@@ -3159,7 +3151,7 @@ add_child_join_rel_equivalences(PlannerInfo *root,
* that have only such parent relations as em_relids are
* already present in the ec_members, and so cannot be
* candidates for additional iteration by
- * EquivalenceAllMemberIterator. Since the iterator needs
+ * EquivalenceMemberIterator. Since the iterator needs
* EquivalenceMembers whose em_relids has child relations,
* skipping the update of this inverted index allows for
* faster iteration.
@@ -3266,8 +3258,8 @@ add_setop_child_rel_equivalences(PlannerInfo *root, RelOptInfo *child_rel,
}
/*
- * setup_eclass_all_member_iterator_for_relids
- * Setup an EquivalenceAllMemberIterator 'it' to iterate over all parent
+ * setup_eclass_member_iterator_with_children
+ * Setup an EquivalenceMemberIterator 'it' to iterate over all parent
* EquivalenceMembers and child members associated with the given 'ec' that
* are relevant to the specified 'relids'.
*
@@ -3280,7 +3272,7 @@ add_setop_child_rel_equivalences(PlannerInfo *root, RelOptInfo *child_rel,
* em_relids is not a subset. So the caller must check that they satisfy
* the desired condition.
* - Once used, the caller should dispose of the iterator by calling
- * dispose_eclass_all_member_iterator_for_relids().
+ * dispose_eclass_member_iterator().
*
* Parameters:
* root - The PlannerInfo context.
@@ -3288,10 +3280,10 @@ add_setop_child_rel_equivalences(PlannerInfo *root, RelOptInfo *child_rel,
* relids - The Relids used to filter for relevant child members.
*/
void
-setup_eclass_all_member_iterator_for_relids(EquivalenceAllMemberIterator *it,
- PlannerInfo *root,
- EquivalenceClass *ec,
- Relids relids)
+setup_eclass_member_iterator_with_children(EquivalenceMemberIterator *it,
+ PlannerInfo *root,
+ EquivalenceClass *ec,
+ Relids relids)
{
Bitmapset *matching_indexes;
int i;
@@ -3300,7 +3292,7 @@ setup_eclass_all_member_iterator_for_relids(EquivalenceAllMemberIterator *it,
* Initialize the iterator.
*/
it->index = -1;
- it->modified = false;
+ it->list_is_copy = false;
it->ec_members = ec->ec_members;
/*
@@ -3321,13 +3313,13 @@ setup_eclass_all_member_iterator_for_relids(EquivalenceAllMemberIterator *it,
* like EquivalenceClassIndexes->joinrel_indexes.
*
* We use an inverted index mechanism to quickly iterate over the members
- * whose em_relids is a subset of the given 'child_relids'. The inverted
- * indexes store RelOptInfo indices that have EquivalenceMembers
- * mentioning them. Taking the union of these indexes allows to find which
- * RelOptInfos have the EquivalenceMember we are looking for. With this
- * method, the em_relids of the newly iterated ones overlap the given
- * 'child_relids', but may not be subsets, so the caller must check that
- * they satisfy the desired condition.
+ * whose em_relids is a subset of the given 'relids'. The inverted indexes
+ * store RelOptInfo indices that have EquivalenceMembers mentioning them.
+ * Taking the union of these indexes allows to find which RelOptInfos have
+ * the EquivalenceMember we are looking for. With this method, the
+ * em_relids of the newly iterated ones overlap the given 'relids', but
+ * may not be subsets, so the caller must check that they satisfy the
+ * desired condition.
*
* The above comments are about joinrels, and for simple rels, this
* mechanism is simpler. It is sufficient to simply add the child
@@ -3416,10 +3408,10 @@ setup_eclass_all_member_iterator_for_relids(EquivalenceAllMemberIterator *it,
* the iterator from RelOptInfo.
*
* This function is expected to be called only from
- * setup_eclass_all_member_iterator_for_relids().
+ * setup_eclass_member_iterator_with_children().
*/
static void
-add_eclass_child_members_to_iterator(EquivalenceAllMemberIterator *it,
+add_eclass_child_members_to_iterator(EquivalenceMemberIterator *it,
PlannerInfo *root,
EquivalenceClass *ec,
RelOptInfo *child_rel)
@@ -3438,10 +3430,10 @@ add_eclass_child_members_to_iterator(EquivalenceAllMemberIterator *it,
* If this is the first time the iterator's list has been modified, we
* need to make a copy of it.
*/
- if (!it->modified)
+ if (!it->list_is_copy)
{
it->ec_members = list_copy(it->ec_members);
- it->modified = true;
+ it->list_is_copy = true;
}
/* Add this child EquivalenceMember to the list */
@@ -3450,13 +3442,13 @@ add_eclass_child_members_to_iterator(EquivalenceAllMemberIterator *it,
}
/*
- * eclass_all_member_iterator_for_relids_next
- * Get a next EquivalenceMember from an EquivalenceAllMemberIterator 'it'
- * that was setup by setup_eclass_all_member_iterator_for_relids(). NULL is
+ * eclass_member_iterator_next
+ * Get a next EquivalenceMember from an EquivalenceMemberIterator 'it'
+ * that was setup by setup_eclass_member_iterator_with_children(). NULL is
* returned if there are no members left.
*/
EquivalenceMember *
-eclass_all_member_iterator_for_relids_next(EquivalenceAllMemberIterator *it)
+eclass_member_iterator_next(EquivalenceMemberIterator *it)
{
if (++it->index < list_length(it->ec_members))
return list_nth_node(EquivalenceMember, it->ec_members, it->index);
@@ -3464,17 +3456,17 @@ eclass_all_member_iterator_for_relids_next(EquivalenceAllMemberIterator *it)
}
/*
- * dispose_eclass_all_member_iterator_for_relids
+ * dispose_eclass_member_iterator
* Free any memory allocated by the iterator.
*/
void
-dispose_eclass_all_member_iterator_for_relids(EquivalenceAllMemberIterator *it)
+dispose_eclass_member_iterator(EquivalenceMemberIterator *it)
{
/*
* XXX Should we use list_free()? I decided to use this style to take
* advantage of speculative execution.
*/
- if (unlikely(it->modified))
+ if (unlikely(it->list_is_copy))
pfree(it->ec_members);
}
@@ -3532,7 +3524,7 @@ generate_implied_equalities_for_column(PlannerInfo *root,
EquivalenceClass *cur_ec = (EquivalenceClass *) list_nth(root->eq_classes, i);
EquivalenceMember *cur_em;
ListCell *lc2;
- EquivalenceAllMemberIterator it;
+ EquivalenceMemberIterator it;
/* Sanity check eclass_indexes only contain ECs for rel */
Assert(is_child_rel || bms_is_subset(rel->relids, cur_ec->ec_relids));
@@ -3554,14 +3546,14 @@ generate_implied_equalities_for_column(PlannerInfo *root,
* corner cases, so for now we live with just reporting the first
* match. See also get_eclass_for_sort_expr.)
*/
- setup_eclass_all_member_iterator_for_relids(&it, root, cur_ec, rel->relids);
- while ((cur_em = eclass_all_member_iterator_for_relids_next(&it)) != NULL)
+ setup_eclass_member_iterator_with_children(&it, root, cur_ec, rel->relids);
+ while ((cur_em = eclass_member_iterator_next(&it)) != NULL)
{
if (bms_equal(cur_em->em_relids, rel->relids) &&
callback(root, rel, cur_ec, cur_em, callback_arg))
break;
}
- dispose_eclass_all_member_iterator_for_relids(&it);
+ dispose_eclass_member_iterator(&it);
if (!cur_em)
continue;
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 38f7322caf9..c206f260633 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -3756,7 +3756,7 @@ match_pathkeys_to_index(PlannerInfo *root, IndexOptInfo *index, List *pathkeys,
{
PathKey *pathkey = (PathKey *) lfirst(lc1);
bool found = false;
- EquivalenceAllMemberIterator it;
+ EquivalenceMemberIterator it;
EquivalenceMember *member;
@@ -3777,9 +3777,9 @@ match_pathkeys_to_index(PlannerInfo *root, IndexOptInfo *index, List *pathkeys,
* be considered to match more than one pathkey list, which is OK
* here. See also get_eclass_for_sort_expr.)
*/
- setup_eclass_all_member_iterator_for_relids(&it, root, pathkey->pk_eclass,
- index->rel->relids);
- while ((member = eclass_all_member_iterator_for_relids_next(&it)) != NULL)
+ setup_eclass_member_iterator_with_children(&it, root, pathkey->pk_eclass,
+ index->rel->relids);
+ while ((member = eclass_member_iterator_next(&it)) != NULL)
{
int indexcol;
@@ -3815,7 +3815,7 @@ match_pathkeys_to_index(PlannerInfo *root, IndexOptInfo *index, List *pathkeys,
if (found) /* don't want to look at remaining members */
break;
}
- dispose_eclass_all_member_iterator_for_relids(&it);
+ dispose_eclass_member_iterator(&it);
/*
* Return the matches found so far when this pathkey couldn't be
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index eff5d93aa3a..163923072df 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -6201,6 +6201,7 @@ make_incrementalsort(Plan *lefttree, int numCols, int nPresortedCols,
* adjusts the plan targetlist if needed to add resjunk sort columns.
*
* Input parameters:
+ * 'root' is the PlannerInfo context
* 'lefttree' is the plan node which yields input tuples
* 'pathkeys' is the list of pathkeys by which the result is to be sorted
* 'relids' identifies the child relation being sorted, if any
@@ -6411,6 +6412,7 @@ prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
* make_sort_from_pathkeys
* Create sort plan to sort according to given pathkeys
*
+ * 'root' is the PlannerInfo context
* 'lefttree' is the node which yields input tuples
* 'pathkeys' is the list of pathkeys by which the result is to be sorted
* 'relids' is the set of relations required by prepare_sort_from_pathkeys()
@@ -6446,6 +6448,7 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
* make_incrementalsort_from_pathkeys
* Create sort plan to sort according to given pathkeys
*
+ * 'root' is the PlannerInfo context
* 'lefttree' is the node which yields input tuples
* 'pathkeys' is the list of pathkeys by which the result is to be sorted
* 'relids' is the set of relations required by prepare_sort_from_pathkeys()
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index 8dc51353791..aa37dda82b8 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -119,6 +119,11 @@ setup_simple_rel_arrays(PlannerInfo *root)
root->simple_rte_array[rti++] = rte;
}
+ /*
+ * eclass_indexes_array is always needed, even if there are no
+ * AppendRelInfos, because it stores indexes for RestrictInfos on base
+ * rels.
+ */
root->eclass_indexes_array = (EquivalenceClassIndexes *)
palloc0(size * sizeof(EquivalenceClassIndexes));
@@ -240,6 +245,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
rel->subplan_params = NIL;
rel->rel_parallel_workers = -1; /* set up in get_relation_info */
rel->amflags = 0;
+ rel->join_rel_list_index = -1;
rel->eclass_child_members = NIL;
rel->serverid = InvalidOid;
if (rte->rtekind == RTE_RELATION)
@@ -633,14 +639,14 @@ set_foreign_rel_properties(RelOptInfo *joinrel, RelOptInfo *outer_rel,
static void
add_join_rel(PlannerInfo *root, RelOptInfo *joinrel)
{
- /* GEQO requires us to append the new joinrel to the end of the list! */
- root->join_rel_list = lappend(root->join_rel_list, joinrel);
-
/*
* Store the index of this joinrel to use in
* add_child_join_rel_equivalences().
*/
- joinrel->join_rel_list_index = list_length(root->join_rel_list) - 1;
+ joinrel->join_rel_list_index = list_length(root->join_rel_list);
+
+ /* GEQO requires us to append the new joinrel to the end of the list! */
+ root->join_rel_list = lappend(root->join_rel_list, joinrel);
/* store it into the auxiliary hashtable if there is one. */
if (root->join_rel_hash)
@@ -754,6 +760,7 @@ build_join_rel(PlannerInfo *root,
joinrel->subplan_params = NIL;
joinrel->rel_parallel_workers = -1;
joinrel->amflags = 0;
+ joinrel->join_rel_list_index = -1;
joinrel->eclass_child_members = NIL;
joinrel->serverid = InvalidOid;
joinrel->userid = InvalidOid;
@@ -942,6 +949,7 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel,
joinrel->subroot = NULL;
joinrel->subplan_params = NIL;
joinrel->amflags = 0;
+ joinrel->join_rel_list_index = -1;
joinrel->eclass_child_members = NIL;
joinrel->serverid = InvalidOid;
joinrel->userid = InvalidOid;
@@ -1505,7 +1513,8 @@ fetch_upper_rel(PlannerInfo *root, UpperRelationKind kind, Relids relids)
upperrel->cheapest_total_path = NULL;
upperrel->cheapest_unique_path = NULL;
upperrel->cheapest_parameterized_paths = NIL;
- upperrel->eclass_child_members = NIL; /* XXX Is this required? */
+ upperrel->join_rel_list_index = -1;
+ upperrel->eclass_child_members = NIL;
root->upper_rels[kind] = lappend(root->upper_rels[kind], upperrel);
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 899165b20d8..c7cf1328d7a 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -276,8 +276,8 @@ struct PlannerInfo
/*
* eclass_indexes_array is the same length as simple_rel_array and holds
- * the indexes of the corresponding rels for faster lookups of
- * RestrictInfo. See the EquivalenceClass comment for more details.
+ * the indexes of the corresponding rels for faster EquivalenceMember
+ * lookups. See the EquivalenceClass comment for more details.
*/
struct EquivalenceClassIndexes *eclass_indexes_array pg_node_attr(read_write_ignore);
@@ -1003,7 +1003,7 @@ typedef struct RelOptInfo
* information about a join rel
*/
/* index in root->join_rel_list of this rel */
- Index join_rel_list_index;
+ int join_rel_list_index;
/*
* EquivalenceMembers referencing this rel
@@ -1431,9 +1431,9 @@ typedef struct JoinDomain
*
* EquivalenceClass->ec_members can only have parent members, and child members
* are stored in RelOptInfos, from which those child members are translated. To
- * lookup child EquivalenceMembers, we use EquivalenceAllMemberIterator. See
+ * lookup child EquivalenceMembers, we use EquivalenceMemberIterator. See
* its comment for usage. The approach to lookup child members quickly is
- * described as setup_eclass_all_member_iterator_for_relids() comment.
+ * described as setup_eclass_member_iterator_with_children() comment.
*
* At various locations in the query planner, we must search for source and
* derived RestrictInfos regarding a given EquivalenceClass. For the common
@@ -1533,9 +1533,9 @@ typedef struct EquivalenceMember
} EquivalenceMember;
/*
- * EquivalenceAllMemberIterator
+ * EquivalenceMemberIterator
*
- * EquivalenceAllMemberIterator is designed to iterate over all parent
+ * EquivalenceMemberIterator is designed to iterate over all parent
* EquivalenceMembers and child members associated with the given 'ec' that
* are relevant to the specified 'relids'. In particular, it iterates over:
* - All parent members stored directly in ec->ec_members.
@@ -1551,23 +1551,23 @@ typedef struct EquivalenceMember
* PlannerInfo *root = given;
* EquivalenceClass *ec = given;
* Relids rel = given;
- * EquivalenceAllMemberIterator it;
+ * EquivalenceMemberIterator it;
* EquivalenceMember *em;
*
- * setup_eclass_all_member_iterator_for_relids(&it, root, ec, rel);
- * while ((em = eclass_all_member_iterator_for_relids_next(&it)) != NULL)
+ * setup_eclass_member_iterator_with_children(&it, root, ec, rel);
+ * while ((em = eclass_member_iterator_next(&it)) != NULL)
* {
* use em ...;
* }
- * dispose_eclass_all_member_iterator_for_relids(&it);
+ * dispose_eclass_member_iterator(&it);
* -----
*/
typedef struct
{
int index; /* current index within 'ec_members'. */
- bool modified; /* is 'ec_members' a newly allocated one? */
+ bool list_is_copy; /* is 'ec_members' a newly allocated one? */
List *ec_members; /* parent and child members */
-} EquivalenceAllMemberIterator;
+} EquivalenceMemberIterator;
/*
* RestrictInfoIterator
diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h
index e8706b2774c..13c739965ba 100644
--- a/src/include/optimizer/paths.h
+++ b/src/include/optimizer/paths.h
@@ -185,12 +185,12 @@ extern void add_setop_child_rel_equivalences(PlannerInfo *root,
RelOptInfo *child_rel,
List *child_tlist,
List *setop_pathkeys);
-extern void setup_eclass_all_member_iterator_for_relids(EquivalenceAllMemberIterator *it,
- PlannerInfo *root,
- EquivalenceClass *ec,
- Relids relids);
-extern EquivalenceMember *eclass_all_member_iterator_for_relids_next(EquivalenceAllMemberIterator *it);
-extern void dispose_eclass_all_member_iterator_for_relids(EquivalenceAllMemberIterator *it);
+extern void setup_eclass_member_iterator_with_children(EquivalenceMemberIterator *it,
+ PlannerInfo *root,
+ EquivalenceClass *ec,
+ Relids relids);
+extern EquivalenceMember *eclass_member_iterator_next(EquivalenceMemberIterator *it);
+extern void dispose_eclass_member_iterator(EquivalenceMemberIterator *it);
extern List *generate_implied_equalities_for_column(PlannerInfo *root,
RelOptInfo *rel,
ec_matches_callback_type callback,
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 85b330df4dd..d2fc11ae19c 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -699,10 +699,10 @@ EphemeralNamedRelation
EphemeralNamedRelationData
EphemeralNamedRelationMetadata
EphemeralNamedRelationMetadataData
-EquivalenceAllMemberIterator
EquivalenceClass
EquivalenceClassIndexes
EquivalenceMember
+EquivalenceMemberIterator
ErrorContextCallback
ErrorData
ErrorSaveContext