solved_conflict_with_self_join_removal.diff
text/x-patch
Filename: solved_conflict_with_self_join_removal.diff
Type: text/x-patch
Part: 0
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: unified
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/equivclass.c | 43 | 59 |
| src/backend/optimizer/plan/analyzejoins.c | 43 | 14 |
| src/include/optimizer/paths.h | 3 | 0 |
diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index e59f38b6ce0..329419c38d9 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -38,8 +38,6 @@ static EquivalenceMember *add_eq_member(EquivalenceClass *ec,
JoinDomain *jdomain,
EquivalenceMember *parent,
Oid datatype);
-static void add_eq_source(PlannerInfo *root, EquivalenceClass *ec,
- RestrictInfo *rinfo);
static void add_eq_derive(PlannerInfo *root, EquivalenceClass *ec,
RestrictInfo *rinfo);
static bool is_exprlist_member(Expr *node, List *exprs);
@@ -78,6 +76,49 @@ static Bitmapset *get_eclass_indexes_for_relids(PlannerInfo *root,
static Bitmapset *get_common_eclass_indexes(PlannerInfo *root, Relids relids1,
Relids relids2);
+/*
+ * add_eq_source - add 'rinfo' in eq_sources for this 'ec'
+ */
+void
+add_eq_source(PlannerInfo *root, EquivalenceClass *ec, RestrictInfo *rinfo)
+{
+ int source_idx = list_length(root->eq_sources);
+ int i;
+
+ ec->ec_source_indexes = bms_add_member(ec->ec_source_indexes, source_idx);
+ root->eq_sources = lappend(root->eq_sources, rinfo);
+
+ i = -1;
+ while ((i = bms_next_member(rinfo->clause_relids, i)) >= 0)
+ {
+ RangeTblEntry *rte = root->simple_rte_array[i];
+
+ rte->eclass_source_indexes = bms_add_member(rte->eclass_source_indexes,
+ source_idx);
+ }
+}
+
+/*
+ * add_eq_derive - add 'rinfo' in eq_derives for this 'ec'
+ */
+static void
+add_eq_derive(PlannerInfo *root, EquivalenceClass *ec, RestrictInfo *rinfo)
+{
+ int derive_idx = list_length(root->eq_derives);
+ int i;
+
+ ec->ec_derive_indexes = bms_add_member(ec->ec_derive_indexes, derive_idx);
+ root->eq_derives = lappend(root->eq_derives, rinfo);
+
+ i = -1;
+ while ((i = bms_next_member(rinfo->clause_relids, i)) >= 0)
+ {
+ RangeTblEntry *rte = root->simple_rte_array[i];
+
+ rte->eclass_derive_indexes = bms_add_member(rte->eclass_derive_indexes,
+ derive_idx);
+ }
+}
/*
* process_equivalence
@@ -561,51 +602,6 @@ add_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids,
return em;
}
-/*
- * add_eq_source - add 'rinfo' in eq_sources for this 'ec'
- */
-static void
-add_eq_source(PlannerInfo *root, EquivalenceClass *ec, RestrictInfo *rinfo)
-{
- int source_idx = list_length(root->eq_sources);
- int i;
-
- ec->ec_source_indexes = bms_add_member(ec->ec_source_indexes, source_idx);
- root->eq_sources = lappend(root->eq_sources, rinfo);
-
- i = -1;
- while ((i = bms_next_member(rinfo->clause_relids, i)) >= 0)
- {
- RangeTblEntry *rte = root->simple_rte_array[i];
-
- rte->eclass_source_indexes = bms_add_member(rte->eclass_source_indexes,
- source_idx);
- }
-}
-
-/*
- * add_eq_derive - add 'rinfo' in eq_derives for this 'ec'
- */
-static void
-add_eq_derive(PlannerInfo *root, EquivalenceClass *ec, RestrictInfo *rinfo)
-{
- int derive_idx = list_length(root->eq_derives);
- int i;
-
- ec->ec_derive_indexes = bms_add_member(ec->ec_derive_indexes, derive_idx);
- root->eq_derives = lappend(root->eq_derives, rinfo);
-
- i = -1;
- while ((i = bms_next_member(rinfo->clause_relids, i)) >= 0)
- {
- RangeTblEntry *rte = root->simple_rte_array[i];
-
- rte->eclass_derive_indexes = bms_add_member(rte->eclass_derive_indexes,
- derive_idx);
- }
-}
-
-
/*
* get_eclass_for_sort_expr
* Given an expression and opfamily/collation info, find an existing
@@ -3398,18 +3394,6 @@ get_ec_source_indexes(PlannerInfo *root, EquivalenceClass *ec, Relids relids)
rel_esis = bms_add_members(rel_esis, rte->eclass_source_indexes);
}
-#ifdef USE_ASSERT_CHECKING
- /* verify the results look sane */
- i = -1;
- while ((i = bms_next_member(rel_esis, i)) >= 0)
- {
- RestrictInfo *rinfo = list_nth_node(RestrictInfo, root->eq_sources,
- i);
-
- Assert(bms_overlap(relids, rinfo->clause_relids));
- }
-#endif
-
/* bitwise-AND to leave only the ones for this EquivalenceClass */
return bms_int_members(rel_esis, ec->ec_source_indexes);
}
diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c
index 0298c26166f..92dcbbdf2e0 100644
--- a/src/backend/optimizer/plan/analyzejoins.c
+++ b/src/backend/optimizer/plan/analyzejoins.c
@@ -61,7 +61,7 @@ static void remove_leftjoinrel_from_query(PlannerInfo *root, int relid,
SpecialJoinInfo *sjinfo);
static void remove_rel_from_restrictinfo(RestrictInfo *rinfo,
int relid, int ojrelid);
-static void remove_rel_from_eclass(EquivalenceClass *ec,
+static void remove_rel_from_eclass(PlannerInfo *root, EquivalenceClass *ec,
int relid, int ojrelid);
static List *remove_rel_from_joinlist(List *joinlist, int relid, int *nremoved);
static bool rel_supports_distinctness(PlannerInfo *root, RelOptInfo *rel);
@@ -578,7 +578,7 @@ remove_leftjoinrel_from_query(PlannerInfo *root, int relid,
if (bms_is_member(relid, ec->ec_relids) ||
bms_is_member(ojrelid, ec->ec_relids))
- remove_rel_from_eclass(ec, relid, ojrelid);
+ remove_rel_from_eclass(root, ec, relid, ojrelid);
}
/*
@@ -663,7 +663,7 @@ remove_rel_from_restrictinfo(RestrictInfo *rinfo, int relid, int ojrelid)
* level(s).
*/
static void
-remove_rel_from_eclass(EquivalenceClass *ec, int relid, int ojrelid)
+remove_rel_from_eclass(PlannerInfo *root, EquivalenceClass *ec, int relid, int ojrelid)
{
ListCell *lc;
int i;
@@ -1530,6 +1530,24 @@ replace_relid(Relids relids, int oldId, int newId)
return relids;
}
+void
+del_eq_derives(PlannerInfo *root, EquivalenceClass *ec)
+{
+ int i = -1;
+
+ while ((i = bms_next_member(ec->ec_derive_indexes, i)) >= 0)
+ {
+ /*
+ * Can't delete the element because we would need to rebuild all
+ * the eq_derives indexes. But add a nuke to detect potential problems.
+ */
+ list_nth_cell(root->eq_derives, i)->ptr_value = NULL;
+ }
+ bms_free(ec->ec_derive_indexes);
+ ec->ec_derive_indexes = NULL;
+}
+
+
/*
* Update EC members to point to the remaining relation instead of the removed
* one, removing duplicates.
@@ -1553,10 +1571,11 @@ replace_relid(Relids relids, int oldId, int newId)
* delete them.
*/
static void
-update_eclasses(EquivalenceClass *ec, int from, int to)
+update_eclass(PlannerInfo *root, EquivalenceClass *ec, int from, int to)
{
List *new_members = NIL;
List *new_sources = NIL;
+ int i = -1;
ListCell *lc;
ListCell *lc1;
@@ -1595,16 +1614,13 @@ update_eclasses(EquivalenceClass *ec, int from, int to)
new_members = lappend(new_members, em);
}
- list_free(ec->ec_members);
- ec->ec_members = new_members;
-
- list_free(ec->ec_derives);
- ec->ec_derives = NULL;
+ del_eq_derives(root, ec);
/* Update EC source expressions */
- foreach(lc, ec->ec_sources)
+ while ((i = bms_next_member(ec->ec_source_indexes, i)) > 0)
{
- RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc);
+ RestrictInfo *rinfo = list_nth_node(RestrictInfo,
+ root->eq_sources, i);
bool is_redundant = false;
if (!bms_is_member(from, rinfo->required_relids))
@@ -1638,8 +1654,21 @@ update_eclasses(EquivalenceClass *ec, int from, int to)
new_sources = lappend(new_sources, rinfo);
}
- list_free(ec->ec_sources);
- ec->ec_sources = new_sources;
+ i=-1;
+
+ while ((i = bms_next_member(ec->ec_source_indexes, i)) > 0)
+ {
+ list_nth_cell(root->eq_sources, i)->ptr_value = NULL;
+ }
+ bms_free(ec->ec_source_indexes);
+ ec->ec_source_indexes = NULL;
+
+ foreach(lc, new_sources)
+ {
+ RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc);
+ add_eq_source(root, ec, rinfo);
+ }
+
ec->ec_relids = replace_relid(ec->ec_relids, from, to);
}
@@ -1817,7 +1846,7 @@ remove_self_join_rel(PlannerInfo *root, PlanRowMark *kmark, PlanRowMark *rmark,
{
EquivalenceClass *ec = (EquivalenceClass *) list_nth(root->eq_classes, i);
- update_eclasses(ec, toRemove->relid, toKeep->relid);
+ update_eclass(root, ec, toRemove->relid, toKeep->relid);
toKeep->eclass_indexes = bms_add_member(toKeep->eclass_indexes, i);
}
diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h
index 469ca518571..83695e2f66f 100644
--- a/src/include/optimizer/paths.h
+++ b/src/include/optimizer/paths.h
@@ -111,6 +111,9 @@ extern bool have_join_order_restriction(PlannerInfo *root,
extern bool have_dangerous_phv(PlannerInfo *root,
Relids outer_relids, Relids inner_params);
extern void mark_dummy_rel(RelOptInfo *rel);
+extern void del_eq_derives(PlannerInfo *root, EquivalenceClass *ec);
+extern void add_eq_source(PlannerInfo *root, EquivalenceClass *ec, RestrictInfo *rinfo);
+
/*
* equivclass.c