⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 var.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	return expression_tree_walker(node,								  contain_vars_above_level_walker,								  (void *) sublevels_up);}/* * find_minimum_var_level *	  Recursively scan a clause to find the lowest variable level it *	  contains --- for example, zero is returned if there are any local *	  variables, one if there are no local variables but there are *	  one-level-up outer references, etc.  Subqueries are scanned to see *	  if they possess relevant outer references.  (But any local variables *	  within subqueries are not relevant.) * *	  -1 is returned if the clause has no variables at all. * * Will recurse into sublinks.	Also, may be invoked directly on a Query. */intfind_minimum_var_level(Node *node){	find_minimum_var_level_context context;	context.min_varlevel = -1;	/* signifies nothing found yet */	context.sublevels_up = 0;	(void) query_or_expression_tree_walker(node,										   find_minimum_var_level_walker,										   (void *) &context,										   0);	return context.min_varlevel;}static boolfind_minimum_var_level_walker(Node *node,							  find_minimum_var_level_context *context){	if (node == NULL)		return false;	if (IsA(node, Var))	{		int			varlevelsup = ((Var *) node)->varlevelsup;		/* convert levelsup to frame of reference of original query */		varlevelsup -= context->sublevels_up;		/* ignore local vars of subqueries */		if (varlevelsup >= 0)		{			if (context->min_varlevel < 0 ||				context->min_varlevel > varlevelsup)			{				context->min_varlevel = varlevelsup;				/*				 * As soon as we find a local variable, we can abort the tree				 * traversal, since min_varlevel is then certainly 0.				 */				if (varlevelsup == 0)					return true;			}		}	}	/*	 * An Aggref must be treated like a Var of its level.  Normally we'd get	 * the same result from looking at the Vars in the aggregate's argument,	 * but this fails in the case of a Var-less aggregate call (COUNT(*)).	 */	if (IsA(node, Aggref))	{		int			agglevelsup = ((Aggref *) node)->agglevelsup;		/* convert levelsup to frame of reference of original query */		agglevelsup -= context->sublevels_up;		/* ignore local aggs of subqueries */		if (agglevelsup >= 0)		{			if (context->min_varlevel < 0 ||				context->min_varlevel > agglevelsup)			{				context->min_varlevel = agglevelsup;				/*				 * As soon as we find a local aggregate, we can abort the tree				 * traversal, since min_varlevel is then certainly 0.				 */				if (agglevelsup == 0)					return true;			}		}	}	if (IsA(node, Query))	{		/* Recurse into subselects */		bool		result;		context->sublevels_up++;		result = query_tree_walker((Query *) node,								   find_minimum_var_level_walker,								   (void *) context,								   0);		context->sublevels_up--;		return result;	}	return expression_tree_walker(node,								  find_minimum_var_level_walker,								  (void *) context);}/* * pull_var_clause *	  Recursively pulls all var nodes from an expression clause. * *	  Upper-level vars (with varlevelsup > 0) are included only *	  if includeUpperVars is true.	Most callers probably want *	  to ignore upper-level vars. * *	  Returns list of varnodes found.  Note the varnodes themselves are not *	  copied, only referenced. * * Does not examine subqueries, therefore must only be used after reduction * of sublinks to subplans! */List *pull_var_clause(Node *node, bool includeUpperVars){	pull_var_clause_context context;	context.varlist = NIL;	context.includeUpperVars = includeUpperVars;	pull_var_clause_walker(node, &context);	return context.varlist;}static boolpull_var_clause_walker(Node *node, pull_var_clause_context *context){	if (node == NULL)		return false;	if (IsA(node, Var))	{		if (((Var *) node)->varlevelsup == 0 || context->includeUpperVars)			context->varlist = lappend(context->varlist, node);		return false;	}	return expression_tree_walker(node, pull_var_clause_walker,								  (void *) context);}/* * flatten_join_alias_vars *	  Replace Vars that reference JOIN outputs with references to the original *	  relation variables instead.  This allows quals involving such vars to be *	  pushed down.	Whole-row Vars that reference JOIN relations are expanded *	  into RowExpr constructs that name the individual output Vars.  This *	  is necessary since we will not scan the JOIN as a base relation, which *	  is the only way that the executor can directly handle whole-row Vars. * * NOTE: this is used on not-yet-planned expressions.  We do not expect it * to be applied directly to a Query node. */Node *flatten_join_alias_vars(PlannerInfo *root, Node *node){	flatten_join_alias_vars_context context;	context.root = root;	context.sublevels_up = 0;	return flatten_join_alias_vars_mutator(node, &context);}static Node *flatten_join_alias_vars_mutator(Node *node,								flatten_join_alias_vars_context *context){	if (node == NULL)		return NULL;	if (IsA(node, Var))	{		Var		   *var = (Var *) node;		RangeTblEntry *rte;		Node	   *newvar;		/* No change unless Var belongs to a JOIN of the target level */		if (var->varlevelsup != context->sublevels_up)			return node;		/* no need to copy, really */		rte = rt_fetch(var->varno, context->root->parse->rtable);		if (rte->rtekind != RTE_JOIN)			return node;		if (var->varattno == InvalidAttrNumber)		{			/* Must expand whole-row reference */			RowExpr    *rowexpr;			List	   *fields = NIL;			AttrNumber	attnum;			ListCell   *l;			attnum = 0;			foreach(l, rte->joinaliasvars)			{				newvar = (Node *) lfirst(l);				attnum++;				/* Ignore dropped columns */				if (IsA(newvar, Const))					continue;				/*				 * If we are expanding an alias carried down from an upper				 * query, must adjust its varlevelsup fields.				 */				if (context->sublevels_up != 0)				{					newvar = copyObject(newvar);					IncrementVarSublevelsUp(newvar, context->sublevels_up, 0);				}				/* Recurse in case join input is itself a join */				newvar = flatten_join_alias_vars_mutator(newvar, context);				fields = lappend(fields, newvar);			}			rowexpr = makeNode(RowExpr);			rowexpr->args = fields;			rowexpr->row_typeid = var->vartype;			rowexpr->row_format = COERCE_IMPLICIT_CAST;			return (Node *) rowexpr;		}		/* Expand join alias reference */		Assert(var->varattno > 0);		newvar = (Node *) list_nth(rte->joinaliasvars, var->varattno - 1);		/*		 * If we are expanding an alias carried down from an upper query, must		 * adjust its varlevelsup fields.		 */		if (context->sublevels_up != 0)		{			newvar = copyObject(newvar);			IncrementVarSublevelsUp(newvar, context->sublevels_up, 0);		}		/* Recurse in case join input is itself a join */		return flatten_join_alias_vars_mutator(newvar, context);	}	if (IsA(node, InClauseInfo))	{		/* Copy the InClauseInfo node with correct mutation of subnodes */		InClauseInfo *ininfo;		ininfo = (InClauseInfo *) expression_tree_mutator(node,											 flatten_join_alias_vars_mutator,														  (void *) context);		/* now fix InClauseInfo's relid sets */		if (context->sublevels_up == 0)		{			ininfo->lefthand = alias_relid_set(context->root,											   ininfo->lefthand);			ininfo->righthand = alias_relid_set(context->root,												ininfo->righthand);		}		return (Node *) ininfo;	}	if (IsA(node, Query))	{		/* Recurse into RTE subquery or not-yet-planned sublink subquery */		Query	   *newnode;		context->sublevels_up++;		newnode = query_tree_mutator((Query *) node,									 flatten_join_alias_vars_mutator,									 (void *) context,									 QTW_IGNORE_JOINALIASES);		context->sublevels_up--;		return (Node *) newnode;	}	/* Already-planned tree not supported */	Assert(!is_subplan(node));	return expression_tree_mutator(node, flatten_join_alias_vars_mutator,								   (void *) context);}/* * alias_relid_set: in a set of RT indexes, replace joins by their * underlying base relids */static Relidsalias_relid_set(PlannerInfo *root, Relids relids){	Relids		result = NULL;	Relids		tmprelids;	int			rtindex;	tmprelids = bms_copy(relids);	while ((rtindex = bms_first_member(tmprelids)) >= 0)	{		RangeTblEntry *rte = rt_fetch(rtindex, root->parse->rtable);		if (rte->rtekind == RTE_JOIN)			result = bms_join(result, get_relids_for_join(root, rtindex));		else			result = bms_add_member(result, rtindex);	}	bms_free(tmprelids);	return result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -