/*-------------------------------------------------------------------------
 *
 * execQual.c
 *	  Routines to evaluate qualification and targetlist expressions
 *
 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	  $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.199.2.3 2007/08/31 18:33:47 tgl Exp $
 *
 *-------------------------------------------------------------------------
 */
/*
 *	 INTERFACE ROUTINES
 *		ExecEvalExpr	- (now a macro) evaluate an expression, return a datum
 *		ExecEvalExprSwitchContext - same, but switch into eval memory context
 *		ExecQual		- return true/false if qualification is satisfied
 *		ExecProject		- form a new tuple by projecting the given tuple
 *
 *	 NOTES
 *		The more heavily used ExecEvalExpr routines, such as ExecEvalVar(),
 *		are hotspots. Making these faster will speed up the entire system.
 *
 *		ExecProject() is used to make tuple projections.  Rather then
 *		trying to speed it up, the execution plan should be pre-processed
 *		to facilitate attribute sharing between nodes wherever possible,
 *		instead of doing needless copying.	-cim 5/31/91
 *
 *		During expression evaluation, we check_stack_depth only in
 *		ExecMakeFunctionResult (and substitute routines) rather than at every
 *		single node.  This is a compromise that trades off precision of the
 *		stack limit setting to gain speed.
 */

#include "postgres.h"

#include "access/heapam.h"
#include "access/nbtree.h"
#include "access/tuptoaster.h"
#include "catalog/pg_type.h"
#include "cdb/cdbvars.h"
#include "cdb/partitionselection.h"
#include "commands/typecmds.h"
#include "executor/execdebug.h"
#include "executor/nodeAgg.h"
#include "executor/nodeSubplan.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/planmain.h"
#include "parser/parse_expr.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/typcache.h"


