restrictinfo.c
来自「postgresql8.3.4源码,开源数据库」· C语言 代码 · 共 598 行 · 第 1/2 页
C
598 行
/* * Does it look like a normal join clause, i.e., a binary operator * relating expressions that come from distinct relations? If so we * might be able to use it in a join algorithm. Note that this is a * purely syntactic test that is made regardless of context. */ if (!bms_is_empty(restrictinfo->left_relids) && !bms_is_empty(restrictinfo->right_relids) && !bms_overlap(restrictinfo->left_relids, restrictinfo->right_relids)) { restrictinfo->can_join = true; /* pseudoconstant should certainly not be true */ Assert(!restrictinfo->pseudoconstant); } } else { /* Not a binary opclause, so mark left/right relid sets as empty */ restrictinfo->left_relids = NULL; restrictinfo->right_relids = NULL; /* and get the total relid set the hard way */ restrictinfo->clause_relids = pull_varnos((Node *) clause); } /* required_relids defaults to clause_relids */ if (required_relids != NULL) restrictinfo->required_relids = required_relids; else restrictinfo->required_relids = restrictinfo->clause_relids; /* * Fill in all the cacheable fields with "not yet set" markers. None of * these will be computed until/unless needed. Note in particular that we * don't mark a binary opclause as mergejoinable or hashjoinable here; * that happens only if it appears in the right context (top level of a * joinclause list). */ restrictinfo->parent_ec = NULL; restrictinfo->eval_cost.startup = -1; restrictinfo->this_selec = -1; restrictinfo->mergeopfamilies = NIL; restrictinfo->left_ec = NULL; restrictinfo->right_ec = NULL; restrictinfo->left_em = NULL; restrictinfo->right_em = NULL; restrictinfo->scansel_cache = NIL; restrictinfo->outer_is_left = false; restrictinfo->hashjoinoperator = InvalidOid; restrictinfo->left_bucketsize = -1; restrictinfo->right_bucketsize = -1; return restrictinfo;}/* * Recursively insert sub-RestrictInfo nodes into a boolean expression. * * We put RestrictInfos above simple (non-AND/OR) clauses and above * sub-OR clauses, but not above sub-AND clauses, because there's no need. * This may seem odd but it is closely related to the fact that we use * implicit-AND lists at top level of RestrictInfo lists. Only ORs and * simple clauses are valid RestrictInfos. * * The same is_pushed_down, outerjoin_delayed, and pseudoconstant flag * values can be applied to all RestrictInfo nodes in the result. * * The given required_relids are attached to our top-level output, * but any OR-clause constituents are allowed to default to just the * contained rels. */static Expr *make_sub_restrictinfos(Expr *clause, bool is_pushed_down, bool outerjoin_delayed, bool pseudoconstant, Relids required_relids){ if (or_clause((Node *) clause)) { List *orlist = NIL; ListCell *temp; foreach(temp, ((BoolExpr *) clause)->args) orlist = lappend(orlist, make_sub_restrictinfos(lfirst(temp), is_pushed_down, outerjoin_delayed, pseudoconstant, NULL)); return (Expr *) make_restrictinfo_internal(clause, make_orclause(orlist), is_pushed_down, outerjoin_delayed, pseudoconstant, required_relids); } else if (and_clause((Node *) clause)) { List *andlist = NIL; ListCell *temp; foreach(temp, ((BoolExpr *) clause)->args) andlist = lappend(andlist, make_sub_restrictinfos(lfirst(temp), is_pushed_down, outerjoin_delayed, pseudoconstant, required_relids)); return make_andclause(andlist); } else return (Expr *) make_restrictinfo_internal(clause, NULL, is_pushed_down, outerjoin_delayed, pseudoconstant, required_relids);}/* * restriction_is_or_clause * * Returns t iff the restrictinfo node contains an 'or' clause. */boolrestriction_is_or_clause(RestrictInfo *restrictinfo){ if (restrictinfo->orclause != NULL) return true; else return false;}/* * get_actual_clauses * * Returns a list containing the bare clauses from 'restrictinfo_list'. * * This is only to be used in cases where none of the RestrictInfos can * be pseudoconstant clauses (for instance, it's OK on indexqual lists). */List *get_actual_clauses(List *restrictinfo_list){ List *result = NIL; ListCell *l; foreach(l, restrictinfo_list) { RestrictInfo *rinfo = (RestrictInfo *) lfirst(l); Assert(IsA(rinfo, RestrictInfo)); Assert(!rinfo->pseudoconstant); result = lappend(result, rinfo->clause); } return result;}/* * extract_actual_clauses * * Extract bare clauses from 'restrictinfo_list', returning either the * regular ones or the pseudoconstant ones per 'pseudoconstant'. */List *extract_actual_clauses(List *restrictinfo_list, bool pseudoconstant){ List *result = NIL; ListCell *l; foreach(l, restrictinfo_list) { RestrictInfo *rinfo = (RestrictInfo *) lfirst(l); Assert(IsA(rinfo, RestrictInfo)); if (rinfo->pseudoconstant == pseudoconstant) result = lappend(result, rinfo->clause); } return result;}/* * extract_actual_join_clauses * * Extract bare clauses from 'restrictinfo_list', separating those that * syntactically match the join level from those that were pushed down. * Pseudoconstant clauses are excluded from the results. * * This is only used at outer joins, since for plain joins we don't care * about pushed-down-ness. */voidextract_actual_join_clauses(List *restrictinfo_list, List **joinquals, List **otherquals){ ListCell *l; *joinquals = NIL; *otherquals = NIL; foreach(l, restrictinfo_list) { RestrictInfo *rinfo = (RestrictInfo *) lfirst(l); Assert(IsA(rinfo, RestrictInfo)); if (rinfo->is_pushed_down) { if (!rinfo->pseudoconstant) *otherquals = lappend(*otherquals, rinfo->clause); } else { /* joinquals shouldn't have been marked pseudoconstant */ Assert(!rinfo->pseudoconstant); *joinquals = lappend(*joinquals, rinfo->clause); } }}/* * select_nonredundant_join_clauses * * Given a list of RestrictInfo clauses that are to be applied in a join, * select the ones that are not redundant with any clause in the * reference_list. This is used only for nestloop-with-inner-indexscan * joins: any clauses being checked by the index should be removed from * the qpquals list. * * "Redundant" means either equal() or derived from the same EquivalenceClass. * We have to check the latter because indxqual.c may select different derived * clauses than were selected by generate_join_implied_equalities(). * * Note that we assume the given restrictinfo_list has already been checked * for local redundancies, so we don't check again. */List *select_nonredundant_join_clauses(PlannerInfo *root, List *restrictinfo_list, List *reference_list){ List *result = NIL; ListCell *item; foreach(item, restrictinfo_list) { RestrictInfo *rinfo = (RestrictInfo *) lfirst(item); /* drop it if redundant with any reference clause */ if (join_clause_is_redundant(root, rinfo, reference_list)) continue; /* otherwise, add it to result list */ result = lappend(result, rinfo); } return result;}/* * join_clause_is_redundant * Test whether rinfo is redundant with any clause in reference_list. */static booljoin_clause_is_redundant(PlannerInfo *root, RestrictInfo *rinfo, List *reference_list){ ListCell *refitem; foreach(refitem, reference_list) { RestrictInfo *refrinfo = (RestrictInfo *) lfirst(refitem); /* always consider exact duplicates redundant */ if (equal(rinfo, refrinfo)) return true; /* check if derived from same EquivalenceClass */ if (rinfo->parent_ec != NULL && rinfo->parent_ec == refrinfo->parent_ec) return true; } return false;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?