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

📄 clauses.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * clauses.c *	  routines to manipulate qualification clauses * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.37.2.1 1999/08/02 06:27:07 scrappy Exp $ * * HISTORY *	  AUTHOR			DATE			MAJOR EVENT *	  Andrew Yu			Nov 3, 1994		clause.c and clauses.c combined * *------------------------------------------------------------------------- */#include "postgres.h"#include "catalog/pg_operator.h"#include "nodes/makefuncs.h"#include "nodes/nodeFuncs.h"#include "nodes/plannodes.h"#include "optimizer/clauses.h"#include "optimizer/internal.h"#include "optimizer/var.h"#include "utils/lsyscache.h"static bool fix_opid_walker(Node *node, void *context);Expr *make_clause(int type, Node *oper, List *args){	if (type == AND_EXPR || type == OR_EXPR || type == NOT_EXPR ||		type == OP_EXPR || type == FUNC_EXPR)	{		Expr	   *expr = makeNode(Expr);		/*		 * assume type checking already done and we don't need the type of		 * the expr any more.		 */		expr->typeOid = InvalidOid;		expr->opType = type;		expr->oper = oper;		/* ignored for AND, OR, NOT */		expr->args = args;		return expr;	}	else	{		elog(ERROR, "make_clause: unsupported type %d", type);		/* will this ever happen? translated from lispy C code - ay 10/94 */		return (Expr *) args;	}}/***************************************************************************** *		OPERATOR clause functions *****************************************************************************//* * is_opclause * * Returns t iff the clause is an operator clause: *				(op expr expr) or (op expr). * * [historical note: is_clause has the exact functionality and is used *		throughout the code. They're renamed to is_opclause for clarity. *												- ay 10/94.] */boolis_opclause(Node *clause){	return (clause != NULL &&	  nodeTag(clause) == T_Expr && ((Expr *) clause)->opType == OP_EXPR);}/* * make_opclause *	  Creates a clause given its operator left operand and right *	  operand (if it is non-null). * */Expr *make_opclause(Oper *op, Var *leftop, Var *rightop){	Expr	   *expr = makeNode(Expr);	expr->typeOid = InvalidOid; /* assume type checking done */	expr->opType = OP_EXPR;	expr->oper = (Node *) op;	if (rightop)		expr->args = lcons(leftop, lcons(rightop, NIL));	else		expr->args = lcons(leftop, NIL);	return expr;}/* * get_leftop * * Returns the left operand of a clause of the form (op expr expr) *		or (op expr) * NB: it is assumed (for now) that all expr must be Var nodes */Var *get_leftop(Expr *clause){	if (clause->args != NULL)		return lfirst(clause->args);	else		return NULL;}/* * get_rightop * * Returns the right operand in a clause of the form (op expr expr). * NB: result will be NULL if applied to a unary op clause. */Var *get_rightop(Expr *clause){	if (clause->args != NULL && lnext(clause->args) != NULL)		return lfirst(lnext(clause->args));	else		return NULL;}/***************************************************************************** *		FUNC clause functions *****************************************************************************//* * is_funcclause * * Returns t iff the clause is a function clause: (func { expr }). * */boolis_funcclause(Node *clause){	return (clause != NULL &&			nodeTag(clause) == T_Expr &&			((Expr *) clause)->opType == FUNC_EXPR);}/* * make_funcclause * * Creates a function clause given the FUNC node and the functional * arguments. * */Expr *make_funcclause(Func *func, List *funcargs){	Expr	   *expr = makeNode(Expr);	expr->typeOid = InvalidOid; /* assume type checking done */	expr->opType = FUNC_EXPR;	expr->oper = (Node *) func;	expr->args = funcargs;	return expr;}/***************************************************************************** *		OR clause functions *****************************************************************************//* * or_clause * * Returns t iff the clause is an 'or' clause: (OR { expr }). * */boolor_clause(Node *clause){	return clause != NULL &&	nodeTag(clause) == T_Expr &&	((Expr *) clause)->opType == OR_EXPR;}/* * make_orclause * * Creates an 'or' clause given a list of its subclauses. * */Expr *make_orclause(List *orclauses){	Expr	   *expr = makeNode(Expr);	expr->typeOid = InvalidOid; /* assume type checking done */	expr->opType = OR_EXPR;	expr->oper = NULL;	expr->args = orclauses;	return expr;}/***************************************************************************** *		NOT clause functions *****************************************************************************//* * not_clause * * Returns t iff this is a 'not' clause: (NOT expr). * */boolnot_clause(Node *clause){	return (clause != NULL &&			nodeTag(clause) == T_Expr &&			((Expr *) clause)->opType == NOT_EXPR);}/* * make_notclause * * Create a 'not' clause given the expression to be negated. * */Expr *make_notclause(Expr *notclause){	Expr	   *expr = makeNode(Expr);	expr->typeOid = InvalidOid; /* assume type checking done */	expr->opType = NOT_EXPR;	expr->oper = NULL;	expr->args = lcons(notclause, NIL);	return expr;}/* * get_notclausearg * * Retrieve the clause within a 'not' clause * */Expr *get_notclausearg(Expr *notclause){	return lfirst(notclause->args);}/***************************************************************************** *		AND clause functions *****************************************************************************//* * and_clause * * Returns t iff its argument is an 'and' clause: (AND { expr }). * */booland_clause(Node *clause){	return (clause != NULL &&			nodeTag(clause) == T_Expr &&			((Expr *) clause)->opType == AND_EXPR);}/* * make_andclause * * Create an 'and' clause given its arguments in a list. * */Expr *make_andclause(List *andclauses){	Expr	   *expr = makeNode(Expr);	expr->typeOid = InvalidOid; /* assume type checking done */	expr->opType = AND_EXPR;	expr->oper = NULL;	expr->args = andclauses;	return expr;}/***************************************************************************** *		CASE clause functions *****************************************************************************//* * case_clause * * Returns t iff its argument is a 'case' clause: (CASE { expr }). * */boolcase_clause(Node *clause){	return (clause != NULL &&			nodeTag(clause) == T_CaseExpr);}/***************************************************************************** *																			 * *																			 * *																			 * *****************************************************************************//* * pull_constant_clauses *	  Scans through a list of qualifications and find those that *	  contain no variables. * * Returns a list of the constant clauses in constantQual and the remaining * quals as the return value. * */List *pull_constant_clauses(List *quals, List **constantQual){	List	   *q;	List	   *constqual = NIL;	List	   *restqual = NIL;	foreach(q, quals)	{		if (!contain_var_clause(lfirst(q)))			constqual = lcons(lfirst(q), constqual);		else			restqual = lcons(lfirst(q), restqual);	}	freeList(quals);	*constantQual = constqual;	return restqual;}/* * clause_relids_vars *	  Retrieves relids and vars appearing within a clause. *	  Returns ((relid1 relid2 ... relidn) (var1 var2 ... varm)) where *	  vars appear in the clause  this is done by recursively searching *	  through the left and right operands of a clause. * * Returns the list of relids and vars. * */voidclause_get_relids_vars(Node *clause, Relids *relids, List **vars){	List	   *clvars = pull_var_clause(clause);	List	   *var_list = NIL;	List	   *varno_list = NIL;	List	   *i;	foreach(i, clvars)	{		Var		   *var = (Var *) lfirst(i);		List	   *vi;		Assert(var->varlevelsup == 0);		if (!intMember(var->varno, varno_list))			varno_list = lappendi(varno_list, var->varno);		foreach(vi, var_list)		{			Var		   *in_list = (Var *) lfirst(vi);			if (in_list->varno == var->varno &&				in_list->varattno == var->varattno)				break;		}		if (vi == NIL)			var_list = lappend(var_list, var);	}	*relids = varno_list;	*vars = var_list;}/* * NumRelids *		(formerly clause_relids) * * Returns the number of different relations referenced in 'clause'. */intNumRelids(Node *clause){	List	   *vars = pull_var_clause(clause);	List	   *var_list = NIL;	List	   *i;	foreach(i, vars)	{		Var		   *var = (Var *) lfirst(i);		if (!intMember(var->varno, var_list))			var_list = lconsi(var->varno, var_list);	}	return length(var_list);}/* * contains_not * * Returns t iff the clause is a 'not' clause or if any of the * subclauses within an 'or' clause contain 'not's. * * NOTE that only the top-level AND/OR structure is searched for NOTs; * we are not interested in buried substructure. */boolcontains_not(Node *clause){	if (single_node(clause))		return false;	if (not_clause(clause))		return true;	if (or_clause(clause) || and_clause(clause))	{		List	   *a;		foreach(a, ((Expr *) clause)->args)		{			if (contains_not(lfirst(a)))				return true;		}	}	return false;}/* * is_joinable * * Returns t iff 'clause' is a valid join clause. * */boolis_joinable(Node *clause){	Node	   *leftop,			   *rightop;	if (!is_opclause(clause))		return false;	leftop = (Node *) get_leftop((Expr *) clause);	rightop = (Node *) get_rightop((Expr *) clause);	if (!rightop)		return false;			/* unary opclauses need not apply */	/*	 * One side of the clause (i.e. left or right operands) must either be	 * a var node ...	 */	if (IsA(leftop, Var) ||IsA(rightop, Var))		return true;

⌨️ 快捷键说明

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