From 501499399e5d9d71075be8af5df47aab4fa075fe Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Mon, 21 Apr 2025 13:35:28 -0400
Subject: [PATCH v2 2/7] Consider a Result node's relids in ExplainPreScanNode.

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                |  4 +++
 .../regress/expected/generated_virtual.out    |  8 ++---
 src/test/regress/expected/join.out            | 32 +++++++++----------
 src/test/regress/expected/partition_join.out  | 12 +++----
 4 files changed, 30 insertions(+), 26 deletions(-)

diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 42723c3a150..e8bd4c560dd 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -1230,6 +1230,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;
 	}
diff --git a/src/test/regress/expected/generated_virtual.out b/src/test/regress/expected/generated_virtual.out
index 8b25e77bb4d..70727623bca 100644
--- a/src/test/regress/expected/generated_virtual.out
+++ b/src/test/regress/expected/generated_virtual.out
@@ -1570,15 +1570,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)), e
+   Output: t2.a, (t2.a * 2), (20), (COALESCE(t2.a, 100)), t2.e
    Join Filter: false
    ->  Seq Scan on generated_virtual_tests.gtest32 t1
          Output: t1.a, t1.b, t1.c, t1.d, t1.e
    ->  Result
-         Output: a, e, 20, COALESCE(a, 100)
+         Output: t2.a, t2.e, 20, COALESCE(t2.a, 100)
          One-Time Filter: false
          Replaces: Scan on t2
 (9 rows)
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index 76083b1ce57..96b5e891d97 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -4133,9 +4133,9 @@ select * from t t1
                         QUERY PLAN                        
 ----------------------------------------------------------
  Nested Loop Left Join
-   Output: t1.i, (1), t2.i2, i3, t4.i4
+   Output: t1.i, (1), t2.i2, t3.i3, t4.i4
    ->  Nested Loop Left Join
-         Output: t1.i, t2.i2, (1), i3
+         Output: t1.i, t2.i2, (1), t3.i3
          Join Filter: false
          ->  Hash Left Join
                Output: t1.i, t2.i2, (1)
@@ -4148,7 +4148,7 @@ select * from t t1
                      ->  Seq Scan on pg_temp.t t2
                            Output: t2.i2, 1
          ->  Result
-               Output: i3
+               Output: t3.i3
                One-Time Filter: false
                Replaces: Scan on t3
    ->  Memoize
@@ -6051,7 +6051,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
@@ -6068,7 +6068,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
@@ -6398,13 +6398,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)
@@ -6757,7 +6757,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
@@ -8747,15 +8747,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)
@@ -8763,14 +8763,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)
diff --git a/src/test/regress/expected/partition_join.out b/src/test/regress/expected/partition_join.out
index 0c495907eca..c94108eb118 100644
--- a/src/test/regress/expected/partition_join.out
+++ b/src/test/regress/expected/partition_join.out
@@ -1630,7 +1630,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)
@@ -1658,9 +1658,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)
@@ -2246,10 +2246,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
-- 
2.39.5 (Apple Git-154)

