v27-0005-Resolve-conflict-with-commit-66c0185.patch
application/octet-stream
Filename: v27-0005-Resolve-conflict-with-commit-66c0185.patch
Type: application/octet-stream
Part: 4
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v27-0005
Subject: Resolve conflict with commit 66c0185
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/equivclass.c | 45 | 6 |
| src/backend/optimizer/util/inherit.c | 6 | 2 |
| src/backend/optimizer/util/relnode.c | 7 | 3 |
| src/include/nodes/pathnodes.h | 1 | 1 |
From 44f04135490cd42ba79e3537183bca4f8e0c44ea Mon Sep 17 00:00:00 2001
From: Yuya Watari <watari.yuya@gmail.com>
Date: Tue, 27 Aug 2024 13:20:29 +0900
Subject: [PATCH v27 5/5] 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 | 51 ++++++++++++++++++++++---
src/backend/optimizer/util/inherit.c | 8 +++-
src/backend/optimizer/util/relnode.c | 10 +++--
src/include/nodes/pathnodes.h | 2 +-
4 files changed, 59 insertions(+), 12 deletions(-)
diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index c54ebd7432..5ff55d71ee 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -3250,7 +3250,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;
@@ -3267,12 +3269,49 @@ 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);
+
+ /*
+ * We save the knowledge that 'child_em' can be translated using
+ * 'child_rel'. This knowledge is useful for
+ * add_transformed_child_version() to find child members from the
+ * given Relids.
+ */
+ parent_em->em_child_relids =
+ bms_add_member(parent_em->em_child_relids, child_rel->relid);
+
+ /*
+ * 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);
}
diff --git a/src/backend/optimizer/util/inherit.c b/src/backend/optimizer/util/inherit.c
index 3c2198ea5b..7b2390687e 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 c219de44d7..5ea9a41008 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
{
@@ -1608,7 +1612,7 @@ find_relids_top_parents_slow(PlannerInfo *root, Relids relids)
{
int top_parent_relid = (int) top_parent_relid_array[i];
- if (top_parent_relid == 0)
+ if (top_parent_relid == -1)
top_parent_relid = i; /* 'i' has no parents, so add itself */
else if (top_parent_relid != i)
is_top_parent = false;
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 3eeaa7068b..8dc32eb606 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -260,7 +260,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