/* static function decls */
static Datum ExecEvalArrayRef(ArrayRefExprState *astate,
				 ExprContext *econtext,
				 bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalAggref(AggrefExprState *aggref,
			   ExprContext *econtext,
			   bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalGroupingFunc(GroupingFuncExprState *gstate,
								  ExprContext *econtext,
								  bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalGrouping(ExprState *gstate,
							  ExprContext *econtext,
							  bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalGroupId(ExprState *gstate,
							 ExprContext *econtext,
							 bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalWindowRef(WindowRefExprState *winref,
			   ExprContext *econtext,
			   bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
			bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
			bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext,
					bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalWholeRowSlow(ExprState *exprstate, ExprContext *econtext,
					bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
			  bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalParam(ExprState *exprstate, ExprContext *econtext,
			  bool *isNull, ExprDoneCond *isDone);
static void ShutdownFuncExpr(Datum arg);
static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod,
				   TupleDesc *cache_field, ExprContext *econtext);
static void ShutdownTupleDescRef(Datum arg);
static void ExecPrepareTuplestoreResult(FuncExprState *fcache,
							ExprContext *econtext,
							Tuplestorestate *resultStore,
							TupleDesc resultDesc);
static void tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc);
static Datum ExecMakeFunctionResult(FuncExprState *fcache,
					   ExprContext *econtext,
					   bool *isNull,
					   ExprDoneCond *isDone);
static Datum ExecMakeFunctionResultNoSets(FuncExprState *fcache,
							 ExprContext *econtext,
							 bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalFunc(FuncExprState *fcache, ExprContext *econtext,
			 bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalOper(FuncExprState *fcache, ExprContext *econtext,
			 bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalDistinct(FuncExprState *fcache, ExprContext *econtext,
				 bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
					  ExprContext *econtext,
					  bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
			bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
		   bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
			bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
					   ExprContext *econtext,
					   bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
			 bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalCaseTestExpr(ExprState *exprstate,
					 ExprContext *econtext,
					 bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalArray(ArrayExprState *astate,
			  ExprContext *econtext,
			  bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalRow(RowExprState *rstate,
			ExprContext *econtext,
			bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalRowCompare(RowCompareExprState *rstate,
				   ExprContext *econtext,
				   bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalTableValue(ExprState   *estate,
								ExprContext *econtext,
								bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr,
				 ExprContext *econtext,
				 bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalMinMax(MinMaxExprState *minmaxExpr,
			   ExprContext *econtext,
			   bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalNullIf(FuncExprState *nullIfExpr,
			   ExprContext *econtext,
			   bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalNullTest(NullTestState *nstate,
				 ExprContext *econtext,
				 bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalBooleanTest(GenericExprState *bstate,
					ExprContext *econtext,
					bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalCoerceToDomain(CoerceToDomainState *cstate,
					   ExprContext *econtext,
					   bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalCoerceToDomainValue(ExprState *exprstate,
							ExprContext *econtext,
							bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalPercentileExpr(PercentileExprState *exprstate,
					ExprContext *econtext,
					bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalFieldSelect(FieldSelectState *fstate,
					ExprContext *econtext,
					bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalFieldStore(FieldStoreState *fstate,
				   ExprContext *econtext,
				   bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalRelabelType(GenericExprState *exprstate,
					ExprContext *econtext,
					bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalPartOidExpr(PartOidExprState *exprstate,
						ExprContext *econtext,
						bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalPartDefaultExpr(PartDefaultExprState *exprstate,
						ExprContext *econtext,
						bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalPartBoundExpr(PartBoundExprState *exprstate,
						ExprContext *econtext,
						bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalPartBoundInclusionExpr(PartBoundInclusionExprState *exprstate,
								ExprContext *econtext,
								bool *isNull, ExprDoneCond *isDone);
static Datum ExecEvalPartBoundOpenExpr(PartBoundOpenExprState *exprstate,
								ExprContext *econtext,
								bool *isNull, ExprDoneCond *isDone);
static bool ExecIsExprUnsafeToConst_walker(Node *node, void *context);
static bool ExecIsExprUnsafeToConst(Node *node);


/* ----------------------------------------------------------------
 *		ExecEvalExpr routines
 *
 *		Recursively evaluate a targetlist or qualification expression.
 *
 * Each of the following routines having the signature
 *		Datum ExecEvalFoo(ExprState *expression,
 *						  ExprContext *econtext,
 *						  bool *isNull,
 *						  ExprDoneCond *isDone);
 * is responsible for evaluating one type or subtype of ExprState node.
 * They are normally called via the ExecEvalExpr macro, which makes use of
 * the function pointer set up when the ExprState node was built by
 * ExecInitExpr.  (In some cases, we change this pointer later to avoid
 * re-executing one-time overhead.)
 *
 * Note: for notational simplicity we declare these functions as taking the
 * specific type of ExprState that they work on.  This requires casting when
 * assigning the function pointer in ExecInitExpr.	Be careful that the
 * function signature is declared correctly, because the cast suppresses
 * automatic checking!
 *
 *
 * All these functions share this calling convention:
 *
 * 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 in these routines
 * because it'd be a waste of cycles during nested expression evaluation.
 * ----------------------------------------------------------------
 */


/*----------
 *	  ExecEvalArrayRef
 *
 *	   This function takes an ArrayRef and returns the extracted Datum
 *	   if it's a simple reference, or the modified array value if it's
 *	   an array assignment (i.e., array element or slice insertion).
 *
 * NOTE: if we get a NULL result from a subscript expression, we return NULL
 * when it's an array reference, or raise an error when it's an assignment.
 *
 * NOTE: we deliberately refrain from applying DatumGetArrayTypeP() here,
 * even though that might seem natural, because this code needs to support
 * both varlena arrays and fixed-length array types.  DatumGetArrayTypeP()
 * only works for the varlena kind.  The routines we call in arrayfuncs.c
 * have to know the difference (that's what they need refattrlength for).
 *----------
 */
static Datum
ExecEvalArrayRef(ArrayRefExprState *astate,
				 ExprContext *econtext,
				 bool *isNull,
				 ExprDoneCond *isDone)
{
	ArrayRef   *arrayRef = (ArrayRef *) astate->xprstate.expr;
	ArrayType  *array_source;
	ArrayType  *resultArray;
	bool		isAssignment = (arrayRef->refassgnexpr != NULL);
	bool		eisnull;
	ListCell   *l;
	int			i = 0,
				j = 0;
	IntArray	upper,
				lower;
	int		   *lIndex;

	array_source = (ArrayType *)
		DatumGetPointer(ExecEvalExpr(astate->refexpr,
									 econtext,
									 isNull,
									 isDone));

	/*
	 * If refexpr yields NULL, and it's a fetch, then result is NULL. In the
	 * assignment case, we'll cons up something below.
	 */
	if (*isNull)
	{
		if (isDone && *isDone == ExprEndResult)
			return 0;	/* end of set result */
		if (!isAssignment)
			return 0;
	}

	foreach(l, astate->refupperindexpr)
	{
		ExprState  *eltstate = (ExprState *) lfirst(l);

		if (i >= MAXDIM)
			ereport(ERROR,
					(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
					 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
							i, MAXDIM)));

		upper.indx[i++] = DatumGetInt32(ExecEvalExpr(eltstate,
													 econtext,
													 &eisnull,
													 NULL));
		/* If any index expr yields NULL, result is NULL or error */
		if (eisnull)
		{
			if (isAssignment)
				ereport(ERROR,
						(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
				  errmsg("array subscript in assignment must not be null")));
			*isNull = true;
			return 0;
		}
	}

	if (astate->reflowerindexpr != NIL)
	{
		foreach(l, astate->reflowerindexpr)
		{
			ExprState  *eltstate = (ExprState *) lfirst(l);

			if (j >= MAXDIM)
				ereport(ERROR,
						(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
						 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
								i, MAXDIM)));

			lower.indx[j++] = DatumGetInt32(ExecEvalExpr(eltstate,
														 econtext,
														 &eisnull,
														 NULL));
			/* If any index expr yields NULL, result is NULL or error */
			if (eisnull)
			{
				if (isAssignment)
					ereport(ERROR,
							(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
							 errmsg("array subscript in assignment must not be null")));
				*isNull = true;
				return 0;
			}
		}
		/* this can't happen unless parser messed up */
		if (i != j)
			elog(ERROR, "upper and lower index lists are not same length");
		lIndex = lower.indx;
	}
	else
		lIndex = NULL;

	if (isAssignment)
	{
		Datum		sourceData;

		/*
		 * Evaluate the value to be assigned into the array.
		 *
		 * XXX At some point we'll need to look into making the old value of
		 * the array element available via CaseTestExpr, as is done by
		 * ExecEvalFieldStore.	This is not needed now but will be needed to
		 * support arrays of composite types; in an assignment to a field of
		 * an array member, the parser would generate a FieldStore that
		 * expects to fetch its input tuple via CaseTestExpr.
		 */
		sourceData = ExecEvalExpr(astate->refassgnexpr,
								  econtext,
								  &eisnull,
								  NULL);

		/*
		 * For an assignment to a fixed-length array type, both the original
		 * array and the value to be assigned into it must be non-NULL, else
		 * we punt and return the original array.
		 */
		if (astate->refattrlength > 0)	/* fixed-length array? */
			if (eisnull || *isNull)
				return PointerGetDatum(array_source);

		/*
		 * For assignment to varlena arrays, we handle a NULL original array
		 * by substituting an empty (zero-dimensional) array; insertion of the
		 * new element will result in a singleton array value.	It does not
		 * matter whether the new element is NULL.
		 */
		if (*isNull)
		{
			array_source = construct_empty_array(arrayRef->refelemtype);
			*isNull = false;
		}

		if (lIndex == NULL)
			resultArray = array_set(array_source, i,
									upper.indx,
									sourceData,
									eisnull,
									astate->refattrlength,
									astate->refelemlength,
									astate->refelembyval,
									astate->refelemalign);
		else
			resultArray = array_set_slice(array_source, i,
										  upper.indx, lower.indx,
								   (ArrayType *) DatumGetPointer(sourceData),
										  eisnull,
										  astate->refattrlength,
										  astate->refelemlength,
										  astate->refelembyval,
										  astate->refelemalign);
		return PointerGetDatum(resultArray);
	}

	if (lIndex == NULL)
		return array_ref(array_source, i, upper.indx,
						 astate->refattrlength,
						 astate->refelemlength,
						 astate->refelembyval,
						 astate->refelemalign,
						 isNull);
	else
	{
		resultArray = array_get_slice(array_source, i,
									  upper.indx, lower.indx,
									  astate->refattrlength,
									  astate->refelemlength,
									  astate->refelembyval,
									  astate->refelemalign);
		return PointerGetDatum(resultArray);
	}
}


/* ----------------------------------------------------------------
 *		ExecEvalAggref
 *
 *		Returns a Datum whose value is the value of the precomputed
 *		aggregate found in the given expression context.
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalAggref(AggrefExprState *aggref, ExprContext *econtext,
			   bool *isNull, ExprDoneCond *isDone)
{
	if (isDone)
		*isDone = ExprSingleResult;

	if (econtext->ecxt_aggvalues == NULL)		/* safety check */
		elog(ERROR, "no aggregates in this expression context");

	*isNull = econtext->ecxt_aggnulls[aggref->aggno];
	return econtext->ecxt_aggvalues[aggref->aggno];
}

/*----------------------------------------------------------------
 *		ExecEvalGroupingFunc
 *
 *		Returns a Datum whose value is the value of a GROUPING_ID
 *		with respect to the given context.
 */
static Datum 
ExecEvalGroupingFunc(GroupingFuncExprState *gstate,
					 ExprContext *econtext,
					 bool *isNull, ExprDoneCond *isDone)
{
	uint64 grpid = 0;
	ListCell *tmp;
	int num_args = list_length(gstate->args);
	int argno = 0;

	if (isDone)
		*isDone = ExprSingleResult;

	foreach(tmp, gstate->args)
	{
		int arg = (int)intVal(lfirst(tmp));
		int pos_in_grpcols = gstate->ngrpcols - arg - 1;
		int pos_in_grpingfunc = num_args - argno - 1;

		Assert(pos_in_grpcols >= 0 && pos_in_grpingfunc >= 0);

		if (econtext->grouping & ( ((uint64)1) << pos_in_grpcols))
			grpid |= ( ((uint64)1) << pos_in_grpingfunc);

		argno++;
	}

	*isNull = false;
	return Int64GetDatum(grpid);
}

/*----------------------------------------------------------------
 *		ExecEvalGrouping
 *
 *		Returns a Datum whose value is the value of a GROUPING
 *		with respect to the given context.
 */
static Datum
ExecEvalGrouping(ExprState *gstate, ExprContext *econtext,
				 bool *isNull, ExprDoneCond *isDone)
{
	if (isDone)
		*isDone = ExprSingleResult;

	*isNull = false;
	return Int64GetDatum(econtext->grouping);
}

/*----------------------------------------------------------------
 *		ExecEvalGroupId
 *
 *		Returns a Datum whose value is the value of a GROUP_ID
 *		with respect to the given context.
 */
static Datum
ExecEvalGroupId(ExprState *gstate, ExprContext *econtext,
				bool *isNull, ExprDoneCond *isDone)
{
	if (isDone)
		*isDone = ExprSingleResult;

	*isNull = false;
	return UInt32GetDatum(econtext->group_id);
}

/* ----------------------------------------------------------------
 *		ExecEvalWindowRef
 *
 *		Returns a Datum whose value is the value of the window
 *		function with respect to the given context.
 *
 * XXX	Note that this routine is essentially the same as
 *      ExecEvalAggref since we use the same buffers. However,
 *      since the state structures for WindowRef and Aggref 
 *      are different, we separate the execution routines, too.
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalWindowRef(WindowRefExprState *winref, ExprContext *econtext,
				  bool *isNull, ExprDoneCond *isDone)
{
	if (isDone)
		*isDone = ExprSingleResult;
	
	if (econtext->ecxt_aggvalues == NULL)		/* safety check */
		elog(ERROR, "no window functions in this expression context");

	*isNull = econtext->ecxt_aggnulls[winref->funcno];
	return econtext->ecxt_aggvalues[winref->funcno];

}

/* ----------------------------------------------------------------
 *		ExecEvalVar
 *
 *		Returns a Datum whose value is the value of a range
 *		variable with respect to given expression context.
 *
 * Note: ExecEvalVar is executed only the first time through in a given plan;
 * it changes the ExprState's function pointer to pass control directly to
 * ExecEvalScalarVar, ExecEvalWholeRowVar, or ExecEvalWholeRowSlow after
 * making one-time checks.
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
			bool *isNull, ExprDoneCond *isDone)
{
	Var		   *variable = (Var *) exprstate->expr;
	TupleTableSlot *slot;
	AttrNumber	attnum;

	if (isDone)
		*isDone = ExprSingleResult;

	Assert(econtext->ecxt_scantuple != NULL || econtext->ecxt_innertuple != NULL || econtext->ecxt_outertuple != NULL);
	/*
	 * Get the input slot and attribute number we want
	 *
	 * The asserts check that references to system attributes only appear at
	 * the level of a relation scan; at higher levels, system attributes must
	 * be treated as ordinary variables (since we no longer have access to the
	 * original tuple).
	 */
	attnum = variable->varattno;

	switch (variable->varno)
	{
		case INNER:				/* get the tuple from the inner node */
			slot = econtext->ecxt_innertuple;
			Assert(attnum > 0);
			break;

		case OUTER:				/* get the tuple from the outer node */
			slot = econtext->ecxt_outertuple;
			Assert(attnum > 0);
			break;

		default:				/* get the tuple from the relation being
								 * scanned */
			slot = econtext->ecxt_scantuple;
			break;
	}

	if (attnum != InvalidAttrNumber)
	{
		/*
		 * Scalar variable case.
		 *
		 * If it's a user attribute, check validity (bogus system attnums will
		 * be caught inside slot_getattr).  What we have to check for here
		 * is the possibility of an attribute having been changed in type
		 * since the plan tree was created.  Ideally the plan would get
		 * invalidated and not re-used, but until that day arrives, we need
		 * defenses.  Fortunately it's sufficient to check once on the first
		 * time through.
		 *
		 * Note: we allow a reference to a dropped attribute.  slot_getattr
		 * will force a NULL result in such cases.
		 *
		 * Note: ideally we'd check typmod as well as typid, but that seems
		 * impractical at the moment: in many cases the tupdesc will have
		 * been generated by ExecTypeFromTL(), and that can't guarantee to
		 * generate an accurate typmod in all cases, because some expression
		 * node types don't carry typmod.
		 */
		if (attnum > 0)
		{
			TupleDesc	slot_tupdesc = slot->tts_tupleDescriptor;
			Form_pg_attribute attr;

			if (attnum > slot_tupdesc->natts)	/* should never happen */
				elog(ERROR, "attribute number %d exceeds number of columns %d",
					 attnum, slot_tupdesc->natts);

			attr = slot_tupdesc->attrs[attnum - 1];

			/* can't check type if dropped, since atttypid is probably 0 */
			if (!attr->attisdropped)
			{
				bool cond = vmthd.GetNType == NULL ?
							variable->vartype != attr->atttypid :
							(variable->vartype != attr->atttypid && vmthd.GetNType(variable->vartype) != attr->atttypid);
				if (cond)
					ereport(ERROR,
							(errmsg("attribute %d has wrong type", attnum),
									errdetail("Table has type %s, but query expects %s.",
											  format_type_be(attr->atttypid),
											  format_type_be(variable->vartype))));
			}
		}

		/* Skip the checking on future executions of node */
		exprstate->evalfunc = ExecEvalScalarVar;

		/* Fetch the value from the slot */
		return slot_getattr(slot, attnum, isNull);
	}
	else
	{
		/*
		 * Whole-row variable.
		 *
		 * If it's a RECORD Var, we'll use the slot's type ID info.  It's
		 * likely that the slot's type is also RECORD; if so, make sure it's
		 * been "blessed", so that the Datum can be interpreted later.
		 *
		 * If the Var identifies a named composite type, we must check that
		 * the actual tuple type is compatible with it.
		 */
		TupleDesc	slot_tupdesc = slot->tts_tupleDescriptor;
		bool		needslow = false;

		if (variable->vartype == RECORDOID)
		{
			if (slot_tupdesc->tdtypeid == RECORDOID &&
				slot_tupdesc->tdtypmod < 0)
				assign_record_type_typmod(slot_tupdesc);
		}
		else
		{
			TupleDesc	var_tupdesc;
			int			i;

			/*
			 * We really only care about number of attributes and data type.
			 * Also, we can ignore type mismatch on columns that are dropped
			 * in the destination type, so long as the physical storage
			 * matches.  This is helpful in some cases involving out-of-date
			 * cached plans.  Also, we have to allow the case that the slot
			 * has more columns than the Var's type, because we might be
			 * looking at the output of a subplan that includes resjunk
			 * columns.  (XXX it would be nice to verify that the extra
			 * columns are all marked resjunk, but we haven't got access to
			 * the subplan targetlist here...)  Resjunk columns should always
			 * be at the end of a targetlist, so it's sufficient to ignore
			 * them here; but we need to use ExecEvalWholeRowSlow to get
			 * rid of them in the eventual output tuples.
			 */
			var_tupdesc = lookup_rowtype_tupdesc(variable->vartype, -1);

			if (var_tupdesc->natts > slot_tupdesc->natts)
				ereport(ERROR,
						(errcode(ERRCODE_DATATYPE_MISMATCH),
						 errmsg("table row type and query-specified row type do not match"),
						 errdetail("Table row contains %d attributes, but query expects %d.",
								   slot_tupdesc->natts, var_tupdesc->natts)));
			else if (var_tupdesc->natts < slot_tupdesc->natts)
				needslow = true;

			for (i = 0; i < var_tupdesc->natts; i++)
			{
				Form_pg_attribute vattr = var_tupdesc->attrs[i];
				Form_pg_attribute sattr = slot_tupdesc->attrs[i];

				if (vattr->atttypid == sattr->atttypid)
					continue;			/* no worries */
				if (!vattr->attisdropped)
					ereport(ERROR,
							(errcode(ERRCODE_DATATYPE_MISMATCH),
							 errmsg("table row type and query-specified row type do not match"),
							 errdetail("Table has type %s at ordinal position %d, but query expects %s.",
									   format_type_be(sattr->atttypid),
									   i + 1,
									   format_type_be(vattr->atttypid))));

				if (vattr->attlen != sattr->attlen ||
					vattr->attalign != sattr->attalign)
					ereport(ERROR,
							(errcode(ERRCODE_DATATYPE_MISMATCH),
							 errmsg("table row type and query-specified row type do not match"),
							 errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
									   i + 1)));
			}

			ReleaseTupleDesc(var_tupdesc);
		}

		/* Skip the checking on future executions of node */
		if (needslow)
			exprstate->evalfunc = ExecEvalWholeRowSlow;
		else
			exprstate->evalfunc = ExecEvalWholeRowVar;

		/* Fetch the value */
		return ExecEvalWholeRowVar(exprstate, econtext, isNull, isDone);
	}
}

/* ----------------------------------------------------------------
 *		ExecEvalScalarVar
 *
 *		Returns a Datum for a scalar variable.
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
				  bool *isNull, ExprDoneCond *isDone)
{
	Var		   *variable = (Var *) exprstate->expr;
	TupleTableSlot *slot;
	AttrNumber	attnum;

	if (isDone)
		*isDone = ExprSingleResult;

	/* Get the input slot and attribute number we want */
	switch (variable->varno)
	{
		case INNER:				/* get the tuple from the inner node */
			slot = econtext->ecxt_innertuple;
			break;

		case OUTER:				/* get the tuple from the outer node */
			slot = econtext->ecxt_outertuple;
			break;

		default:				/* get the tuple from the relation being
								 * scanned */
			slot = econtext->ecxt_scantuple;
			break;
	}

	attnum = variable->varattno;

	/* Fetch the value from the slot */
	return slot_getattr(slot, attnum, isNull);
}

/* ----------------------------------------------------------------
 *		ExecEvalWholeRowVar
 *
 *		Returns a Datum for a whole-row variable.
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext,
					bool *isNull, ExprDoneCond *isDone)
{
	Var		   *variable = (Var *) exprstate->expr;
	TupleTableSlot *slot = econtext->ecxt_scantuple;
	HeapTuple	tuple;
	TupleDesc	tupleDesc;
	HeapTupleHeader dtuple;

	if (isDone)
		*isDone = ExprSingleResult;
	*isNull = false;

	tuple = ExecFetchSlotHeapTuple(slot);
	tupleDesc = slot->tts_tupleDescriptor;

	/*
	 * We have to make a copy of the tuple so we can safely insert the Datum
	 * overhead fields, which are not set in on-disk tuples.
	 */
	dtuple = (HeapTupleHeader) palloc(tuple->t_len);
	memcpy((char *) dtuple, (char *) tuple->t_data, tuple->t_len);

	HeapTupleHeaderSetDatumLength(dtuple, tuple->t_len);

	/*
	 * If the Var identifies a named composite type, label the tuple with that
	 * type; otherwise use what is in the tupleDesc.
	 */
	if (variable->vartype != RECORDOID)
	{
		HeapTupleHeaderSetTypeId(dtuple, variable->vartype);
		HeapTupleHeaderSetTypMod(dtuple, variable->vartypmod);
	}
	else
	{
		HeapTupleHeaderSetTypeId(dtuple, tupleDesc->tdtypeid);
		HeapTupleHeaderSetTypMod(dtuple, tupleDesc->tdtypmod);
	}

	return PointerGetDatum(dtuple);
}

/* ----------------------------------------------------------------
 *		ExecEvalWholeRowSlow
 *
 *		Returns a Datum for a whole-row variable, in the "slow" case where
 *		we can't just copy the subplan's output.
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalWholeRowSlow(ExprState *exprstate, ExprContext *econtext,
					 bool *isNull, ExprDoneCond *isDone)
{
	Var		   *variable = (Var *) exprstate->expr;
	TupleTableSlot *slot = econtext->ecxt_scantuple;
	HeapTuple	tuple;
	TupleDesc	var_tupdesc;
	HeapTupleHeader dtuple;

	if (isDone)
		*isDone = ExprSingleResult;
	*isNull = false;

	/*
	 * Currently, the only case handled here is stripping of trailing
	 * resjunk fields, which we do in a slightly chintzy way by just
	 * adjusting the tuple's natts header field.  Possibly there will someday
	 * be a need for more-extensive rearrangements, in which case it'd
	 * be worth disassembling and reassembling the tuple (perhaps use a
	 * JunkFilter for that?)
	 */
	Assert(variable->vartype != RECORDOID);
	var_tupdesc = lookup_rowtype_tupdesc(variable->vartype, -1);

	tuple = ExecFetchSlotHeapTuple(slot);

	/*
	 * We have to make a copy of the tuple so we can safely insert the Datum
	 * overhead fields, which are not set in on-disk tuples; not to mention
	 * fooling with its natts field.
	 */
	dtuple = (HeapTupleHeader) palloc(tuple->t_len);
	memcpy((char *) dtuple, (char *) tuple->t_data, tuple->t_len);

	HeapTupleHeaderSetDatumLength(dtuple, tuple->t_len);
	HeapTupleHeaderSetTypeId(dtuple, variable->vartype);
	HeapTupleHeaderSetTypMod(dtuple, variable->vartypmod);

	Assert(HeapTupleHeaderGetNatts(dtuple) >= var_tupdesc->natts);
	HeapTupleHeaderSetNatts(dtuple, var_tupdesc->natts);
	
	ReleaseTupleDesc(var_tupdesc);

	return PointerGetDatum(dtuple);
}

/* ----------------------------------------------------------------
 *		ExecEvalConst
 *
 *		Returns the value of a constant.
 *
 *		Note that for pass-by-ref datatypes, we return a pointer to the
 *		actual constant node.  This is one of the reasons why functions
 *		must treat their input arguments as read-only.
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
			  bool *isNull, ExprDoneCond *isDone)
{
	Const	   *con = (Const *) exprstate->expr;

	if (isDone)
		*isDone = ExprSingleResult;

	*isNull = con->constisnull;
	return con->constvalue;
}

/* ----------------------------------------------------------------
 *		ExecEvalParam
 *
 *		Returns the value of a parameter.  A param node contains
 *		something like ($.name) and the expression context contains
 *		the current parameter bindings (name = "sam") (age = 34)...
 *		so our job is to find and return the appropriate datum ("sam").
 * ----------------------------------------------------------------
 */

/*
 * Greenplum Database Changes:
 * In executor mode, a PARAM_EXEC parameter can not be evaluated by executing
 * the subplan.  The subplan was executed on the dispatcher prior to
 * launching the main query.  The value of the result is passed to the qExec
 * in the ParamInfo, with a kind of PARAM_EXEC_REMOTE.
 * So, this function was changed to just do a lookup in that case.
 */
static Datum
ExecEvalParam(ExprState *exprstate, ExprContext *econtext,
			  bool *isNull, ExprDoneCond *isDone)
{
	Param	   *expression = (Param *) exprstate->expr;
	int			thisParamId = expression->paramid;

	if (isDone)
		*isDone = ExprSingleResult;

	if (expression->paramkind == PARAM_EXEC)
	{
		/*
		 * PARAM_EXEC params (internal executor parameters) are stored in the
		 * ecxt_param_exec_vals array, and can be accessed by array index.
		 */
		ParamExecData *prmExec = &(econtext->ecxt_param_exec_vals[thisParamId]);
		
		/* 
		 * Maybe this parameter has already been evaluated. If so, execPlan
		 * would be NULL.
		 */
		if (prmExec->execPlan != NULL)
		{
			/* Parameter not evaluated yet, so go do it */
			ExecSetParamPlan(prmExec->execPlan, econtext, NULL);
			/* ExecSetParamPlan should have processed this param... */
			Assert(prmExec->execPlan == NULL);
		}
		
		*isNull = prmExec->isnull;
		return prmExec->value;
	}
	else
	{
		/*
		 * PARAM_EXTERN parameters must be sought in ecxt_param_list_info.
		 */
		ParamListInfo paramInfo = econtext->ecxt_param_list_info;

		Assert(expression->paramkind == PARAM_EXTERN);
		if (paramInfo &&
			thisParamId > 0 && thisParamId <= paramInfo->numParams)
		{
			ParamExternData *prm = &paramInfo->params[thisParamId - 1];

			if (OidIsValid(prm->ptype))
			{
				Assert(prm->ptype == expression->paramtype);
				*isNull = prm->isnull;
				return prm->value;
			}
		}
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("no value found for parameter %d", thisParamId)));
		return (Datum) 0;		/* keep compiler quiet */
	}
}


/* ----------------------------------------------------------------
 *		ExecEvalOper / ExecEvalFunc support routines
 * ----------------------------------------------------------------
 */

/*
 *		GetAttributeByName
 *		GetAttributeByNum
 *
 *		These functions return the value of the requested attribute
 *		out of the given tuple Datum.
 *		C functions which take a tuple as an argument are expected
 *		to use these.  Ex: overpaid(EMP) might call GetAttributeByNum().
 *		Note: these are actually rather slow because they do a typcache
 *		lookup on each call.
 */
Datum
GetAttributeByNum(HeapTupleHeader tuple,
				  AttrNumber attrno,
				  bool *isNull)
{
	Datum		result;
	Oid			tupType;
	int32		tupTypmod;
	TupleDesc	tupDesc;
	HeapTupleData tmptup;

	if (!AttributeNumberIsValid(attrno))
		elog(ERROR, "invalid attribute number %d", attrno);

	if (isNull == NULL)
		elog(ERROR, "a NULL isNull pointer was passed");

	if (tuple == NULL)
	{
		/* Kinda bogus but compatible with old behavior... */
		*isNull = true;
		return (Datum) 0;
	}

	tupType = HeapTupleHeaderGetTypeId(tuple);
	tupTypmod = HeapTupleHeaderGetTypMod(tuple);
	tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);

	/*
	 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set all
	 * the fields in the struct just in case user tries to inspect system
	 * columns.
	 */
	tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
	ItemPointerSetInvalid(&(tmptup.t_self));
	tmptup.t_data = tuple;

	result = heap_getattr(&tmptup,
						  attrno,
						  tupDesc,
						  isNull);

	ReleaseTupleDesc(tupDesc);

	return result;
}

Datum
GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
{
	AttrNumber	attrno;
	Datum		result;
	Oid			tupType;
	int32		tupTypmod;
	TupleDesc	tupDesc;
	HeapTupleData tmptup;
	int			i;

	if (attname == NULL)
		elog(ERROR, "invalid attribute name");

	if (isNull == NULL)
		elog(ERROR, "a NULL isNull pointer was passed");

	if (tuple == NULL)
	{
		/* Kinda bogus but compatible with old behavior... */
		*isNull = true;
		return (Datum) 0;
	}

	tupType = HeapTupleHeaderGetTypeId(tuple);
	tupTypmod = HeapTupleHeaderGetTypMod(tuple);
	tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);

	attrno = InvalidAttrNumber;
	for (i = 0; i < tupDesc->natts; i++)
	{
		if (namestrcmp(&(tupDesc->attrs[i]->attname), attname) == 0)
		{
			attrno = tupDesc->attrs[i]->attnum;
			break;
		}
	}

	if (attrno == InvalidAttrNumber)
		elog(ERROR, "attribute \"%s\" does not exist", attname);

	/*
	 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set all
	 * the fields in the struct just in case user tries to inspect system
	 * columns.
	 */
	tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
	ItemPointerSetInvalid(&(tmptup.t_self));
	tmptup.t_data = tuple;

	result = heap_getattr(&tmptup,
						  attrno,
						  tupDesc,
						  isNull);

	ReleaseTupleDesc(tupDesc);

	return result;
}

/*
 * init_fcache - initialize a FuncExprState node during first use
 */
void
init_fcache(Oid foid, FuncExprState *fcache,
			MemoryContext fcacheCxt, bool needDescForSets)
{
	AclResult	aclresult;

	/* Check permission to call function */
	aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
	if (aclresult != ACLCHECK_OK)
		aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(foid));

	/*
	 * Safety check on nargs.  Under normal circumstances this should never
	 * fail, as parser should check sooner.  But possibly it might fail if
	 * server has been compiled with FUNC_MAX_ARGS smaller than some functions
	 * declared in pg_proc?
	 */
	if (list_length(fcache->args) > FUNC_MAX_ARGS)
		ereport(ERROR,
				(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
				 errmsg("cannot pass more than %d arguments to a function",
						FUNC_MAX_ARGS)));

	/* Set up the primary fmgr lookup information */
	fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
	fcache->func.fn_expr = (Node *) fcache->xprstate.expr;

	/* If function returns set, prepare expected tuple descriptor */
	if (fcache->func.fn_retset && needDescForSets)
	{
		TypeFuncClass functypclass;
		Oid			funcrettype;
		TupleDesc	tupdesc;
		MemoryContext oldcontext;

		functypclass = get_expr_result_type(fcache->func.fn_expr,
											&funcrettype,
											&tupdesc);

		/* Must save tupdesc in fcache's context */
		oldcontext = MemoryContextSwitchTo(fcacheCxt);

		if (functypclass == TYPEFUNC_COMPOSITE)
		{
			/* Composite data type, e.g. a table's row type */
			Assert(tupdesc);
			/* Must copy it out of typcache for safety */
			fcache->funcResultDesc = CreateTupleDescCopy(tupdesc);
			fcache->funcReturnsTuple = true;
		}
		else if (functypclass == TYPEFUNC_SCALAR)
		{
			/* Base data type, i.e. scalar */
			tupdesc = CreateTemplateTupleDesc(1, false);
			TupleDescInitEntry(tupdesc,
							   (AttrNumber) 1,
							   NULL,
							   funcrettype,
							   -1,
							   0);
			fcache->funcResultDesc = tupdesc;
			fcache->funcReturnsTuple = false;
		}
		else
		{
			/* Else, we will complain if function wants materialize mode */
			fcache->funcResultDesc = NULL;
		}

		MemoryContextSwitchTo(oldcontext);
	}
	else
	{
		fcache->funcResultDesc = NULL;
	}

	/* Initialize additional state */
	fcache->funcResultStore = NULL;
	fcache->funcResultSlot = NULL;
	fcache->setArgsValid = false;
	fcache->shutdown_reg = false;
}

/*
 * callback function in case a FuncExpr returning a set needs to be shut down
 * before it has been run to completion
 */
static void
ShutdownFuncExpr(Datum arg)
{
	FuncExprState *fcache = (FuncExprState *) DatumGetPointer(arg);

	/* If we have a slot, make sure it's let go of any tuplestore pointer */
	if (fcache->funcResultSlot)
		ExecClearTuple(fcache->funcResultSlot);

	/* Release any open tuplestore */
	if (fcache->funcResultStore)
		tuplestore_end(fcache->funcResultStore);
	fcache->funcResultStore = NULL;

	/* Clear any active set-argument state */
	fcache->setArgsValid = false;

	/* execUtils will deregister the callback... */
	fcache->shutdown_reg = false;
}

/*
 * get_cached_rowtype: utility function to lookup a rowtype tupdesc
 *
 * type_id, typmod: identity of the rowtype
 * cache_field: where to cache the TupleDesc pointer in expression state node
 *		(field must be initialized to NULL)
 * econtext: expression context we are executing in
 *
 * NOTE: because the shutdown callback will be called during plan rescan,
 * must be prepared to re-do this during any node execution; cannot call
 * just once during expression initialization
 */
static TupleDesc
get_cached_rowtype(Oid type_id, int32 typmod,
				   TupleDesc *cache_field, ExprContext *econtext)
{
	TupleDesc	tupDesc = *cache_field;

	/* Do lookup if no cached value or if requested type changed */
	if (tupDesc == NULL ||
		type_id != tupDesc->tdtypeid ||
		typmod != tupDesc->tdtypmod)
	{
		tupDesc = lookup_rowtype_tupdesc(type_id, typmod);

		if (*cache_field)
		{
			/* Release old tupdesc; but callback is already registered */
			ReleaseTupleDesc(*cache_field);
		}
		else
		{
			/* Need to register shutdown callback to release tupdesc */
			RegisterExprContextCallback(econtext,
										ShutdownTupleDescRef,
										PointerGetDatum(cache_field));
		}
		*cache_field = tupDesc;
	}
	return tupDesc;
}

/*
 * Callback function to release a tupdesc refcount at expression tree shutdown
 */
static void
ShutdownTupleDescRef(Datum arg)
{
	TupleDesc  *cache_field = (TupleDesc *) DatumGetPointer(arg);

	if (*cache_field)
		ReleaseTupleDesc(*cache_field);
	*cache_field = NULL;
}

/*
 * Evaluate arguments for a function.
 */
ExprDoneCond
ExecEvalFuncArgs(FunctionCallInfo fcinfo,
				 List *argList,
				 ExprContext *econtext)
{
	ExprDoneCond argIsDone;
	int			i;
	ListCell   *arg;

	argIsDone = ExprSingleResult;		/* default assumption */

	i = 0;
	foreach(arg, argList)
	{
		ExprState  *argstate = (ExprState *) lfirst(arg);
		ExprDoneCond thisArgIsDone;

		fcinfo->arg[i] = ExecEvalExpr(argstate,
									  econtext,
									  &fcinfo->argnull[i],
									  &thisArgIsDone);

		if (thisArgIsDone != ExprSingleResult)
		{
			/*
			 * We allow only one argument to have a set value; we'd need much
			 * more complexity to keep track of multiple set arguments (cf.
			 * ExecTargetList) and it doesn't seem worth it.
			 */
			if (argIsDone != ExprSingleResult)
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("functions and operators can take at most one set argument")));
			argIsDone = thisArgIsDone;
		}
		i++;
	}

	fcinfo->nargs = i;

	return argIsDone;
}

/*
 *		ExecPrepareTuplestoreResult
 *
 * Subroutine for ExecMakeFunctionResult: prepare to extract rows from a
 * tuplestore function result.  We must set up a funcResultSlot (unless
 * already done in a previous call cycle) and verify that the function
 * returned the expected tuple descriptor.
 */
static void
ExecPrepareTuplestoreResult(FuncExprState *fcache,
							ExprContext *econtext,
							Tuplestorestate *resultStore,
							TupleDesc resultDesc)
{
	fcache->funcResultStore = resultStore;

	if (fcache->funcResultSlot == NULL)
	{
		/* Create a slot so we can read data out of the tuplestore */
		MemoryContext oldcontext;

		/* We must have been able to determine the result rowtype */
		if (fcache->funcResultDesc == NULL)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("function returning setof record called in "
							"context that cannot accept type record")));

		oldcontext = MemoryContextSwitchTo(fcache->func.fn_mcxt);
		fcache->funcResultSlot =
			MakeSingleTupleTableSlot(fcache->funcResultDesc);
		MemoryContextSwitchTo(oldcontext);
	}

	/*
	 * If function provided a tupdesc, cross-check it.	We only really
	 * need to do this for functions returning RECORD, but might as well
	 * do it always.
	 */
	if (resultDesc)
	{
		if (fcache->funcResultDesc)
			tupledesc_match(fcache->funcResultDesc, resultDesc);

		/*
		 * If it is a dynamically-allocated TupleDesc, free it: it is
		 * typically allocated in a per-query context, so we must avoid
		 * leaking it across multiple usages.
		 */
		if (resultDesc->tdrefcount == -1)
			FreeTupleDesc(resultDesc);
	}

	/* Register cleanup callback if we didn't already */
	if (!fcache->shutdown_reg)
	{
		RegisterExprContextCallback(econtext,
									ShutdownFuncExpr,
									PointerGetDatum(fcache));
		fcache->shutdown_reg = true;
	}
}

/*
 * Check that function result tuple type (src_tupdesc) matches or can
 * be considered to match what the query expects (dst_tupdesc). If
 * they don't match, ereport.
 *
 * We really only care about number of attributes and data type.
 * Also, we can ignore type mismatch on columns that are dropped in the
 * destination type, so long as the physical storage matches.  This is
 * helpful in some cases involving out-of-date cached plans.
 */
static void
tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc)
{
	int			i;

	if (dst_tupdesc->natts != src_tupdesc->natts)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("function return row and query-specified return row do not match"),
				 errdetail("Returned row contains %d attributes, but query expects %d.",
						   src_tupdesc->natts, dst_tupdesc->natts)));

	for (i = 0; i < dst_tupdesc->natts; i++)
	{
		Form_pg_attribute dattr = dst_tupdesc->attrs[i];
		Form_pg_attribute sattr = src_tupdesc->attrs[i];

		if (dattr->atttypid == sattr->atttypid)
			continue;			/* no worries */
		if (!dattr->attisdropped)
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("function return row and query-specified return row do not match"),
					 errdetail("Returned type %s at ordinal position %d, but query expects %s.",
							   format_type_be(sattr->atttypid),
							   i + 1,
							   format_type_be(dattr->atttypid))));

		if (dattr->attlen != sattr->attlen ||
			dattr->attalign != sattr->attalign)
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("function return row and query-specified return row do not match"),
					 errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
							   i + 1)));
	}
}

/*
 *		ExecMakeFunctionResult
 *
 * Evaluate the arguments to a function and then the function itself.
 * init_fcache is presumed already run on the FuncExprState.
 *
 * This function handles the most general case, wherein the function or
 * one of its arguments might (or might not) return a set.  If we find
 * no sets involved, we will change the FuncExprState's function pointer
 * to use a simpler method on subsequent calls.
 */
static Datum
ExecMakeFunctionResult(FuncExprState *fcache,
					   ExprContext *econtext,
					   bool *isNull,
					   ExprDoneCond *isDone)
{
	Datum		result;
	FunctionCallInfoData fcinfo;
	ReturnSetInfo rsinfo;		/* for functions returning sets */
	ExprDoneCond argDone;
	bool		hasSetArg;
	int			i;

restart:

	/* Guard against stack overflow due to overly complex expressions */
	check_stack_depth();

	/*
	 * If a previous call of the function returned a set result in the form
	 * of a tuplestore, continue reading rows from the tuplestore until it's
	 * empty.
	 */
	if (fcache->funcResultStore)
	{
		Assert(isDone);				/* it was provided before ... */
		if (tuplestore_gettupleslot(fcache->funcResultStore, true,
									fcache->funcResultSlot))
		{
			*isDone = ExprMultipleResult;
			if (fcache->funcReturnsTuple)
			{
				/* We must return the whole tuple as a Datum. */
				*isNull = false;
				return ExecFetchSlotTupleDatum(fcache->funcResultSlot);
			}
			else
			{
				/* Extract the first column and return it as a scalar. */
				return slot_getattr(fcache->funcResultSlot, 1, isNull);
			}
		}
		/* Exhausted the tuplestore, so clean up */
		tuplestore_end(fcache->funcResultStore);
		fcache->funcResultStore = NULL;
		/* We are done unless there was a set-valued argument */
		if (!fcache->setHasSetArg)
		{
			*isDone = ExprEndResult;
			*isNull = true;
			return (Datum) 0;
		}
		/* If there was, continue evaluating the argument values */
		Assert(!fcache->setArgsValid);
	}

	/*
	 * arguments is a list of expressions to evaluate before passing to the
	 * function manager.  We skip the evaluation if it was already done in the
	 * previous call (ie, we are continuing the evaluation of a set-valued
	 * function).  Otherwise, collect the current argument values into fcinfo.
	 */
	List	   *arguments = fcache->args;
	if (!fcache->setArgsValid)
	{
		/* Need to prep callinfo structure */
		InitFunctionCallInfoData(fcinfo, &(fcache->func), 0, NULL, NULL);
		argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);
		if (argDone == ExprEndResult)
		{
			/* input is an empty set, so return an empty set. */
			*isNull = true;
			if (isDone)
				*isDone = ExprEndResult;
			else
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("set-valued function called in context that cannot accept a set")));
			return (Datum) 0;
		}
		hasSetArg = (argDone != ExprSingleResult);
	}
	else
	{
		/* Copy callinfo from previous evaluation */
		memcpy(&fcinfo, &fcache->setArgs, sizeof(fcinfo));
		hasSetArg = fcache->setHasSetArg;
		/* Reset flag (we may set it again below) */
		fcache->setArgsValid = false;
	}

	/*
	 * Prepare a resultinfo node for communication.  If the function
	 * doesn't itself return set, we don't pass the resultinfo to the
	 * function, but we need to fill it in anyway for internal use.
	 */
	if (fcache->func.fn_retset)
	{
		fcinfo.resultinfo = (Node *) &rsinfo;
	}
	rsinfo.type = (fmNodeTag) T_ReturnSetInfo;
	rsinfo.econtext = econtext;
	rsinfo.expectedDesc = fcache->funcResultDesc;
	rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
	/* note we do not set SFRM_Materialize_Random or _Preferred */
	rsinfo.returnMode = SFRM_ValuePerCall;
	/* isDone is filled below */
	rsinfo.setResult = NULL;
	rsinfo.setDesc = NULL;

	/*
	 * Now call the function, passing the evaluated parameter values.
	 */
	if (fcache->func.fn_retset || hasSetArg)
	{
		/*
		 * We need to return a set result.	Complain if caller not ready to
		 * accept one.
		 */
		if (isDone == NULL)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("set-valued function called in context that cannot accept a set")));

		/*
		 * This loop handles the situation where we have both a set argument
		 * and a set-valued function.  Once we have exhausted the function's
		 * value(s) for a particular argument value, we have to get the next
		 * argument value and start the function over again. We might have to
		 * do it more than once, if the function produces an empty result set
		 * for a particular input value.
		 */
		for (;;)
		{
			/*
			 * If function is strict, and there are any NULL arguments, skip
			 * calling the function (at least for this set of args).
			 */
			bool		callit = true;

			if (fcache->func.fn_strict)
			{
				for (i = 0; i < fcinfo.nargs; i++)
				{
					if (fcinfo.argnull[i])
					{
						callit = false;
						break;
					}
				}
			}

			if (callit)
			{
				fcinfo.isnull = false;
				rsinfo.isDone = ExprSingleResult;

				bool savedImmediateInterruptOK = ImmediateInterruptOK;
				/* Allow "die" interrupt to be processed while waiting */
				ImmediateInterruptOK = true;
				InterruptWhenCallingPLUDF = true;
				result = FunctionCallInvoke(&fcinfo);
				InterruptWhenCallingPLUDF = false;
				ImmediateInterruptOK = savedImmediateInterruptOK;

				*isNull = fcinfo.isnull;
				*isDone = rsinfo.isDone;
			}
			else
			{
				result = (Datum) 0;
				*isNull = true;
				*isDone = ExprEndResult;
			}

			/* Which protocol does function want to use? */
			if (rsinfo.returnMode == SFRM_ValuePerCall)
			{
				if (*isDone != ExprEndResult)
				{
					/*
					 * Got a result from current argument. If function itself
					 * returns set, save the current argument values to re-use
					 * on the next call.
					 */
					if (fcache->func.fn_retset &&
						*isDone == ExprMultipleResult)
					{
						memcpy(&fcache->setArgs, &fcinfo, sizeof(fcinfo));
						fcache->setHasSetArg = hasSetArg;
						fcache->setArgsValid = true;
						/* Register cleanup callback if we didn't already */
						if (!fcache->shutdown_reg)
						{
							RegisterExprContextCallback(econtext,
														ShutdownFuncExpr,
														PointerGetDatum(fcache));
							fcache->shutdown_reg = true;
						}
					}

					/*
					 * Make sure we say we are returning a set, even if the
					 * function itself doesn't return sets.
					 */
					if (hasSetArg)
						*isDone = ExprMultipleResult;
					break;
				}
			}
			else if (rsinfo.returnMode == SFRM_Materialize)
			{
				/* check we're on the same page as the function author */
				if (rsinfo.isDone != ExprSingleResult)
					ereport(ERROR,
							(errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
							 errmsg("table-function protocol for materialize mode was not followed")));
				if (rsinfo.setResult != NULL)
				{
					/* prepare to return values from the tuplestore */
					ExecPrepareTuplestoreResult(fcache, econtext,
												rsinfo.setResult,
												rsinfo.setDesc);
					/* remember whether we had set arguments */
					fcache->setHasSetArg = hasSetArg;
					/* loop back to top to start returning from tuplestore */
					goto restart;
				}
				/* if setResult was left null, treat it as empty set */
				*isDone = ExprEndResult;
				*isNull = true;
				result = (Datum) 0;
			}
			else
				ereport(ERROR,
						(errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
						 errmsg("unrecognized table-function returnMode: %d",
								(int) rsinfo.returnMode)));

			/* Else, done with this argument */
			if (!hasSetArg)
				break;			/* input not a set, so done */

			/* Re-eval args to get the next element of the input set */
			argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);

			if (argDone != ExprMultipleResult)
			{
				/* End of argument set, so we're done. */
				*isNull = true;
				*isDone = ExprEndResult;
				result = (Datum) 0;
				break;
			}

			/*
			 * If we reach here, loop around to run the function on the new
			 * argument.
			 */
		}
	}
	else
	{
		/*
		 * Non-set case: much easier.
		 *
		 * We change the ExprState function pointer to use the simpler
		 * ExecMakeFunctionResultNoSets on subsequent calls.  This amounts to
		 * assuming that no argument can return a set if it didn't do so the
		 * first time.
		 */
		fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResultNoSets;

		if (isDone)
			*isDone = ExprSingleResult;

		/*
		 * If function is strict, and there are any NULL arguments, skip
		 * calling the function and return NULL.
		 */
		if (fcache->func.fn_strict)
		{
			for (i = 0; i < fcinfo.nargs; i++)
			{
				if (fcinfo.argnull[i])
				{
					*isNull = true;
					return (Datum) 0;
				}
			}
		}
		fcinfo.isnull = false;

		bool savedImmediateInterruptOK = ImmediateInterruptOK;
		/* Allow "die" interrupt to be processed while waiting */
		ImmediateInterruptOK = true;
		InterruptWhenCallingPLUDF = true;
		result = FunctionCallInvoke(&fcinfo);
		InterruptWhenCallingPLUDF = false;
		ImmediateInterruptOK = savedImmediateInterruptOK;

		*isNull = fcinfo.isnull;
	}

	return result;
}

