From 75a2c7a00d1c02e996f523b3f6350f7d5d6b4f91 Mon Sep 17 00:00:00 2001 From: Richard Guo 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