summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2023-02-06 15:44:57 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2023-02-06 15:45:03 -0500
commitcad56920513e5b7ccdd3d41b0ea893eb3383f863 (patch)
treed6e50b32e18f2a3ffca1ef7a51dcb06c90411c8c /src/test
parent7ba09efe248fe5e15bd6d4c4d0612ea63b66a860 (diff)
Fix up join removal's interaction with PlaceHolderVars.
The portion of join_is_removable() that checks PlaceHolderVars can be made a little more accurate and intelligible than it was. The key point is that we can allow join removal even if a PHV mentions the target rel in ph_eval_at, if that mention was only added as a consequence of forcing the PHV up to a join level that's at/above the outer join we're trying to get rid of. We can check that by testing for the OJ's relid appearing in ph_eval_at, indicating that it's supposed to be evaluated after the outer join, plus the existing test that the contained expression doesn't actually mention the target rel. While here, add an explicit check that there'll be something left in ph_eval_at after we remove the target rel and OJ relid. There is an Assert later on about that, and I'm not too sure that the case could happen for a PHV satisfying the other constraints, but let's just check. (There was previously a bms_is_subset test that meant to cover this risk, but it's broken now because it doesn't account for the fact that we'll also remove the OJ relid.) The real reason for revisiting this code though is that the Assert I left behind in 8538519db turns out to be easily reachable, because if a PHV of this sort appears in an upper-level qual clause then that clause's clause_relids will include the PHV's ph_eval_at relids. This is a mirage though: we have or soon will remove these relids from the PHV's ph_eval_at, and therefore they no longer belong in qual clauses' clause_relids either. Remove that Assert in join_is_removable, and replace the similar one in remove_rel_from_query with code to remove the deleted relids from clause_relids. Per bug #17773 from Robins Tharakan. Discussion: https://postgr.es/m/17773-a592e6cedbc7bac5@postgresql.org
Diffstat (limited to 'src/test')
-rw-r--r--src/test/regress/expected/join.out20
-rw-r--r--src/test/regress/sql/join.sql8
2 files changed, 28 insertions, 0 deletions
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index 037c7d0d566..07f5aad5ea4 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -5213,6 +5213,26 @@ SELECT q2 FROM
Index Cond: (id = int8_tbl.q2)
(5 rows)
+-- join removal bug #17773: otherwise-removable PHV appears in a qual condition
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT q2 FROM
+ (SELECT q2, 'constant'::text AS x
+ FROM int8_tbl LEFT JOIN innertab ON q2 = id) ss
+ RIGHT JOIN int4_tbl ON NULL
+ WHERE x >= x;
+ QUERY PLAN
+------------------------------------------------------
+ Nested Loop Left Join
+ Output: 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
+ One-Time Filter: false
+(9 rows)
+
rollback;
-- another join removal bug: we must clean up correctly when removing a PHV
begin;
diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql
index 1f2b7f62f0f..7157b5cccca 100644
--- a/src/test/regress/sql/join.sql
+++ b/src/test/regress/sql/join.sql
@@ -1888,6 +1888,14 @@ SELECT q2 FROM
FROM int8_tbl LEFT JOIN innertab ON q2 = id) ss
WHERE COALESCE(dat1, 0) = q1;
+-- join removal bug #17773: otherwise-removable PHV appears in a qual condition
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT q2 FROM
+ (SELECT q2, 'constant'::text AS x
+ FROM int8_tbl LEFT JOIN innertab ON q2 = id) ss
+ RIGHT JOIN int4_tbl ON NULL
+ WHERE x >= x;
+
rollback;
-- another join removal bug: we must clean up correctly when removing a PHV