/*
 *		ExecMakeFunctionResultNoSets
 *
 * Simplified version of ExecMakeFunctionResult that can only handle
 * non-set cases.  Hand-tuned for speed.
 */
static Datum
ExecMakeFunctionResultNoSets(FuncExprState *fcache,
							 ExprContext *econtext,
							 bool *isNull,
							 ExprDoneCond *isDone)
{
	ListCell   *arg;
	Datum		result;
	FunctionCallInfoData fcinfo;
	int			i;

	/* Guard against stack overflow due to overly complex expressions */
	check_stack_depth();

	if (isDone)
		*isDone = ExprSingleResult;

	/* inlined, simplified version of ExecEvalFuncArgs */
	i = 0;
	foreach(arg, fcache->args)
	{
		ExprState  *argstate = (ExprState *) lfirst(arg);

		fcinfo.arg[i] = ExecEvalExpr(argstate,
									 econtext,
									 &fcinfo.argnull[i],
									 NULL);
		i++;
	}

	InitFunctionCallInfoData(fcinfo, &(fcache->func), i, NULL, NULL);

	/*
	 * If function is strict, and there are any NULL arguments, skip calling
	 * the function and return NULL.
	 */
	if (fcache->func.fn_strict)
	{
		while (--i >= 0)
		{
			if (fcinfo.argnull[i])
			{
				*isNull = true;
				return (Datum) 0;
			}
		}
	}
	/* fcinfo.isnull = false; */	/* handled by InitFunctionCallInfoData */

	bool savedImmediateInterruptOK = ImmediateInterruptOK;
	/* Allow "die" interrupt to be processed while waiting */
	ImmediateInterruptOK = true;
	InterruptWhenCallingPLUDF = true;
	result = FunctionCallInvoke(&fcinfo);
	InterruptWhenCallingPLUDF = false;
	ImmediateInterruptOK = savedImmediateInterruptOK;

	*isNull = fcinfo.isnull;

	return result;
}


/*
 *		ExecMakeTableFunctionResult
 *
 * Evaluate a table function, producing a materialized result in a Tuplestore
 * object.
 */
Tuplestorestate *
ExecMakeTableFunctionResult(ExprState *funcexpr,
							ExprContext *econtext,
							TupleDesc expectedDesc,
							uint64 operatorMemKB) 
{
	Tuplestorestate *tupstore = NULL;
	TupleDesc	tupdesc = NULL;
	MemTupleBinding *mt_bind = NULL;
	Oid			funcrettype;
	bool		returnsTuple;
	bool		returnsSet = false;
	FunctionCallInfoData fcinfo;
	ReturnSetInfo rsinfo;
	HeapTupleData tmptup;
	MemoryContext callerContext;
	MemoryContext oldcontext;
	bool		direct_function_call;
	bool		first_time = true;

	callerContext = CurrentMemoryContext;

	funcrettype = exprType((Node *) funcexpr->expr);

	returnsTuple = type_is_rowtype(funcrettype);

	/*
	 * Prepare a resultinfo node for communication.  We always do this even if
	 * not expecting a set result, so that we can pass expectedDesc.  In the
	 * generic-expression case, the expression doesn't actually get to see the
	 * resultinfo, but set it up anyway because we use some of the fields as
	 * our own state variables.
	 */
	InitFunctionCallInfoData(fcinfo, NULL, 0, NULL, (Node *) &rsinfo);
	rsinfo.type = (fmNodeTag) T_ReturnSetInfo;
	rsinfo.econtext = econtext;
	rsinfo.expectedDesc = expectedDesc;
	rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
	rsinfo.returnMode = SFRM_ValuePerCall;
	/* isDone is filled below */
	rsinfo.setResult = NULL;
	rsinfo.setDesc = NULL;

	/*
	 * Normally the passed expression tree will be a FuncExprState, since the
	 * grammar only allows a function call at the top level of a table
	 * function reference.	However, if the function doesn't return set then
	 * the planner might have replaced the function call via constant-folding
	 * or inlining.  So if we see any other kind of expression node, execute
	 * it via the general ExecEvalExpr() code; the only difference is that we
	 * don't get a chance to pass a special ReturnSetInfo to any functions
	 * buried in the expression.
	 */
	if (funcexpr && IsA(funcexpr, FuncExprState) &&
		IsA(funcexpr->expr, FuncExpr))
	{
		FuncExprState *fcache = (FuncExprState *) funcexpr;
		ExprDoneCond argDone;

		/*
		 * This path is similar to ExecMakeFunctionResult.
		 */
		direct_function_call = true;

		/*
		 * Initialize function cache if first time through
		 */
		if (fcache->func.fn_oid == InvalidOid)
		{
			FuncExpr   *func = (FuncExpr *) fcache->xprstate.expr;

			init_fcache(func->funcid, fcache,
						econtext->ecxt_per_query_memory, false);
		}
		returnsSet = fcache->func.fn_retset;

		/*
		 * Evaluate the function's argument list.
		 *
		 * Note: ideally, we'd do this in the per-tuple context, but then the
		 * argument values would disappear when we reset the context in the
		 * inner loop.	So do it in caller context.  Perhaps we should make a
		 * separate context just to hold the evaluated arguments?
		 */
		fcinfo.flinfo = &(fcache->func);
		argDone = ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
		/* We don't allow sets in the arguments of the table function */
		if (argDone != ExprSingleResult)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("set-valued function called in context that cannot accept a set")));

		/*
		 * If function is strict, and there are any NULL arguments, skip
		 * calling the function and act like it returned NULL (or an empty
		 * set, in the returns-set case).
		 */
		if (fcache->func.fn_strict)
		{
			int			i;

			for (i = 0; i < fcinfo.nargs; i++)
			{
				if (fcinfo.argnull[i])
					goto no_function_result;
			}
		}
	}
	else
	{
		/* Treat funcexpr as a generic expression */
		direct_function_call = false;
	}

	/*
	 * Switch to short-lived context for calling the function or expression.
	 */
	MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);

	/*
	 * Loop to handle the ValuePerCall protocol (which is also the same
	 * behavior needed in the generic ExecEvalExpr path).
	 */
	for (;;)
	{
		Datum		result;
		MemTuple	tuple;

		CHECK_FOR_INTERRUPTS();

		/*
		 * reset per-tuple memory context before each call of the function or
		 * expression. This cleans up any local memory the function may leak
		 * when called.
		 */
		ResetExprContext(econtext);

		/* Call the function or expression one time */
		if (direct_function_call)
		{
			fcinfo.isnull = false;
			rsinfo.isDone = ExprSingleResult;

			bool savedImmediateInterruptOK = ImmediateInterruptOK;
			/* Allow "die" interrupt to be processed while waiting */
			ImmediateInterruptOK = true;
			InterruptWhenCallingPLUDF = true;
			result = FunctionCallInvoke(&fcinfo);
			InterruptWhenCallingPLUDF = false;
			ImmediateInterruptOK = savedImmediateInterruptOK;
		}
		else
		{
			result = ExecEvalExpr(funcexpr, econtext,
								  &fcinfo.isnull, &rsinfo.isDone);
		}

		/* Which protocol does function want to use? */
		if (rsinfo.returnMode == SFRM_ValuePerCall)
		{
			/*
			 * Check for end of result set.
			 */
			if (rsinfo.isDone == ExprEndResult)
				break;

			/*
			 * Can't do anything very useful with NULL rowtype values. For a
			 * function returning set, we consider this a protocol violation
			 * (but another alternative would be to just ignore the result and
			 * "continue" to get another row).	For a function not returning
			 * set, we fall out of the loop; we'll cons up an all-nulls result
			 * row below.
			 */
			if (returnsTuple && fcinfo.isnull)
			{
				if (!returnsSet)
					break;
				ereport(ERROR,
						(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
						 errmsg("function returning set of rows cannot return null value")));
			}

			/*
			 * If first time through, build tupdesc and tuplestore for result
			 */
			if (first_time)
			{
				oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
				if (returnsTuple)
				{
					/*
					 * Use the type info embedded in the rowtype Datum to look
					 * up the needed tupdesc.  Make a copy for the query.
					 */
					HeapTupleHeader td;

					td = DatumGetHeapTupleHeader(result);
					tupdesc = lookup_rowtype_tupdesc_copy(HeapTupleHeaderGetTypeId(td),
											   HeapTupleHeaderGetTypMod(td));
				}
				else
				{
					/*
					 * Scalar type, so make a single-column descriptor
					 */
					tupdesc = CreateTemplateTupleDesc(1, false);
					TupleDescInitEntry(tupdesc,
									   (AttrNumber) 1,
									   "column",
									   funcrettype,
									   -1,
									   0);
				}

				mt_bind = create_memtuple_binding(tupdesc);

				tupstore = tuplestore_begin_heap(true, false, operatorMemKB); 
				MemoryContextSwitchTo(oldcontext);
				rsinfo.setResult = tupstore;
				rsinfo.setDesc = tupdesc;
			}

			/*
			 * Store current resultset item.
			 */
			if (returnsTuple)
			{
			    const int staticBufferLimit = 200;
				HeapTupleHeader td;
				Datum staticPd[staticBufferLimit];
				bool staticNull[staticBufferLimit];
				Datum *pd;
				bool *pn;

                /**
                 * use memory on stack if possible, to save palloc calls
                 */
				if ( tupdesc->natts > staticBufferLimit)
				{
                    pd = (Datum *) palloc(tupdesc->natts * sizeof(Datum));
                    pn = (bool *) palloc(tupdesc->natts * sizeof(bool));
                }
                else
                {
                    pd = staticPd;
                    pn = staticNull;
                }


				td = DatumGetHeapTupleHeader(result);

				/*
				 * tuplestore_puttuple needs a HeapTuple not a bare
				 * HeapTupleHeader, but it doesn't need all the fields.
				 */
				tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
				tmptup.t_data = td;

				heap_deform_tuple(&tmptup, tupdesc, pd, pn);
				tuple = memtuple_form_to(mt_bind, pd, pn, NULL, NULL, false);
			}
			else
			{
				tuple = memtuple_form_to(mt_bind, &result, &fcinfo.isnull, NULL, NULL, false);
			}

			oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
			tuplestore_puttuple(tupstore, (HeapTuple) tuple);
			MemoryContextSwitchTo(oldcontext);

			/*
			 * Are we done?
			 */
			if (rsinfo.isDone != ExprMultipleResult)
				break;
		}
		else if (rsinfo.returnMode == SFRM_Materialize)
		{
			/* check we're on the same page as the function author */
			if (!first_time || rsinfo.isDone != ExprSingleResult)
				ereport(ERROR,
						(errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
						 errmsg("table-function protocol for materialize mode was not followed")));
			/* Done evaluating the set result */
			break;
		}
		else
			ereport(ERROR,
					(errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
					 errmsg("unrecognized table-function returnMode: %d",
							(int) rsinfo.returnMode)));

		first_time = false;
	}

