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 + -
显示快捷键?