From fee7b77b9000f35e445de9954a8cbf241f181e60 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 7 Feb 2023 18:26:16 -0500 Subject: Rethink nullingrel marking rules in build_joinrel_tlist(). The logic for when to add the current outer join's own relid to the nullingrels sets of output Vars and PHVs was overly complicated and underly correct. Not sure why I didn't think of this before, but since what we want is marking per the syntactic structure, we can just consult our records about the syntactic structure, ie syn_righthand/syn_lefthand. Also, tighten the rule about when to add the commute_above_r bits, in hopes of eliminating some squishy reasoning. I do not know of a reason to think that that's broken as-is, but this way seems better. Per bug #17781 from Robins Tharakan. Discussion: https://postgr.es/m/17781-c0405c8b3cd5e072@postgresql.org --- src/test/regress/expected/join.out | 44 ++++++++++++++++++++++++++++++++++++++ src/test/regress/sql/join.sql | 28 ++++++++++++++++++++++++ 2 files changed, 72 insertions(+) (limited to 'src/test') diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out index eea8978fad..18b5e8f750 100644 --- a/src/test/regress/expected/join.out +++ b/src/test/regress/expected/join.out @@ -5008,6 +5008,50 @@ select a1.id from Seq Scan on a a1 (1 row) +-- another example (bug #17781) +explain (costs off) +select ss1.f1 +from int4_tbl as t1 + left join (int4_tbl as t2 + right join int4_tbl as t3 on null + left join (int4_tbl as t4 + right join int8_tbl as t5 on null) + on t2.f1 = t4.f1 + left join ((select null as f1 from int4_tbl as t6) as ss1 + inner join int8_tbl as t7 on null) + on t5.q1 = t7.q2) + on false; + QUERY PLAN +-------------------------------- + Nested Loop Left Join + Join Filter: false + -> Seq Scan on int4_tbl t1 + -> Result + One-Time Filter: false +(5 rows) + +-- variant with Var rather than PHV coming from t6 +explain (costs off) +select ss1.f1 +from int4_tbl as t1 + left join (int4_tbl as t2 + right join int4_tbl as t3 on null + left join (int4_tbl as t4 + right join int8_tbl as t5 on null) + on t2.f1 = t4.f1 + left join ((select f1 from int4_tbl as t6) as ss1 + inner join int8_tbl as t7 on null) + on t5.q1 = t7.q2) + on false; + QUERY PLAN +-------------------------------- + Nested Loop Left Join + Join Filter: false + -> Seq Scan on int4_tbl t1 + -> Result + One-Time Filter: false +(5 rows) + -- check that join removal works for a left join when joining a subquery -- that is guaranteed to be unique by its GROUP BY clause explain (costs off) diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql index 9d20b88d71..7806c910b4 100644 --- a/src/test/regress/sql/join.sql +++ b/src/test/regress/sql/join.sql @@ -1785,6 +1785,34 @@ select a1.id from (a a3 left join a a4 on a3.id = a4.id) on a2.id = a3.id; +-- another example (bug #17781) +explain (costs off) +select ss1.f1 +from int4_tbl as t1 + left join (int4_tbl as t2 + right join int4_tbl as t3 on null + left join (int4_tbl as t4 + right join int8_tbl as t5 on null) + on t2.f1 = t4.f1 + left join ((select null as f1 from int4_tbl as t6) as ss1 + inner join int8_tbl as t7 on null) + on t5.q1 = t7.q2) + on false; + +-- variant with Var rather than PHV coming from t6 +explain (costs off) +select ss1.f1 +from int4_tbl as t1 + left join (int4_tbl as t2 + right join int4_tbl as t3 on null + left join (int4_tbl as t4 + right join int8_tbl as t5 on null) + on t2.f1 = t4.f1 + left join ((select f1 from int4_tbl as t6) as ss1 + inner join int8_tbl as t7 on null) + on t5.q1 = t7.q2) + on false; + -- check that join removal works for a left join when joining a subquery -- that is guaranteed to be unique by its GROUP BY clause explain (costs off) -- cgit v1.2.3