no_function_result:

	/*
	 * If we got nothing from the function (ie, an empty-set or NULL result),
	 * we have to create the tuplestore to return, and if it's a
	 * non-set-returning function then insert a single all-nulls row.
	 */
	if (rsinfo.setResult == NULL)
	{
		MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
		tupstore = tuplestore_begin_heap(true, false, operatorMemKB); 
		rsinfo.setResult = tupstore;  
		if (!returnsSet)
		{
			int			natts = expectedDesc->natts;
			Datum	   *nulldatums;
			bool	   *nullflags;
			HeapTuple	tuple;

			MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
			nulldatums = (Datum *) palloc0(natts * sizeof(Datum));
			nullflags = (bool *) palloc(natts * sizeof(bool));
			MemSetAligned(nullflags, true, natts * sizeof(bool));
			tuple = heap_form_tuple(expectedDesc, nulldatums, nullflags);
			MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
			tuplestore_puttuple(tupstore, tuple);
		}
	}

	/*
	 * If function provided a tupdesc, cross-check it.	We only really
	 * need to do this for functions returning RECORD, but might as well
	 * do it always.
	 */
	if (rsinfo.setDesc)
	{
		tupledesc_match(expectedDesc, rsinfo.setDesc);

		/*
		 * If it is a dynamically-allocated TupleDesc, free it: it is
		 * typically allocated in a per-query context, so we must avoid
		 * leaking it across multiple usages.
		 */
		if (rsinfo.setDesc->tdrefcount == -1)
		{
			FreeTupleDesc(rsinfo.setDesc);
			rsinfo.setDesc = NULL;
		}
	}

	MemoryContextSwitchTo(callerContext);

	/* All done, pass back the tuplestore */
	return rsinfo.setResult;
}


/* ----------------------------------------------------------------
 *		ExecEvalFunc
 *		ExecEvalOper
 *
 *		Evaluate the functional result of a list of arguments by calling the
 *		function manager.
 * ----------------------------------------------------------------
 */

/* ----------------------------------------------------------------
 *		ExecEvalFunc
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalFunc(FuncExprState *fcache,
			 ExprContext *econtext,
			 bool *isNull,
			 ExprDoneCond *isDone)
{
	/* This is called only the first time through */
	FuncExpr   *func = (FuncExpr *) fcache->xprstate.expr;

	/* Initialize function lookup info */
	init_fcache(func->funcid, fcache, econtext->ecxt_per_query_memory, true);

	/* Go directly to ExecMakeFunctionResult on subsequent uses */
	fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;

	return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
}

/* ----------------------------------------------------------------
 *		ExecEvalOper
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalOper(FuncExprState *fcache,
			 ExprContext *econtext,
			 bool *isNull,
			 ExprDoneCond *isDone)
{
	/* This is called only the first time through */
	OpExpr	   *op = (OpExpr *) fcache->xprstate.expr;

	/* Initialize function lookup info */
	init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory, true);

	/* Go directly to ExecMakeFunctionResult on subsequent uses */
	fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;

	return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
}

/* ----------------------------------------------------------------
 *		ExecEvalDistinct
 *
 * IS DISTINCT FROM must evaluate arguments to determine whether
 * they are NULL; if either is NULL then the result is already
 * known. If neither is NULL, then proceed to evaluate the
 * function. Note that this is *always* derived from the equals
 * operator, but since we need special processing of the arguments
 * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalDistinct(FuncExprState *fcache,
				 ExprContext *econtext,
				 bool *isNull,
				 ExprDoneCond *isDone)
{
	Datum		result;
	FunctionCallInfoData fcinfo;
	ExprDoneCond argDone;
	List	   *argList;

	/* Set default values for result flags: non-null, not a set result */
	*isNull = false;
	if (isDone)
		*isDone = ExprSingleResult;

	/*
	 * Initialize function cache if first time through
	 */
	if (fcache->func.fn_oid == InvalidOid)
	{
		DistinctExpr *op = (DistinctExpr *) fcache->xprstate.expr;

		init_fcache(op->opfuncid, fcache,
					econtext->ecxt_per_query_memory, true);
		Assert(!fcache->func.fn_retset);
	}

	/*
	 * extract info from fcache
	 */
	argList = fcache->args;

	/* Need to prep callinfo structure */
	InitFunctionCallInfoData(fcinfo, &(fcache->func), 0, NULL, NULL);
	argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
	if (argDone != ExprSingleResult)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("IS DISTINCT FROM does not support set arguments")));
	Assert(fcinfo.nargs == 2);

	if (fcinfo.argnull[0] && fcinfo.argnull[1])
	{
		/* Both NULL? Then is not distinct... */
		result = BoolGetDatum(FALSE);
	}
	else if (fcinfo.argnull[0] || fcinfo.argnull[1])
	{
		/* Only one is NULL? Then is distinct... */
		result = BoolGetDatum(TRUE);
	}
	else
	{
		fcinfo.isnull = false;
		result = FunctionCallInvoke(&fcinfo);
		*isNull = fcinfo.isnull;
		/* Must invert result of "=" */
		result = BoolGetDatum(!DatumGetBool(result));
	}

	return result;
}

static inline void ExecEvalFPStrict2Arg(FuncExprState *expr, ExprContext *econtext, bool *isNull, ExprDoneCond *isDone)
{ 
	ExprDoneCond argDone[2];

	Assert(expr->fp_arg[0] && expr->fp_arg[1]);
	if(isDone)
		*isDone = ExprSingleResult;
	
	expr->fp_datum[0] = ExecEvalExpr(expr->fp_arg[0], econtext, &expr->fp_null[0], &argDone[0]);
	expr->fp_datum[1] = ExecEvalExpr(expr->fp_arg[1], econtext, &expr->fp_null[1], &argDone[1]);

	*isNull = expr->fp_null[0] || expr->fp_null[1];
}

static Datum ExecEvalFPStrict2_Int2Eq(FuncExprState *fstate, ExprContext *ctxt, bool *isNull, ExprDoneCond *isDone)
{
	ExecEvalFPStrict2Arg(fstate, ctxt, isNull, isDone);
	return BoolGetDatum(
			DatumGetInt16(fstate->fp_datum[0]) == DatumGetInt16(fstate->fp_datum[1])
			);
}

static Datum ExecEvalFPStrict2_Int4Eq(FuncExprState *fstate, ExprContext *ctxt, bool *isNull, ExprDoneCond *isDone)
{

	ExecEvalFPStrict2Arg(fstate, ctxt, isNull, isDone);
	return BoolGetDatum(
			DatumGetInt32(fstate->fp_datum[0]) == DatumGetInt32(fstate->fp_datum[1])
			);
}

static Datum ExecEvalFPStrict2_Int8Eq(FuncExprState *fstate, ExprContext *ctxt, bool *isNull, ExprDoneCond *isDone)
{
	ExecEvalFPStrict2Arg(fstate, ctxt, isNull, isDone);
	return BoolGetDatum(fstate->fp_datum[0] == fstate->fp_datum[1]);
}

/* Some Oids that we want to fast path.  See pg_proc.h */
#define INT2EQ_OID 63
#define INT4EQ_OID 65
#define TEXTEQ_OID 67
#define INT8EQ_OID 467
#define BPCHAREQ_OID 1048
#define DATE_EQ_OID 1086

/* Optimize x op y if op has no side effect.  Almost all our functions are
 * strict, 2 args.  
 * 
 * NOTE: You need to implement the ExecEvalFPStrict2_FUNC FAITHFULLY.  
 * For example, before you fast path int4add, make sure your implementation 
 * is the same as the old int4add, that is, you need to handle under/over flow etc.
 */
static void FastPathStrict2Func(Oid funcoid, FuncExprState *fstate)
{
	static Oid strict2oid[] = {
		INT2EQ_OID,
		INT4EQ_OID,
		DATE_EQ_OID,
		INT8EQ_OID,
	};
	static ExprStateEvalFunc strict2func[] = {
		(ExprStateEvalFunc) ExecEvalFPStrict2_Int2Eq,
		(ExprStateEvalFunc) ExecEvalFPStrict2_Int4Eq,
		(ExprStateEvalFunc) ExecEvalFPStrict2_Int4Eq, /* date_eq is int4 eq */
		(ExprStateEvalFunc) ExecEvalFPStrict2_Int8Eq,
	};

	int i;

	COMPILE_ASSERT(ARRAY_SIZE(strict2oid) == ARRAY_SIZE(strict2func));

	for(i=0; i<ARRAY_SIZE(strict2oid); ++i)
	{
		if (strict2oid[i] == funcoid)
		{
			fstate->xprstate.evalfunc = strict2func[i];
			fstate->fp_arg[0] = linitial(fstate->args);
			fstate->fp_arg[1] = lsecond(fstate->args);
			return;
		}
	}
}

static Datum
ExecEvalFPScalarArrayInt(ScalarArrayOpExprState *sstate,
					  ExprContext *econtext,
					  bool *isNull, ExprDoneCond *isDone)
{
	ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) sstate->fxprstate.xprstate.expr;
	Oid fnoid = opexpr->opfuncid;
	ExprState *arg = linitial(sstate->fxprstate.args);

	ExprDoneCond argDone;
	Datum d;
	bool isnull;

	int i;

	d = ExecEvalExpr(arg, econtext, &isnull, &argDone);
	Assert(argDone == ExprSingleResult);

	if (isDone)
		*isDone = ExprSingleResult;
		
	if (isnull)
	{
		*isNull = true;
		return 0;
	}

	*isNull = false;
	if (fnoid == INT4EQ_OID || fnoid == DATE_EQ_OID)
		d = Int32GetDatum(DatumGetInt32(d));
	else if (fnoid != INT8EQ_OID)
	{
		Assert(fnoid == INT2EQ_OID);
		d = Int16GetDatum(DatumGetInt16(d));
	}

	for(i=0; i<sstate->fp_n; ++i)
	{
		if(d == sstate->fp_datum[i])
			return BoolGetDatum(true);
	}

	return BoolGetDatum(false);
}

static Datum
ExecEvalFPScalarArrayStr(ScalarArrayOpExprState *sstate,
					  ExprContext *econtext,
					  bool *isNull, ExprDoneCond *isDone)
{
	ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) sstate->fxprstate.xprstate.expr;
	Oid fnoid = opexpr->opfuncid;
	ExprState *arg = linitial(sstate->fxprstate.args);

	ExprDoneCond argDone;
	Datum d;
	bool isnull;
	Datum ret;

	char *p; void *tofree; int len;

	int i;

	d = ExecEvalExpr(arg, econtext, &isnull, &argDone);
	Assert(argDone == ExprSingleResult);

	if (isDone)
		*isDone = ExprSingleResult;
		
	if (isnull)
	{
		*isNull = true;
		return 0;
	}

	*isNull = false;

	ret = BoolGetDatum(false);

	varattrib_untoast_ptr_len(d, &p, &len, &tofree);

	/* bpchareq, rid of trailing white space.  see bpeq and bcTruelen */
	if(fnoid == BPCHAREQ_OID)
	{
		while(len > 0 && p[len-1] == ' ')
			--len;
	}

	for(i=0; i<sstate->fp_n; ++i)
	{
		if(sstate->fp_len[i] != len)
			continue;
		if(memcmp(p, DatumGetPointer(sstate->fp_datum[i]), sstate->fp_len[i]) == 0)
		{
			ret = BoolGetDatum(true);
			break;
		}
	}

	if(tofree)
		pfree(tofree);

	return ret;
}

/* Optimize x in ('A', 'B', 'C') */
static void FastPathScalarArrayOp(ScalarArrayOpExpr *opexpr, ScalarArrayOpExprState *sstate)
{
	ExprState *argstate;
	Const *argconst;
	ArrayType *arr;

	char *s;
	bits8 *bitmap;
	int bitmask;

	int16		typlen;
	bool		typbyval;
	char		typalign;

	Oid fnoid = InvalidOid;

	static int4 optimize_func_oid[] = {
		INT2EQ_OID,
		INT4EQ_OID,
		TEXTEQ_OID,
		INT8EQ_OID,
		BPCHAREQ_OID,
		DATE_EQ_OID,
	};

	int i;
		
	/* IN will be evaluated as OR */
	if (!opexpr->useOr)
		return;

	/* Check if we optimize these types */
	for (i=0; i<ARRAY_SIZE(optimize_func_oid); ++i)
	{
		if (optimize_func_oid[i] == opexpr->opfuncid)
		{
			fnoid = opexpr->opfuncid;
			break;
		}
	}

	if(fnoid == InvalidOid)
		return;

	/* Better to have just two args */
	Assert(list_length(sstate->fxprstate.args) == 2);
	
	/* only if the second args are const */
	argstate = (ExprState *) lsecond(sstate->fxprstate.args);
	if (argstate->evalfunc != ExecEvalConst)
		return;

	argconst = (Const *) argstate->expr;

	/* We do not handle null */
	if (argconst->constisnull)
		return;

	arr = DatumGetArrayTypeP(argconst->constvalue);
	sstate->fp_n = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));

	/* We do not handle this case */
	if (sstate->fp_n <= 0)
		return;

	sstate->fp_len = (int *) palloc(sizeof(int) * sstate->fp_n);
	sstate->fp_datum = (Datum *) palloc(sizeof(Datum) * sstate->fp_n);

	/* Type stuff */
	if (sstate->element_type != ARR_ELEMTYPE(arr))
	{
		get_typlenbyvalalign(ARR_ELEMTYPE(arr),
				&sstate->typlen,
				&sstate->typbyval,
				&sstate->typalign);
		sstate->element_type = ARR_ELEMTYPE(arr);
	}
	typlen = sstate->typlen;
	typbyval = sstate->typbyval;
	typalign = sstate->typalign;

	/* Loop over the array elements */
	s = (char *) ARR_DATA_PTR(arr);
	bitmap = ARR_NULLBITMAP(arr);
	bitmask = 1;

	for (i = 0; i < sstate->fp_n; i++)
	{
		Datum elt;
		
		/* Do not deal with null yet */
		if (bitmap && (*bitmap & bitmask) == 0)
			return;
		
		elt = fetch_att(s, typbyval, typlen);
		s = att_addlength(s, typlen, PointerGetDatum(s));
		s = (char *) att_align(s, typalign);

		/* int type */
		if (fnoid == INT2EQ_OID)
			sstate->fp_datum[i] = Int16GetDatum(DatumGetInt16(elt));
		else if (fnoid == INT4EQ_OID || fnoid == DATE_EQ_OID)
			sstate->fp_datum[i] = Int32GetDatum(DatumGetInt32(elt));
		else if (fnoid == INT8EQ_OID)
			sstate->fp_datum[i] = elt;
		else if (fnoid == TEXTEQ_OID || fnoid == BPCHAREQ_OID)
		{
			char *p; void *tofree; int len;
			char *pdest;

			varattrib_untoast_ptr_len(elt, &p, &len, &tofree);

			/* bpchareq, rid of trailing white space.  see bpeq and bcTruelen */
			if(fnoid == BPCHAREQ_OID)
			{
				while(len > 0 && p[len-1] == ' ')
					--len;
			}

			sstate->fp_len[i] = len;
			pdest = palloc(len);
			sstate->fp_datum[i] = PointerGetDatum(pdest);

			memcpy(pdest, p, len);

			if(tofree)
				pfree(tofree);
		}
		else
			Assert(!"Wrong optimize_funcoid");

		/* advance bitmap pointer if any */
		if (bitmap)
		{
			bitmask <<= 1;
			if (bitmask == 0x100 /* 1<<8 */)
			{
				bitmap++;
				bitmask = 1;
			}
		}
	}

	/* Now we are sure we can fast path this */
	if (fnoid == INT2EQ_OID || fnoid == INT4EQ_OID || fnoid == INT8EQ_OID || fnoid == DATE_EQ_OID)
		sstate->fxprstate.xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFPScalarArrayInt;
	else if (fnoid == TEXTEQ_OID || fnoid == BPCHAREQ_OID) 
		sstate->fxprstate.xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFPScalarArrayStr; 
	else
		Assert(!"Wrong optimize_funcoid");
}
	
