Consider a Result node's relids in ExplainPreScanNode.
authorRobert Haas <rhaas@postgresql.org>
Mon, 21 Apr 2025 17:35:28 +0000 (13:35 -0400)
committerRobert Haas <rhaas@postgresql.org>
Mon, 19 May 2025 15:02:50 +0000 (11:02 -0400)
Now that a Result node has a relids set, add the relids that it
carries the set accumulated by ExplainPreScanNode so that we
generate unique relation aliases for all of the referenced relations
when it calls select_rtable_names_for_explain. The effect of this
changes is that a few things get schema-qualified in the regression
test outputs that previously were not. In similar cases not involving
a Result node, we were already schema-qualifying, so this appears to
be an improvement.

XXX. I have broken this out as a separate commit for now; however,
it could be merged with the commit to add 'relids' to 'Result'; or
the patch series could even be rejiggered to present this as the
primary benefit of that change, leaving the EXPLAIN changes as a
secondary benefit, instead of the current organization, which does
the reverse.

src/backend/commands/explain.c
src/test/regress/expected/generated_virtual.out
src/test/regress/expected/join.out
src/test/regress/expected/partition_join.out

index bf0185e1ca14a6b58815e8615ae720dab9a2ed02..a4bec7ac3237009ee629cc367097b3b72393c249 100644 (file)
@@ -1242,6 +1242,10 @@ ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used)
                        *rels_used = bms_add_members(*rels_used,
                                                                                 ((MergeAppend *) plan)->apprelids);
                        break;
+               case T_Result:
+                       *rels_used = bms_add_members(*rels_used,
+                                                                                ((Result *) plan)->relids);
+                       break;
                default:
                        break;
        }
index 1793c3f35785a04aea51f8be876656b9aa2ea9c9..53509c864339b56b1532b86295955bf572eb786d 100644 (file)
@@ -1551,15 +1551,15 @@ where coalesce(t2.b, 1) = 2 or t1.a is null;
 -- Ensure that the generation expressions are wrapped into PHVs if needed
 explain (verbose, costs off)
 select t2.* from gtest32 t1 left join gtest32 t2 on false;
-                      QUERY PLAN                      
-------------------------------------------------------
+                       QUERY PLAN                        
+---------------------------------------------------------
  Nested Loop Left Join
-   Output: a, (a * 2), (20), (COALESCE(a, 100))
+   Output: t2.a, (t2.a * 2), (20), (COALESCE(t2.a, 100))
    Join Filter: false
    ->  Seq Scan on generated_virtual_tests.gtest32 t1
          Output: t1.a, t1.b, t1.c, t1.d
    ->  Result
-         Output: a, 20, COALESCE(a, 100)
+         Output: t2.a, 20, COALESCE(t2.a, 100)
          One-Time Filter: false
          Replaces: Scan on t2
 (9 rows)
index f298aa7c1dca0c1063365d514a0c5dda5b5156fa..23913249a8f3ebb83a4200eaf01c5640cb5f1c42 100644 (file)
@@ -5808,7 +5808,7 @@ on t1.q1 = t2.q1;
                  QUERY PLAN                 
 --------------------------------------------
  Hash Left Join
-   Hash Cond: (t1.q1 = q1)
+   Hash Cond: (t1.q1 = t2.q1)
    ->  Seq Scan on int8_tbl t1
    ->  Hash
          ->  Result
@@ -5825,7 +5825,7 @@ on t1.q1 = t2.q1;
                  QUERY PLAN                 
 --------------------------------------------
  Hash Left Join
-   Hash Cond: (t1.q1 = q1)
+   Hash Cond: (t1.q1 = t2.q1)
    ->  Seq Scan on int8_tbl t1
    ->  Hash
          ->  Result
@@ -6155,13 +6155,13 @@ SELECT q2 FROM
                       QUERY PLAN                      
 ------------------------------------------------------
  Nested Loop Left Join
-   Output: q2
+   Output: int8_tbl.q2
    Join Filter: NULL::boolean
    Filter: (('constant'::text) >= ('constant'::text))
    ->  Seq Scan on public.int4_tbl
          Output: int4_tbl.f1
    ->  Result
