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

📄 execqual.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 5 页
字号:
 * *		Evaluate a NullTest node. * ---------------------------------------------------------------- */static DatumExecEvalNullTest(GenericExprState *nstate,				 ExprContext *econtext,				 bool *isNull,				 ExprDoneCond *isDone){	NullTest   *ntest = (NullTest *) nstate->xprstate.expr;	Datum		result;	result = ExecEvalExpr(nstate->arg, econtext, isNull, isDone);	if (isDone && *isDone == ExprEndResult)		return result;			/* nothing to check */	switch (ntest->nulltesttype)	{		case IS_NULL:			if (*isNull)			{				*isNull = false;				return BoolGetDatum(true);			}			else				return BoolGetDatum(false);		case IS_NOT_NULL:			if (*isNull)			{				*isNull = false;				return BoolGetDatum(false);			}			else				return BoolGetDatum(true);		default:			elog(ERROR, "unrecognized nulltesttype: %d",				 (int) ntest->nulltesttype);			return (Datum) 0;	/* keep compiler quiet */	}}/* ---------------------------------------------------------------- *		ExecEvalBooleanTest * *		Evaluate a BooleanTest node. * ---------------------------------------------------------------- */static DatumExecEvalBooleanTest(GenericExprState *bstate,					ExprContext *econtext,					bool *isNull,					ExprDoneCond *isDone){	BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;	Datum		result;	result = ExecEvalExpr(bstate->arg, econtext, isNull, isDone);	if (isDone && *isDone == ExprEndResult)		return result;			/* nothing to check */	switch (btest->booltesttype)	{		case IS_TRUE:			if (*isNull)			{				*isNull = false;				return BoolGetDatum(false);			}			else if (DatumGetBool(result))				return BoolGetDatum(true);			else				return BoolGetDatum(false);		case IS_NOT_TRUE:			if (*isNull)			{				*isNull = false;				return BoolGetDatum(true);			}			else if (DatumGetBool(result))				return BoolGetDatum(false);			else				return BoolGetDatum(true);		case IS_FALSE:			if (*isNull)			{				*isNull = false;				return BoolGetDatum(false);			}			else if (DatumGetBool(result))				return BoolGetDatum(false);			else				return BoolGetDatum(true);		case IS_NOT_FALSE:			if (*isNull)			{				*isNull = false;				return BoolGetDatum(true);			}			else if (DatumGetBool(result))				return BoolGetDatum(true);			else				return BoolGetDatum(false);		case IS_UNKNOWN:			if (*isNull)			{				*isNull = false;				return BoolGetDatum(true);			}			else				return BoolGetDatum(false);		case IS_NOT_UNKNOWN:			if (*isNull)			{				*isNull = false;				return BoolGetDatum(false);			}			else				return BoolGetDatum(true);		default:			elog(ERROR, "unrecognized booltesttype: %d",				 (int) btest->booltesttype);			return (Datum) 0;	/* keep compiler quiet */	}}/* * ExecEvalCoerceToDomain * * Test the provided data against the domain constraint(s).  If the data * passes the constraint specifications, pass it through (return the * datum) otherwise throw an error. */static DatumExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,					   bool *isNull, ExprDoneCond *isDone){	CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;	Datum		result;	List	   *l;	result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);	if (isDone && *isDone == ExprEndResult)		return result;			/* nothing to check */	foreach(l, cstate->constraints)	{		DomainConstraintState *con = (DomainConstraintState *) lfirst(l);		switch (con->constrainttype)		{			case DOM_CONSTRAINT_NOTNULL:				if (*isNull)					ereport(ERROR,							(errcode(ERRCODE_NOT_NULL_VIOLATION),						   errmsg("domain %s does not allow null values",								  format_type_be(ctest->resulttype))));				break;			case DOM_CONSTRAINT_CHECK:				{					Datum		conResult;					bool		conIsNull;					Datum		save_datum;					bool		save_isNull;					/*					 * Set up value to be returned by CoerceToDomainValue					 * nodes. We must save and restore prior setting of					 * econtext's domainValue fields, in case this node is					 * itself within a check expression for another					 * domain.					 */					save_datum = econtext->domainValue_datum;					save_isNull = econtext->domainValue_isNull;					econtext->domainValue_datum = result;					econtext->domainValue_isNull = *isNull;					conResult = ExecEvalExpr(con->check_expr,											 econtext, &conIsNull, NULL);					if (!conIsNull &&						!DatumGetBool(conResult))						ereport(ERROR,								(errcode(ERRCODE_CHECK_VIOLATION),								 errmsg("value for domain %s violates check constraint \"%s\"",										format_type_be(ctest->resulttype),										con->name)));					econtext->domainValue_datum = save_datum;					econtext->domainValue_isNull = save_isNull;					break;				}			default:				elog(ERROR, "unrecognized constraint type: %d",					 (int) con->constrainttype);				break;		}	}	/* If all has gone well (constraints did not fail) return the datum */	return result;}/* * ExecEvalCoerceToDomainValue * * Return the value stored by CoerceToDomain. */static DatumExecEvalCoerceToDomainValue(CoerceToDomainValue *conVal,							ExprContext *econtext, bool *isNull){	*isNull = econtext->domainValue_isNull;	return econtext->domainValue_datum;}/* ---------------------------------------------------------------- *		ExecEvalFieldSelect * *		Evaluate a FieldSelect node. * ---------------------------------------------------------------- */static DatumExecEvalFieldSelect(GenericExprState *fstate,					ExprContext *econtext,					bool *isNull,					ExprDoneCond *isDone){	FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;	Datum		result;	TupleTableSlot *resSlot;	result = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);	/* this test covers the isDone exception too: */	if (*isNull)		return result;	resSlot = (TupleTableSlot *) DatumGetPointer(result);	Assert(resSlot != NULL && IsA(resSlot, TupleTableSlot));	result = heap_getattr(resSlot->val,						  fselect->fieldnum,						  resSlot->ttc_tupleDescriptor,						  isNull);	return result;}/* ---------------------------------------------------------------- *		ExecEvalExpr * *		Recursively evaluate a targetlist or qualification expression. * * Inputs: *		expression: the expression state tree to evaluate *		econtext: evaluation context information * * Outputs: *		return value: Datum value of result *		*isNull: set to TRUE if result is NULL (actual return value is *				 meaningless if so); set to FALSE if non-null result *		*isDone: set to indicator of set-result status * * A caller that can only accept a singleton (non-set) result should pass * NULL for isDone; if the expression computes a set result then an error * will be reported via ereport.  If the caller does pass an isDone pointer * then *isDone is set to one of these three states: *		ExprSingleResult		singleton result (not a set) *		ExprMultipleResult		return value is one element of a set *		ExprEndResult			there are no more elements in the set * When ExprMultipleResult is returned, the caller should invoke * ExecEvalExpr() repeatedly until ExprEndResult is returned.  ExprEndResult * is returned after the last real set element.  For convenience isNull will * always be set TRUE when ExprEndResult is returned, but this should not be * taken as indicating a NULL element of the set.  Note that these return * conventions allow us to distinguish among a singleton NULL, a NULL element * of a set, and an empty set. * * The caller should already have switched into the temporary memory * context econtext->ecxt_per_tuple_memory.  The convenience entry point * ExecEvalExprSwitchContext() is provided for callers who don't prefer to * do the switch in an outer loop.	We do not do the switch here because * it'd be a waste of cycles during recursive entries to ExecEvalExpr(). * * This routine is an inner loop routine and must be as fast as possible. * ---------------------------------------------------------------- */DatumExecEvalExpr(ExprState *expression,			 ExprContext *econtext,			 bool *isNull,			 ExprDoneCond *isDone){	Datum		retDatum;	Expr	   *expr;	/* Set default values for result flags: non-null, not a set result */	*isNull = false;	if (isDone)		*isDone = ExprSingleResult;	/* Is this still necessary?  Doubtful... */	if (expression == NULL)	{		*isNull = true;		return (Datum) 0;	}	/*	 * here we dispatch the work to the appropriate type of function given	 * the type of our expression.	 */	expr = expression->expr;	switch (nodeTag(expr))	{		case T_Var:			retDatum = ExecEvalVar((Var *) expr, econtext, isNull);			break;		case T_Const:			{				Const	   *con = (Const *) expr;				retDatum = con->constvalue;				*isNull = con->constisnull;				break;			}		case T_Param:			retDatum = ExecEvalParam((Param *) expr, econtext, isNull);			break;		case T_Aggref:			retDatum = ExecEvalAggref((AggrefExprState *) expression,									  econtext,									  isNull);			break;		case T_ArrayRef:			retDatum = ExecEvalArrayRef((ArrayRefExprState *) expression,										econtext,										isNull,										isDone);			break;		case T_FuncExpr:			retDatum = ExecEvalFunc((FuncExprState *) expression, econtext,									isNull, isDone);			break;		case T_OpExpr:			retDatum = ExecEvalOper((FuncExprState *) expression, econtext,									isNull, isDone);			break;		case T_DistinctExpr:			retDatum = ExecEvalDistinct((FuncExprState *) expression, econtext,										isNull);			break;		case T_ScalarArrayOpExpr:			retDatum = ExecEvalScalarArrayOp((ScalarArrayOpExprState *) expression,											 econtext, isNull);			break;		case T_BoolExpr:			{				BoolExprState *state = (BoolExprState *) expression;				switch (((BoolExpr *) expr)->boolop)				{					case AND_EXPR:						retDatum = ExecEvalAnd(state, econtext, isNull);						break;					case OR_EXPR:						retDatum = ExecEvalOr(state, econtext, isNull);						break;					case NOT_EXPR:						retDatum = ExecEvalNot(state, econtext, isNull);						break;					default:						elog(ERROR, "unrecognized boolop: %d",							 (int) ((BoolExpr *) expr)->boolop);						retDatum = 0;	/* keep compiler quiet */						break;				}				break;			}		case T_SubPlan:			retDatum = ExecSubPlan((SubPlanState *) expression,								   econtext,								   isNull);			break;		case T_FieldSelect:			retDatum = ExecEvalFieldSelect((GenericExprState *) expression,										   econtext,										   isNull,										   isDone);			break;		case T_RelabelType:			retDatum = ExecEvalExpr(((GenericExprState *) expression)->arg,									econtext,									isNull,									isDone);			break;		case T_CaseExpr:			retDatum = ExecEvalCase((CaseExprState *) expression,									econtext,									isNull,									isDone);			break;		case T_ArrayExpr:			retDatum = ExecEvalArray((ArrayExprState *) expression,									 econtext,									 isNull);			break;		case T_CoalesceExpr:			retDatum = ExecEvalCoalesce((CoalesceExprState *) expression,										econtext,										isNull);			break;		case T_NullIfExpr:			retDatum = ExecEvalNullIf((FuncExprState *) expression,									  econtext,									  isNull);			break;		case T_NullTest:			retDatum = ExecEvalNullTest((GenericExprState *) expression,										econtext,										isNull,										isDone);			break;		case T_BooleanTest:			retDatum = ExecEvalBooleanTest((GenericExprState *) expression,										   econtext,										   isNull,										   isDone);			break;		case T_CoerceToDomain:			retDatum = ExecEvalCoerceToDomain((CoerceToDomainState *) expression,											  econtext,											  isNull,											  isDone);			break;		case T_CoerceToDomainValue:			retDatum = ExecEvalCoerceToDomainValue((CoerceToDomainValue *) expr,												   econtext,												   isNull);			break;		default:			elog(ERROR, "unrecognized node type: %d",				 (int) nodeTag(expression));			retDatum = 0;		/* keep compiler quiet */			break;	}	return retDatum;}	/* ExecEvalExpr() *//* * Same as above, but get into the right allocation context explicitly. */DatumExecEvalExprSwitchContext(ExprState *expression,						  ExprContext *econtext,						  bool *isNull,						  ExprDoneCond *isDone){	Datum		retDatum;	MemoryContext oldContext;	oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);	retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);	MemoryContextSwitchTo(oldContext);	return retDatum;}/* * ExecInitExpr: prepare an expression tree for execution * * This function builds and returns an ExprState tree

⌨️ 快捷键说明

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