/*
 * ExecEvalScalarArrayOp
 *
 * Evaluate "scalar op ANY/ALL (array)".  The operator always yields boolean,
 * and we combine the results across all array elements using OR and AND
 * (for ANY and ALL respectively).	Of course we short-circuit as soon as
 * the result is known.
 */
	static Datum
ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
		ExprContext *econtext,
		bool *isNull, ExprDoneCond *isDone)
{
	ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) sstate->fxprstate.xprstate.expr;
	bool		useOr = opexpr->useOr;
	ArrayType  *arr;
	int			nitems;
	Datum		result;
	bool		resultnull;
	FunctionCallInfoData fcinfo;
	ExprDoneCond argDone;
	int			i;
	int16		typlen;
	bool		typbyval;
	char		typalign;
	char	   *s;
	bits8	   *bitmap;
	int			bitmask;

	/* Set default values for result flags: non-null, not a set result */
	*isNull = false;
	if (isDone)
		*isDone = ExprSingleResult;

	/*
	 * Initialize function cache if first time through
	 */
	if (sstate->fxprstate.func.fn_oid == InvalidOid)
	{
		init_fcache(opexpr->opfuncid, &sstate->fxprstate,
			    econtext->ecxt_per_query_memory, true);
		Assert(!sstate->fxprstate.func.fn_retset);
	}

	/* Need to prep callinfo structure */
	InitFunctionCallInfoData(fcinfo, &(sstate->fxprstate.func), 0, NULL, NULL);
	argDone = ExecEvalFuncArgs(&fcinfo, sstate->fxprstate.args, econtext);
	if (argDone != ExprSingleResult)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("op ANY/ALL (array) does not support set arguments")));
	Assert(fcinfo.nargs == 2);

	/*
	 * If the array is NULL then we return NULL --- it's not very meaningful
	 * to do anything else, even if the operator isn't strict.
	 */
	if (fcinfo.argnull[1])
	{
		*isNull = true;
		return (Datum) 0;
	}
	/* Else okay to fetch and detoast the array */
	arr = DatumGetArrayTypeP(fcinfo.arg[1]);

	/*
	 * If the array is empty, we return either FALSE or TRUE per the useOr
	 * flag.  This is correct even if the scalar is NULL; since we would
	 * evaluate the operator zero times, it matters not whether it would want
	 * to return NULL.
	 */
	nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
	if (nitems <= 0)
		return BoolGetDatum(!useOr);

	/*
	 * If the scalar is NULL, and the function is strict, return NULL; no
	 * point in iterating the loop.
	 */
	if (fcinfo.argnull[0] && sstate->fxprstate.func.fn_strict)
	{
		*isNull = true;
		return (Datum) 0;
	}

	/*
	 * We arrange to look up info about the element type only once per series
	 * of calls, assuming the element type doesn't change underneath us.
	 */
	if (sstate->element_type != ARR_ELEMTYPE(arr))
	{
		get_typlenbyvalalign(ARR_ELEMTYPE(arr),
				&sstate->typlen,
				&sstate->typbyval,
				&sstate->typalign);
		sstate->element_type = ARR_ELEMTYPE(arr);
	}
	typlen = sstate->typlen;
	typbyval = sstate->typbyval;
	typalign = sstate->typalign;

	result = BoolGetDatum(!useOr);
	resultnull = false;

	/* Loop over the array elements */
	s = (char *) ARR_DATA_PTR(arr);
	bitmap = ARR_NULLBITMAP(arr);
	bitmask = 1;

	for (i = 0; i < nitems; i++)
	{
		Datum		elt;
		Datum		thisresult;

		/* Get array element, checking for NULL */
		if (bitmap && (*bitmap & bitmask) == 0)
		{
			fcinfo.arg[1] = (Datum) 0;
			fcinfo.argnull[1] = true;
		}
		else
		{
			elt = fetch_att(s, typbyval, typlen);
			s = att_addlength(s, typlen, PointerGetDatum(s));
			s = (char *) att_align(s, typalign);
			fcinfo.arg[1] = elt;
			fcinfo.argnull[1] = false;
		}

		/* Call comparison function */
		if (fcinfo.argnull[1] && sstate->fxprstate.func.fn_strict)
		{
			fcinfo.isnull = true;
			thisresult = (Datum) 0;
		}
		else
		{
			fcinfo.isnull = false;
			thisresult = FunctionCallInvoke(&fcinfo);
		}

		/* Combine results per OR or AND semantics */
		if (fcinfo.isnull)
			resultnull = true;
		else if (useOr)
		{
			if (DatumGetBool(thisresult))
			{
				result = BoolGetDatum(true);
				resultnull = false;
				break;			/* needn't look at any more elements */
			}
		}
		else
		{
			if (!DatumGetBool(thisresult))
			{
				result = BoolGetDatum(false);
				resultnull = false;
				break;			/* needn't look at any more elements */
			}
		}

		/* advance bitmap pointer if any */
		if (bitmap)
		{
			bitmask <<= 1;
			if (bitmask == 0x100 /* 1<<8 */)
			{
				bitmap++;
				bitmask = 1;
			}
		}
	}

	*isNull = resultnull;
	return result;
}

/* ----------------------------------------------------------------
 *		ExecEvalNot
 *		ExecEvalOr
 *		ExecEvalAnd
 *
 *		Evaluate boolean expressions, with appropriate short-circuiting.
 *
 *		The query planner reformulates clause expressions in the
 *		qualification to conjunctive normal form.  If we ever get
 *		an AND to evaluate, we can be sure that it's not a top-level
 *		clause in the qualification, but appears lower (as a function
 *		argument, for example), or in the target list.	Not that you
 *		need to know this, mind you...
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
			bool *isNull, ExprDoneCond *isDone)
{
	ExprState  *clause = linitial(notclause->args);
	Datum		expr_value;

	if (isDone)
		*isDone = ExprSingleResult;

	expr_value = ExecEvalExpr(clause, econtext, isNull, NULL);

	/*
	 * if the expression evaluates to null, then we just cascade the null back
	 * to whoever called us.
	 */
	if (*isNull)
		return expr_value;

	/*
	 * evaluation of 'not' is simple.. expr is false, then return 'true' and
	 * vice versa.
	 */
	return BoolGetDatum(!DatumGetBool(expr_value));
}

/* ----------------------------------------------------------------
 *		ExecEvalOr
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
		   bool *isNull, ExprDoneCond *isDone)
{
	List	   *clauses = orExpr->args;
	ListCell   *clause;
	bool		AnyNull;

	if (isDone)
		*isDone = ExprSingleResult;

	AnyNull = false;

	/*
	 * If any of the clauses is TRUE, the OR result is TRUE regardless of the
	 * states of the rest of the clauses, so we can stop evaluating and return
	 * TRUE immediately.  If none are TRUE and one or more is NULL, we return
	 * NULL; otherwise we return FALSE.  This makes sense when you interpret
	 * NULL as "don't know": if we have a TRUE then the OR is TRUE even if we
	 * aren't sure about some of the other inputs. If all the known inputs are
	 * FALSE, but we have one or more "don't knows", then we have to report
	 * that we "don't know" what the OR's result should be --- perhaps one of
	 * the "don't knows" would have been TRUE if we'd known its value.  Only
	 * when all the inputs are known to be FALSE can we state confidently that
	 * the OR's result is FALSE.
	 */
	foreach(clause, clauses)
	{
		ExprState  *clausestate = (ExprState *) lfirst(clause);
		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 Datum
ExecEvalAnd(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 Datum
ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
					   ExprContext *econtext,
					   bool *isNull, ExprDoneCond *isDone)
{
	ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) cstate->xprstate.expr;
	HeapTuple	result;
	Datum		tupDatum;
	HeapTupleHeader tuple;
	HeapTupleData tmptup;
	AttrNumber *attrMap;
	Datum	   *invalues;
	bool	   *inisnull;
	Datum	   *outvalues;
	bool	   *outisnull;
	int			i;
	int			outnatts;

	tupDatum = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);

	/* this test covers the isDone exception too: */
	if (*isNull)
		return tupDatum;

	tuple = DatumGetHeapTupleHeader(tupDatum);

	/* Lookup tupdescs if first time through or after rescan */
	if (cstate->indesc == NULL)
		get_cached_rowtype(exprType((Node *) convert->arg), -1,
						   &cstate->indesc, econtext);
	if (cstate->outdesc == NULL)
		get_cached_rowtype(convert->resulttype, -1,
						   &cstate->outdesc, econtext);

	Assert(HeapTupleHeaderGetTypeId(tuple) == cstate->indesc->tdtypeid);
	Assert(HeapTupleHeaderGetTypMod(tuple) == cstate->indesc->tdtypmod);

	/* if first time through, initialize */
	if (cstate->attrMap == NULL)
	{
		MemoryContext old_cxt;
		int			n;

		/* allocate state in long-lived memory context */
		old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);

		/* prepare map from old to new attribute numbers */
		n = cstate->outdesc->natts;
		cstate->attrMap = (AttrNumber *) palloc0(n * sizeof(AttrNumber));
		for (i = 0; i < n; i++)
		{
			Form_pg_attribute att = cstate->outdesc->attrs[i];
			char	   *attname;
			Oid			atttypid;
			int32		atttypmod;
			int			j;

			if (att->attisdropped)
				continue;		/* attrMap[i] is already 0 */
			attname = NameStr(att->attname);
			atttypid = att->atttypid;
			atttypmod = att->atttypmod;
			for (j = 0; j < cstate->indesc->natts; j++)
			{
				att = cstate->indesc->attrs[j];
				if (att->attisdropped)
					continue;
				if (strcmp(attname, NameStr(att->attname)) == 0)
				{
					/* Found it, check type */
					if (atttypid != att->atttypid || atttypmod != att->atttypmod)
						elog(ERROR, "attribute \"%s\" of type %s does not match corresponding attribute of type %s",
							 attname,
							 format_type_be(cstate->indesc->tdtypeid),
							 format_type_be(cstate->outdesc->tdtypeid));
					cstate->attrMap[i] = (AttrNumber) (j + 1);
					break;
				}
			}
			if (cstate->attrMap[i] == 0)
				elog(ERROR, "attribute \"%s\" of type %s does not exist",
					 attname,
					 format_type_be(cstate->indesc->tdtypeid));
		}
		/* preallocate workspace for Datum arrays */
		n = cstate->indesc->natts + 1;	/* +1 for NULL */
		cstate->invalues = (Datum *) palloc(n * sizeof(Datum));
		cstate->inisnull = (bool *) palloc(n * sizeof(bool));
		n = cstate->outdesc->natts;
		cstate->outvalues = (Datum *) palloc(n * sizeof(Datum));
		cstate->outisnull = (bool *) palloc(n * sizeof(bool));

		MemoryContextSwitchTo(old_cxt);
	}

	attrMap = cstate->attrMap;
	invalues = cstate->invalues;
	inisnull = cstate->inisnull;
	outvalues = cstate->outvalues;
	outisnull = cstate->outisnull;
	outnatts = cstate->outdesc->natts;

	/*
	 * 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 Datum
ExecEvalCase(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)
	{
		/*
		 * caseValue_datum and caseValue_isNull from econtext store the results of case
		 * expression. caseValue_isNull will be true if caseValue_datum store null value.
		 * Both caseValue_datum and caseValue_isNull should change at same time and they shouldn't
		 * go out of sync.
		 * Hence pass temporary variable(caseValue_isNull) and once evaluation is done,
		 * update the caseValue_isNull from econtext.
		 */
		bool caseValue_isNull = false;
		econtext->caseValue_datum = ExecEvalExpr(caseExpr->arg,
												 econtext,
												 &caseValue_isNull,
												 NULL);
		econtext->caseValue_isNull = caseValue_isNull;
	}

	/*
	 * 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 Datum
ExecEvalCaseTestExpr(ExprState *exprstate,
					 ExprContext *econtext,
					 bool *isNull, ExprDoneCond *isDone)
{
	if (isDone)
		*isDone = ExprSingleResult;
	*isNull = econtext->caseValue_isNull;
	return econtext->caseValue_datum;
}

/* ----------------------------------------------------------------
 *		ExecEvalArray - ARRAY[] expressions
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalArray(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;
		bool	   *dnulls;
		int			i = 0;

		ndims = 1;
		nelems = list_length(astate->elements);

		/* Shouldn't happen here, but if length is 0, return empty array */
		if (nelems == 0)
			return PointerGetDatum(construct_empty_array(element_type));

		dvalues = (Datum *) palloc(nelems * sizeof(Datum));
		dnulls = (bool *) palloc(nelems * sizeof(bool));

		/* loop through and build array of datums */
		foreach(element, astate->elements)
		{
			ExprState  *e = (ExprState *) lfirst(element);

			dvalues[i] = ExecEvalExpr(e, econtext, &dnulls[i], NULL);
			i++;
		}

		/* setup for 1-D array of the given length */
		dims[0] = nelems;
		lbs[0] = 1;

		result = construct_md_array(dvalues, dnulls, ndims, dims, lbs,
									element_type,
									astate->elemlength,
									astate->elembyval,
									astate->elemalign);
	}
	else
	{
		/* Must be nested array expressions */
		int			nbytes = 0;
		int			nitems = 0;
		int			outer_nelems = 0;
		int			elem_ndims = 0;
		int		   *elem_dims = NULL;
		int		   *elem_lbs = NULL;
		bool		firstone = true;
		bool		havenulls = false;
		bool		haveempty = false;
		char	  **subdata;
		bits8	  **subbitmaps;
		int		   *subbytes;
		int		   *subnitems;
		int			i;
		int32		dataoffset;
		char	   *dat;
		int			iitem;

		i = list_length(astate->elements);
		subdata = (char **) palloc(i * sizeof(char *));
		subbitmaps = (bits8 **) palloc(i * sizeof(bits8 *));
		subbytes = (int *) palloc(i * sizeof(int));
		subnitems = (int *) palloc(i * sizeof(int));

		/* 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			this_ndims;

			arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
			/* temporarily ignore null subarrays */
			if (eisnull)
			{
				haveempty = true;
				continue;
			}

			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))));

			this_ndims = ARR_NDIM(array);
			/* temporarily ignore zero-dimensional subarrays */
			if (this_ndims <= 0)
			{
				haveempty = true;
				continue;
			}

			if (firstone)
			{
				/* Get sub-array details from first member */
				elem_ndims = this_ndims;
				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 != this_ndims ||
					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")));
			}

			subdata[outer_nelems] = ARR_DATA_PTR(array);
			subbitmaps[outer_nelems] = ARR_NULLBITMAP(array);
			subbytes[outer_nelems] = ARR_SIZE(array) - ARR_DATA_OFFSET(array);
			nbytes += subbytes[outer_nelems];
			subnitems[outer_nelems] = ArrayGetNItems(this_ndims,
													 ARR_DIMS(array));
			nitems += subnitems[outer_nelems];
			havenulls |= ARR_HASNULL(array);
			outer_nelems++;
		}

		/*
		 * If all items were null or empty arrays, return an empty array;
		 * otherwise, if some were and some weren't, raise error.  (Note:
		 * we must special-case this somehow to avoid trying to generate
		 * a 1-D array formed from empty arrays.  It's not ideal...)
		 */
		if (haveempty)
		{
			if (ndims == 0)		/* didn't find any nonempty array */
				return PointerGetDatum(construct_empty_array(element_type));
			ereport(ERROR,
					(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
					 errmsg("multidimensional arrays must have array "
							"expressions with matching dimensions")));
		}

		/* 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];
		}

		if (havenulls)
		{
			dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nitems);
			nbytes += dataoffset;
		}
		else
		{
			dataoffset = 0;		/* marker for no null bitmap */
			nbytes += ARR_OVERHEAD_NONULLS(ndims);
		}

		result = (ArrayType *) palloc(nbytes);
		SET_VARSIZE(result, nbytes);
		result->ndim = ndims;
		result->dataoffset = dataoffset;
		result->elemtype = element_type;
		memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
		memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));

		dat = ARR_DATA_PTR(result);
		iitem = 0;
		for (i = 0; i < outer_nelems; i++)
		{
			memcpy(dat, subdata[i], subbytes[i]);
			dat += subbytes[i];
			if (havenulls)
				array_bitmap_copy(ARR_NULLBITMAP(result), iitem,
								  subbitmaps[i], 0,
								  subnitems[i]);
			iitem += subnitems[i];
		}
	}

	return PointerGetDatum(result);
}

/* ----------------------------------------------------------------
 *		ExecEvalRow - ROW() expressions
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalRow(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 */
	MemSetAligned(isnull, true, natts * sizeof(bool));

	/* Evaluate field values */
	i = 0;
	foreach(arg, rstate->args)
	{
		ExprState  *e = (ExprState *) lfirst(arg);

		values[i] = ExecEvalExpr(e, econtext, &isnull[i], NULL);
		i++;
	}

	tuple = heap_form_tuple(rstate->tupdesc, values, isnull);

	pfree(values);
	pfree(isnull);

	return HeapTupleGetDatum(tuple);
}

/* ----------------------------------------------------------------
 *		ExecEvalRowCompare - ROW() comparison-op ROW()
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalRowCompare(RowCompareExprState *rstate,
				   ExprContext *econtext,
				   bool *isNull, ExprDoneCond *isDone)
{
	bool		result;
	RowCompareType rctype = ((RowCompareExpr *) rstate->xprstate.expr)->rctype;
	int32		cmpresult = 0;
	ListCell   *l;
	ListCell   *r;
	int			i;

	if (isDone)
		*isDone = ExprSingleResult;
	*isNull = true;				/* until we get a result */

	i = 0;
	forboth(l, rstate->largs, r, rstate->rargs)
	{
		ExprState  *le = (ExprState *) lfirst(l);
		ExprState  *re = (ExprState *) lfirst(r);
		FunctionCallInfoData locfcinfo;

		InitFunctionCallInfoData(locfcinfo, &(rstate->funcs[i]), 2,
								 NULL, NULL);
		locfcinfo.arg[0] = ExecEvalExpr(le, econtext,
										&locfcinfo.argnull[0], NULL);
		locfcinfo.arg[1] = ExecEvalExpr(re, econtext,
										&locfcinfo.argnull[1], NULL);
		if (rstate->funcs[i].fn_strict &&
			(locfcinfo.argnull[0] || locfcinfo.argnull[1]))
			return (Datum) 0;	/* force NULL result */
		locfcinfo.isnull = false;
		cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
		if (locfcinfo.isnull)
			return (Datum) 0;	/* force NULL result */
		if (cmpresult != 0)
			break;				/* no need to compare remaining columns */
		i++;
	}

	switch (rctype)
	{
			/* EQ and NE cases aren't allowed here */
		case ROWCOMPARE_LT:
			result = (cmpresult < 0);
			break;
		case ROWCOMPARE_LE:
			result = (cmpresult <= 0);
			break;
		case ROWCOMPARE_GE:
			result = (cmpresult >= 0);
			break;
		case ROWCOMPARE_GT:
			result = (cmpresult > 0);
			break;
		default:
			elog(ERROR, "unrecognized RowCompareType: %d", (int) rctype);
			result = 0;			/* keep compiler quiet */
			break;
	}

	*isNull = false;
	return BoolGetDatum(result);
}

/* ----------------------------------------------------------------
 *		ExecEvalTableValue
 * ----------------------------------------------------------------
 */
static Datum 
ExecEvalTableValue(ExprState	*estate,
				   ExprContext	*econtext,
				   bool			*isNull, 
				   ExprDoneCond	*isDone)
{
	/* Guard against stack overflow due to overly complex expressions */
	check_stack_depth();

	if (isDone)
		*isDone = ExprSingleResult;

	/*
	 * When evaluated as an expression a TableValueExpr will return NULL,
	 * this NULL is replaced by an AnyTable datum within nodeTableFunction.c
	 *
	 * Is there a better way to do this?
	 */
	*isNull = true;
	return (Datum) 0;
}

/* ----------------------------------------------------------------
 *		ExecEvalCoalesce
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
				 bool *isNull, ExprDoneCond *isDone)
{
	ListCell   *arg;

	if (isDone)
		*isDone = ExprSingleResult;

	/* Simply loop through until something NOT NULL is found */
	foreach(arg, coalesceExpr->args)
	{
		ExprState  *e = (ExprState *) lfirst(arg);
		Datum		value;

		value = ExecEvalExpr(e, econtext, isNull, NULL);
		if (!*isNull)
			return value;
	}

	/* Else return NULL */
	*isNull = true;
	return (Datum) 0;
}

