summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Rowley <drowley@postgresql.org>2025-11-05 11:48:09 +1300
committerDavid Rowley <drowley@postgresql.org>2025-11-05 11:48:09 +1300
commitfdda78e361f136ec2b8de579b366c1e66bba1199 (patch)
tree455c10b037bcd94d1f82502b4c6a17bf970398fe /src
parent0a3d27bfe0fb229253aa95feccd0360530b7edd8 (diff)
Fix possible usage of incorrect UPPERREL_SETOP RelOptInfo
03d40e4b5 allowed dummy UNION [ALL] children to be removed from the plan by checking for is_dummy_rel(). That commit neglected to still account for the relids from the dummy rel so that the correct UPPERREL_SETOP RelOptInfo could be found and used for adding the Paths to. Not doing this could result in processing of subsequent UNIONs using the same RelOptInfo as a previously processed UNION, which could result in add_path() freeing old Paths that are needed by the previous UNION. The same fix was independently submitted (2 mins later) by Richard Guo. Reported-by: Alexander Lakhin <exclusion@gmail.com> Author: David Rowley <dgrowleyml@gmail.com> Discussion: https://postgr.es/m/bee34aec-659c-46f1-9ab7-7bbae0b7616c@gmail.com
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/prep/prepunion.c8
-rw-r--r--src/test/regress/expected/union.out6
2 files changed, 9 insertions, 5 deletions
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 55665824179..72539545656 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -773,6 +773,12 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root,
RelOptInfo *rel = lfirst(lc);
Path *ordered_path;
+ /*
+ * Record the relids so that we can identify the correct
+ * UPPERREL_SETOP RelOptInfo below.
+ */
+ relids = bms_add_members(relids, rel->relids);
+
/* Skip any UNION children that are proven not to yield any rows */
if (is_dummy_rel(rel))
continue;
@@ -815,8 +821,6 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root,
partial_pathlist = lappend(partial_pathlist,
linitial(rel->partial_pathlist));
}
-
- relids = bms_add_members(relids, rel->relids);
}
/* Build result relation. */
diff --git a/src/test/regress/expected/union.out b/src/test/regress/expected/union.out
index fb77d108337..4533967e84a 100644
--- a/src/test/regress/expected/union.out
+++ b/src/test/regress/expected/union.out
@@ -1260,14 +1260,14 @@ SELECT four FROM tenk1 WHERE 1=2
UNION
SELECT ten FROM tenk1 WHERE 1=2
ORDER BY 1;
- QUERY PLAN
---------------------------------------
+ QUERY PLAN
+-----------------------------------------------------------------------------------------
Sort
Output: unnamed_subquery.two
Sort Key: unnamed_subquery.two
-> Result
Output: unnamed_subquery.two
- Replaces: Aggregate
+ Replaces: Aggregate on unnamed_subquery, unnamed_subquery_1, unnamed_subquery_2
One-Time Filter: false
(7 rows)