From f145ef33bd40507148a31ba0a7c5d084c2d928c0 Mon Sep 17 00:00:00 2001 From: Yuya Watari Date: Tue, 27 Aug 2024 13:20:29 +0900 Subject: [PATCH v31 2/4] Resolve conflict with commit 66c0185 This commit resolves a conflict with 66c0185, which added add_setop_child_rel_equivalences(). The function creates child EquivalenceMembers to efficiently implement UNION queries. This commit adjusts our optimization to handle this type of child EquivalenceMembers based on UNION parent-child relationships. --- src/backend/optimizer/path/equivclass.c | 46 ++++++++++++++++++++----- src/backend/optimizer/util/inherit.c | 8 +++-- src/backend/optimizer/util/relnode.c | 8 +++-- src/include/nodes/pathnodes.h | 2 +- 4 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c index aebf809a645..26834953a89 100644 --- a/src/backend/optimizer/path/equivclass.c +++ b/src/backend/optimizer/path/equivclass.c @@ -2976,7 +2976,7 @@ add_child_join_rel_equivalences(PlannerInfo *root, * relations, skipping the update of this inverted index * allows for faster iteration. */ - if (root->top_parent_relid_array[j] == 0) + if (root->top_parent_relid_array[j] == -1) continue; indexes->joinrel_indexes = bms_add_member(indexes->joinrel_indexes, @@ -3013,7 +3013,9 @@ add_setop_child_rel_equivalences(PlannerInfo *root, RelOptInfo *child_rel, { TargetEntry *tle = lfirst_node(TargetEntry, lc); EquivalenceMember *parent_em; + EquivalenceMember *child_em; PathKey *pk; + Index parent_relid; if (tle->resjunk) continue; @@ -3030,12 +3032,40 @@ add_setop_child_rel_equivalences(PlannerInfo *root, RelOptInfo *child_rel, * likewise, the JoinDomain can be that of the initial member of the * Pathkey's EquivalenceClass. */ - add_parent_eq_member(pk->pk_eclass, - tle->expr, - child_rel->relids, - parent_em->em_jdomain, - parent_em, - exprType((Node *) tle->expr)); + child_em = make_eq_member(pk->pk_eclass, + tle->expr, + child_rel->relids, + parent_em->em_jdomain, + parent_em, + exprType((Node *) tle->expr)); + child_rel->eclass_child_members = + lappend(child_rel->eclass_child_members, child_em); + + /* + * 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 + * relationships. We use the same array here to retrieve UNION child + * members. + * + * 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; lc2 = lnext(setop_pathkeys, lc2); } @@ -3121,7 +3151,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] == 0) + if (root->top_parent_relid_array[i] == -1) continue; /* diff --git a/src/backend/optimizer/util/inherit.c b/src/backend/optimizer/util/inherit.c index 734d54a7305..08cd39a6c85 100644 --- a/src/backend/optimizer/util/inherit.c +++ b/src/backend/optimizer/util/inherit.c @@ -582,9 +582,13 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte, * 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 *) palloc0(root->simple_rel_array_size * sizeof(Index)); - Assert(root->top_parent_relid_array[childRTindex] == 0); + (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) diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index a07bca8431b..c8e535617b8 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -133,7 +133,9 @@ setup_simple_rel_arrays(PlannerInfo *root) root->append_rel_array = (AppendRelInfo **) palloc0(size * sizeof(AppendRelInfo *)); root->top_parent_relid_array = (Index *) - palloc0(size * sizeof(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, @@ -206,7 +208,9 @@ expand_planner_arrays(PlannerInfo *root, int add_size) root->append_rel_array = repalloc0_array(root->append_rel_array, AppendRelInfo *, root->simple_rel_array_size, new_size); root->top_parent_relid_array = - repalloc0_array(root->top_parent_relid_array, Index, root->simple_rel_array_size, new_size); + 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 { diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 6bdac3bad2c..645c5898d4d 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -276,7 +276,7 @@ struct PlannerInfo /* * 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 zero if the rel has no parents, + * 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); -- 2.45.2.windows.1