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

📄 execqual.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
		Datum		clause_value;		clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);		/*		 * if we have a non-null true result, then return it.		 */		if (*isNull)			AnyNull = true;		/* remember we got a null */		else if (DatumGetBool(clause_value))			return clause_value;	}	/* AnyNull is true if at least one clause evaluated to NULL */	*isNull = AnyNull;	return BoolGetDatum(false);}/* ---------------------------------------------------------------- *		ExecEvalAnd * ---------------------------------------------------------------- */static DatumExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,			bool *isNull, ExprDoneCond *isDone){	List	   *clauses = andExpr->args;	ListCell   *clause;	bool		AnyNull;	if (isDone)		*isDone = ExprSingleResult;	AnyNull = false;	/*	 * If any of the clauses is FALSE, the AND result is FALSE regardless of	 * the states of the rest of the clauses, so we can stop evaluating and	 * return FALSE immediately.  If none are FALSE and one or more is NULL,	 * we return NULL; otherwise we return TRUE.  This makes sense when you	 * interpret NULL as "don't know", using the same sort of reasoning as for	 * OR, above.	 */	foreach(clause, clauses)	{		ExprState  *clausestate = (ExprState *) lfirst(clause);		Datum		clause_value;		clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);		/*		 * if we have a non-null false result, then return it.		 */		if (*isNull)			AnyNull = true;		/* remember we got a null */		else if (!DatumGetBool(clause_value))			return clause_value;	}	/* AnyNull is true if at least one clause evaluated to NULL */	*isNull = AnyNull;	return BoolGetDatum(!AnyNull);}/* ---------------------------------------------------------------- *		ExecEvalConvertRowtype * *		Evaluate a rowtype coercion operation.	This may require *		rearranging field positions. * ---------------------------------------------------------------- */static DatumExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,					   ExprContext *econtext,					   bool *isNull, ExprDoneCond *isDone){	HeapTuple	result;	Datum		tupDatum;	HeapTupleHeader tuple;	HeapTupleData tmptup;	AttrNumber *attrMap = cstate->attrMap;	Datum	   *invalues = cstate->invalues;	bool	   *inisnull = cstate->inisnull;	Datum	   *outvalues = cstate->outvalues;	bool	   *outisnull = cstate->outisnull;	int			i;	int			outnatts = cstate->outdesc->natts;	tupDatum = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);	/* this test covers the isDone exception too: */	if (*isNull)		return tupDatum;	tuple = DatumGetHeapTupleHeader(tupDatum);	Assert(HeapTupleHeaderGetTypeId(tuple) == cstate->indesc->tdtypeid);	Assert(HeapTupleHeaderGetTypMod(tuple) == cstate->indesc->tdtypmod);	/*	 * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader.	 */	tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);	tmptup.t_data = tuple;	/*	 * Extract all the values of the old tuple, offsetting the arrays so that	 * invalues[0] is NULL and invalues[1] is the first source attribute; this	 * exactly matches the numbering convention in attrMap.	 */	heap_deform_tuple(&tmptup, cstate->indesc, invalues + 1, inisnull + 1);	invalues[0] = (Datum) 0;	inisnull[0] = true;	/*	 * Transpose into proper fields of the new tuple.	 */	for (i = 0; i < outnatts; i++)	{		int			j = attrMap[i];		outvalues[i] = invalues[j];		outisnull[i] = inisnull[j];	}	/*	 * Now form the new tuple.	 */	result = heap_form_tuple(cstate->outdesc, outvalues, outisnull);	return HeapTupleGetDatum(result);}/* ---------------------------------------------------------------- *		ExecEvalCase * *		Evaluate a CASE clause. Will have boolean expressions *		inside the WHEN clauses, and will have expressions *		for results. *		- thomas 1998-11-09 * ---------------------------------------------------------------- */static DatumExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,			 bool *isNull, ExprDoneCond *isDone){	List	   *clauses = caseExpr->args;	ListCell   *clause;	Datum		save_datum;	bool		save_isNull;	if (isDone)		*isDone = ExprSingleResult;	/*	 * If there's a test expression, we have to evaluate it and save the value	 * where the CaseTestExpr placeholders can find it. We must save and	 * restore prior setting of econtext's caseValue fields, in case this node	 * is itself within a larger CASE.	 */	save_datum = econtext->caseValue_datum;	save_isNull = econtext->caseValue_isNull;	if (caseExpr->arg)	{		econtext->caseValue_datum = ExecEvalExpr(caseExpr->arg,												 econtext,												 &econtext->caseValue_isNull,												 NULL);	}	/*	 * we evaluate each of the WHEN clauses in turn, as soon as one is true we	 * return the corresponding result. If none are true then we return the	 * value of the default clause, or NULL if there is none.	 */	foreach(clause, clauses)	{		CaseWhenState *wclause = lfirst(clause);		Datum		clause_value;		clause_value = ExecEvalExpr(wclause->expr,									econtext,									isNull,									NULL);		/*		 * if we have a true test, then we return the result, since the case		 * statement is satisfied.	A NULL result from the test is not		 * considered true.		 */		if (DatumGetBool(clause_value) && !*isNull)		{			econtext->caseValue_datum = save_datum;			econtext->caseValue_isNull = save_isNull;			return ExecEvalExpr(wclause->result,								econtext,								isNull,								isDone);		}	}	econtext->caseValue_datum = save_datum;	econtext->caseValue_isNull = save_isNull;	if (caseExpr->defresult)	{		return ExecEvalExpr(caseExpr->defresult,							econtext,							isNull,							isDone);	}	*isNull = true;	return (Datum) 0;}/* * ExecEvalCaseTestExpr * * Return the value stored by CASE. */static DatumExecEvalCaseTestExpr(ExprState *exprstate,					 ExprContext *econtext,					 bool *isNull, ExprDoneCond *isDone){	if (isDone)		*isDone = ExprSingleResult;	*isNull = econtext->caseValue_isNull;	return econtext->caseValue_datum;}/* ---------------------------------------------------------------- *		ExecEvalArray - ARRAY[] expressions * * NOTE: currently, if any input value is NULL then we return a NULL array, * so the ARRAY[] construct can be considered strict.  Eventually this will * change; when it does, be sure to fix contain_nonstrict_functions(). * ---------------------------------------------------------------- */static DatumExecEvalArray(ArrayExprState *astate, ExprContext *econtext,			  bool *isNull, ExprDoneCond *isDone){	ArrayExpr  *arrayExpr = (ArrayExpr *) astate->xprstate.expr;	ArrayType  *result;	ListCell   *element;	Oid			element_type = arrayExpr->element_typeid;	int			ndims = 0;	int			dims[MAXDIM];	int			lbs[MAXDIM];	/* Set default values for result flags: non-null, not a set result */	*isNull = false;	if (isDone)		*isDone = ExprSingleResult;	if (!arrayExpr->multidims)	{		/* Elements are presumably of scalar type */		int			nelems;		Datum	   *dvalues;		int			i = 0;		ndims = 1;		nelems = list_length(astate->elements);		/* Shouldn't happen here, but if length is 0, return NULL */		if (nelems == 0)		{			*isNull = true;			return (Datum) 0;		}		dvalues = (Datum *) palloc(nelems * sizeof(Datum));		/* loop through and build array of datums */		foreach(element, astate->elements)		{			ExprState  *e = (ExprState *) lfirst(element);			bool		eisnull;			dvalues[i++] = ExecEvalExpr(e, econtext, &eisnull, NULL);			if (eisnull)			{				*isNull = true;				return (Datum) 0;			}		}		/* setup for 1-D array of the given length */		dims[0] = nelems;		lbs[0] = 1;		result = construct_md_array(dvalues, ndims, dims, lbs,									element_type,									astate->elemlength,									astate->elembyval,									astate->elemalign);	}	else	{		/* Must be nested array expressions */		char	   *dat = NULL;		Size		ndatabytes = 0;		int			nbytes;		int			outer_nelems = list_length(astate->elements);		int			elem_ndims = 0;		int		   *elem_dims = NULL;		int		   *elem_lbs = NULL;		bool		firstone = true;		int			i;		/* loop through and get data area from each element */		foreach(element, astate->elements)		{			ExprState  *e = (ExprState *) lfirst(element);			bool		eisnull;			Datum		arraydatum;			ArrayType  *array;			int			elem_ndatabytes;			arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);			if (eisnull)			{				*isNull = true;				return (Datum) 0;			}			array = DatumGetArrayTypeP(arraydatum);			/* run-time double-check on element type */			if (element_type != ARR_ELEMTYPE(array))				ereport(ERROR,						(errcode(ERRCODE_DATATYPE_MISMATCH),						 errmsg("cannot merge incompatible arrays"),						 errdetail("Array with element type %s cannot be "						 "included in ARRAY construct with element type %s.",								   format_type_be(ARR_ELEMTYPE(array)),								   format_type_be(element_type))));			if (firstone)			{				/* Get sub-array details from first member */				elem_ndims = ARR_NDIM(array);				ndims = elem_ndims + 1;				if (ndims <= 0 || ndims > MAXDIM)					ereport(ERROR,							(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),						  errmsg("number of array dimensions (%d) exceeds " \								 "the maximum allowed (%d)", ndims, MAXDIM)));				elem_dims = (int *) palloc(elem_ndims * sizeof(int));				memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));				elem_lbs = (int *) palloc(elem_ndims * sizeof(int));				memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));				firstone = false;			}			else			{				/* Check other sub-arrays are compatible */				if (elem_ndims != ARR_NDIM(array) ||					memcmp(elem_dims, ARR_DIMS(array),						   elem_ndims * sizeof(int)) != 0 ||					memcmp(elem_lbs, ARR_LBOUND(array),						   elem_ndims * sizeof(int)) != 0)					ereport(ERROR,							(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),							 errmsg("multidimensional arrays must have array "									"expressions with matching dimensions")));			}			elem_ndatabytes = ARR_SIZE(array) - ARR_OVERHEAD(elem_ndims);			ndatabytes += elem_ndatabytes;			if (dat == NULL)				dat = (char *) palloc(ndatabytes);			else				dat = (char *) repalloc(dat, ndatabytes);			memcpy(dat + (ndatabytes - elem_ndatabytes),				   ARR_DATA_PTR(array),				   elem_ndatabytes);		}		/* setup for multi-D array */		dims[0] = outer_nelems;		lbs[0] = 1;		for (i = 1; i < ndims; i++)		{			dims[i] = elem_dims[i - 1];			lbs[i] = elem_lbs[i - 1];		}		nbytes = ndatabytes + ARR_OVERHEAD(ndims);		result = (ArrayType *) palloc(nbytes);		result->size = nbytes;		result->ndim = ndims;		result->flags = 0;		result->elemtype = element_type;		memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));		memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));		if (ndatabytes > 0)			memcpy(ARR_DATA_PTR(result), dat, ndatabytes);		if (dat != NULL)			pfree(dat);	}	return PointerGetDatum(result);}/* ---------------------------------------------------------------- *		ExecEvalRow - ROW() expressions * ---------------------------------------------------------------- */static DatumExecEvalRow(RowExprState *rstate,			ExprContext *econtext,			bool *isNull, ExprDoneCond *isDone){	HeapTuple	tuple;	Datum	   *values;	bool	   *isnull;	int			natts;	ListCell   *arg;	int			i;	/* Set default values for result flags: non-null, not a set result */	*isNull = false;	if (isDone)		*isDone = ExprSingleResult;	/* Allocate workspace */	natts = rstate->tupdesc->natts;	values = (Datum *) palloc0(natts * sizeof(Datum));	isnull = (bool *) palloc(natts * sizeof(bool));	/* preset to nulls in case rowtype has some later-added columns */	memset(isnull, true, natts * sizeof(bool));	/* Evaluate field values */	i = 0;	foreach(arg, rstate->args)	{		ExprState  *e = (ExprState *) lfirst(arg);		values[i] = ExecEvalExpr(e, econ

⌨️ 快捷键说明

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