37 bool is_child,
Oid datatype);
51 Relids nominal_join_relids,
53 Relids nominal_inner_relids,
56 Oid lefttype,
Oid righttype);
120 bool below_outer_join)
132 item1_nullable_relids,
133 item2_nullable_relids;
152 opno = ((
OpExpr *) clause)->opno;
153 collation = ((
OpExpr *) clause)->inputcollid;
176 if (
equal(item1, item2))
214 if (below_outer_join)
356 elog(
ERROR,
"too late to merge equivalence classes");
399 em2 =
add_eq_member(ec1, item2, item2_relids, item2_nullable_relids,
417 em1 =
add_eq_member(ec2, item1, item1_relids, item1_nullable_relids,
451 em1 =
add_eq_member(ec, item1, item1_relids, item1_nullable_relids,
453 em2 =
add_eq_member(ec, item2, item2_relids, item2_nullable_relids,
506 if (IsPolymorphicType(req_type) || req_type == RECORDOID)
507 req_type = expr_type;
512 if (expr_type != req_type ||
522 if (expr_type != req_type)
532 req_type, req_typmod, req_collation,
544 Relids nullable_relids,
bool is_child,
Oid datatype)
653 (sortref == 0 || sortref != cur_ec->
ec_sortref))
714 elog(
ERROR,
"volatile EquivalenceClass has no sortref");
720 nullable_relids =
bms_intersect(nullable_relids, expr_relids);
723 nullable_relids,
false, opcintype);
933 bool can_generate_joinclause =
false;
956 can_generate_joinclause =
977 if (can_generate_joinclause)
1031 Assert(const_em != NULL);
1041 if (cur_em == const_em)
1109 Assert(relid < root->simple_rel_array_size);
1111 if (prev_ems[relid] != NULL)
1150 prev_ems[relid] = cur_em;
1255 Relids nominal_inner_relids;
1256 Relids nominal_join_relids;
1268 nominal_join_relids =
bms_union(outer_relids, nominal_inner_relids);
1272 nominal_inner_relids = inner_relids;
1273 nominal_join_relids = join_relids;
1310 nominal_join_relids,
1312 nominal_inner_relids,
1334 Relids nominal_inner_relids;
1335 Relids nominal_join_relids;
1346 nominal_join_relids =
bms_union(outer_relids, nominal_inner_relids);
1350 nominal_inner_relids = inner_relids;
1351 nominal_join_relids = join_relids;
1354 foreach(lc, eclasses)
1382 nominal_join_relids,
1384 nominal_inner_relids,
1431 outer_members =
lappend(outer_members, cur_em);
1433 inner_members =
lappend(inner_members, cur_em);
1435 new_members =
lappend(new_members, cur_em);
1447 if (outer_members && inner_members)
1452 int best_score = -1;
1455 foreach(lc1, outer_members)
1460 foreach(lc2, inner_members)
1483 if (score > best_score)
1485 best_outer_em = outer_em;
1486 best_inner_em = inner_em;
1489 if (best_score == 3)
1493 if (best_score == 3)
1508 best_outer_em, best_inner_em,
1511 result =
lappend(result, rinfo);
1533 foreach(lc1, new_members)
1537 if (prev_em != NULL)
1555 result =
lappend(result, rinfo);
1575 Relids nominal_join_relids,
1577 Relids nominal_inner_relids,
1591 result =
lappend(result, restrictinfo);
1676 if (rinfo->
left_em == leftem &&
1686 if (rinfo->
left_em == leftem &&
1916 inner_nullable_relids;
1933 inner_datatype = right_type;
1940 inner_datatype = left_type;
2040 left_nullable_relids,
2041 right_nullable_relids;
2113 if (
equal(leftvar, cfirst) &&
equal(rightvar, csecond))
2130 matchleft = matchright =
false;
2178 if (matchleft && matchright)
2216 bool item1member =
false;
2217 bool item2member =
false;
2235 if (item1member && item2member)
2308 if (!(var &&
IsA(var,
Var)))
2314 else if (var->
varno == var2varno && var->
varattno == var2attno)
2318 if (item1_em && item2_em)
2325 if (opfamilies ==
NIL)
2329 fkinfo->
eclass[colno] = ec;
2430 for (
int pos = 0; pos < num_members; pos++)
2454 Relids new_nullable_relids;
2459 child_expr = (
Expr *)
2467 child_expr = (
Expr *)
2489 if (
bms_overlap(new_nullable_relids, top_parent_relids))
2498 new_relids, new_nullable_relids,
2568 for (
int pos = 0; pos < num_members; pos++)
2595 Relids new_nullable_relids;
2600 child_expr = (
Expr *)
2603 nappinfos, appinfos);
2609 child_expr = (
Expr *)
2631 if (
bms_overlap(new_nullable_relids, top_parent_relids))
2632 new_nullable_relids =
2634 new_nullable_relids,
2639 new_relids, new_nullable_relids,
2694 parent_relids = NULL;
2728 callback(root, rel, cur_ec, cur_em, callback_arg))
2750 if (other_em == cur_em ||
2777 result =
lappend(result, rinfo);
2978 if (parent_ec == NULL)
2981 foreach(lc, clauselist)
3004 foreach(lc, indexclauses)
3014 if (rinfo == otherrinfo)
3017 if (parent_ec && otherrinfo->
parent_ec == parent_ec)
bool exprs_known_equal(PlannerInfo *root, Node *item1, Node *item2)
static bool reconsider_full_join_clause(PlannerInfo *root, RestrictInfo *rinfo)
static void generate_base_implied_equalities_no_const(PlannerInfo *root, EquivalenceClass *ec)
bool get_func_leakproof(Oid funcid)
static RestrictInfo * create_join_clause(PlannerInfo *root, EquivalenceClass *ec, Oid opno, EquivalenceMember *leftem, EquivalenceMember *rightem, EquivalenceClass *parent_ec)
#define IsA(nodeptr, _type_)
bool is_redundant_derived_clause(RestrictInfo *rinfo, List *clauselist)
Bitmapset * bms_copy(const Bitmapset *a)
RestrictInfo * make_restrictinfo(Expr *clause, bool is_pushed_down, bool outerjoin_delayed, bool pseudoconstant, Index security_level, Relids required_relids, Relids outer_relids, Relids nullable_relids)
bool equal(const void *a, const void *b)
Node * applyRelabelType(Node *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat, int rlocation, bool overwrite_ok)
int32 exprTypmod(const Node *expr)
#define IS_OTHER_REL(rel)
bool eclass_useful_for_merging(PlannerInfo *root, EquivalenceClass *eclass, RelOptInfo *rel)
Relids em_nullable_relids
List * get_mergejoin_opfamilies(Oid opno)
int bms_next_member(const Bitmapset *a, int prevbit)
bool expression_returns_set(Node *clause)
EquivalenceClass * get_eclass_for_sort_expr(PlannerInfo *root, Expr *expr, Relids nullable_relids, List *opfamilies, Oid opcintype, Oid collation, Index sortref, Relids rel, bool create_it)
Bitmapset * bms_difference(const Bitmapset *a, const Bitmapset *b)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static void generate_base_implied_equalities_broken(PlannerInfo *root, EquivalenceClass *ec)
List * list_copy(const List *oldlist)
List * list_concat(List *list1, const List *list2)
bool bms_get_singleton_member(const Bitmapset *a, int *member)
Relids adjust_child_relids_multilevel(PlannerInfo *root, Relids relids, Relids child_relids, Relids top_parent_relids)
EquivalenceClass * right_ec
List * pull_var_clause(Node *node, int flags)
static bool reconsider_outer_join_clause(PlannerInfo *root, RestrictInfo *rinfo, bool outer_on_left)
void add_child_rel_equivalences(PlannerInfo *root, AppendRelInfo *appinfo, RelOptInfo *parent_rel, RelOptInfo *child_rel)
bool contain_volatile_functions(Node *clause)
#define OidIsValid(objectId)
#define IS_SIMPLE_REL(rel)
static struct cvec * eclass(struct vars *v, chr c, int cases)
struct RelOptInfo ** simple_rel_array
Node * adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node, Relids child_relids, Relids top_parent_relids)
#define foreach_delete_current(lst, cell)
void add_vars_to_targetlist(PlannerInfo *root, List *vars, Relids where_needed, bool create_new_ph)
void add_child_join_rel_equivalences(PlannerInfo *root, int nappinfos, AppendRelInfo **appinfos, RelOptInfo *parent_joinrel, RelOptInfo *child_joinrel)
bool is_parallel_safe(PlannerInfo *root, Node *node)
void pfree(void *pointer)
void distribute_restrictinfo_to_rels(PlannerInfo *root, RestrictInfo *restrictinfo)
bool op_hashjoinable(Oid opno, Oid inputtype)
bool process_equivalence(PlannerInfo *root, RestrictInfo **p_restrictinfo, bool below_outer_join)
static void * list_nth(const List *list, int n)
List * generate_join_implied_equalities(PlannerInfo *root, Relids join_relids, Relids outer_relids, RelOptInfo *inner_rel)
EquivalenceMember * left_em
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
static Bitmapset * get_eclass_indexes_for_relids(PlannerInfo *root, Relids relids)
Oid conpfeqop[INDEX_MAX_KEYS]
EquivalenceClass * parent_ec
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
bool is_redundant_with_indexclauses(RestrictInfo *rinfo, List *indexclauses)
Expr * canonicalize_ec_expression(Expr *expr, Oid req_type, Oid req_collation)
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
#define lfirst_node(type, lc)
static Oid select_equality_operator(EquivalenceClass *ec, Oid lefttype, Oid righttype)
Expr * find_em_expr_usable_for_sorting_rel(PlannerInfo *root, EquivalenceClass *ec, RelOptInfo *rel, bool require_parallel_safe)
static List * generate_join_implied_equalities_broken(PlannerInfo *root, EquivalenceClass *ec, Relids nominal_join_relids, Relids outer_relids, Relids nominal_inner_relids, RelOptInfo *inner_rel)
struct RestrictInfo * rinfo
Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy)
Expr * find_em_expr_for_rel(EquivalenceClass *ec, RelOptInfo *rel)
void op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
static Node * get_leftop(const void *clause)
bool has_relevant_eclass_joinclause(PlannerInfo *root, RelOptInfo *rel1)
static List * generate_join_implied_equalities_normal(PlannerInfo *root, EquivalenceClass *ec, Relids join_relids, Relids outer_relids, Relids inner_relids)
int simple_rel_array_size
Relids pull_varnos(Node *node)
bool contain_window_function(Node *clause)
List * lappend(List *list, void *datum)
EquivalenceMember * right_em
bool bms_is_empty(const Bitmapset *a)
struct EquivalenceClass * eclass[INDEX_MAX_KEYS]
#define PVC_INCLUDE_PLACEHOLDERS
BMS_Membership bms_membership(const Bitmapset *a)
struct EquivalenceMember * fk_eclass_member[INDEX_MAX_KEYS]
void * palloc0(Size size)
List * generate_join_implied_equalities_for_ecs(PlannerInfo *root, List *eclasses, Relids join_relids, Relids outer_relids, RelOptInfo *inner_rel)
AttrNumber conkey[INDEX_MAX_KEYS]
static Bitmapset * get_common_eclass_indexes(PlannerInfo *root, Relids relids1, Relids relids2)
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
void generate_base_implied_equalities(PlannerInfo *root)
bool have_relevant_eclass_joinclause(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
NullTestType nulltesttype
Relids find_childrel_parents(PlannerInfo *root, RelOptInfo *rel)
EquivalenceClass * match_eclasses_to_foreign_key_col(PlannerInfo *root, ForeignKeyOptInfo *fkinfo, int colno)
static Node * get_rightop(const void *clause)
RegProcedure get_opcode(Oid opno)
void reconsider_outer_join_clauses(PlannerInfo *root)
bool(* ec_matches_callback_type)(PlannerInfo *root, RelOptInfo *rel, EquivalenceClass *ec, EquivalenceMember *em, void *arg)
#define Assert(condition)
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Oid exprType(const Node *expr)
static int list_length(const List *l)
Oid exprCollation(const Node *expr)
RestrictInfo * build_implied_join_equality(Oid opno, Oid collation, Expr *item1, Expr *item2, Relids qualscope, Relids nullable_relids, Index security_level)
Bitmapset * bms_add_member(Bitmapset *a, int x)
bool func_strict(Oid funcid)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
bool contain_agg_clause(Node *clause)
EquivalenceClass * left_ec
void set_opfuncid(OpExpr *opexpr)
#define PVC_RECURSE_WINDOWFUNCS
void list_free(List *list)
RestrictInfo * find_derived_clause_for_ec_member(EquivalenceClass *ec, EquivalenceMember *em)
static EquivalenceMember * add_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids, Relids nullable_relids, bool is_child, Oid datatype)
#define IS_SRF_CALL(node)
static void generate_base_implied_equalities_const(PlannerInfo *root, EquivalenceClass *ec)
MemoryContext planner_cxt
List * right_join_clauses
bool contain_nonstrict_functions(Node *clause)
static bool is_opclause(const void *clause)
List * list_delete_nth_cell(List *list, int n)
Bitmapset * bms_int_members(Bitmapset *a, const Bitmapset *b)
AttrNumber confkey[INDEX_MAX_KEYS]
#define PVC_RECURSE_AGGREGATES
Bitmapset * eclass_indexes
struct EquivalenceClass * ec_merged
#define BTEqualStrategyNumber
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
#define foreach_current_index(cell)
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
Node * adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos, AppendRelInfo **appinfos)
List * generate_implied_equalities_for_column(PlannerInfo *root, RelOptInfo *rel, ec_matches_callback_type callback, void *callback_arg, Relids prohibited_rels)
RestrictInfo * process_implied_equality(PlannerInfo *root, Oid opno, Oid collation, Expr *item1, Expr *item2, Relids qualscope, Relids nullable_relids, Index security_level, bool below_outer_join, bool both_const)