v1-ignore-commutable-joins-in-qual-removal.patch
text/x-diff
Filename: v1-ignore-commutable-joins-in-qual-removal.patch
Type: text/x-diff
Part: 0
Patch
Format: unified
Series: patch v1
| File | + | − |
|---|---|---|
| src/backend/optimizer/plan/analyzejoins.c | 21 | 6 |
diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c
index a61e35f92d..54ae0379b3 100644
--- a/src/backend/optimizer/plan/analyzejoins.c
+++ b/src/backend/optimizer/plan/analyzejoins.c
@@ -35,7 +35,8 @@
/* local functions */
static bool join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo);
-static void remove_rel_from_query(PlannerInfo *root, int relid, int ojrelid,
+static void remove_rel_from_query(PlannerInfo *root, int relid,
+ SpecialJoinInfo *removable_sjinfo,
Relids joinrelids);
static void remove_rel_from_restrictinfo(RestrictInfo *rinfo,
int relid, int ojrelid);
@@ -93,7 +94,7 @@ restart:
if (sjinfo->ojrelid != 0)
joinrelids = bms_add_member(joinrelids, sjinfo->ojrelid);
- remove_rel_from_query(root, innerrelid, sjinfo->ojrelid, joinrelids);
+ remove_rel_from_query(root, innerrelid, sjinfo, joinrelids);
/* We verify that exactly one reference gets removed from joinlist */
nremoved = 0;
@@ -331,10 +332,13 @@ join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo)
* the planner's data structures that will actually be consulted later.
*/
static void
-remove_rel_from_query(PlannerInfo *root, int relid, int ojrelid,
+remove_rel_from_query(PlannerInfo *root, int relid,
+ SpecialJoinInfo *removable_sjinfo,
Relids joinrelids)
{
RelOptInfo *rel = find_base_rel(root, relid);
+ int ojrelid = removable_sjinfo->ojrelid;
+ Relids join_plus_commute;
List *joininfos;
Index rti;
ListCell *l;
@@ -454,8 +458,19 @@ remove_rel_from_query(PlannerInfo *root, int relid, int ojrelid,
* outerjoin-delayed quals, which can get marked as requiring the rel in
* order to force them to be evaluated at or above the join. We can't
* just discard them, though. Only quals that logically belonged to the
- * outer join being discarded should be removed from the query.
- *
+ * outer join being discarded should be removed from the query. However,
+ * we might encounter a qual that is a clone of a deletable qual with some
+ * outer-join relids added (see deconstruct_distribute_oj_quals). To
+ * ensure we get rid of such clones as well, add the relids of all OJs
+ * commutable with this one to the set we test against for
+ * pushed-down-ness.
+ */
+ join_plus_commute = bms_union(joinrelids,
+ removable_sjinfo->commute_below_l);
+ join_plus_commute = bms_add_members(join_plus_commute,
+ removable_sjinfo->commute_above_r);
+
+ /*
* We must make a copy of the rel's old joininfo list before starting the
* loop, because otherwise remove_join_clause_from_rels would destroy the
* list while we're scanning it.
@@ -467,7 +482,7 @@ remove_rel_from_query(PlannerInfo *root, int relid, int ojrelid,
remove_join_clause_from_rels(root, rinfo, rinfo->required_relids);
- if (RINFO_IS_PUSHED_DOWN(rinfo, joinrelids))
+ if (RINFO_IS_PUSHED_DOWN(rinfo, join_plus_commute))
{
/*
* There might be references to relid or ojrelid in the