-         Output: q2, 'constant'::text
+         Output: int8_tbl.q2, 'constant'::text
          One-Time Filter: false
          Replaces: Scan on int8_tbl
 (10 rows)
@@ -6514,7 +6514,7 @@ where q1.x = q2.y;
 --------------------------
  Result
    One-Time Filter: false
-   Replaces: Scan on sj_1
+   Replaces: Scan on sj
 (3 rows)
 
 -- We can't use a cross-EC generated self join qual because of current logic of
@@ -8504,15 +8504,15 @@ select * from int4_tbl t1,
 explain (verbose, costs off)
 select * from int8_tbl i8 left join lateral
   (select *, i8.q2 from int4_tbl where false) ss on true;
-              QUERY PLAN              
---------------------------------------
+                  QUERY PLAN                  
+----------------------------------------------
  Nested Loop Left Join
-   Output: i8.q1, i8.q2, f1, (i8.q2)
+   Output: i8.q1, i8.q2, int4_tbl.f1, (i8.q2)
    Join Filter: false
    ->  Seq Scan on public.int8_tbl i8
          Output: i8.q1, i8.q2
    ->  Result
-         Output: f1, i8.q2
+         Output: int4_tbl.f1, i8.q2
          One-Time Filter: false
          Replaces: Scan on int4_tbl
 (9 rows)
@@ -8520,14 +8520,14 @@ select * from int8_tbl i8 left join lateral
 explain (verbose, costs off)
 select * from int8_tbl i8 left join lateral
   (select *, i8.q2 from int4_tbl i1, int4_tbl i2 where false) ss on true;
-               QUERY PLAN                
------------------------------------------
+                  QUERY PLAN                   
+-----------------------------------------------
  Nested Loop Left Join
-   Output: i8.q1, i8.q2, f1, f1, (i8.q2)
+   Output: i8.q1, i8.q2, i1.f1, i2.f1, (i8.q2)
    ->  Seq Scan on public.int8_tbl i8
          Output: i8.q1, i8.q2
    ->  Result
-         Output: f1, f1, i8.q2
+         Output: i1.f1, i2.f1, i8.q2
          One-Time Filter: false
          Replaces: Join on i1, i2
 (8 rows)
index 52c4ffffd81de3aeb5dceb77d136da7629bd3796..966b2eb6eb93be29299f559d18f78e51125584b3 100644 (file)
@@ -1626,7 +1626,7 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1
                     QUERY PLAN                    
 --------------------------------------------------
  Hash Left Join
-   Hash Cond: (t2.b = a)
+   Hash Cond: (t2.b = prt1.a)
    ->  Append
          ->  Hash Join
                Hash Cond: (t3_1.a = t2_1.b)
@@ -1654,9 +1654,9 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1
                  QUERY PLAN                 
 --------------------------------------------
  Sort
-   Sort Key: a, t2.b
+   Sort Key: prt1.a, t2.b
    ->  Hash Left Join
-         Hash Cond: (t2.b = a)
+         Hash Cond: (t2.b = prt1.a)
          ->  Append
                ->  Seq Scan on prt2_p1 t2_1
                      Filter: (a = 0)
@@ -2242,10 +2242,10 @@ SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL
 -- join with one side empty
 EXPLAIN (COSTS OFF)
 SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE a = 1 AND a = 2) t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.b = t2.a AND t1.c = t2.c;
-                               QUERY PLAN                                
--------------------------------------------------------------------------
+                                          QUERY PLAN                                          
+----------------------------------------------------------------------------------------------
  Hash Left Join
-   Hash Cond: ((t2.b = a) AND (t2.a = b) AND ((t2.c)::text = (c)::text))
+   Hash Cond: ((t2.b = prt1_l.a) AND (t2.a = prt1_l.b) AND ((t2.c)::text = (prt1_l.c)::text))
    ->  Append
          ->  Seq Scan on prt2_l_p1 t2_1
          ->  Seq Scan on prt2_l_p2_p1 t2_2