72 Oid lefttype,
Oid righttype);
124#define EC_DERIVES_HASH_THRESHOLD 32
126#define SH_PREFIX derives
127#define SH_ELEMENT_TYPE ECDerivesEntry
128#define SH_KEY_TYPE ECDerivesKey
130#define SH_HASH_KEY(tb, key) \
131 hash_bytes((const unsigned char *) &(key), sizeof(ECDerivesKey))
132#define SH_EQUAL(tb, a, b) \
133 ((a).em1 == (b).em1 && (a).em2 == (b).em2 && (a).parent_ec == (b).parent_ec)
134#define SH_SCOPE static inline
211 opno = ((
OpExpr *) clause)->opno;
212 collation = ((
OpExpr *) clause)->inputcollid;
254 ntest->argisrow =
false;
255 ntest->location = -1;
311 if (
cur_ec->ec_has_volatile)
318 if (collation !=
cur_ec->ec_collation)
343 if (
cur_em->em_is_const &&
cur_em->em_jdomain != jdomain)
380 ec1->ec_min_security =
Min(
ec1->ec_min_security,
382 ec1->ec_max_security =
Max(
ec1->ec_max_security,
399 if (
root->ec_merging_done)
400 elog(
ERROR,
"too late to merge equivalence classes");
418 ec1->ec_has_const |=
ec2->ec_has_const;
420 ec1->ec_min_security =
Min(
ec1->ec_min_security,
421 ec2->ec_min_security);
422 ec1->ec_max_security =
Max(
ec1->ec_max_security,
423 ec2->ec_max_security);
432 ec1->ec_min_security =
Min(
ec1->ec_min_security,
434 ec1->ec_max_security =
Max(
ec1->ec_max_security,
449 ec1->ec_min_security =
Min(
ec1->ec_min_security,
451 ec1->ec_max_security =
Max(
ec1->ec_max_security,
466 ec2->ec_min_security =
Min(
ec2->ec_min_security,
468 ec2->ec_max_security =
Max(
ec2->ec_max_security,
598 em->em_relids = relids;
599 em->em_is_const =
false;
600 em->em_is_child = (parent !=
NULL);
601 em->em_datatype = datatype;
602 em->em_jdomain = jdomain;
603 em->em_parent = parent;
616 em->em_is_const =
true;
681 root->simple_rel_array_size);
776 if (
cur_ec->ec_has_volatile &&
780 if (collation !=
cur_ec->ec_collation)
791 if (
cur_em->em_is_child &&
799 if (
cur_em->em_is_const &&
cur_em->em_jdomain != jdomain)
802 if (opcintype ==
cur_em->em_datatype &&
821 newec->ec_collation = collation;
822 newec->ec_childmembers_size = 0;
829 newec->ec_has_const =
false;
831 newec->ec_broken =
false;
834 newec->ec_max_security = 0;
838 elog(
ERROR,
"volatile EquivalenceClass has no sortref");
854 if (
newec->ec_has_const)
856 if (
newec->ec_has_volatile ||
861 newec->ec_has_const =
false;
862 newem->em_is_const =
false;
872 if (
root->ec_merging_done)
882 if (
i ==
root->group_rtindex)
942 if (
em->em_is_child &&
1022 if (
em->em_is_const)
1028 if (
em->em_is_child &&
1199 root->ec_merging_done =
true;
1202 foreach(
lc,
root->eq_classes)
1245 if (
i ==
root->group_rtindex)
1355 if (rinfo && rinfo->mergeopfamilies)
1358 rinfo->left_ec = rinfo->right_ec = ec;
1436 if (rinfo && rinfo->mergeopfamilies)
1439 rinfo->left_ec = rinfo->right_ec = ec;
1441 rinfo->right_em =
cur_em;
1595 if (sjinfo && sjinfo->
ojrelid != 0)
1835 result =
lappend(result, rinfo);
1880 result =
lappend(result, rinfo);
2045 rinfo->parent_ec = parent_ec;
2051 rinfo->left_ec = ec;
2052 rinfo->right_ec = ec;
2145 foreach(cell,
root->left_join_clauses)
2155 root->left_join_clauses =
2173 foreach(cell,
root->right_join_clauses)
2183 root->right_join_clauses =
2201 foreach(cell,
root->full_join_clauses)
2211 root->full_join_clauses =
2230 foreach(cell,
root->left_join_clauses)
2236 foreach(cell,
root->right_join_clauses)
2242 foreach(cell,
root->full_join_clauses)
2293 foreach(
lc1,
root->eq_classes)
2303 if (!
cur_ec->ec_has_const)
2306 if (
cur_ec->ec_has_volatile)
2309 if (collation !=
cur_ec->ec_collation)
2311 if (!
equal(rinfo->mergeopfamilies,
cur_ec->ec_opfamilies))
2343 if (!
cur_em->em_is_const)
2356 cur_ec->ec_min_security);
2408 foreach(
lc1,
root->eq_classes)
2422 if (!
cur_ec->ec_has_const)
2425 if (
cur_ec->ec_has_volatile)
2428 if (collation !=
cur_ec->ec_collation)
2430 if (!
equal(rinfo->mergeopfamilies,
cur_ec->ec_opfamilies))
2501 if (!
cur_em->em_is_const)
2514 cur_ec->ec_min_security);
2531 cur_ec->ec_min_security);
2577 foreach(
lc,
root->eq_classes)
2620 foreach(
lc,
root->join_domains)
2627 elog(
ERROR,
"failed to find appropriate JoinDomain");
2651 foreach(
lc1,
root->eq_classes)
2729 rel2->eclass_indexes);
2757 var = (
Var *)
em->em_expr;
2760 if (!(var &&
IsA(var,
Var)))
2781 fkinfo->eclass[colno] = ec;
2858 if (
cur_ec->ec_has_volatile)
2976 if (
cur_ec->ec_has_volatile)
3010 nappinfos, appinfos);
3099 elog(
ERROR,
"too few pathkeys for set operation");
3161 it->current_relid = -1;
3176 while (
it->current_list !=
NULL)
3178 while (
it->current_cell !=
NULL)
3184 it->current_cell =
lnext(
it->current_list,
it->current_cell);
3195 if (
it->current_relid >=
it->ec->ec_childmembers_size)
3198 it->current_list =
it->ec->ec_childmembers[
it->current_relid];
3201 if (
it->current_list !=
NIL)
3341 result =
lappend(result, rinfo);
3555 if (parent_ec ==
NULL)
3581 foreach(
lc, indexclauses)
3594 if (parent_ec &&
otherrinfo->parent_ec == parent_ec)
3625 if (
i ==
root->group_rtindex)
3659 rel2ecs =
root->simple_rel_array[relid]->eclass_indexes;
3708 Assert(!clause->left_em->em_is_const);
3714 Assert(!clause->parent_ec || !clause->right_em->em_is_const);
3776 key->parent_ec = parent_ec;
3798 Assert(!rinfo->left_em->em_is_const);
3804 Assert(!rinfo->parent_ec || !rinfo->right_em->em_is_const);
3813 rinfo->right_em->em_is_const ?
NULL : rinfo->right_em,
3817 entry->
rinfo = rinfo;
3861 if (rinfo->left_em ==
leftem &&
3863 rinfo->parent_ec == parent_ec)
3865 if (rinfo->left_em ==
rightem &&
3866 rinfo->right_em ==
leftem &&
3867 rinfo->parent_ec == parent_ec)
3913 rinfo = entry->
rinfo;
3926 rinfo->left_em ==
leftem)
3928 Assert(rinfo->right_em->em_is_const);
3931 if (rinfo->left_em ==
leftem &&
3933 rinfo->parent_ec == parent_ec)
3935 if (rinfo->left_em ==
rightem &&
3936 rinfo->right_em ==
leftem &&
3937 rinfo->parent_ec == parent_ec)
Node * adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos, AppendRelInfo **appinfos)
Node * adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node, RelOptInfo *childrel, RelOptInfo *parentrel)
Bitmapset * bms_difference(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_make_singleton(int x)
Bitmapset * bms_int_members(Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
int bms_next_member(const Bitmapset *a, int prevbit)
Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
bool bms_is_member(int x, const Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
BMS_Membership bms_membership(const Bitmapset *a)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
bool bms_get_singleton_member(const Bitmapset *a, int *member)
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Bitmapset * bms_copy(const Bitmapset *a)
#define Assert(condition)
#define OidIsValid(objectId)
bool contain_agg_clause(Node *clause)
bool contain_window_function(Node *clause)
bool is_parallel_safe(PlannerInfo *root, Node *node)
bool contain_volatile_functions(Node *clause)
bool equal(const void *a, const void *b)
void rebuild_eclass_attr_needed(PlannerInfo *root)
EquivalenceClass * get_eclass_for_sort_expr(PlannerInfo *root, Expr *expr, List *opfamilies, Oid opcintype, Oid collation, Index sortref, Relids rel, bool create_it)
void add_child_rel_equivalences(PlannerInfo *root, AppendRelInfo *appinfo, RelOptInfo *parent_rel, RelOptInfo *child_rel)
bool is_redundant_with_indexclauses(RestrictInfo *rinfo, List *indexclauses)
void generate_base_implied_equalities(PlannerInfo *root)
bool exprs_known_equal(PlannerInfo *root, Node *item1, Node *item2, Oid opfamily)
static List * generate_join_implied_equalities_normal(PlannerInfo *root, EquivalenceClass *ec, Relids join_relids, Relids outer_relids, Relids inner_relids)
static RestrictInfo * ec_search_derived_clause_for_ems(PlannerInfo *root, EquivalenceClass *ec, EquivalenceMember *leftem, EquivalenceMember *rightem, EquivalenceClass *parent_ec)
static void ec_build_derives_hash(PlannerInfo *root, EquivalenceClass *ec)
Expr * canonicalize_ec_expression(Expr *expr, Oid req_type, Oid req_collation)
EquivalenceMember * find_ec_member_matching_expr(EquivalenceClass *ec, Expr *expr, Relids relids)
static void ec_add_clause_to_derives_hash(EquivalenceClass *ec, RestrictInfo *rinfo)
static JoinDomain * find_join_domain(PlannerInfo *root, Relids relids)
bool relation_can_be_sorted_early(PlannerInfo *root, RelOptInfo *rel, EquivalenceClass *ec, bool require_parallel_safe)
void setup_eclass_member_iterator(EquivalenceMemberIterator *it, EquivalenceClass *ec, Relids child_relids)
static void generate_base_implied_equalities_broken(PlannerInfo *root, EquivalenceClass *ec)
void ec_clear_derived_clauses(EquivalenceClass *ec)
static void ec_add_derived_clause(EquivalenceClass *ec, RestrictInfo *clause)
bool process_equivalence(PlannerInfo *root, RestrictInfo **p_restrictinfo, JoinDomain *jdomain)
List * generate_implied_equalities_for_column(PlannerInfo *root, RelOptInfo *rel, ec_matches_callback_type callback, void *callback_arg, Relids prohibited_rels)
static EquivalenceMember * add_child_eq_member(PlannerInfo *root, EquivalenceClass *ec, int ec_index, Expr *expr, Relids relids, JoinDomain *jdomain, EquivalenceMember *parent_em, Oid datatype, Index child_relid)
#define EC_DERIVES_HASH_THRESHOLD
EquivalenceMember * eclass_member_iterator_next(EquivalenceMemberIterator *it)
bool have_relevant_eclass_joinclause(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
EquivalenceMember * find_computable_ec_member(PlannerInfo *root, EquivalenceClass *ec, List *exprs, Relids relids, bool require_parallel_safe)
static Bitmapset * get_common_eclass_indexes(PlannerInfo *root, Relids relids1, Relids relids2)
List * generate_join_implied_equalities_for_ecs(PlannerInfo *root, List *eclasses, Relids join_relids, Relids outer_relids, RelOptInfo *inner_rel)
void add_setop_child_rel_equivalences(PlannerInfo *root, RelOptInfo *child_rel, List *child_tlist, List *setop_pathkeys)
static void fill_ec_derives_key(ECDerivesKey *key, EquivalenceMember *leftem, EquivalenceMember *rightem, EquivalenceClass *parent_ec)
void reconsider_outer_join_clauses(PlannerInfo *root)
bool eclass_useful_for_merging(PlannerInfo *root, EquivalenceClass *eclass, RelOptInfo *rel)
void add_child_join_rel_equivalences(PlannerInfo *root, int nappinfos, AppendRelInfo **appinfos, RelOptInfo *parent_joinrel, RelOptInfo *child_joinrel)
static RestrictInfo * create_join_clause(PlannerInfo *root, EquivalenceClass *ec, Oid opno, EquivalenceMember *leftem, EquivalenceMember *rightem, EquivalenceClass *parent_ec)
static void ec_add_derived_clauses(EquivalenceClass *ec, List *clauses)
static Bitmapset * get_eclass_indexes_for_relids(PlannerInfo *root, Relids relids)
bool is_redundant_derived_clause(RestrictInfo *rinfo, List *clauselist)
RestrictInfo * find_derived_clause_for_ec_member(PlannerInfo *root, EquivalenceClass *ec, EquivalenceMember *em)
static RestrictInfo * ec_search_clause_for_ems(PlannerInfo *root, EquivalenceClass *ec, EquivalenceMember *leftem, EquivalenceMember *rightem, EquivalenceClass *parent_ec)
static void generate_base_implied_equalities_no_const(PlannerInfo *root, EquivalenceClass *ec)
static void generate_base_implied_equalities_const(PlannerInfo *root, EquivalenceClass *ec)
static Oid select_equality_operator(EquivalenceClass *ec, Oid lefttype, Oid righttype)
EquivalenceClass * match_eclasses_to_foreign_key_col(PlannerInfo *root, ForeignKeyOptInfo *fkinfo, int colno)
static EquivalenceMember * make_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids, JoinDomain *jdomain, EquivalenceMember *parent, Oid datatype)
static bool reconsider_outer_join_clause(PlannerInfo *root, OuterJoinClauseInfo *ojcinfo, bool outer_on_left)
List * generate_join_implied_equalities(PlannerInfo *root, Relids join_relids, Relids outer_relids, RelOptInfo *inner_rel, SpecialJoinInfo *sjinfo)
static EquivalenceMember * add_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids, JoinDomain *jdomain, Oid datatype)
bool has_relevant_eclass_joinclause(PlannerInfo *root, RelOptInfo *rel1)
static bool reconsider_full_join_clause(PlannerInfo *root, OuterJoinClauseInfo *ojcinfo)
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)
#define palloc0_array(type, count)
void distribute_restrictinfo_to_rels(PlannerInfo *root, RestrictInfo *restrictinfo)
RestrictInfo * build_implied_join_equality(PlannerInfo *root, Oid opno, Oid collation, Expr *item1, Expr *item2, Relids qualscope, Index security_level)
void add_vars_to_targetlist(PlannerInfo *root, List *vars, Relids where_needed)
RestrictInfo * process_implied_equality(PlannerInfo *root, Oid opno, Oid collation, Expr *item1, Expr *item2, Relids qualscope, Index security_level, bool both_const)
void add_vars_to_attr_needed(PlannerInfo *root, List *vars, Relids where_needed)
Relids add_outer_joins_to_relids(PlannerInfo *root, Relids input_relids, SpecialJoinInfo *sjinfo, List **pushed_down_joins)
List * lappend(List *list, void *datum)
List * list_delete_nth_cell(List *list, int n)
List * list_concat(List *list1, const List *list2)
List * list_copy(const List *oldlist)
void list_free(List *list)
bool list_member_oid(const List *list, Oid datum)
bool list_member(const List *list, const void *datum)
Oid get_opfamily_member_for_cmptype(Oid opfamily, Oid lefttype, Oid righttype, CompareType cmptype)
bool op_hashjoinable(Oid opno, Oid inputtype)
RegProcedure get_opcode(Oid opno)
bool func_strict(Oid funcid)
bool get_func_leakproof(Oid funcid)
List * get_mergejoin_opfamilies(Oid opno)
void op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
Node * makeBoolConst(bool value, bool isnull)
void pfree(void *pointer)
void * palloc0(Size size)
Oid exprType(const Node *expr)
int32 exprTypmod(const Node *expr)
Oid exprCollation(const Node *expr)
Node * applyRelabelType(Node *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat, int rlocation, bool overwrite_ok)
bool expression_returns_set(Node *clause)
void set_opfuncid(OpExpr *opexpr)
static Node * get_rightop(const void *clause)
static bool is_opclause(const void *clause)
static Node * get_leftop(const void *clause)
#define IsA(nodeptr, _type_)
#define PVC_RECURSE_AGGREGATES
#define PVC_RECURSE_WINDOWFUNCS
#define PVC_INCLUDE_WINDOWFUNCS
#define PVC_INCLUDE_PLACEHOLDERS
#define PVC_INCLUDE_AGGREGATES
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define repalloc0_array(pointer, type, oldcount, count)
#define IS_SIMPLE_REL(rel)
@ RELOPT_OTHER_MEMBER_REL
#define IS_OTHER_REL(rel)
bool(* ec_matches_callback_type)(PlannerInfo *root, RelOptInfo *rel, EquivalenceClass *ec, EquivalenceMember *em, void *arg)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define linitial_node(type, l)
#define foreach_current_index(var_or_cell)
#define foreach_delete_current(lst, var_or_cell)
static void * list_nth(const List *list, int n)
#define foreach_node(type, var, lst)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
static struct cvec * eclass(struct vars *v, chr c, int cases)
Relids find_childrel_parents(PlannerInfo *root, RelOptInfo *rel)
RestrictInfo * make_restrictinfo(PlannerInfo *root, Expr *clause, bool is_pushed_down, bool has_clone, bool is_clone, bool pseudoconstant, Index security_level, Relids required_relids, Relids incompatible_relids, Relids outer_relids)
Node * remove_nulling_relids(Node *node, const Bitmapset *removable_relids, const Bitmapset *except_relids)
EquivalenceClass * parent_ec
struct EquivalenceClass * ec_merged
struct derives_hash * ec_derives_hash
struct PathTarget * reltarget
Bitmapset * eclass_indexes
Relids incompatible_relids
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Relids pull_varnos(PlannerInfo *root, Node *node)
List * pull_var_clause(Node *node, int flags)