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

📄 clauses.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
			else				aggtranstypmod = -1;			avgwidth = get_typavgwidth(aggtranstype, aggtranstypmod);			avgwidth = MAXALIGN(avgwidth);			counts->transitionSpace += avgwidth + 2 * sizeof(void *);		}		/*		 * Complain if the aggregate's argument contains any aggregates;		 * nested agg functions are semantically nonsensical.		 */		if (contain_agg_clause((Node *) aggref->target))			ereport(ERROR,					(errcode(ERRCODE_GROUPING_ERROR),					 errmsg("aggregate function calls may not be nested")));		/*		 * Having checked that, we need not recurse into the argument.		 */		return false;	}	Assert(!IsA(node, SubLink));	return expression_tree_walker(node, count_agg_clauses_walker,								  (void *) counts);}/***************************************************************************** *		Support for expressions returning sets *****************************************************************************//* * expression_returns_set *	  Test whether an expression returns a set result. * * Because we use expression_tree_walker(), this can also be applied to * whole targetlists; it'll produce TRUE if any one of the tlist items * returns a set. */boolexpression_returns_set(Node *clause){	return expression_returns_set_walker(clause, NULL);}static boolexpression_returns_set_walker(Node *node, void *context){	if (node == NULL)		return false;	if (IsA(node, FuncExpr))	{		FuncExpr   *expr = (FuncExpr *) node;		if (expr->funcretset)			return true;		/* else fall through to check args */	}	if (IsA(node, OpExpr))	{		OpExpr	   *expr = (OpExpr *) node;		if (expr->opretset)			return true;		/* else fall through to check args */	}	/* Avoid recursion for some cases that can't return a set */	if (IsA(node, Aggref))		return false;	if (IsA(node, DistinctExpr))		return false;	if (IsA(node, ScalarArrayOpExpr))		return false;	if (IsA(node, BoolExpr))		return false;	if (IsA(node, SubLink))		return false;	if (IsA(node, SubPlan))		return false;	if (IsA(node, ArrayExpr))		return false;	if (IsA(node, RowExpr))		return false;	if (IsA(node, CoalesceExpr))		return false;	if (IsA(node, MinMaxExpr))		return false;	if (IsA(node, NullIfExpr))		return false;	return expression_tree_walker(node, expression_returns_set_walker,								  context);}/***************************************************************************** *		Subplan clause manipulation *****************************************************************************//* * contain_subplans *	  Recursively search for subplan nodes within a clause. * * If we see a SubLink node, we will return TRUE.  This is only possible if * the expression tree hasn't yet been transformed by subselect.c.  We do not * know whether the node will produce a true subplan or just an initplan, * but we make the conservative assumption that it will be a subplan. * * Returns true if any subplan found. */boolcontain_subplans(Node *clause){	return contain_subplans_walker(clause, NULL);}static boolcontain_subplans_walker(Node *node, void *context){	if (node == NULL)		return false;	if (IsA(node, SubPlan) ||		IsA(node, SubLink))		return true;			/* abort the tree traversal and return true */	return expression_tree_walker(node, contain_subplans_walker, context);}/***************************************************************************** *		Check clauses for mutable functions *****************************************************************************//* * contain_mutable_functions *	  Recursively search for mutable functions within a clause. * * Returns true if any mutable function (or operator implemented by a * mutable function) is found.	This test is needed so that we don't * mistakenly think that something like "WHERE random() < 0.5" can be treated * as a constant qualification. * * XXX we do not examine sub-selects to see if they contain uses of * mutable functions.  It's not real clear if that is correct or not... */boolcontain_mutable_functions(Node *clause){	return contain_mutable_functions_walker(clause, NULL);}static boolcontain_mutable_functions_walker(Node *node, void *context){	if (node == NULL)		return false;	if (IsA(node, FuncExpr))	{		FuncExpr   *expr = (FuncExpr *) node;		if (func_volatile(expr->funcid) != PROVOLATILE_IMMUTABLE)			return true;		/* else fall through to check args */	}	if (IsA(node, OpExpr))	{		OpExpr	   *expr = (OpExpr *) node;		if (op_volatile(expr->opno) != PROVOLATILE_IMMUTABLE)			return true;		/* else fall through to check args */	}	if (IsA(node, DistinctExpr))	{		DistinctExpr *expr = (DistinctExpr *) node;		if (op_volatile(expr->opno) != PROVOLATILE_IMMUTABLE)			return true;		/* else fall through to check args */	}	if (IsA(node, ScalarArrayOpExpr))	{		ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;		if (op_volatile(expr->opno) != PROVOLATILE_IMMUTABLE)			return true;		/* else fall through to check args */	}	if (IsA(node, NullIfExpr))	{		NullIfExpr *expr = (NullIfExpr *) node;		if (op_volatile(expr->opno) != PROVOLATILE_IMMUTABLE)			return true;		/* else fall through to check args */	}	if (IsA(node, SubLink))	{		SubLink    *sublink = (SubLink *) node;		ListCell   *opid;		foreach(opid, sublink->operOids)		{			if (op_volatile(lfirst_oid(opid)) != PROVOLATILE_IMMUTABLE)				return true;		}		/* else fall through to check args */	}	return expression_tree_walker(node, contain_mutable_functions_walker,								  context);}/***************************************************************************** *		Check clauses for volatile functions *****************************************************************************//* * contain_volatile_functions *	  Recursively search for volatile functions within a clause. * * Returns true if any volatile function (or operator implemented by a * volatile function) is found. This test prevents invalid conversions * of volatile expressions into indexscan quals. * * XXX we do not examine sub-selects to see if they contain uses of * volatile functions.	It's not real clear if that is correct or not... */boolcontain_volatile_functions(Node *clause){	return contain_volatile_functions_walker(clause, NULL);}static boolcontain_volatile_functions_walker(Node *node, void *context){	if (node == NULL)		return false;	if (IsA(node, FuncExpr))	{		FuncExpr   *expr = (FuncExpr *) node;		if (func_volatile(expr->funcid) == PROVOLATILE_VOLATILE)			return true;		/* else fall through to check args */	}	if (IsA(node, OpExpr))	{		OpExpr	   *expr = (OpExpr *) node;		if (op_volatile(expr->opno) == PROVOLATILE_VOLATILE)			return true;		/* else fall through to check args */	}	if (IsA(node, DistinctExpr))	{		DistinctExpr *expr = (DistinctExpr *) node;		if (op_volatile(expr->opno) == PROVOLATILE_VOLATILE)			return true;		/* else fall through to check args */	}	if (IsA(node, ScalarArrayOpExpr))	{		ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;		if (op_volatile(expr->opno) == PROVOLATILE_VOLATILE)			return true;		/* else fall through to check args */	}	if (IsA(node, NullIfExpr))	{		NullIfExpr *expr = (NullIfExpr *) node;		if (op_volatile(expr->opno) == PROVOLATILE_VOLATILE)			return true;		/* else fall through to check args */	}	if (IsA(node, SubLink))	{		SubLink    *sublink = (SubLink *) node;		ListCell   *opid;		foreach(opid, sublink->operOids)		{			if (op_volatile(lfirst_oid(opid)) == PROVOLATILE_VOLATILE)				return true;		}		/* else fall through to check args */	}	return expression_tree_walker(node, contain_volatile_functions_walker,								  context);}/***************************************************************************** *		Check clauses for nonstrict functions *****************************************************************************//* * contain_nonstrict_functions *	  Recursively search for nonstrict functions within a clause. * * Returns true if any nonstrict construct is found --- ie, anything that * could produce non-NULL output with a NULL input. * * The idea here is that the caller has verified that the expression contains * one or more Var or Param nodes (as appropriate for the caller's need), and * now wishes to prove that the expression result will be NULL if any of these * inputs is NULL.	If we return false, then the proof succeeded. */boolcontain_nonstrict_functions(Node *clause){	return contain_nonstrict_functions_walker(clause, NULL);}static boolcontain_nonstrict_functions_walker(Node *node, void *context){	if (node == NULL)		return false;	if (IsA(node, Aggref))	{		/* an aggregate could return non-null with null input */		return true;	}	if (IsA(node, ArrayRef))	{		/* array assignment is nonstrict */		if (((ArrayRef *) node)->refassgnexpr != NULL)			return true;		/* else fall through to check args */	}	if (IsA(node, FuncExpr))	{		FuncExpr   *expr = (FuncExpr *) node;		if (!func_strict(expr->funcid))			return true;		/* else fall through to check args */	}	if (IsA(node, OpExpr))	{		OpExpr	   *expr = (OpExpr *) node;		if (!op_strict(expr->opno))			return true;		/* else fall through to check args */	}	if (IsA(node, DistinctExpr))	{		/* IS DISTINCT FROM is inherently non-strict */		return true;	}	if (IsA(node, ScalarArrayOpExpr))	{		/* inherently non-strict, consider null scalar and empty array */		return true;	}	if (IsA(node, BoolExpr))	{		BoolExpr   *expr = (BoolExpr *) node;		switch (expr->boolop)		{			case AND_EXPR:			case OR_EXPR:				/* AND, OR are inherently non-strict */				return true;			default:				break;		}	}	if (IsA(node, SubLink))	{		/* In some cases a sublink might be strict, but in general not */		return true;	}	if (IsA(node, SubPlan))		return true;	if (IsA(node, FieldStore))		return true;	if (IsA(node, CaseExpr))		return true;	if (IsA(node, CaseWhen))		return true;	/* NB: ArrayExpr might someday be nonstrict */	if (IsA(node, RowExpr))		return true;	if (IsA(node, CoalesceExpr))		return true;	if (IsA(node, MinMaxExpr))		return true;	if (IsA(node, NullIfExpr))		return true;	if (IsA(node, NullTest))		return true;	if (IsA(node, BooleanTest))		return true;	return expression_tree_walker(node, contain_nonstrict_functions_walker,								  context);}/***************************************************************************** *		Check for "pseudo-constant" clauses *****************************************************************************//* * is_pseudo_constant_clause *	  Detect whether a clause is "constant", ie, it contains no variables *	  of the current query level and no uses of volatile functions. *	  Such a clause is not necessarily a true constant: it can still contain *	  Params and outer-level Vars, not to mention functions whose results *	  may vary from one statement to the next.	However, the clause's value *	  will be constant over any one scan of the current query, so it can be *	  used as an indexscan key or (if a top-level qual) can be pushed up to *	  become a gating qual. */boolis_pseudo_constant_clause(Node *clause){	/*	 * We could implement this check in one recursive scan.  But since the	 * check for volatile functions is both moderately expensive and unlikely	 * to fail, it seems better to look for Vars first and only check for	 * volatile functions if we find no Vars.	 */	if (!contain_var_clause(clause) &&		!contain_volatile_functions(clause))		return true;	return false;}/* * is_pseudo_constant_clause_relids *	  Same as above, except caller already has available the var membership *	  of the clause; this lets us avoid the contain_var_clause() scan. */boolis_pseudo_constant_clause_relids(Node *clause, Relids relids){	if (bms_is_empty(relids) &&		!contain_volatile_functions(clause))		return true;	return false;}/* * pull_constant_clauses *		Scan through a list of qualifications and separate "constant" quals *		from those that are not.

⌨️ 快捷键说明

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