v2-0004-Fix-self-join-elimination-work-with-PlaceHolderIn.patch
application/octet-stream
Filename: v2-0004-Fix-self-join-elimination-work-with-PlaceHolderIn.patch
Type: application/octet-stream
Part: 2
Message:
Re: Removing unneeded self joins
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v2-0004
Subject: Fix self-join elimination work with PlaceHolderInfo.ph_lateral
| File | + | − |
|---|---|---|
| src/backend/optimizer/plan/analyzejoins.c | 7 | 0 |
| src/test/regress/expected/join.out | 13 | 0 |
| src/test/regress/sql/join.sql | 8 | 0 |
From f8f776c0338e7b923bed9fe80e2b3e5bb9326026 Mon Sep 17 00:00:00 2001
From: Alexander Korotkov <akorotkov@postgresql.org>
Date: Fri, 3 May 2024 01:51:13 +0300
Subject: [PATCH v2 4/4] Fix self-join elimination work with
PlaceHolderInfo.ph_lateral
After removing the relation participating in the later, relation may end up
depending on itself according to the PlaceHolderInfo.ph_lateral. This commit
makes remove_rel_from_query() revise PlaceHolderInfo.ph_lateral after
replacing relids there.
Discussion: https://postgr.es/m/CAMbWs49Q8g1LPVCeNHYv-Y-gFo826ertrg6nYNC9LL%3D8%3DzHP3g%40mail.gmail.com
Author: Richard Guo
Reviewed-by: Alexander Korotkov
---
src/backend/optimizer/plan/analyzejoins.c | 7 +++++++
src/test/regress/expected/join.out | 13 +++++++++++++
src/test/regress/sql/join.sql | 8 ++++++++
3 files changed, 28 insertions(+)
diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c
index d82d86b37f4..b52cce05da8 100644
--- a/src/backend/optimizer/plan/analyzejoins.c
+++ b/src/backend/optimizer/plan/analyzejoins.c
@@ -462,7 +462,14 @@ remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel,
phinfo->ph_needed = replace_relid(phinfo->ph_needed, ojrelid, subst);
/* ph_needed might or might not become empty */
+ /*
+ * ph_lateral might contain rels mentioned in ph_eval_at after the
+ * replacement. We will remove them. But first check they aren't
+ * overlapping already.
+ */
+ Assert(!bms_overlap(phinfo->ph_lateral, phinfo->ph_eval_at));
phinfo->ph_lateral = replace_relid(phinfo->ph_lateral, relid, subst);
+ phinfo->ph_lateral = bms_difference(phinfo->ph_lateral, phinfo->ph_eval_at);
/* ph_lateral might or might not be empty */
phv->phrels = replace_relid(phv->phrels, relid, subst);
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index 02765a7bc93..1b0b11c048d 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -6234,6 +6234,19 @@ select * from sj t1
Filter: (t1.a = a)
(8 rows)
+-- Ensure that SJE does not form a self-referential lateral dependency
+explain (costs off)
+select * from sj t1
+ left join lateral
+ (select t1.a as t1a, * from sj t2) s
+ on true
+where t1.a = s.a;
+ QUERY PLAN
+---------------------------
+ Seq Scan on sj t2
+ Filter: (a IS NOT NULL)
+(2 rows)
+
-- Degenerated case.
explain (costs off)
select * from
diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql
index 0a4ea3df19c..a9844892067 100644
--- a/src/test/regress/sql/join.sql
+++ b/src/test/regress/sql/join.sql
@@ -2360,6 +2360,14 @@ select * from sj t1
(select * from sj tablesample system(t1.b)) s
on t1.a = s.a;
+-- Ensure that SJE does not form a self-referential lateral dependency
+explain (costs off)
+select * from sj t1
+ left join lateral
+ (select t1.a as t1a, * from sj t2) s
+ on true
+where t1.a = s.a;
+
-- Degenerated case.
explain (costs off)
select * from
--
2.39.3 (Apple Git-145)