diff-v33-v34.txt
text/plain
Filename: diff-v33-v34.txt
Type: text/plain
Part: 0
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index d4a26b59330..2eb0f16b0f6 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -7830,11 +7830,11 @@ EquivalenceMember *
find_em_for_rel(PlannerInfo *root, EquivalenceClass *ec, RelOptInfo *rel)
{
PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private;
- EquivalenceChildMemberIterator it;
+ EquivalenceAllMemberIterator it;
EquivalenceMember *em;
- setup_eclass_child_member_iterator(&it, root, ec, rel->relids);
- while ((em = eclass_child_member_iterator_next(&it)) != NULL)
+ setup_eclass_all_member_iterator_for_relids(&it, root, ec, rel->relids);
+ while ((em = eclass_all_member_iterator_for_relids_next(&it)) != NULL)
{
/*
* Note we require !bms_is_empty, else we'd accept constant
@@ -7846,7 +7846,7 @@ find_em_for_rel(PlannerInfo *root, EquivalenceClass *ec, RelOptInfo *rel)
is_foreign_expr(root, rel, em->em_expr))
return em;
}
- dispose_eclass_child_member_iterator(&it);
+ dispose_eclass_all_member_iterator_for_relids(&it);
return NULL;
}
diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c
index 21c2593e959..5aecf96cbb7 100644
--- a/src/backend/nodes/bitmapset.c
+++ b/src/backend/nodes/bitmapset.c
@@ -1302,8 +1302,8 @@ bms_join(Bitmapset *a, Bitmapset *b)
* It makes no difference in simple loop usage, but complex iteration logic
* might need such an ability.
*
- * NOTE: The routine here is similar to eclass_rinfo_iterator_next(). If you
- * change here, you should adjust the logic there.
+ * NOTE: The routine here is similar to eclass_rinfo_iterator_for_relids_next().
+ * If you change here, you should adjust the logic there.
*/
int
bms_next_member(const Bitmapset *a, int prevbit)
diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index e0f95da9a18..c6ecfb874c8 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -76,10 +76,10 @@ 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_transformed_child_version(EquivalenceChildMemberIterator *it,
- PlannerInfo *root,
- EquivalenceClass *ec,
- RelOptInfo *child_rel);
+static void add_eclass_child_members_to_iterator(EquivalenceAllMemberIterator *it,
+ PlannerInfo *root,
+ EquivalenceClass *ec,
+ RelOptInfo *child_rel);
static Bitmapset *get_eclass_indexes_for_relids(PlannerInfo *root,
Relids relids);
static Bitmapset *get_common_eclass_indexes(PlannerInfo *root, Relids relids1,
@@ -821,7 +821,7 @@ get_eclass_for_sort_expr(PlannerInfo *root,
foreach(lc1, root->eq_classes)
{
EquivalenceClass *cur_ec = (EquivalenceClass *) lfirst(lc1);
- EquivalenceChildMemberIterator it;
+ EquivalenceAllMemberIterator it;
EquivalenceMember *cur_em;
/*
@@ -837,8 +837,8 @@ get_eclass_for_sort_expr(PlannerInfo *root,
if (!equal(opfamilies, cur_ec->ec_opfamilies))
continue;
- setup_eclass_child_member_iterator(&it, root, cur_ec, rel);
- while ((cur_em = eclass_child_member_iterator_next(&it)) != NULL)
+ setup_eclass_all_member_iterator_for_relids(&it, root, cur_ec, rel);
+ while ((cur_em = eclass_all_member_iterator_for_relids_next(&it)) != NULL)
{
/*
* Ignore child members unless they match the request.
@@ -858,7 +858,7 @@ get_eclass_for_sort_expr(PlannerInfo *root,
equal(expr, cur_em->em_expr))
return cur_ec; /* Match! */
}
- dispose_eclass_child_member_iterator(&it);
+ dispose_eclass_all_member_iterator_for_relids(&it);
}
/* No match; does caller want a NULL result? */
@@ -970,15 +970,15 @@ find_ec_member_matching_expr(PlannerInfo *root, EquivalenceClass *ec,
Expr *expr,
Relids relids)
{
- EquivalenceChildMemberIterator it;
+ EquivalenceAllMemberIterator it;
EquivalenceMember *em;
/* We ignore binary-compatible relabeling on both ends */
while (expr && IsA(expr, RelabelType))
expr = ((RelabelType *) expr)->arg;
- setup_eclass_child_member_iterator(&it, root, ec, relids);
- while ((em = eclass_child_member_iterator_next(&it)) != NULL)
+ setup_eclass_all_member_iterator_for_relids(&it, root, ec, relids);
+ while ((em = eclass_all_member_iterator_for_relids_next(&it)) != NULL)
{
Expr *emexpr;
@@ -1006,7 +1006,7 @@ find_ec_member_matching_expr(PlannerInfo *root, EquivalenceClass *ec,
if (equal(emexpr, expr))
return em;
}
- dispose_eclass_child_member_iterator(&it);
+ dispose_eclass_all_member_iterator_for_relids(&it);
return NULL;
}
@@ -1049,7 +1049,7 @@ find_computable_ec_member(PlannerInfo *root,
bool require_parallel_safe)
{
List *exprvars;
- EquivalenceChildMemberIterator it;
+ EquivalenceAllMemberIterator it;
EquivalenceMember *em;
/*
@@ -1064,8 +1064,8 @@ find_computable_ec_member(PlannerInfo *root,
PVC_INCLUDE_PLACEHOLDERS |
PVC_INCLUDE_CONVERTROWTYPES);
- setup_eclass_child_member_iterator(&it, root, ec, relids);
- while ((em = eclass_child_member_iterator_next(&it)) != NULL)
+ setup_eclass_all_member_iterator_for_relids(&it, root, ec, relids);
+ while ((em = eclass_all_member_iterator_for_relids_next(&it)) != NULL)
{
List *emvars;
ListCell *lc2;
@@ -1110,7 +1110,7 @@ find_computable_ec_member(PlannerInfo *root,
return em; /* found usable expression */
}
- dispose_eclass_child_member_iterator(&it);
+ dispose_eclass_all_member_iterator_for_relids(&it);
return NULL;
}
@@ -1777,7 +1777,7 @@ generate_join_implied_equalities_normal(PlannerInfo *root,
List *new_members = NIL;
List *outer_members = NIL;
List *inner_members = NIL;
- EquivalenceChildMemberIterator it;
+ EquivalenceAllMemberIterator it;
EquivalenceMember *cur_em;
/*
@@ -1789,8 +1789,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_child_member_iterator(&it, root, ec, join_relids);
- while ((cur_em = eclass_child_member_iterator_next(&it)) != NULL)
+ setup_eclass_all_member_iterator_for_relids(&it, root, ec, join_relids);
+ while ((cur_em = eclass_all_member_iterator_for_relids_next(&it)) != NULL)
{
/*
* We don't need to check explicitly for child EC members. This test
@@ -1807,7 +1807,7 @@ generate_join_implied_equalities_normal(PlannerInfo *root,
else
new_members = lappend(new_members, cur_em);
}
- dispose_eclass_child_member_iterator(&it);
+ dispose_eclass_all_member_iterator_for_relids(&it);
/*
* First, select the joinclause if needed. We can equate any one outer
@@ -1957,9 +1957,9 @@ generate_join_implied_equalities_broken(PlannerInfo *root,
RestrictInfo *restrictinfo;
RestrictInfoIterator iter;
- setup_eclass_rinfo_iterator(&iter, root, ec, nominal_join_relids, true,
- false);
- while ((restrictinfo = eclass_rinfo_iterator_next(&iter)) != NULL)
+ setup_eclass_rinfo_iterator_for_relids(&iter, root, ec, nominal_join_relids, true,
+ false);
+ while ((restrictinfo = eclass_rinfo_iterator_for_relids_next(&iter)) != NULL)
{
Relids clause_relids = restrictinfo->required_relids;
@@ -1968,7 +1968,7 @@ generate_join_implied_equalities_broken(PlannerInfo *root,
!bms_is_subset(clause_relids, nominal_inner_relids))
result = lappend(result, restrictinfo);
}
- dispose_eclass_rinfo_iterator(&iter);
+ dispose_eclass_rinfo_iterator_for_relids(&iter);
/*
* If we have to translate, just brute-force apply adjust_appendrel_attrs
@@ -2054,10 +2054,10 @@ create_join_clause(PlannerInfo *root,
* it's not identical, it'd better have the same effects, or the operator
* families we're using are broken.
*/
- setup_eclass_rinfo_iterator(&iter, root, ec,
- bms_union(leftem->em_relids, rightem->em_relids),
- true, true);
- while ((rinfo = eclass_rinfo_iterator_next(&iter)) != NULL)
+ setup_eclass_rinfo_iterator_for_relids(&iter, root, ec,
+ bms_union(leftem->em_relids, rightem->em_relids),
+ true, true);
+ while ((rinfo = eclass_rinfo_iterator_for_relids_next(&iter)) != NULL)
{
if (rinfo->left_em == leftem &&
rinfo->right_em == rightem &&
@@ -2068,12 +2068,12 @@ create_join_clause(PlannerInfo *root,
rinfo->parent_ec == parent_ec)
return rinfo;
}
- dispose_eclass_rinfo_iterator(&iter);
+ dispose_eclass_rinfo_iterator_for_relids(&iter);
- setup_eclass_rinfo_iterator(&iter, root, ec,
- bms_union(leftem->em_relids, rightem->em_relids),
- false, true);
- while ((rinfo = eclass_rinfo_iterator_next(&iter)) != NULL)
+ setup_eclass_rinfo_iterator_for_relids(&iter, root, ec,
+ bms_union(leftem->em_relids, rightem->em_relids),
+ false, true);
+ while ((rinfo = eclass_rinfo_iterator_for_relids_next(&iter)) != NULL)
{
if (rinfo->left_em == leftem &&
rinfo->right_em == rightem &&
@@ -2084,7 +2084,7 @@ create_join_clause(PlannerInfo *root,
rinfo->parent_ec == parent_ec)
return rinfo;
}
- dispose_eclass_rinfo_iterator(&iter);
+ dispose_eclass_rinfo_iterator_for_relids(&iter);
/*
* Not there, so build it, in planner context so we can re-use it. (Not
@@ -3159,12 +3159,12 @@ 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
- * EquivalenceChildMemberIterator. Since the iterator
- * needs EquivalenceMembers whose em_relids has child
- * relations, skipping the update of this inverted index
- * allows for faster iteration.
+ * EquivalenceAllMemberIterator. Since the iterator needs
+ * EquivalenceMembers whose em_relids has child relations,
+ * skipping the update of this inverted index allows for
+ * faster iteration.
*/
- if (root->top_parent_relid_array[j] == -1)
+ if (root->append_rel_array[j] == NULL)
continue;
indexes->joinrel_indexes =
bms_add_member(indexes->joinrel_indexes,
@@ -3203,7 +3203,6 @@ add_setop_child_rel_equivalences(PlannerInfo *root, RelOptInfo *child_rel,
EquivalenceMember *parent_em;
EquivalenceMember *child_em;
PathKey *pk;
- Index parent_relid;
if (tle->resjunk)
continue;
@@ -3232,28 +3231,26 @@ add_setop_child_rel_equivalences(PlannerInfo *root, RelOptInfo *child_rel,
/*
* Make an UNION parent-child relationship between parent_em and
* child_rel->relid. We record this relationship in
- * root->top_parent_relid_array, which generally has AppendRelInfo
+ * root->append_rel_array, which generally has AppendRelInfo
* relationships. We use the same array here to retrieve UNION child
* members.
*
+ * XXX Here we create a dummy AppendRelInfo object to know that the
+ * relation of 'child_rel->relid' is a child and there are some
+ * children because root->append_rel_array is not NULL. However this
+ * is just a workaround. We must consider better way.
+ *
* XXX Here we treat the first member of parent_em->em_relids as a
* parent of child_rel. Is this correct? What happens if
* parent_em->em_relids has two or more members?
*/
- parent_relid = bms_next_member(parent_em->em_relids, -1);
- if (root->top_parent_relid_array == NULL)
- {
- /*
- * If the array is NULL, allocate it here.
- */
- root->top_parent_relid_array = (Index *)
- palloc(root->simple_rel_array_size * sizeof(Index));
- MemSet(root->top_parent_relid_array, -1,
- sizeof(Index) * root->simple_rel_array_size);
- }
- Assert(root->top_parent_relid_array[child_rel->relid] == -1 ||
- root->top_parent_relid_array[child_rel->relid] == parent_relid);
- root->top_parent_relid_array[child_rel->relid] = parent_relid;
+ if (root->append_rel_array == NULL)
+ root->append_rel_array = palloc0_array(AppendRelInfo *, root->simple_rel_array_size);
+ root->append_rel_array[child_rel->relid] = makeNode(AppendRelInfo);
+ root->append_rel_array[child_rel->relid]->parent_relid =
+ bms_next_member(parent_em->em_relids, -1);
+ root->append_rel_array[child_rel->relid]->child_relid =
+ child_rel->relid;
lc2 = lnext(setop_pathkeys, lc2);
}
@@ -3269,18 +3266,32 @@ add_setop_child_rel_equivalences(PlannerInfo *root, RelOptInfo *child_rel,
}
/*
- * setup_eclass_child_member_iterator
- * Setup an EquivalenceChildMemberIterator 'it' so that it can iterate over
- * EquivalenceMembers in 'ec'.
+ * setup_eclass_all_member_iterator_for_relids
+ * Setup an EquivalenceAllMemberIterator 'it' to iterate over all parent
+ * EquivalenceMembers and child members associated with the given 'ec' that
+ * are relevant to the specified 'relids'.
*
- * Once used, the caller should dispose of the iterator by calling
- * dispose_eclass_child_member_iterator().
+ * This iterator returns:
+ * - All parent members stored directly in ec->ec_members.
+ * - The child members whose em_relids is a subset of the given 'relids'.
+ *
+ * Note:
+ * - The iterator may return false positives, i.e., child members whose
+ * 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().
+ *
+ * Parameters:
+ * root - The PlannerInfo context.
+ * ec - The EquivalenceClass from which to iterate members.
+ * relids - The Relids used to filter for relevant child members.
*/
void
-setup_eclass_child_member_iterator(EquivalenceChildMemberIterator *it,
- PlannerInfo *root,
- EquivalenceClass *ec,
- Relids relids)
+setup_eclass_all_member_iterator_for_relids(EquivalenceAllMemberIterator *it,
+ PlannerInfo *root,
+ EquivalenceClass *ec,
+ Relids relids)
{
Bitmapset *matching_indexes;
int i;
@@ -3296,7 +3307,7 @@ setup_eclass_child_member_iterator(EquivalenceChildMemberIterator *it,
* If there are no child relations, there is nothing to do. This
* effectively avoids regression for non-partitioned cases.
*/
- if (root->top_parent_relid_array == NULL)
+ if (root->append_rel_array == NULL)
return;
/*
@@ -3339,7 +3350,7 @@ setup_eclass_child_member_iterator(EquivalenceChildMemberIterator *it,
/*
* If this relation is a parent, we don't have to do anything.
*/
- if (root->top_parent_relid_array[i] == -1)
+ if (root->append_rel_array[i] == NULL)
continue;
/*
@@ -3347,7 +3358,7 @@ setup_eclass_child_member_iterator(EquivalenceChildMemberIterator *it,
*/
child_rel = root->simple_rel_array[i];
if (child_rel != NULL)
- add_transformed_child_version(it, root, ec, child_rel);
+ add_eclass_child_members_to_iterator(it, root, ec, child_rel);
/*
* Union indexes for join rels.
@@ -3373,7 +3384,7 @@ setup_eclass_child_member_iterator(EquivalenceChildMemberIterator *it,
* child EquivalenceMembers it holds should never be a subset either.
*/
if (bms_is_subset(child_joinrel->relids, relids))
- add_transformed_child_version(it, root, ec, child_joinrel);
+ add_eclass_child_members_to_iterator(it, root, ec, child_joinrel);
#ifdef USE_ASSERT_CHECKING
else
{
@@ -3400,18 +3411,18 @@ setup_eclass_child_member_iterator(EquivalenceChildMemberIterator *it,
}
/*
- * add_transformed_child_version
- * Add a transformed EquivalenceMember referencing the given child_rel to
- * the iterator.
+ * add_eclass_child_members_to_iterator
+ * Add a child EquivalenceMember referencing the given child_rel to
+ * the iterator from RelOptInfo.
*
* This function is expected to be called only from
- * setup_eclass_child_member_iterator().
+ * setup_eclass_all_member_iterator_for_relids().
*/
static void
-add_transformed_child_version(EquivalenceChildMemberIterator *it,
- PlannerInfo *root,
- EquivalenceClass *ec,
- RelOptInfo *child_rel)
+add_eclass_child_members_to_iterator(EquivalenceAllMemberIterator *it,
+ PlannerInfo *root,
+ EquivalenceClass *ec,
+ RelOptInfo *child_rel)
{
ListCell *lc;
@@ -3439,13 +3450,13 @@ add_transformed_child_version(EquivalenceChildMemberIterator *it,
}
/*
- * eclass_child_member_iterator_next
- * Get a next EquivalenceMember from an EquivalenceChildMemberIterator 'it'
- * that was setup by setup_eclass_child_member_iterator(). NULL is returned
- * if there are no members left.
+ * 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
+ * returned if there are no members left.
*/
EquivalenceMember *
-eclass_child_member_iterator_next(EquivalenceChildMemberIterator *it)
+eclass_all_member_iterator_for_relids_next(EquivalenceAllMemberIterator *it)
{
if (++it->index < list_length(it->ec_members))
return list_nth_node(EquivalenceMember, it->ec_members, it->index);
@@ -3453,11 +3464,11 @@ eclass_child_member_iterator_next(EquivalenceChildMemberIterator *it)
}
/*
- * dispose_eclass_child_member_iterator
+ * dispose_eclass_all_member_iterator_for_relids
* Free any memory allocated by the iterator.
*/
void
-dispose_eclass_child_member_iterator(EquivalenceChildMemberIterator *it)
+dispose_eclass_all_member_iterator_for_relids(EquivalenceAllMemberIterator *it)
{
/*
* XXX Should we use list_free()? I decided to use this style to take
@@ -3521,7 +3532,7 @@ generate_implied_equalities_for_column(PlannerInfo *root,
EquivalenceClass *cur_ec = (EquivalenceClass *) list_nth(root->eq_classes, i);
EquivalenceMember *cur_em;
ListCell *lc2;
- EquivalenceChildMemberIterator it;
+ EquivalenceAllMemberIterator it;
/* Sanity check eclass_indexes only contain ECs for rel */
Assert(is_child_rel || bms_is_subset(rel->relids, cur_ec->ec_relids));
@@ -3543,14 +3554,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_child_member_iterator(&it, root, cur_ec, rel->relids);
- while ((cur_em = eclass_child_member_iterator_next(&it)) != NULL)
+ 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)
{
if (bms_equal(cur_em->em_relids, rel->relids) &&
callback(root, rel, cur_ec, cur_em, callback_arg))
break;
}
- dispose_eclass_child_member_iterator(&it);
+ dispose_eclass_all_member_iterator_for_relids(&it);
if (!cur_em)
continue;
@@ -3921,20 +3932,21 @@ get_common_eclass_indexes(PlannerInfo *root, Relids relids1, Relids relids2)
}
/*
- * setup_eclass_rinfo_iterator
- * Setup a RestrictInfoIterator 'iter' so that it can iterate over
- * RestrictInfos. We iterate through root->eq_sources if 'is_source' is
- * true, or root->eq_derives otherwise. The members must be from 'ec' and
- * satisfy "bms_is_subset(relids, rinfo->clause_relids)" if 'is_strict' is
- * true, or "bms_overlap(relids, rinfo->clause_relids)" otherwise.
+ * setup_eclass_rinfo_iterator_for_relids
+ * Setup a RestrictInfoIterator 'iter' to iterate over RestrictInfos
+ * associated with the given 'ec'. It iterates through root->eq_sources if
+ * 'is_source' is true, or root->eq_derives otherwise. The members must be
+ * from 'ec' and satisfy "bms_is_subset(relids, rinfo->clause_relids)" if
+ * 'is_strict' is true, or "bms_overlap(relids, rinfo->clause_relids)"
+ * otherwise.
*
* Once used, the caller should dispose of the iterator by calling
- * dispose_eclass_rinfo_iterator().
+ * dispose_eclass_rinfo_iterator_for_relids().
*/
void
-setup_eclass_rinfo_iterator(RestrictInfoIterator *iter, PlannerInfo *root,
- EquivalenceClass *ec, Relids relids,
- bool is_source, bool is_strict)
+setup_eclass_rinfo_iterator_for_relids(RestrictInfoIterator *iter, PlannerInfo *root,
+ EquivalenceClass *ec, Relids relids,
+ bool is_source, bool is_strict)
{
iter->root = root;
iter->ec = ec;
@@ -3947,13 +3959,13 @@ setup_eclass_rinfo_iterator(RestrictInfoIterator *iter, PlannerInfo *root,
}
/*
- * eclass_rinfo_iterator_next
+ * eclass_rinfo_iterator_for_relids_next
* Get a next RestrictInfo from an RestrictInfoIterator 'iter' that was
- * setup by setup_eclass_rinfo_iterator(). NULL is returned if there are no
- * members left.
+ * setup by setup_eclass_rinfo_iterator_for_relids(). NULL is returned if
+ * there are no members left.
*/
RestrictInfo *
-eclass_rinfo_iterator_next(RestrictInfoIterator *iter)
+eclass_rinfo_iterator_for_relids_next(RestrictInfoIterator *iter)
{
RestrictInfo *rinfo;
bitmapword mask;
@@ -4074,11 +4086,11 @@ eclass_rinfo_iterator_next(RestrictInfoIterator *iter)
}
/*
- * dispose_eclass_rinfo_iterator
+ * dispose_eclass_rinfo_iterator_for_relids
* Free any memory allocated by the iterator.
*/
void
-dispose_eclass_rinfo_iterator(RestrictInfoIterator *iter)
+dispose_eclass_rinfo_iterator_for_relids(RestrictInfoIterator *iter)
{
/* Do nothing */
}
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 30e443d1554..38f7322caf9 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;
- EquivalenceChildMemberIterator it;
+ EquivalenceAllMemberIterator 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_child_member_iterator(&it, root, pathkey->pk_eclass,
- index->rel->relids);
- while ((member = eclass_child_member_iterator_next(&it)) != NULL)
+ 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)
{
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_child_member_iterator(&it);
+ dispose_eclass_all_member_iterator_for_relids(&it);
/*
* Return the matches found so far when this pathkey couldn't be
diff --git a/src/backend/optimizer/util/inherit.c b/src/backend/optimizer/util/inherit.c
index 08cd39a6c85..17e51cd75d7 100644
--- a/src/backend/optimizer/util/inherit.c
+++ b/src/backend/optimizer/util/inherit.c
@@ -470,7 +470,6 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte,
RelationGetRelid(parentrel);
Oid childOID = RelationGetRelid(childrel);
RangeTblEntry *childrte;
- Index topParentRTindex;
Index childRTindex;
AppendRelInfo *appinfo;
TupleDesc child_tupdesc;
@@ -578,23 +577,6 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte,
Assert(root->append_rel_array[childRTindex] == NULL);
root->append_rel_array[childRTindex] = appinfo;
- /*
- * Find a top parent rel's index and save it to top_parent_relid_array.
- */
- if (root->top_parent_relid_array == NULL)
- {
- root->top_parent_relid_array =
- (Index *) palloc(root->simple_rel_array_size * sizeof(Index));
- MemSet(root->top_parent_relid_array, -1,
- sizeof(Index) * root->simple_rel_array_size);
- }
- Assert(root->top_parent_relid_array[childRTindex] == -1);
- topParentRTindex = parentRTindex;
- while (root->append_rel_array[topParentRTindex] != NULL &&
- root->append_rel_array[topParentRTindex]->parent_relid != 0)
- topParentRTindex = root->append_rel_array[topParentRTindex]->parent_relid;
- root->top_parent_relid_array[childRTindex] = topParentRTindex;
-
/*
* Build a PlanRowMark if parent is marked FOR UPDATE/SHARE.
*/
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index ff25cd86448..8dc51353791 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -126,16 +126,11 @@ setup_simple_rel_arrays(PlannerInfo *root)
if (root->append_rel_list == NIL)
{
root->append_rel_array = NULL;
- root->top_parent_relid_array = NULL;
return;
}
root->append_rel_array = (AppendRelInfo **)
palloc0(size * sizeof(AppendRelInfo *));
- root->top_parent_relid_array = (Index *)
- palloc(size * sizeof(Index));
- MemSet(root->top_parent_relid_array, -1,
- sizeof(Index) * size);
/*
* append_rel_array is filled with any already-existing AppendRelInfos,
@@ -156,27 +151,6 @@ setup_simple_rel_arrays(PlannerInfo *root)
root->append_rel_array[child_relid] = appinfo;
}
-
- /*
- * Find a top parent rel's relid for each AppendRelInfo. We cannot do this
- * in the last foreach loop because there may be multi-level parent-child
- * relations.
- */
- for (int i = 0; i < size; i++)
- {
- int top_parent_relid;
-
- if (root->append_rel_array[i] == NULL)
- continue;
-
- top_parent_relid = root->append_rel_array[i]->parent_relid;
-
- while (root->append_rel_array[top_parent_relid] != NULL &&
- root->append_rel_array[top_parent_relid]->parent_relid != 0)
- top_parent_relid = root->append_rel_array[top_parent_relid]->parent_relid;
-
- root->top_parent_relid_array[i] = top_parent_relid;
- }
}
/*
@@ -204,27 +178,12 @@ expand_planner_arrays(PlannerInfo *root, int add_size)
repalloc0_array(root->simple_rte_array, RangeTblEntry *, root->simple_rel_array_size, new_size);
if (root->append_rel_array)
- {
root->append_rel_array =
repalloc0_array(root->append_rel_array, AppendRelInfo *, root->simple_rel_array_size, new_size);
- root->top_parent_relid_array =
- repalloc_array(root->top_parent_relid_array, Index, new_size);
- MemSet(root->top_parent_relid_array + root->simple_rel_array_size, -1,
- sizeof(Index) * add_size);
- }
else
- {
root->append_rel_array =
palloc0_array(AppendRelInfo *, new_size);
- /*
- * We do not allocate top_parent_relid_array here so that
- * setup_eclass_child_member_iterator() can early find all of the
- * given Relids are top-level.
- */
- root->top_parent_relid_array = NULL;
- }
-
root->eclass_indexes_array =
repalloc0_array(root->eclass_indexes_array, EquivalenceClassIndexes, root->simple_rel_array_size, new_size);
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 3f0d686108c..0abd8dd4d9b 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -278,14 +278,6 @@ struct PlannerInfo
*/
struct EquivalenceClassIndexes *eclass_indexes_array pg_node_attr(read_write_ignore);
- /*
- * top_parent_relid_array is the same length as simple_rel_array and holds
- * the top-level parent indexes of the corresponding rels within
- * simple_rel_array. The element can be -1 if the rel has no parents,
- * i.e., is itself in a top-level.
- */
- Index *top_parent_relid_array pg_node_attr(read_write_ignore);
-
/*
* all_baserels is a Relids set of all base relids (but not joins or
* "other" rels) in the query. This is computed in deconstruct_jointree.
@@ -1436,9 +1428,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 EquivalenceChildMemberIterator. See
+ * lookup child EquivalenceMembers, we use EquivalenceAllMemberIterator. See
* its comment for usage. The approach to lookup child members quickly is
- * described as iterate_child_rel_equivalences() comment.
+ * described as setup_eclass_all_member_iterator_for_relids() comment.
*
* At various locations in the query planner, we must search for source and
* derived RestrictInfos regarding a given EquivalenceClass. For the common
@@ -1538,28 +1530,33 @@ typedef struct EquivalenceMember
} EquivalenceMember;
/*
- * EquivalenceChildMemberIterator
+ * EquivalenceAllMemberIterator
*
- * EquivalenceClass contains only parent members. Use the
- * EquivalenceChildMemberIterator to iterate over child members whose em_relids
- * is a subset of the specified 'child_relids' in addition to the parent
- * members. Note that the iterator may yield false positives, so callers must
- * verify that each member satisfies the condition.
+ * EquivalenceAllMemberIterator 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.
+ * - The child members whose em_relids is a subset of the given 'relids'.
*
- * The most common way to use this struct is as follows:
+ * Note:
+ * - The iterator may return false positives, i.e., child members whose
+ * em_relids is not a subset. So the caller must check that they satisfy
+ * the desired condition.
+ *
+ * The most common way to use this iterator is as follows:
* -----
* PlannerInfo *root = given;
* EquivalenceClass *ec = given;
* Relids rel = given;
- * EquivalenceChildMemberIterator it;
+ * EquivalenceAllMemberIterator it;
* EquivalenceMember *em;
*
- * setup_eclass_child_member_iterator(&it, root, ec, rel);
- * while ((em = eclass_child_member_iterator_next(&it)) != NULL)
+ * setup_eclass_all_member_iterator_for_relids(&it, root, ec, rel);
+ * while ((em = eclass_all_member_iterator_for_relids_next(&it)) != NULL)
* {
* use em ...;
* }
- * dispose_eclass_child_member_iterator(&it);
+ * dispose_eclass_all_member_iterator_for_relids(&it);
* -----
*/
typedef struct
@@ -1567,7 +1564,7 @@ typedef struct
int index; /* current index within 'ec_members'. */
bool modified; /* is 'ec_members' a newly allocated one? */
List *ec_members; /* parent and child members */
-} EquivalenceChildMemberIterator;
+} EquivalenceAllMemberIterator;
/*
* RestrictInfoIterator
@@ -1576,7 +1573,7 @@ typedef struct
* EquivalenceClass that satisfy a certain condition. You need to first
* initialize an iterator, and then use move next during the iteration. You
* can specify the condition during initialization. For more details, see the
- * comment in setup_eclass_rinfo_iterator().
+ * comment in setup_eclass_rinfo_iterator_for_relids().
*
* The most common way to use this struct is as follows:
* -----
@@ -1586,12 +1583,12 @@ typedef struct
* RestrictInfoIterator iter;
* RestrictInfo *rinfo;
*
- * setup_eclass_rinfo_iterator(&iter, root, ec, relids, true, true);
- * while ((rinfo = eclass_rinfo_iterator_next(&iter)) != NULL)
+ * setup_eclass_rinfo_iterator_for_relids(&iter, root, ec, relids, true, true);
+ * while ((rinfo = eclass_rinfo_iterator_for_relids_next(&iter)) != NULL)
* {
* use rinfo ...;
* }
- * dispose_eclass_rinfo_iterator(&iter);
+ * dispose_eclass_rinfo_iterator_for_relids(&iter);
* -----
*/
typedef struct
diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h
index 1361e20641a..e8706b2774c 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_child_member_iterator(EquivalenceChildMemberIterator *it,
- PlannerInfo *root,
- EquivalenceClass *ec,
- Relids relids);
-extern EquivalenceMember *eclass_child_member_iterator_next(EquivalenceChildMemberIterator *it);
-extern void dispose_eclass_child_member_iterator(EquivalenceChildMemberIterator *it);
+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 List *generate_implied_equalities_for_column(PlannerInfo *root,
RelOptInfo *rel,
ec_matches_callback_type callback,
@@ -206,14 +206,14 @@ extern bool eclass_useful_for_merging(PlannerInfo *root,
extern bool is_redundant_derived_clause(RestrictInfo *rinfo, List *clauselist);
extern bool is_redundant_with_indexclauses(RestrictInfo *rinfo,
List *indexclauses);
-extern void setup_eclass_rinfo_iterator(RestrictInfoIterator *iter,
- PlannerInfo *root,
- EquivalenceClass *ec,
- Relids relids,
- bool is_source,
- bool is_strict);
-extern RestrictInfo *eclass_rinfo_iterator_next(RestrictInfoIterator *iter);
-extern void dispose_eclass_rinfo_iterator(RestrictInfoIterator *iter);
+extern void setup_eclass_rinfo_iterator_for_relids(RestrictInfoIterator *iter,
+ PlannerInfo *root,
+ EquivalenceClass *ec,
+ Relids relids,
+ bool is_source,
+ bool is_strict);
+extern RestrictInfo *eclass_rinfo_iterator_for_relids_next(RestrictInfoIterator *iter);
+extern void dispose_eclass_rinfo_iterator_for_relids(RestrictInfoIterator *iter);
#ifdef USE_ASSERT_CHECKING
extern void verify_eclass_indexes(PlannerInfo *root,
EquivalenceClass *ec);
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 433577a3d8a..51d45b6677c 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -696,7 +696,7 @@ EphemeralNamedRelation
EphemeralNamedRelationData
EphemeralNamedRelationMetadata
EphemeralNamedRelationMetadataData
-EquivalenceChildMemberIterator
+EquivalenceAllMemberIterator
EquivalenceClass
EquivalenceClassIndexes
EquivalenceMember