v1-0001-Remove-references-to-the-removed-rel-from-EquivalenceClasses.patch
application/octet-stream
Filename: v1-0001-Remove-references-to-the-removed-rel-from-EquivalenceClasses.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v1-0001
Subject: Remove references to the removed rel from EquivalenceClasses
| File | + | − |
|---|---|---|
| src/backend/optimizer/plan/analyzejoins.c | 31 | 0 |
| src/test/regress/expected/join.out | 31 | 0 |
| src/test/regress/sql/join.sql | 23 | 0 |
From d8ead6d480e1454e1e18e5797bb6fe18ce09aef4 Mon Sep 17 00:00:00 2001
From: Richard Guo <guofenglinux@gmail.com>
Date: Thu, 15 Jun 2023 14:36:31 +0800
Subject: [PATCH v1] Remove references to the removed rel from
EquivalenceClasses
---
src/backend/optimizer/plan/analyzejoins.c | 31 +++++++++++++++++++++++
src/test/regress/expected/join.out | 31 +++++++++++++++++++++++
src/test/regress/sql/join.sql | 23 +++++++++++++++++
3 files changed, 85 insertions(+)
diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c
index 6476e55e56..f00e99b077 100644
--- a/src/backend/optimizer/plan/analyzejoins.c
+++ b/src/backend/optimizer/plan/analyzejoins.c
@@ -335,6 +335,7 @@ remove_rel_from_query(PlannerInfo *root, int relid, SpecialJoinInfo *sjinfo)
List *joininfos;
Index rti;
ListCell *l;
+ int i;
/* Compute the relid set for the join we are considering */
joinrelids = bms_union(sjinfo->min_lefthand, sjinfo->min_righthand);
@@ -449,6 +450,36 @@ remove_rel_from_query(PlannerInfo *root, int relid, SpecialJoinInfo *sjinfo)
}
}
+ /*
+ * Likewise remove references from EquivalenceClasses.
+ */
+ i = -1;
+ while ((i = bms_next_member(rel->eclass_indexes, i)) >= 0)
+ {
+ EquivalenceClass *cur_ec = (EquivalenceClass *) list_nth(root->eq_classes, i);
+
+ /* Sanity check eclass_indexes only contain ECs for rel */
+ Assert(bms_is_subset(rel->relids, cur_ec->ec_relids));
+
+ cur_ec->ec_relids = bms_del_member(cur_ec->ec_relids, relid);
+ cur_ec->ec_relids = bms_del_member(cur_ec->ec_relids, ojrelid);
+
+ foreach(l, cur_ec->ec_members)
+ {
+ EquivalenceMember *cur_em = (EquivalenceMember *) lfirst(l);
+
+ cur_em->em_relids = bms_del_member(cur_em->em_relids, relid);
+ cur_em->em_relids = bms_del_member(cur_em->em_relids, ojrelid);
+ }
+
+ foreach(l, cur_ec->ec_sources)
+ {
+ RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
+
+ remove_rel_from_restrictinfo(rinfo, relid, ojrelid);
+ }
+ }
+
/*
* Remove any joinquals referencing the rel from the joininfo lists.
*
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index 98b2667821..cc4c122fdd 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -5881,6 +5881,37 @@ where ss.stringu2 !~* ss.case1;
doh!
(1 row)
+rollback;
+-- another join removal bug: we must clean up EquivalenceClasses too
+begin;
+create temp table t (a int unique);
+insert into t values (1);
+explain (costs off)
+select 1
+from t t1
+ left join (select 2 as c
+ from t t2 left join t t3 on t2.a = t3.a) s
+ on true
+where t1.a = s.c;
+ QUERY PLAN
+------------------------------
+ Nested Loop Left Join
+ Filter: (t1.a = (2))
+ -> Seq Scan on t t1
+ -> Materialize
+ -> Seq Scan on t t2
+(5 rows)
+
+select 1
+from t t1
+ left join (select 2 as c
+ from t t2 left join t t3 on t2.a = t3.a) s
+ on true
+where t1.a = s.c;
+ ?column?
+----------
+(0 rows)
+
rollback;
-- test cases where we can remove a join, but not a PHV computed at it
begin;
diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql
index 7daa390b1d..e77e469570 100644
--- a/src/test/regress/sql/join.sql
+++ b/src/test/regress/sql/join.sql
@@ -2167,6 +2167,29 @@ where ss.stringu2 !~* ss.case1;
rollback;
+-- another join removal bug: we must clean up EquivalenceClasses too
+begin;
+
+create temp table t (a int unique);
+insert into t values (1);
+
+explain (costs off)
+select 1
+from t t1
+ left join (select 2 as c
+ from t t2 left join t t3 on t2.a = t3.a) s
+ on true
+where t1.a = s.c;
+
+select 1
+from t t1
+ left join (select 2 as c
+ from t t2 left join t t3 on t2.a = t3.a) s
+ on true
+where t1.a = s.c;
+
+rollback;
+
-- test cases where we can remove a join, but not a PHV computed at it
begin;
--
2.31.0