/* ----------------------------------------------------------------
 *		ExecEvalMinMax
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
			   bool *isNull, ExprDoneCond *isDone)
{
	Datum		result = (Datum) 0;
	MinMaxOp	op = ((MinMaxExpr *) minmaxExpr->xprstate.expr)->op;
	FunctionCallInfoData locfcinfo;
	ListCell   *arg;

	if (isDone)
		*isDone = ExprSingleResult;
	*isNull = true;				/* until we get a result */

	InitFunctionCallInfoData(locfcinfo, &minmaxExpr->cfunc, 2, NULL, NULL);
	locfcinfo.argnull[0] = false;
	locfcinfo.argnull[1] = false;

	foreach(arg, minmaxExpr->args)
	{
		ExprState  *e = (ExprState *) lfirst(arg);
		Datum		value;
		bool		valueIsNull;
		int32		cmpresult;

		value = ExecEvalExpr(e, econtext, &valueIsNull, NULL);
		if (valueIsNull)
			continue;			/* ignore NULL inputs */

		if (*isNull)
		{
			/* first nonnull input, adopt value */
			result = value;
			*isNull = false;
		}
		else
		{
			/* apply comparison function */
			locfcinfo.arg[0] = result;
			locfcinfo.arg[1] = value;
			locfcinfo.isnull = false;
			cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
			if (locfcinfo.isnull)		/* probably should not happen */
				continue;
			if (cmpresult > 0 && op == IS_LEAST)
				result = value;
			else if (cmpresult < 0 && op == IS_GREATEST)
				result = value;
		}
	}

	return result;
}

/* ----------------------------------------------------------------
 *		ExecEvalNullIf
 *
 * Note that this is *always* derived from the equals operator,
 * but since we need special processing of the arguments
 * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalNullIf(FuncExprState *nullIfExpr,
			   ExprContext *econtext,
			   bool *isNull, ExprDoneCond *isDone)
{
	Datum		result;
	FunctionCallInfoData fcinfo;
	ExprDoneCond argDone;
	List	   *argList;

	if (isDone)
		*isDone = ExprSingleResult;

	/*
	 * Initialize function cache if first time through
	 */
	if (nullIfExpr->func.fn_oid == InvalidOid)
	{
		NullIfExpr *op = (NullIfExpr *) nullIfExpr->xprstate.expr;

		init_fcache(op->opfuncid, nullIfExpr,
					econtext->ecxt_per_query_memory, true);
		Assert(!nullIfExpr->func.fn_retset);
	}

	/*
	 * extract info from nullIfExpr
	 */
	argList = nullIfExpr->args;

	/* Need to prep callinfo structure */
	InitFunctionCallInfoData(fcinfo, &(nullIfExpr->func), 0, NULL, NULL);
	argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
	if (argDone != ExprSingleResult)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("NULLIF does not support set arguments")));
	Assert(fcinfo.nargs == 2);

	/* if either argument is NULL they can't be equal */
	if (!fcinfo.argnull[0] && !fcinfo.argnull[1])
	{
		fcinfo.isnull = false;
		result = FunctionCallInvoke(&fcinfo);
		/* if the arguments are equal return null */
		if (!fcinfo.isnull && DatumGetBool(result))
		{
			*isNull = true;
			return (Datum) 0;
		}
	}

	/* else return first argument */
	*isNull = fcinfo.argnull[0];
	return fcinfo.arg[0];
}

/* ----------------------------------------------------------------
 *		ExecEvalNullTest
 *
 *		Evaluate a NullTest node.
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalNullTest(NullTestState *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 */

	if (nstate->argisrow && !(*isNull))
	{
		HeapTupleHeader tuple;
		Oid			tupType;
		int32		tupTypmod;
		TupleDesc	tupDesc;
		HeapTupleData tmptup;
		int			att;

		tuple = DatumGetHeapTupleHeader(result);

		tupType = HeapTupleHeaderGetTypeId(tuple);
		tupTypmod = HeapTupleHeaderGetTypMod(tuple);

		/* Lookup tupdesc if first time through or if type changes */
		tupDesc = get_cached_rowtype(tupType, tupTypmod,
									 &nstate->argdesc, econtext);

		/*
		 * heap_attisnull needs a HeapTuple not a bare HeapTupleHeader.
		 */
		tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
		tmptup.t_data = tuple;

		for (att = 1; att <= tupDesc->natts; att++)
		{
			/* ignore dropped columns */
			if (tupDesc->attrs[att - 1]->attisdropped)
				continue;
			if (heap_attisnull(&tmptup, att))
			{
				/* null field disproves IS NOT NULL */
				if (ntest->nulltesttype == IS_NOT_NULL)
					return BoolGetDatum(false);
			}
			else
			{
				/* non-null field disproves IS NULL */
				if (ntest->nulltesttype == IS_NULL)
					return BoolGetDatum(false);
			}
		}

		return BoolGetDatum(true);
	}
	else
	{
		/* Simple scalar-argument case, or a null rowtype datum */
		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 Datum
ExecEvalBooleanTest(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 Datum
ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
					   bool *isNull, ExprDoneCond *isDone)
{
	CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
	Datum		result;
	ListCell   *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 Datum
ExecEvalCoerceToDomainValue(ExprState *exprstate,
							ExprContext *econtext,
							bool *isNull, ExprDoneCond *isDone)
{
	if (isDone)
		*isDone = ExprSingleResult;
	*isNull = econtext->domainValue_isNull;
	return econtext->domainValue_datum;
}

/*
 * ExecEvalPercentileExpr
 *
 * Returns a Datum whose value is the value of the precomputed
 * the value at the percentile found in the given expression context.
 * Actually,  this is almost same as ExecEvalAggref.  The main reason
 * to add this is because we don't change the catalog at the moment.
 * This will be cleaned when we can change the catalog.
 */
static Datum
ExecEvalPercentileExpr(PercentileExprState *exprstate,
					   ExprContext *econtext,
					   bool *isNull, ExprDoneCond *isDone)
{
	if (isDone)
		*isDone = ExprSingleResult;

	if (econtext->ecxt_aggvalues == NULL)		/* safety check */
		elog(ERROR, "no aggregates in this expression context");

	*isNull = econtext->ecxt_aggnulls[exprstate->aggno];
	return econtext->ecxt_aggvalues[exprstate->aggno];
}

/* ----------------------------------------------------------------
 *		ExecEvalFieldSelect
 *
 *		Evaluate a FieldSelect node.
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalFieldSelect(FieldSelectState *fstate,
					ExprContext *econtext,
					bool *isNull,
					ExprDoneCond *isDone)
{
	FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
	AttrNumber	fieldnum = fselect->fieldnum;
	Datum		result;
	Datum		tupDatum;
	HeapTupleHeader tuple;
	Oid			tupType;
	int32		tupTypmod;
	TupleDesc	tupDesc;
	Form_pg_attribute attr;
	HeapTupleData tmptup;

	tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);

	/* this test covers the isDone exception too: */
	if (*isNull)
		return tupDatum;

	tuple = DatumGetHeapTupleHeader(tupDatum);

	tupType = HeapTupleHeaderGetTypeId(tuple);
	tupTypmod = HeapTupleHeaderGetTypMod(tuple);

	/* Lookup tupdesc if first time through or if type changes */
	tupDesc = get_cached_rowtype(tupType, tupTypmod,
								 &fstate->argdesc, econtext);

	/* Check for dropped column, and force a NULL result if so */
	if (fieldnum <= 0 ||
		fieldnum > tupDesc->natts)	/* should never happen */
				elog(ERROR, "attribute number %d exceeds number of columns %d",
					 fieldnum, tupDesc->natts);
	attr = tupDesc->attrs[fieldnum - 1];
	if (attr->attisdropped)
	{
		*isNull = true;
		return (Datum) 0;
	}

	/* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
	/* As in ExecEvalVar, we should but can't check typmod */
	if (fselect->resulttype != attr->atttypid)
		ereport(ERROR,
				(errmsg("attribute %d has wrong type", fieldnum),
				 errdetail("Table has type %s, but query expects %s.",
						   format_type_be(attr->atttypid),
						   format_type_be(fselect->resulttype))));

	/*
	 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set all
	 * the fields in the struct just in case user tries to inspect system
	 * columns.
	 */
	tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
	ItemPointerSetInvalid(&(tmptup.t_self));
	tmptup.t_data = tuple;

	result = heap_getattr(&tmptup,
						  fieldnum,
						  tupDesc,
						  isNull);
	return result;
}

/* ----------------------------------------------------------------
 *		ExecEvalFieldStore
 *
 *		Evaluate a FieldStore node.
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalFieldStore(FieldStoreState *fstate,
				   ExprContext *econtext,
				   bool *isNull,
				   ExprDoneCond *isDone)
{
	FieldStore *fstore = (FieldStore *) fstate->xprstate.expr;
	HeapTuple	tuple;
	Datum		tupDatum;
	TupleDesc	tupDesc;
	Datum	   *values;
	bool	   *isnull;
	Datum		save_datum;
	bool		save_isNull;
	ListCell   *l1,
			   *l2;

	tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);

	if (isDone && *isDone == ExprEndResult)
		return tupDatum;

	/* Lookup tupdesc if first time through or after rescan */
	tupDesc = get_cached_rowtype(fstore->resulttype, -1,
								 &fstate->argdesc, econtext);

	/* Allocate workspace */
	values = (Datum *) palloc(tupDesc->natts * sizeof(Datum));
	isnull = (bool *) palloc(tupDesc->natts * sizeof(bool));

	if (!*isNull)
	{
		/*
		 * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader. We
		 * set all the fields in the struct just in case.
		 */
		HeapTupleHeader tuphdr;
		HeapTupleData tmptup;

		tuphdr = DatumGetHeapTupleHeader(tupDatum);
		tmptup.t_len = HeapTupleHeaderGetDatumLength(tuphdr);
		ItemPointerSetInvalid(&(tmptup.t_self));
		tmptup.t_data = tuphdr;

		heap_deform_tuple(&tmptup, tupDesc, values, isnull);
	}
	else
	{
		/* Convert null input tuple into an all-nulls row */
		MemSetAligned(isnull, true, tupDesc->natts * sizeof(bool));
	}

	/* Result is never null */
	*isNull = false;

	save_datum = econtext->caseValue_datum;
	save_isNull = econtext->caseValue_isNull;

	forboth(l1, fstate->newvals, l2, fstore->fieldnums)
	{
		ExprState  *newval = (ExprState *) lfirst(l1);
		AttrNumber	fieldnum = lfirst_int(l2);

		Assert(fieldnum > 0 && fieldnum <= tupDesc->natts);

		/*
		 * Use the CaseTestExpr mechanism to pass down the old value of the
		 * field being replaced; this is useful in case we have a nested field
		 * update situation.  It's safe to reuse the CASE mechanism because
		 * there cannot be a CASE between here and where the value would be
		 * needed.
		 */
		econtext->caseValue_datum = values[fieldnum - 1];
		econtext->caseValue_isNull = isnull[fieldnum - 1];

		values[fieldnum - 1] = ExecEvalExpr(newval,
											econtext,
											&isnull[fieldnum - 1],
											NULL);
	}

	econtext->caseValue_datum = save_datum;
	econtext->caseValue_isNull = save_isNull;

	tuple = heap_form_tuple(tupDesc, values, isnull);

	pfree(values);
	pfree(isnull);

	return HeapTupleGetDatum(tuple);
}

/* ----------------------------------------------------------------
 *		ExecEvalRelabelType
 *
 *		Evaluate a RelabelType node.
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalRelabelType(GenericExprState *exprstate,
					ExprContext *econtext,
					bool *isNull, ExprDoneCond *isDone)
{
	return ExecEvalExpr(exprstate->arg, econtext, isNull, isDone);
}

/* ----------------------------------------------------------------
 *		ExecEvalPartOidExpr
 *
 *		Evaluate a PartOidExpr
 * ----------------------------------------------------------------
 */
static Datum ExecEvalPartOidExpr(PartOidExprState *exprstate,
						ExprContext *econtext,
						bool *isNull, ExprDoneCond *isDone)
{

	Assert(NULL != exprstate);
	Assert(NULL != isNull);

	if (isDone)
	{
		*isDone = ExprSingleResult;
	}

	PartitionConstraints *constraint = *exprstate->acceptedLeafPart;
	if (NULL != constraint)
	{
		*isNull = false;
		return UInt32GetDatum(constraint->pRule->parchildrelid);
	}

	*isNull = true;
	return PointerGetDatum(NULL);
}

/* ----------------------------------------------------------------
 *		ExecEvalPartDefaultExpr
 *
 *		Evaluate a PartDefaultExpr
 * ----------------------------------------------------------------
 */
static Datum ExecEvalPartDefaultExpr(PartDefaultExprState *exprstate,
						ExprContext *econtext,
						bool *isNull, ExprDoneCond *isDone)
{
	Assert(NULL != exprstate);
	Assert(NULL != isNull);

	PartDefaultExpr *expr = (PartDefaultExpr *) exprstate->xprstate.expr;
	PartitionConstraints *constraint = (PartitionConstraints *) exprstate->levelPartConstraints[expr->level];
	Assert (NULL != constraint);

	if (isDone)
	{
		*isDone = ExprSingleResult;
	}
	*isNull = false;

	return BoolGetDatum(constraint->defaultPart);
}

/* ----------------------------------------------------------------
 *		ExecEvalPartBoundExpr
 *
 *		Evaluate a PartBoundExpr
 * ----------------------------------------------------------------
 */
static Datum ExecEvalPartBoundExpr(PartBoundExprState *exprstate,
						ExprContext *econtext,
						bool *isNull, ExprDoneCond *isDone)
{
	Assert(NULL != exprstate);
	Assert(NULL != isNull);

	PartBoundExpr *expr = (PartBoundExpr *) exprstate->xprstate.expr;
	PartitionConstraints *constraint = (PartitionConstraints *) exprstate->levelPartConstraints[expr->level];
	Assert (NULL != constraint);
	Const *con = constraint->upperBound;
	if (expr->isLowerBound)
	{
		con = constraint->lowerBound;
	}

	if (isDone)
	{
		*isDone = ExprSingleResult;
	}

	if (NULL != con)
	{
		*isNull = con->constisnull;
		return con->constvalue;
	}

	/* return NULL if no upper bound or lower bound exists */
	*isNull = true;
	return PointerGetDatum(NULL);
}

/* ----------------------------------------------------------------
 *		ExecEvalPartBoundInclusionExpr
 *
 *		Evaluate a PartBoundInclusionExpr
 * ----------------------------------------------------------------
 */
static Datum ExecEvalPartBoundInclusionExpr(PartBoundInclusionExprState *exprstate,
							ExprContext *econtext,
							bool *isNull, ExprDoneCond *isDone)
{
	Assert(NULL != exprstate);
	Assert(NULL != isNull);

	PartBoundInclusionExpr *expr = (PartBoundInclusionExpr *) exprstate->xprstate.expr;
	PartitionConstraints *constraint = (PartitionConstraints *) exprstate->levelPartConstraints[expr->level];
	Assert (NULL != constraint);
	if (isDone)
	{
		*isDone = ExprSingleResult;
	}
	*isNull = false;
	if (expr->isLowerBound)
	{
		return BoolGetDatum(constraint->lbInclusive);
	}
	return BoolGetDatum(constraint->upInclusive);
}

/* ----------------------------------------------------------------
 *		ExecEvalPartBoundOpenExpr
 *
 *		Evaluate a PartBoundOpenExpr
 * ----------------------------------------------------------------
 */
static Datum ExecEvalPartBoundOpenExpr(PartBoundOpenExprState *exprstate,
							ExprContext *econtext,
							bool *isNull, ExprDoneCond *isDone)
{
	Assert(NULL != exprstate);
	Assert(NULL != isNull);

	PartBoundOpenExpr *expr = (PartBoundOpenExpr *) exprstate->xprstate.expr;
	PartitionConstraints *constraint = (PartitionConstraints *) exprstate->levelPartConstraints[expr->level];
	Assert (NULL != constraint);
	if (isDone)
	{
		*isDone = ExprSingleResult;
	}
	*isNull = false;
	if (expr->isLowerBound)
	{
		return BoolGetDatum(constraint->lbOpen);
	}
	return BoolGetDatum(constraint->upOpen);
}

/* ----------------------------------------------------------------
 *    ExecEvalCurrentOfExpr
 *
 *    Evaluate CURRENT OF
 *
 *    Constant folding must have bound observed values of 
 * 	gp_segment_id, ctid, and tableoid into the CurrentOfExpr for
 *	this function's consumption.
 * ----------------------------------------------------------------
 */
static Datum
ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
						bool *isNull, ExprDoneCond *isDone)
{
	CurrentOfExpr 	*cexpr = (CurrentOfExpr *) exprstate->expr;
	bool 			result = false;
	TupleTableSlot	*slot;

	if (isDone)
		*isDone = ExprSingleResult;
	*isNull = false;

	Assert(cexpr->cvarno != INNER);
	Assert(cexpr->cvarno != OUTER);

	slot = econtext->ecxt_scantuple;
	Assert(!TupIsNull(slot));

	/* 
	 * The currently scanned tuple must use heap storage for it to possibly
	 * satisfy the CURRENT OF qualification. Despite our grand attempts during
	 * parsing and constant folding to demand heap storage, the scanning of an 
	 * AO part is still possible, when the current row uses heap storage, but the 
	 * CURRENT OF invocation uses an unpruned scan of the partition table, yielding 
	 * tuples from the AO parts before the desired heap tuple.
	 */
	if (TupHasHeapTuple(slot))
	{
		if (cexpr->gp_segment_id == GetQEIndex() &&
			ItemPointerEquals(&cexpr->ctid, slot_get_ctid(slot)))
		{
			/*
			 * If tableoid is InvalidOid, this implies that constant folding had
			 * had determined tableoid was not necessary in uniquely identifying a tuple.
			 * Otherwise, the given tuple's tableoid must match the CURRENT OF tableoid.
			 */
			if (!OidIsValid(cexpr->tableoid) ||
				cexpr->tableoid == slot->tts_tableOid)
			{
				result = true;
			}
		}
	}

	return BoolGetDatum(result);
}


/*
 * ExecEvalExprSwitchContext
 *
 * Same as ExecEvalExpr, but get into the right allocation context explicitly.
 */
