From 5757eaaec4fda492957cb829e9c261e2e7e1ede0 Mon Sep 17 00:00:00 2001 From: "dgrowley@gmail.com" Date: Thu, 18 Jul 2019 18:31:25 +1200 Subject: [PATCH 2/2] Special purpose generate_join_implied_equalities implementation --- src/backend/optimizer/path/equivclass.c | 68 +++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 5 deletions(-) diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c index 6e7db4b969..c82d5d97ef 100644 --- a/src/backend/optimizer/path/equivclass.c +++ b/src/backend/optimizer/path/equivclass.c @@ -1127,11 +1127,69 @@ generate_join_implied_equalities(PlannerInfo *root, Relids outer_relids, RelOptInfo *inner_rel) { - return generate_join_implied_equalities_for_ecs(root, - root->eq_classes, - join_relids, - outer_relids, - inner_rel); + List *result = NIL; + Relids inner_relids = inner_rel->relids; + Relids nominal_inner_relids; + Relids nominal_join_relids; + Bitmapset * matching_ecs; + int i; + + /* If inner rel is a child, extra setup work is needed */ + if (IS_OTHER_REL(inner_rel)) + { + Assert(!bms_is_empty(inner_rel->top_parent_relids)); + + /* Fetch relid set for the topmost parent rel */ + nominal_inner_relids = inner_rel->top_parent_relids; + /* ECs will be marked with the parent's relid, not the child's */ + nominal_join_relids = bms_union(outer_relids, nominal_inner_relids); + } + else + { + nominal_inner_relids = inner_relids; + nominal_join_relids = join_relids; + } + + /* Get all eclasses in common between inner_relids and join_relids */ + matching_ecs = get_common_eclass_indexes(root, inner_relids, join_relids); + + i = -1; + while ((i = bms_next_member(matching_ecs, i)) >= 0) + { + EquivalenceClass *ec = (EquivalenceClass *) list_nth(root->eq_classes, i); + List *sublist = NIL; + + /* ECs containing consts do not need any further enforcement */ + if (ec->ec_has_const) + continue; + + /* Single-member ECs won't generate any deductions */ + if (list_length(ec->ec_members) <= 1) + continue; + + /* Sanity check that this eclass overlaps the join */ + Assert(bms_overlap(ec->ec_relids, nominal_join_relids)); + + if (!ec->ec_broken) + sublist = generate_join_implied_equalities_normal(root, + ec, + join_relids, + outer_relids, + inner_relids); + + /* Recover if we failed to generate required derived clauses */ + if (ec->ec_broken) + sublist = generate_join_implied_equalities_broken(root, + ec, + nominal_join_relids, + outer_relids, + nominal_inner_relids, + inner_rel); + + result = list_concat(result, sublist); + } + + return result; } /* -- 2.17.1