1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-07 19:06:32 +03:00

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
This commit is contained in:
David Rowley
2025-11-05 11:48:09 +13:00
parent 0a3d27bfe0
commit fdda78e361
2 changed files with 9 additions and 5 deletions

View File

@@ -773,6 +773,12 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root,
RelOptInfo *rel = lfirst(lc); RelOptInfo *rel = lfirst(lc);
Path *ordered_path; 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 */ /* Skip any UNION children that are proven not to yield any rows */
if (is_dummy_rel(rel)) if (is_dummy_rel(rel))
continue; continue;
@@ -815,8 +821,6 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root,
partial_pathlist = lappend(partial_pathlist, partial_pathlist = lappend(partial_pathlist,
linitial(rel->partial_pathlist)); linitial(rel->partial_pathlist));
} }
relids = bms_add_members(relids, rel->relids);
} }
/* Build result relation. */ /* Build result relation. */

View File

@@ -1260,14 +1260,14 @@ SELECT four FROM tenk1 WHERE 1=2
UNION UNION
SELECT ten FROM tenk1 WHERE 1=2 SELECT ten FROM tenk1 WHERE 1=2
ORDER BY 1; ORDER BY 1;
QUERY PLAN QUERY PLAN
-------------------------------------- -----------------------------------------------------------------------------------------
Sort Sort
Output: unnamed_subquery.two Output: unnamed_subquery.two
Sort Key: unnamed_subquery.two Sort Key: unnamed_subquery.two
-> Result -> Result
Output: unnamed_subquery.two Output: unnamed_subquery.two
Replaces: Aggregate Replaces: Aggregate on unnamed_subquery, unnamed_subquery_1, unnamed_subquery_2
One-Time Filter: false One-Time Filter: false
(7 rows) (7 rows)