Fix possible usage of incorrect UPPERREL_SETOP RelOptInfo
authorDavid Rowley <[email protected]>
Tue, 4 Nov 2025 22:48:09 +0000 (11:48 +1300)
committerDavid Rowley <[email protected]>
Tue, 4 Nov 2025 22:48:09 +0000 (11:48 +1300)
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 <[email protected]>
Author: David Rowley <[email protected]>
Discussion: https://postgr.es/m/bee34aec-659c-46f1-9ab7-7bbae0b7616c@gmail.com

src/backend/optimizer/prep/prepunion.c
src/test/regress/expected/union.out

index 55665824179291c89f890eb2b6dae2fd71a96f5e..7253954565676530cbbd87d6c27f716bfa5c8a11 100644 (file)
@@ -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. */
index fb77d108337ed9c8297528dfda4f25a6b4884002..4533967e84acb3b60b4f1d9a1191e11f01d33bc5 100644 (file)
@@ -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)