v1-0001-Fix-how-SJE-removes-references-from-PHVs.patch

application/octet-stream

Filename: v1-0001-Fix-how-SJE-removes-references-from-PHVs.patch
Type: application/octet-stream
Part: 0
Message: Re: BUG #18187: Unexpected error: "variable not found in subplan target lists" triggered by JOIN

Patch

Format: format-patch
Series: patch v1-0001
Subject: Fix how SJE removes references from PHVs
File+
src/backend/optimizer/plan/analyzejoins.c 2 2
src/test/regress/expected/join.out 19 0
src/test/regress/sql/join.sql 8 0
From 75a2c7a00d1c02e996f523b3f6350f7d5d6b4f91 Mon Sep 17 00:00:00 2001
From: Richard Guo <guofenglinux@gmail.com>
Date: Thu, 9 Nov 2023 11:28:26 +0800
Subject: [PATCH v1] Fix how SJE removes references from PHVs

---
 src/backend/optimizer/plan/analyzejoins.c |  4 ++--
 src/test/regress/expected/join.out        | 19 +++++++++++++++++++
 src/test/regress/sql/join.sql             |  8 ++++++++
 3 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c
index 953e381d6f..271f694d99 100644
--- a/src/backend/optimizer/plan/analyzejoins.c
+++ b/src/backend/optimizer/plan/analyzejoins.c
@@ -474,9 +474,9 @@ remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel,
 			/* ph_needed might or might not become empty */
 			phv->phrels = replace_relid(phv->phrels, relid, subst);
 			phv->phrels = replace_relid(phv->phrels, ojrelid, subst);
-			phinfo->ph_lateral = replace_relid(phinfo->ph_lateral, relid, subst);
-			phinfo->ph_var->phrels = replace_relid(phinfo->ph_var->phrels, relid, subst);
 			Assert(!bms_is_empty(phv->phrels));
+			replace_varno((Node *) phv->phexpr, relid, subst);
+			phinfo->ph_lateral = replace_relid(phinfo->ph_lateral, relid, subst);
 			Assert(phv->phnullingrels == NULL); /* no need to adjust */
 		}
 	}
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index 892ea5f170..ddc4e69232 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -6776,6 +6776,25 @@ SELECT c3.code FROM emp1 c3;
                ->  Seq Scan on emp1 c3
 (7 rows)
 
+-- Check that SJE removes references from PHVs correctly
+explain (costs off)
+select * from emp1 t1 left join
+    (select coalesce(t3.code, 1) from emp1 t2
+        left join (emp1 t3 join emp1 t4 on t3.id = t4.id)
+        on true)
+on true;
+                     QUERY PLAN                     
+----------------------------------------------------
+ Nested Loop Left Join
+   ->  Seq Scan on emp1 t1
+   ->  Materialize
+         ->  Nested Loop Left Join
+               ->  Seq Scan on emp1 t2
+               ->  Materialize
+                     ->  Seq Scan on emp1 t4
+                           Filter: (id IS NOT NULL)
+(8 rows)
+
 -- We can remove the join even if we find the join can't duplicate rows and
 -- the base quals of each side are different.  In the following case we end up
 -- moving quals over to s1 to make it so it can't match any rows.
diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql
index 559c36dc07..a41787d1f1 100644
--- a/src/test/regress/sql/join.sql
+++ b/src/test/regress/sql/join.sql
@@ -2580,6 +2580,14 @@ WHERE c2.id IS NOT NULL
 EXCEPT ALL
 SELECT c3.code FROM emp1 c3;
 
+-- Check that SJE removes references from PHVs correctly
+explain (costs off)
+select * from emp1 t1 left join
+    (select coalesce(t3.code, 1) from emp1 t2
+        left join (emp1 t3 join emp1 t4 on t3.id = t4.id)
+        on true)
+on true;
+
 -- We can remove the join even if we find the join can't duplicate rows and
 -- the base quals of each side are different.  In the following case we end up
 -- moving quals over to s1 to make it so it can't match any rows.
-- 
2.31.0