Datum
ExecEvalExprSwitchContext(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 paralleling the given
 * Expr node tree.	The ExprState tree can then be handed to ExecEvalExpr
 * for execution.  Because the Expr tree itself is read-only as far as
 * ExecInitExpr and ExecEvalExpr are concerned, several different executions
 * of the same plan tree can occur concurrently.
 *
 * This must be called in a memory context that will last as long as repeated
 * executions of the expression are needed.  Typically the context will be
 * the same as the per-query context of the associated ExprContext.
 *
 * Any Aggref and SubPlan nodes found in the tree are added to the lists
 * of such nodes held by the parent PlanState.	Otherwise, we do very little
 * initialization here other than building the state-node tree.  Any nontrivial
 * work associated with initializing runtime info for a node should happen
 * during the first actual evaluation of that node.  (This policy lets us
 * avoid work if the node is never actually evaluated.)
 *
 * Note: there is no ExecEndExpr function; we assume that any resource
 * cleanup needed will be handled by just releasing the memory context
 * in which the state tree is built.  Functions that require additional
 * cleanup work can register a shutdown callback in the ExprContext.
 *
 *	'node' is the root of the expression tree to examine
 *	'parent' is the PlanState node that owns the expression.
 *
 * 'parent' may be NULL if we are preparing an expression that is not
 * associated with a plan tree.  (If so, it can't have aggs or subplans.)
 * This case should usually come through ExecPrepareExpr, not directly here.
 */
ExprState *
ExecInitExpr(Expr *node, PlanState *parent)
{
	ExprState  *state;

	if (node == NULL)
		return NULL;

	/* Guard against stack overflow due to overly complex expressions */
	check_stack_depth();

	/* Initialize the vectorzied expressions */
	if( vmthd.vectorized_executor_enable
		&& vmthd.ExecInitExpr_Hook
		&& parent
		&& parent->plan->vectorized)
	{
		state = vmthd.ExecInitExpr_Hook(node, parent);
		if(NULL != state)
			return state;
	}

	switch (nodeTag(node))
	{
		case T_Var:
			state = (ExprState *) makeNode(ExprState);
			state->evalfunc = ExecEvalVar;
			break;
		case T_Const:
			state = (ExprState *) makeNode(ExprState);
			state->evalfunc = ExecEvalConst;
			break;
		case T_Param:
			state = (ExprState *) makeNode(ExprState);
			state->evalfunc = ExecEvalParam;
			break;
		case T_CoerceToDomainValue:
			state = (ExprState *) makeNode(ExprState);
			state->evalfunc = ExecEvalCoerceToDomainValue;
			break;
		case T_CaseTestExpr:
			state = (ExprState *) makeNode(ExprState);
			state->evalfunc = ExecEvalCaseTestExpr;
			break;
		case T_Aggref:
			{
				Aggref	   *aggref = (Aggref *) node;
				AggrefExprState *astate = makeNode(AggrefExprState);

				astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAggref;
				if (parent && IsA(parent, AggState))
				{
					AggState   *aggstate = (AggState *) parent;
					int			naggs;

					aggstate->aggs = lcons(astate, aggstate->aggs);
					naggs = ++aggstate->numaggs;

					/*
					 * Combine the argument and sortkey expressions into a single list
					 * along with the corresponding sortkey clauses, if any.
					 * The code here is a bit different from postgres, because
					 * GPDB does different things in parser for the ordered aggregate;
					 * We don't construct target list in parser but do it here.
					 * These lists are referenced in ExecInitAgg()
					 */
					astate->inputTargets =
							combineAggrefArgs(aggref, &astate->inputSortClauses);
					astate->args = (List *) ExecInitExpr((Expr *) astate->inputTargets,
														 parent);

					/*
					 * Complain if the aggregate's arguments contain any
					 * aggregates; nested agg functions are semantically
					 * nonsensical.  (This should have been caught earlier,
					 * but we defend against it here anyway.)
					 */
					if (naggs != aggstate->numaggs)
						ereport(ERROR,
								(errcode(ERRCODE_GROUPING_ERROR),
								 errmsg("aggregate function calls may not be nested")));
				}
				else
				{
					/* planner messed up */
					elog(ERROR, "aggref found in non-Agg plan node");
				}
				state = (ExprState *) astate;
			}
			break;
		case T_GroupingFunc:
			{
				GroupingFunc *gf = (GroupingFunc *)node;
				GroupingFuncExprState *gstate = makeNode(GroupingFuncExprState);

				gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalGroupingFunc;
				gstate->args = gf->args;
				gstate->ngrpcols = gf->ngrpcols;
				state = (ExprState *) gstate;
			}
			break;
		case T_Grouping:
			{
				ExprState *gstate = makeNode(ExprState);
				gstate->evalfunc = (ExprStateEvalFunc) ExecEvalGrouping;
				state = (ExprState *) gstate;
			}
			break;
		case T_GroupId:
			{
				ExprState *gstate = makeNode(ExprState);
				gstate->evalfunc = (ExprStateEvalFunc) ExecEvalGroupId;
				state = (ExprState *) gstate;
			}
			break;
		case T_WindowRef:
			{
				WindowRef *windowref = (WindowRef *)node;
				WindowRefExprState *wrstate = makeNode(WindowRefExprState);
				int numrefs;
				WindowState   *winstate = (WindowState *) parent;
				
				wrstate->xprstate.evalfunc = 
					(ExprStateEvalFunc) ExecEvalWindowRef;
				
				Insist(parent && IsA(parent, WindowState));

				winstate->wrxstates = lcons(wrstate, winstate->wrxstates);
				numrefs = list_length(winstate->wrxstates);

				wrstate->args = (List *) ExecInitExpr((Expr *) windowref->args,
													  parent);
				/* 
				 * Nested window functions are invalid and should not have 
				 * reached this point in processing.
				 */
				if (numrefs != list_length(winstate->wrxstates))
					elog(ERRCODE_INTERNAL_ERROR, "nested windowref calls "
						 "found in Window plan node");
				state = (ExprState *) wrstate;
			}
			break;
		case T_ArrayRef:
			{
				ArrayRef   *aref = (ArrayRef *) node;
				ArrayRefExprState *astate = makeNode(ArrayRefExprState);

				astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayRef;
				astate->refupperindexpr = (List *)
					ExecInitExpr((Expr *) aref->refupperindexpr, parent);
				astate->reflowerindexpr = (List *)
					ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
				astate->refexpr = ExecInitExpr(aref->refexpr, parent);
				astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
													parent);
				/* do one-time catalog lookups for type info */
				astate->refattrlength = get_typlen(aref->refarraytype);
				get_typlenbyvalalign(aref->refelemtype,
									 &astate->refelemlength,
									 &astate->refelembyval,
									 &astate->refelemalign);
				state = (ExprState *) astate;
			}
			break;
		case T_FuncExpr:
			{
				FuncExpr   *funcexpr = (FuncExpr *) node;
				FuncExprState *fstate = makeNode(FuncExprState);

				fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFunc;
				fstate->args = (List *)
					ExecInitExpr((Expr *) funcexpr->args, parent);
				fstate->func.fn_oid = InvalidOid;		/* not initialized */
				FastPathStrict2Func(funcexpr->funcid, fstate);
				state = (ExprState *) fstate;
			}
			break;
		case T_OpExpr:
			{
				OpExpr	   *opexpr = (OpExpr *) node;
				FuncExprState *fstate = makeNode(FuncExprState);

				fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOper;
				fstate->args = (List *)
					ExecInitExpr((Expr *) opexpr->args, parent);
				fstate->func.fn_oid = InvalidOid;		/* not initialized */
				FastPathStrict2Func(opexpr->opfuncid, fstate);
				state = (ExprState *) fstate;
			}
			break;
		case T_DistinctExpr:
			{
				DistinctExpr *distinctexpr = (DistinctExpr *) node;
				FuncExprState *fstate = makeNode(FuncExprState);

				fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalDistinct;
				fstate->args = (List *)
					ExecInitExpr((Expr *) distinctexpr->args, parent);
				fstate->func.fn_oid = InvalidOid;		/* not initialized */
				state = (ExprState *) fstate;
			}
			break;
		case T_ScalarArrayOpExpr:
			{
				ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
				ScalarArrayOpExprState *sstate = makeNode(ScalarArrayOpExprState);

				sstate->fxprstate.xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalScalarArrayOp;
				sstate->fxprstate.args = (List *)
					ExecInitExpr((Expr *) opexpr->args, parent);
				sstate->fxprstate.func.fn_oid = InvalidOid;		/* not initialized */
				sstate->element_type = InvalidOid;		/* ditto */

				FastPathScalarArrayOp(opexpr, sstate);
				state = (ExprState *) sstate;

			}
			break;
		case T_BoolExpr:
			{
				BoolExpr   *boolexpr = (BoolExpr *) node;
				BoolExprState *bstate = makeNode(BoolExprState);

				switch (boolexpr->boolop)
				{
					case AND_EXPR:
						bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAnd;
						break;
					case OR_EXPR:
						bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOr;
						break;
					case NOT_EXPR:
						bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNot;
						break;
					default:
						elog(ERROR, "unrecognized boolop: %d",
							 (int) boolexpr->boolop);
						break;
				}
				bstate->args = (List *)
					ExecInitExpr((Expr *) boolexpr->args, parent);
				state = (ExprState *) bstate;
			}
			break;
		case T_SubPlan:
			{
				/* Keep this in sync with ExecInitExprInitPlan, below */
				SubPlan    *subplan = (SubPlan *) node;
				SubPlanState *sstate = makeNode(SubPlanState);

				sstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecSubPlan;

				if (!parent)
					elog(ERROR, "SubPlan found with no parent plan");

				/*
				 * Here we just add the SubPlanState nodes to parent->subPlan.
				 * The subplans will be initialized later.
				 */
				parent->subPlan = lcons(sstate, parent->subPlan);
				sstate->sub_estate = NULL;
				sstate->planstate = NULL;

				sstate->testexpr =
					ExecInitExpr((Expr *) subplan->testexpr, parent);
				sstate->args = (List *)
					ExecInitExpr((Expr *) subplan->args, parent);

				state = (ExprState *) sstate;
			}
			break;
		case T_FieldSelect:
			{
				FieldSelect *fselect = (FieldSelect *) node;
				FieldSelectState *fstate = makeNode(FieldSelectState);

				fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldSelect;
				fstate->arg = ExecInitExpr(fselect->arg, parent);
				fstate->argdesc = NULL;
				state = (ExprState *) fstate;
			}
			break;
		case T_FieldStore:
			{
				FieldStore *fstore = (FieldStore *) node;
				FieldStoreState *fstate = makeNode(FieldStoreState);

				fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldStore;
				fstate->arg = ExecInitExpr(fstore->arg, parent);
				fstate->newvals = (List *) ExecInitExpr((Expr *) fstore->newvals, parent);
				fstate->argdesc = NULL;
				state = (ExprState *) fstate;
			}
			break;
		case T_RelabelType:
			{
				RelabelType *relabel = (RelabelType *) node;
				GenericExprState *gstate = makeNode(GenericExprState);

				gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRelabelType;
				gstate->arg = ExecInitExpr(relabel->arg, parent);
				state = (ExprState *) gstate;
			}
			break;
		case T_ConvertRowtypeExpr:
			{
				ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) node;
				ConvertRowtypeExprState *cstate = makeNode(ConvertRowtypeExprState);

				cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalConvertRowtype;
				cstate->arg = ExecInitExpr(convert->arg, parent);
				state = (ExprState *) cstate;
			}
			break;
		case T_CaseExpr:
			{
				CaseExpr   *caseexpr = (CaseExpr *) node;
				CaseExprState *cstate = makeNode(CaseExprState);
				List	   *outlist = NIL;
				ListCell   *l;

				cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCase;
				cstate->arg = ExecInitExpr(caseexpr->arg, parent);
				foreach(l, caseexpr->args)
				{
					CaseWhen   *when = (CaseWhen *) lfirst(l);
					CaseWhenState *wstate = makeNode(CaseWhenState);

					Assert(IsA(when, CaseWhen));
					wstate->xprstate.evalfunc = NULL;	/* not used */
					wstate->xprstate.expr = (Expr *) when;
					wstate->expr = ExecInitExpr(when->expr, parent);
					wstate->result = ExecInitExpr(when->result, parent);
					outlist = lappend(outlist, wstate);
				}
				cstate->args = outlist;
				cstate->defresult = ExecInitExpr(caseexpr->defresult, parent);
				state = (ExprState *) cstate;
			}
			break;
		case T_ArrayExpr:
			{
				ArrayExpr  *arrayexpr = (ArrayExpr *) node;
				ArrayExprState *astate = makeNode(ArrayExprState);
				List	   *outlist = NIL;
				ListCell   *l;

				astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArray;
				foreach(l, arrayexpr->elements)
				{
					Expr	   *e = (Expr *) lfirst(l);
					ExprState  *estate;

					estate = ExecInitExpr(e, parent);
					outlist = lappend(outlist, estate);
				}
				astate->elements = outlist;
				/* do one-time catalog lookup for type info */
				get_typlenbyvalalign(arrayexpr->element_typeid,
									 &astate->elemlength,
									 &astate->elembyval,
									 &astate->elemalign);
				state = (ExprState *) astate;
			}
			break;
		case T_RowExpr:
			{
				RowExpr    *rowexpr = (RowExpr *) node;
				RowExprState *rstate = makeNode(RowExprState);
				Form_pg_attribute *attrs;
				List	   *outlist = NIL;
				ListCell   *l;
				int			i;

				rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRow;
				/* Build tupdesc to describe result tuples */
				if (rowexpr->row_typeid == RECORDOID)
				{
					/* generic record, use runtime type assignment */
					rstate->tupdesc = ExecTypeFromExprList(rowexpr->args);
					BlessTupleDesc(rstate->tupdesc);
					/* we won't need to redo this at runtime */
				}
				else
				{
					/* it's been cast to a named type, use that */
					rstate->tupdesc = lookup_rowtype_tupdesc_copy(rowexpr->row_typeid, -1);
				}
				/* Set up evaluation, skipping any deleted columns */
				Assert(list_length(rowexpr->args) <= rstate->tupdesc->natts);
				attrs = rstate->tupdesc->attrs;
				i = 0;
				foreach(l, rowexpr->args)
				{
					Expr	   *e = (Expr *) lfirst(l);
					ExprState  *estate;

					if (!attrs[i]->attisdropped)
					{
						/*
						 * Guard against ALTER COLUMN TYPE on rowtype since
						 * the RowExpr was created.  XXX should we check
						 * typmod too?	Not sure we can be sure it'll be the
						 * same.
						 */
						if (exprType((Node *) e) != attrs[i]->atttypid)
							ereport(ERROR,
									(errcode(ERRCODE_DATATYPE_MISMATCH),
									 errmsg("ROW() column has type %s instead of type %s",
										format_type_be(exprType((Node *) e)),
									   format_type_be(attrs[i]->atttypid))));
					}
					else
					{
						/*
						 * Ignore original expression and insert a NULL. We
						 * don't really care what type of NULL it is, so
						 * always make an int4 NULL.
						 */
						e = (Expr *) makeNullConst(INT4OID, -1);
					}
					estate = ExecInitExpr(e, parent);
					outlist = lappend(outlist, estate);
					i++;
				}
				rstate->args = outlist;
				state = (ExprState *) rstate;
			}
			break;
		case T_RowCompareExpr:
			{
				RowCompareExpr *rcexpr = (RowCompareExpr *) node;
				RowCompareExprState *rstate = makeNode(RowCompareExprState);
				int			nopers = list_length(rcexpr->opnos);
				List	   *outlist;
				ListCell   *l;
				ListCell   *l2;
				int			i;

				rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRowCompare;
				Assert(list_length(rcexpr->largs) == nopers);
				outlist = NIL;
				foreach(l, rcexpr->largs)
				{
					Expr	   *e = (Expr *) lfirst(l);
					ExprState  *estate;

					estate = ExecInitExpr(e, parent);
					outlist = lappend(outlist, estate);
				}
				rstate->largs = outlist;
				Assert(list_length(rcexpr->rargs) == nopers);
				outlist = NIL;
				foreach(l, rcexpr->rargs)
				{
					Expr	   *e = (Expr *) lfirst(l);
					ExprState  *estate;

					estate = ExecInitExpr(e, parent);
					outlist = lappend(outlist, estate);
				}
				rstate->rargs = outlist;
				Assert(list_length(rcexpr->opclasses) == nopers);
				rstate->funcs = (FmgrInfo *) palloc(nopers * sizeof(FmgrInfo));
				i = 0;
				forboth(l, rcexpr->opnos, l2, rcexpr->opclasses)
				{
					Oid			opno = lfirst_oid(l);
					Oid			opclass = lfirst_oid(l2);
					int			strategy;
					Oid			subtype;
					bool		recheck;
					Oid			proc;

					get_op_opclass_properties(opno, opclass,
											  &strategy, &subtype, &recheck);
					proc = get_opclass_proc(opclass, subtype, BTORDER_PROC);

					/*
					 * If we enforced permissions checks on index support
					 * functions, we'd need to make a check here.  But the
					 * index support machinery doesn't do that, and neither
					 * does this code.
					 */
					fmgr_info(proc, &(rstate->funcs[i]));
					i++;
				}
				state = (ExprState *) rstate;
			}
			break;
		case T_TableValueExpr:
			state = (ExprState *) makeNode(ExprState);
			state->evalfunc = ExecEvalTableValue;
			break;
		case T_CoalesceExpr:
			{
				CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
				CoalesceExprState *cstate = makeNode(CoalesceExprState);
				List	   *outlist = NIL;
				ListCell   *l;

				cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoalesce;
				foreach(l, coalesceexpr->args)
				{
					Expr	   *e = (Expr *) lfirst(l);
					ExprState  *estate;

					estate = ExecInitExpr(e, parent);
					outlist = lappend(outlist, estate);
				}
				cstate->args = outlist;
				state = (ExprState *) cstate;
			}
			break;
		case T_MinMaxExpr:
			{
				MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
				MinMaxExprState *mstate = makeNode(MinMaxExprState);
				List	   *outlist = NIL;
				ListCell   *l;
				TypeCacheEntry *typentry;

				mstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalMinMax;
				foreach(l, minmaxexpr->args)
				{
					Expr	   *e = (Expr *) lfirst(l);
					ExprState  *estate;

					estate = ExecInitExpr(e, parent);
					outlist = lappend(outlist, estate);
				}
				mstate->args = outlist;
				/* Look up the btree comparison function for the datatype */
				typentry = lookup_type_cache(minmaxexpr->minmaxtype,
											 TYPECACHE_CMP_PROC);
				if (!OidIsValid(typentry->cmp_proc))
					ereport(ERROR,
							(errcode(ERRCODE_UNDEFINED_FUNCTION),
							 errmsg("could not identify a comparison function for type %s",
									format_type_be(minmaxexpr->minmaxtype))));

				/*
				 * If we enforced permissions checks on index support
				 * functions, we'd need to make a check here.  But the index
				 * support machinery doesn't do that, and neither does this
				 * code.
				 */
				fmgr_info(typentry->cmp_proc, &(mstate->cfunc));
				state = (ExprState *) mstate;
			}
			break;
		case T_NullIfExpr:
			{
				NullIfExpr *nullifexpr = (NullIfExpr *) node;
				FuncExprState *fstate = makeNode(FuncExprState);

				fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullIf;
				fstate->args = (List *)
					ExecInitExpr((Expr *) nullifexpr->args, parent);
				fstate->func.fn_oid = InvalidOid;		/* not initialized */
				state = (ExprState *) fstate;
			}
			break;
		case T_NullTest:
			{
				NullTest   *ntest = (NullTest *) node;
				NullTestState *nstate = makeNode(NullTestState);

				nstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullTest;
				nstate->arg = ExecInitExpr(ntest->arg, parent);
				nstate->argisrow = type_is_rowtype(exprType((Node *) ntest->arg));
				nstate->argdesc = NULL;
				state = (ExprState *) nstate;
			}
			break;
		case T_BooleanTest:
			{
				BooleanTest *btest = (BooleanTest *) node;
				GenericExprState *gstate = makeNode(GenericExprState);

				gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalBooleanTest;
				gstate->arg = ExecInitExpr(btest->arg, parent);
				state = (ExprState *) gstate;
			}
			break;
		case T_CoerceToDomain:
			{
				CoerceToDomain *ctest = (CoerceToDomain *) node;
				CoerceToDomainState *cstate = makeNode(CoerceToDomainState);

				cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceToDomain;
				cstate->arg = ExecInitExpr(ctest->arg, parent);
				cstate->constraints = GetDomainConstraints(ctest->resulttype);
				state = (ExprState *) cstate;
			}
			break;
		case T_CurrentOfExpr:
			state = (ExprState *) makeNode(ExprState);
			state->evalfunc = ExecEvalCurrentOfExpr;
			break;
		case T_PercentileExpr:
			{
				PercentileExpr	   *p = (PercentileExpr *) node;
				PercentileExprState *pstate = makeNode(PercentileExprState);
				AggState		   *aggstate = (AggState *) parent;
				int					naggs;

				if (!IsA(aggstate, AggState))
					elog(ERROR, "PercentileExpr found in non-Agg plan node: %d",
							(int) nodeTag(parent));

				aggstate->percs = lcons(pstate, aggstate->percs);
				naggs = ++aggstate->numaggs;

				pstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalPercentileExpr;


				/* This is to build TupleDesc. */
				pstate->tlist = combinePercentileArgs(p);

				/* This is to build ProjectionInfo. */
				pstate->args = (List *) ExecInitExpr((Expr *) pstate->tlist, parent);

				/*
				 * Complain if the aggregate's arguments contain any
				 * aggregates; nested agg functions are semantically
				 * nonsensical.  (This should have been caught earlier,
				 * but we defend against it here anyway.)
				 */
				if (naggs != aggstate->numaggs)
					ereport(ERROR,
							(errcode(ERRCODE_GROUPING_ERROR),
							 errmsg("aggregate function calls may not be nested")));

				state = (ExprState *) pstate;
			}
			break;
		case T_TargetEntry:
			{
				TargetEntry *tle = (TargetEntry *) node;
				GenericExprState *gstate = makeNode(GenericExprState);

				gstate->xprstate.evalfunc = NULL;		/* not used */
				gstate->arg = ExecInitExpr(tle->expr, parent);
				state = (ExprState *) gstate;
			}
			break;
		case T_List:
			{
				List	   *outlist = NIL;
				ListCell   *l;

				foreach(l, (List *) node)
				{
					outlist = lappend(outlist,
									  ExecInitExpr((Expr *) lfirst(l),
												   parent));
				}
				/* Don't fall through to the "common" code below */
				return (ExprState *) outlist;
			}
		case T_PartOidExpr:
			{
				Insist(parent && IsA(parent, PartitionSelectorState));
				PartitionSelectorState *psstate = (PartitionSelectorState *) parent;
				PartOidExprState *exprstate = makeNode(PartOidExprState);
#if USE_ASSERT_CHECKING
				PartOidExpr *expr = (PartOidExpr *) node;
				Assert (expr->level == ((PartitionSelector *) psstate->ps.plan)->nLevels - 1 &&
						"PartOidExpr can only refer to leaf level.");
#endif
				exprstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalPartOidExpr;
				/*
				 * exprstate->acceptedLeafPart is a double pointer, pointing
				 * to the field in the PartitionSelector state that will
				 * be holding the actual PartitionConstraints value (GPSQL-2956)
				 * computed for each tuple.
				 */
				exprstate->acceptedLeafPart = psstate->acceptedLeafPart;

				state = (ExprState *) exprstate;
			}
			break;
		case T_PartDefaultExpr:
			{
				Insist(parent && IsA(parent, PartitionSelectorState));
				PartitionSelectorState *psstate = (PartitionSelectorState *) parent;
				PartDefaultExprState *exprstate = makeNode(PartDefaultExprState);
				exprstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalPartDefaultExpr;
				exprstate->levelPartConstraints = psstate->levelPartConstraints;

				state = (ExprState *) exprstate;
			}
			break;
		case T_PartBoundExpr:
			{
				Insist(parent && IsA(parent, PartitionSelectorState));
				PartitionSelectorState *psstate = (PartitionSelectorState *) parent;
				PartBoundExprState *exprstate = makeNode(PartBoundExprState);
				exprstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalPartBoundExpr;
				exprstate->levelPartConstraints = psstate->levelPartConstraints;

				state = (ExprState *) exprstate;
			}
			break;
		case T_PartBoundInclusionExpr:
			{
				Insist(parent && IsA(parent, PartitionSelectorState));
				PartitionSelectorState *psstate = (PartitionSelectorState *) parent;
				PartBoundInclusionExprState *exprstate = makeNode(PartBoundInclusionExprState);
				exprstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalPartBoundInclusionExpr;
				exprstate->levelPartConstraints = psstate->levelPartConstraints;

				state = (ExprState *) exprstate;
			}
			break;
		case T_PartBoundOpenExpr:
			{
				Insist(parent && IsA(parent, PartitionSelectorState));
				PartitionSelectorState *psstate = (PartitionSelectorState *) parent;
				PartBoundOpenExprState *exprstate = makeNode(PartBoundOpenExprState);
				exprstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalPartBoundOpenExpr;
				exprstate->levelPartConstraints = psstate->levelPartConstraints;

				state = (ExprState *) exprstate;
			}
			break;
		default:
			elog(ERROR, "unrecognized node type: %d",
				 (int) nodeTag(node));
			state = NULL;		/* keep compiler quiet */
			break;
	}

	/* Common code for all state-node types */
	state->expr = node;

	return state;
}

