Fix the way SJE removes references from PHVs
authorAlexander Korotkov <[email protected]>
Thu, 9 Nov 2023 12:06:11 +0000 (14:06 +0200)
committerAlexander Korotkov <[email protected]>
Thu, 9 Nov 2023 12:25:13 +0000 (14:25 +0200)
Add missing replacement of relids in phv->phexpr.  Also, remove extra
replace_relid() over phv->phrels.

Reported-by: Zuming Jiang
Bug: #18187
Discussion: https://postgr.es/m/flat/18187-831da249cbd2ff8e%40postgresql.org
Author: Richard Guo
Reviewed-by: Andrei Lepikhov
src/backend/optimizer/plan/analyzejoins.c
src/test/regress/expected/join.out
src/test/regress/sql/join.sql

index 953e381d6f933e7d1e3cfce52793526dd99674b2..271f694d996c5cff4fa8cb8bf9247ee8c06d2caf 100644 (file)
@@ -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 */
                }
        }
index 892ea5f17023eb538e8db2fecf5706b07ac0e919..ddc4e692329954216023a687ae9fe1cbd7829431 100644 (file)
@@ -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.
index 559c36dc0740dace68f822bfcf702546fdc69977..a41787d1f1e0e7715b705b42bc926965b686c8fd 100644 (file)
@@ -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.