/*
 * ExecInitExprInitPlan --- initialize a subplan expr that's being handled
 * as an InitPlan.	This is identical to ExecInitExpr's handling of a regular
 * subplan expr, except we do NOT want to add the node to the parent's
 * subplan list.
 */
SubPlanState *
ExecInitExprInitPlan(SubPlan *node, PlanState *parent)
{
	SubPlanState *sstate = makeNode(SubPlanState);

	/* The subplan's state will be initialized later */
	sstate->sub_estate = NULL;
	sstate->planstate = NULL;

	if (parent != NULL)
	{
		sstate->testexpr = ExecInitExpr((Expr *) node->testexpr, parent);
		sstate->args = (List *) ExecInitExpr((Expr *) node->args, parent);
	}
	else
	{
		sstate->testexpr = NULL;
		sstate->args = NULL;
	}

	sstate->xprstate.expr = (Expr *) node;

	return sstate;
}

/*
 * ExecPrepareExpr --- initialize for expression execution outside a normal
 * Plan tree context.
 *
 * This differs from ExecInitExpr in that we don't assume the caller is
 * already running in the EState's per-query context.  Also, we apply
 * fix_opfuncids() to the passed expression tree to be sure it is ready
 * to run.	(In ordinary Plan trees the planner will have fixed opfuncids,
 * but callers outside the executor will not have done this.)
 */
ExprState *
ExecPrepareExpr(Expr *node, EState *estate)
{
	ExprState  *result;
	MemoryContext oldcontext;

	fix_opfuncids((Node *) node);

	oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);

	result = ExecInitExpr(node, NULL);

	MemoryContextSwitchTo(oldcontext);

	return result;
}


/* ----------------------------------------------------------------
 *					 ExecQual / ExecTargetList / ExecProject
 * ----------------------------------------------------------------
 */

/* ----------------------------------------------------------------
 *		ExecQual
 *
 *		Evaluates a conjunctive boolean expression (qual list) and
 *		returns true iff none of the subexpressions are false.
 *		(We also return true if the list is empty.)
 *
 *	If some of the subexpressions yield NULL but none yield FALSE,
 *	then the result of the conjunction is NULL (ie, unknown)
 *	according to three-valued boolean logic.  In this case,
 *	we return the value specified by the "resultForNull" parameter.
 *
 *	Callers evaluating WHERE clauses should pass resultForNull=FALSE,
 *	since SQL specifies that tuples with null WHERE results do not
 *	get selected.  On the other hand, callers evaluating constraint
 *	conditions should pass resultForNull=TRUE, since SQL also specifies
 *	that NULL constraint conditions are not failures.
 *
 *	NOTE: it would not be correct to use this routine to evaluate an
 *	AND subclause of a boolean expression; for that purpose, a NULL
 *	result must be returned as NULL so that it can be properly treated
 *	in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
 *	This routine is only used in contexts where a complete expression
 *	is being evaluated and we know that NULL can be treated the same
 *	as one boolean result or the other.
 *
 * ----------------------------------------------------------------
 */
bool
ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
{
	bool		result;
	MemoryContext oldContext;
	ListCell   *l;

	/*
	 * debugging stuff
	 */
	EV_printf("ExecQual: qual is ");
	EV_nodeDisplay(qual);
	EV_printf("\n");

	IncrProcessed();

	/*
	 * Run in short-lived per-tuple context while computing expressions.
	 */
	oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);

	/*
	 * Evaluate the qual conditions one at a time.	If we find a FALSE result,
	 * we can stop evaluating and return FALSE --- the AND result must be
	 * FALSE.  Also, if we find a NULL result when resultForNull is FALSE, we
	 * can stop and return FALSE --- the AND result must be FALSE or NULL in
	 * that case, and the caller doesn't care which.
	 *
	 * If we get to the end of the list, we can return TRUE.  This will happen
	 * when the AND result is indeed TRUE, or when the AND result is NULL (one
	 * or more NULL subresult, with all the rest TRUE) and the caller has
	 * specified resultForNull = TRUE.
	 */
	result = true;

	foreach(l, qual)
	{
		ExprState  *clause = (ExprState *) lfirst(l);
		Datum		expr_value;
		bool		isNull;

		expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);

		if (isNull)
		{
			if (resultForNull == false)
			{
				result = false; /* treat NULL as FALSE */
				break;
			}
		}
		else
		{
			if (!DatumGetBool(expr_value))
			{
				result = false; /* definitely FALSE */
				break;
			}
		}
	}

	MemoryContextSwitchTo(oldContext);

	return result;
}

/*
 * Number of items in a tlist (including any resjunk items!)
 */
int
ExecTargetListLength(List *targetlist)
{
	/* This used to be more complex, but fjoins are dead */
	return list_length(targetlist);
}

/*
 * Number of items in a tlist, not including any resjunk items
 */
int
ExecCleanTargetListLength(List *targetlist)
{
	int			len = 0;
	ListCell   *tl;

	foreach(tl, targetlist)
	{
		TargetEntry *curTle = (TargetEntry *) lfirst(tl);

		Assert(IsA(curTle, TargetEntry));
		if (!curTle->resjunk)
			len++;
	}
	return len;
}

/*
 * ExecTargetList
 *		Evaluates a targetlist with respect to the given
 *		expression context.  Returns TRUE if we were able to create
 *		a result, FALSE if we have exhausted a set-valued expression.
 *
 * Results are stored into the passed values and isnull arrays.
 * The caller must provide an itemIsDone array that persists across calls.
 *
 * As with ExecEvalExpr, the caller should pass isDone = NULL if not
 * prepared to deal with sets of result tuples.  Otherwise, a return
 * of *isDone = ExprMultipleResult signifies a set element, and a return
 * of *isDone = ExprEndResult signifies end of the set of tuple.
 */
static bool
ExecTargetList(List *targetlist,
			   ExprContext *econtext,
			   Datum *values,
			   bool *isnull,
			   ExprDoneCond *itemIsDone,
			   ExprDoneCond *isDone)
{
	MemoryContext oldContext;
	ListCell   *tl;
	bool		haveDoneSets;

	/*
	 * Run in short-lived per-tuple context while computing expressions.
	 */
	oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);

	/*
	 * evaluate all the expressions in the target list
	 */
	if (isDone)
		*isDone = ExprSingleResult;		/* until proven otherwise */

	haveDoneSets = false;		/* any exhausted set exprs in tlist? */

	foreach(tl, targetlist)
	{
		GenericExprState *gstate = (GenericExprState *) lfirst(tl);
		TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
		AttrNumber	resind = tle->resno - 1;

		values[resind] = ExecEvalExpr(gstate->arg,
									  econtext,
									  &isnull[resind],
									  &itemIsDone[resind]);

		if (itemIsDone[resind] != ExprSingleResult)
		{
			/* We have a set-valued expression in the tlist */
			if (isDone == NULL)
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("set-valued function called in context that cannot accept a set")));
			if (itemIsDone[resind] == ExprMultipleResult)
			{
				/* we have undone sets in the tlist, set flag */
				*isDone = ExprMultipleResult;
			}
			else
			{
				/* we have done sets in the tlist, set flag for that */
				haveDoneSets = true;
			}
		}
	}

	if (haveDoneSets)
	{
		/*
		 * note: can't get here unless we verified isDone != NULL
		 */
		if (*isDone == ExprSingleResult)
		{
			/*
			 * all sets are done, so report that tlist expansion is complete.
			 */
			*isDone = ExprEndResult;
			MemoryContextSwitchTo(oldContext);
			return false;
		}
		else
		{
			/*
			 * We have some done and some undone sets.	Restart the done ones
			 * so that we can deliver a tuple (if possible).
			 */
			foreach(tl, targetlist)
			{
				GenericExprState *gstate = (GenericExprState *) lfirst(tl);
				TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
				AttrNumber	resind = tle->resno - 1;

				if (itemIsDone[resind] == ExprEndResult)
				{
					values[resind] = ExecEvalExpr(gstate->arg,
												  econtext,
												  &isnull[resind],
												  &itemIsDone[resind]);

					if (itemIsDone[resind] == ExprEndResult)
					{
						/*
						 * Oh dear, this item is returning an empty set. Guess
						 * we can't make a tuple after all.
						 */
						*isDone = ExprEndResult;
						break;
					}
				}
			}

			/*
			 * If we cannot make a tuple because some sets are empty, we still
			 * have to cycle the nonempty sets to completion, else resources
			 * will not be released from subplans etc.
			 *
			 * XXX is that still necessary?
			 */
			if (*isDone == ExprEndResult)
			{
				foreach(tl, targetlist)
				{
					GenericExprState *gstate = (GenericExprState *) lfirst(tl);
					TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
					AttrNumber	resind = tle->resno - 1;

					while (itemIsDone[resind] == ExprMultipleResult)
					{
						values[resind] = ExecEvalExpr(gstate->arg,
													  econtext,
													  &isnull[resind],
													  &itemIsDone[resind]);
					}
				}

				MemoryContextSwitchTo(oldContext);
				return false;
			}
		}
	}

	/* Report success */
	MemoryContextSwitchTo(oldContext);

	return true;
}

/*
 * ExecVariableList
 *		Evaluates a simple-Variable-list projection.
 *
 * Results are stored into the passed values and isnull arrays.
 */
static void
ExecVariableList(ProjectionInfo *projInfo,
				 Datum *values,
				 bool *isnull)
{
	ExprContext *econtext = projInfo->pi_exprContext;
	int		   *varSlotOffsets = projInfo->pi_varSlotOffsets;
	int		   *varNumbers = projInfo->pi_varNumbers;
	int			i;

	/*
	 * Assign to result by direct extraction of fields from source slots ... a
	 * mite ugly, but fast ...
	 */
	for (i = list_length(projInfo->pi_targetlist) - 1; i >= 0; i--)
	{
		char	   *slotptr = ((char *) econtext) + varSlotOffsets[i];
		TupleTableSlot *varSlot = *((TupleTableSlot **) slotptr);
		int			varNumber = varNumbers[i] - 1;

		values[i] = slot_getattr(varSlot, varNumber+1, &(isnull[i])); 
	}
}

/*
 * ExecProject
 *
 *		projects a tuple based on projection info and stores
 *		it in the previously specified tuple table slot.
 *
 *		Note: the result is always a virtual tuple; therefore it
 *		may reference the contents of the exprContext's scan tuples
 *		and/or temporary results constructed in the exprContext.
 *		If the caller wishes the result to be valid longer than that
 *		data will be valid, he must call ExecMaterializeSlot on the
 *		result slot.
 */
TupleTableSlot *
ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
{
	TupleTableSlot *slot;

	/*
	 * sanity checks
	 */
	Assert(projInfo != NULL);

	/*
	 * get the projection info we want
	 */
	slot = projInfo->pi_slot;

	/*
	 * Clear any former contents of the result slot.  This makes it safe for
	 * us to use the slot's Datum/isnull arrays as workspace. (Also, we can
	 * return the slot as-is if we decide no rows can be projected.)
	 */
	ExecClearTuple(slot); 

	/*
	 * form a new result tuple (if possible); if successful, mark the result
	 * slot as containing a valid virtual tuple
	 */
	if (projInfo->pi_isVarList)
	{
		/* simple Var list: this always succeeds with one result row */
		if (isDone)
			*isDone = ExprSingleResult;

		ExecVariableList(projInfo, slot_get_values(slot), slot_get_isnull(slot));
		ExecStoreVirtualTuple(slot);
	}
	else
	{
		if (ExecTargetList(projInfo->pi_targetlist,
						   projInfo->pi_exprContext,
						   slot_get_values(slot),
						   slot_get_isnull(slot),
						   (ExprDoneCond *) projInfo->pi_itemIsDone,
						   isDone))
			ExecStoreVirtualTuple(slot);
	}

	return slot;
}

/*
 * ExecIsExprUnsafeToConst_walker
 *
 * Almost all of the expressions are not allowed without the executor.
 * Returns true as soon as possible we find such unsafe nodes.
 */
static bool
ExecIsExprUnsafeToConst_walker(Node *node, void *context)
{
	switch(nodeTag(node))
	{
		/*
		 * Param can be a Const in some situation, but the demanded use case
		 * so far doesn't want it.
		 */
		case T_Const:
		case T_CaseTestExpr:
		case T_FuncExpr:
		case T_OpExpr:
		case T_DistinctExpr:
		case T_ScalarArrayOpExpr:
		case T_BoolExpr:
		case T_CaseExpr:
		case T_CoalesceExpr:
		case T_MinMaxExpr:
		case T_NullIfExpr:
		case T_NullTest:
		case T_BooleanTest:
		case T_List:
		case T_TypeCast:
			return false;

		default:
			return true;
	}
}

/*
 * ExecIsExprUnsafeToConst
 *
 * Returns true if the expression cannot be evaluated to a const value.
 */
static bool
ExecIsExprUnsafeToConst(Node *node)
{
	Assert(node != NULL);
	return ExecIsExprUnsafeToConst_walker(node, NULL);
}

/*
 * ExecEvalFunctionArgToConst
 *
 * Evaluates an argument of function expression and returns the result.
 * This is assumed to be used in the parser stage, where
 * dynamic evaluation such like Var is not available, though we put it
 * here so that we can extend it to be useful in other places later.
 */
Datum
ExecEvalFunctionArgToConst(FuncExpr *fexpr, int argno, bool *isnull)
{
	Expr		   *aexpr;
	Oid				argtype;
	Const		   *result;

	/* argument number sanity check */
	if (argno < 0 || list_length(fexpr->args) <= argno)
		elog(ERROR, "invalid argument number found during evaluating function argument");

	aexpr = (Expr *) list_nth(fexpr->args, argno);
	/*
	 * Check if the expression can be evaluated in the Const fasion.
	 */
	if (ExecIsExprUnsafeToConst((Node *) aexpr))
		elog(ERROR, "unable to resolve function argument");

	argtype = exprType((Node *) aexpr);
	if (!OidIsValid(argtype))
		elog(ERROR, "unable to resolve function argument type");

	result = (Const *) evaluate_expr(aexpr, argtype);
	/* evaluate_expr always returns Const */
	Assert(IsA(result, Const));

	if (isnull)
		*isnull = result->constisnull;

	return result->constvalue;
}

typedef struct neededColumnContext
{
	bool *mask;
	int n;
} neededColumnContext;

static bool
neededColumnContextWalker(Node *node, neededColumnContext *c)
{
	if (node == NULL)
		return false;

	if (IsA(node, Var))
	{
		Var *var = (Var *)node;

		if (var->varattno > 0) 
		{
			Assert(var->varattno <= c->n);
			c->mask[var->varattno - 1] = true;
		}
		/*
		 * If all attributes are included,
		 * set all entries in mask to true.
		 */
		else if (var->varattno == 0)
		{
			int i;

			for (i=0; i < c->n; i++)
				c->mask[i] = true;
		}

		return false;
	}
	return expression_tree_walker(node, neededColumnContextWalker, (void * )c);
}

/*
 * n specifies the number of allowed entries in mask: we use
 * it for bounds-checking in the walker above.
 */
void GetNeededColumnsForScan(Node *expr, bool *mask, int n)
{
	neededColumnContext c;

	c.mask = mask;
	c.n = n;

	neededColumnContextWalker(expr, &c);
}

/* ----------------------------------------------------------------
 *	isJoinExprNull
 *
 *	Checks if the join expression evaluates to NULL for a given
 *	input tuple.
 *
 *	The input tuple has to be present in the correct TupleTableSlot
 *	in the ExprContext. For example, if all the expressions
 *	in joinExpr refer to the inner side of the join,
 *	econtext->ecxt_innertuple must be valid.
 * ----------------------------------------------------------------
 */
bool
isJoinExprNull(List *joinExpr, ExprContext *econtext)
{

	Assert(NULL != joinExpr);
	bool joinkeys_null = true;

	ListCell   *lc;
	foreach(lc, joinExpr)
	{
		ExprState  *keyexpr = (ExprState *) lfirst(lc);
		bool		isNull = false;

		/*
		 * Evaluate the current join attribute value of the tuple
		 */
		ExecEvalExpr(keyexpr, econtext, &isNull, NULL);

		if (!isNull)
		{
			/* Found at least one non-null join expression, we're done */
			joinkeys_null = false;
			break;
		}
	}

	return joinkeys_null;
}
