text: /*-------------------------------------------------------------------------
   *
   * execExpr.h
   *	  Low level infrastructure related to expression evaluation
   *
   *
   * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
   * Portions Copyright (c) 1994, Regents of the University of California
   *
   * src/include/executor/execExpr.h
   *
   *-------------------------------------------------------------------------
   */
  #ifndef EXEC_EXPR_H
  #define EXEC_EXPR_H
  
  #include "executor/nodeAgg.h"
  #include "nodes/execnodes.h"
  
  /* forward references to avoid circularity */
  struct ExprEvalStep;
  struct SubscriptingRefState;
  
  /* Bits in ExprState->flags (see also execnodes.h for public flag bits): */
  /* expression's interpreter has been initialized */
  #define EEO_FLAG_INTERPRETER_INITIALIZED	(1 << 1)
  /* jump-threading is in use */
  #define EEO_FLAG_DIRECT_THREADED			(1 << 2)
  
  /* Typical API for out-of-line evaluation subroutines */
  typedef void (*ExecEvalSubroutine) (ExprState *state,
  									struct ExprEvalStep *op,
  									ExprContext *econtext);
  
  /*
   * Discriminator for ExprEvalSteps.
   *
   * Identifies the operation to be executed and which member in the
   * ExprEvalStep->d union is valid.
   *
   * The order of entries needs to be kept in sync with the dispatch_table[]
   * array in execExprInterp.c:ExecInterpExpr().
   */
  typedef enum ExprEvalOp
  {
  	/* entire expression has been evaluated completely, return */
  	EEOP_DONE,
  
  	/* apply slot_getsomeattrs on corresponding tuple slot */
  	EEOP_INNER_FETCHSOME,
  	EEOP_OUTER_FETCHSOME,
  	EEOP_SCAN_FETCHSOME,
  
  	/* compute non-system Var value */
  	EEOP_INNER_VAR,
  	EEOP_OUTER_VAR,
  	EEOP_SCAN_VAR,
  
  	/* compute system Var value */
  	EEOP_INNER_SYSVAR,
  	EEOP_OUTER_SYSVAR,
  	EEOP_SCAN_SYSVAR,
  
  	/* compute wholerow Var */
  	EEOP_WHOLEROW,
  
  	/*
  	 * Compute non-system Var value, assign it into ExprState's resultslot.
  	 * These are not used if a CheckVarSlotCompatibility() check would be
  	 * needed.
  	 */
  	EEOP_ASSIGN_INNER_VAR,
  	EEOP_ASSIGN_OUTER_VAR,
  	EEOP_ASSIGN_SCAN_VAR,
  
  	/* assign ExprState's resvalue/resnull to a column of its resultslot */
  	EEOP_ASSIGN_TMP,
  	/* ditto, applying MakeExpandedObjectReadOnly() */
  	EEOP_ASSIGN_TMP_MAKE_RO,
  
  	/* evaluate Const value */
  	EEOP_CONST,
  
  	/*
  	 * Evaluate function call (including OpExprs etc).  For speed, we
  	 * distinguish in the opcode whether the function is strict and/or
  	 * requires usage stats tracking.
  	 */
  	EEOP_FUNCEXPR,
  	EEOP_FUNCEXPR_STRICT,
  	EEOP_FUNCEXPR_FUSAGE,
  	EEOP_FUNCEXPR_STRICT_FUSAGE,
  
  	/*
  	 * Evaluate boolean AND expression, one step per subexpression. FIRST/LAST
  	 * subexpressions are special-cased for performance.  Since AND always has
  	 * at least two subexpressions, FIRST and LAST never apply to the same
  	 * subexpression.
  	 */
  	EEOP_BOOL_AND_STEP_FIRST,
  	EEOP_BOOL_AND_STEP,
  	EEOP_BOOL_AND_STEP_LAST,
  
  	/* similarly for boolean OR expression */
  	EEOP_BOOL_OR_STEP_FIRST,
  	EEOP_BOOL_OR_STEP,
  	EEOP_BOOL_OR_STEP_LAST,
  
  	/* evaluate boolean NOT expression */
  	EEOP_BOOL_NOT_STEP,
  
  	/* simplified version of BOOL_AND_STEP for use by ExecQual() */
  	EEOP_QUAL,
  
  	/* unconditional jump to another step */
  	EEOP_JUMP,
  
  	/* conditional jumps based on current result value */
  	EEOP_JUMP_IF_NULL,
  	EEOP_JUMP_IF_NOT_NULL,
  	EEOP_JUMP_IF_NOT_TRUE,
  
  	/* perform NULL tests for scalar values */
  	EEOP_NULLTEST_ISNULL,
  	EEOP_NULLTEST_ISNOTNULL,
  
  	/* perform NULL tests for row values */
  	EEOP_NULLTEST_ROWISNULL,
  	EEOP_NULLTEST_ROWISNOTNULL,
  
  	/* evaluate a BooleanTest expression */
  	EEOP_BOOLTEST_IS_TRUE,
  	EEOP_BOOLTEST_IS_NOT_TRUE,
  	EEOP_BOOLTEST_IS_FALSE,
  	EEOP_BOOLTEST_IS_NOT_FALSE,
  
  	/* evaluate PARAM_EXEC/EXTERN parameters */
  	EEOP_PARAM_EXEC,
  	EEOP_PARAM_EXTERN,
  	EEOP_PARAM_CALLBACK,
  
  	/* return CaseTestExpr value */
  	EEOP_CASE_TESTVAL,
  
  	/* apply MakeExpandedObjectReadOnly() to target value */
  	EEOP_MAKE_READONLY,
  
  	/* evaluate assorted special-purpose expression types */
  	EEOP_IOCOERCE,
  	EEOP_DISTINCT,
  	EEOP_NOT_DISTINCT,
  	EEOP_NULLIF,
  	EEOP_SQLVALUEFUNCTION,
  	EEOP_CURRENTOFEXPR,
  	EEOP_NEXTVALUEEXPR,
  	EEOP_ARRAYEXPR,
  	EEOP_ARRAYCOERCE,
  	EEOP_ROW,
  
  	/*
  	 * Compare two individual elements of each of two compared ROW()
  	 * expressions.  Skip to ROWCOMPARE_FINAL if elements are not equal.
  	 */
  	EEOP_ROWCOMPARE_STEP,
  
  	/* evaluate boolean value based on previous ROWCOMPARE_STEP operations */
  	EEOP_ROWCOMPARE_FINAL,
  
  	/* evaluate GREATEST() or LEAST() */
  	EEOP_MINMAX,
  
  	/* evaluate FieldSelect expression */
  	EEOP_FIELDSELECT,
  
  	/*
  	 * Deform tuple before evaluating new values for individual fields in a
  	 * FieldStore expression.
  	 */
  	EEOP_FIELDSTORE_DEFORM,
  
  	/*
  	 * Form the new tuple for a FieldStore expression.  Individual fields will
  	 * have been evaluated into columns of the tuple deformed by the preceding
  	 * DEFORM step.
  	 */
  	EEOP_FIELDSTORE_FORM,
  
  	/* Process a container subscript; short-circuit expression to NULL if NULL */
  	EEOP_SBSREF_SUBSCRIPT,
  
  	/*
  	 * Compute old container element/slice when a SubscriptingRef assignment
  	 * expression contains SubscriptingRef/FieldStore subexpressions. Value is
  	 * accessed using the CaseTest mechanism.
  	 */
  	EEOP_SBSREF_OLD,
  
  	/* compute new value for SubscriptingRef assignment expression */
  	EEOP_SBSREF_ASSIGN,
  
  	/* compute element/slice for SubscriptingRef fetch expression */
  	EEOP_SBSREF_FETCH,
  
  	/* evaluate value for CoerceToDomainValue */
  	EEOP_DOMAIN_TESTVAL,
  
  	/* evaluate a domain's NOT NULL constraint */
  	EEOP_DOMAIN_NOTNULL,
  
  	/* evaluate a single domain CHECK constraint */
  	EEOP_DOMAIN_CHECK,
  
  	/* evaluate assorted special-purpose expression types */
  	EEOP_CONVERT_ROWTYPE,
  	EEOP_SCALARARRAYOP,
  	EEOP_XMLEXPR,
  	EEOP_AGGREF,
  	EEOP_GROUPING_FUNC,
  	EEOP_WINDOW_FUNC,
  	EEOP_SUBPLAN,
  
  	/* aggregation related nodes */
  	EEOP_AGG_STRICT_DESERIALIZE,
  	EEOP_AGG_DESERIALIZE,
  	EEOP_AGG_STRICT_INPUT_CHECK_ARGS,
  	EEOP_AGG_STRICT_INPUT_CHECK_NULLS,
  	EEOP_AGG_PLAIN_PERGROUP_NULLCHECK,
  	EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL,
  	EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL,
  	EEOP_AGG_PLAIN_TRANS_BYVAL,
  	EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF,
  	EEOP_AGG_PLAIN_TRANS_STRICT_BYREF,
  	EEOP_AGG_PLAIN_TRANS_BYREF,
  	EEOP_AGG_ORDERED_TRANS_DATUM,
  	EEOP_AGG_ORDERED_TRANS_TUPLE,
  
  	/* non-existent operation, used e.g. to check array lengths */
  	EEOP_LAST
  } ExprEvalOp;
  
  
  typedef struct ExprEvalStep
  {
  	/*
  	 * Instruction to be executed.  During instruction preparation this is an
  	 * enum ExprEvalOp, but later it can be changed to some other type, e.g. a
  	 * pointer for computed goto (that's why it's an intptr_t).
  	 */
  	intptr_t	opcode;
  
  	/* where to store the result of this step */
  	Datum	   *resvalue;
  	bool	   *resnull;
  
  	/*
  	 * Inline data for the operation.  Inline data is faster to access, but
  	 * also bloats the size of all instructions.  The union should be kept to
  	 * no more than 40 bytes on 64-bit systems (so that the entire struct is
  	 * no more than 64 bytes, a single cacheline on common systems).
  	 */
  	union
  	{
  		/* for EEOP_INNER/OUTER/SCAN_FETCHSOME */
  		struct
  		{
  			/* attribute number up to which to fetch (inclusive) */
  			int			last_var;
  			/* will the type of slot be the same for every invocation */
  			bool		fixed;
  			/* tuple descriptor, if known */
  			TupleDesc	known_desc;
  			/* type of slot, can only be relied upon if fixed is set */
  			const TupleTableSlotOps *kind;
  		}			fetch;
  
  		/* for EEOP_INNER/OUTER/SCAN_[SYS]VAR[_FIRST] */
  		struct
  		{
  			/* attnum is attr number - 1 for regular VAR ... */
  			/* but it's just the normal (negative) attr number for SYSVAR */
  			int			attnum;
  			Oid			vartype;	/* type OID of variable */
  		}			var;
  
  		/* for EEOP_WHOLEROW */
  		struct
  		{
  			Var		   *var;	/* original Var node in plan tree */
  			bool		first;	/* first time through, need to initialize? */
  			bool		slow;	/* need runtime check for nulls? */
  			TupleDesc	tupdesc;	/* descriptor for resulting tuples */
  			JunkFilter *junkFilter; /* JunkFilter to remove resjunk cols */
  		}			wholerow;
  
  		/* for EEOP_ASSIGN_*_VAR */
  		struct
  		{
  			/* target index in ExprState->resultslot->tts_values/nulls */
  			int			resultnum;
  			/* source attribute number - 1 */
  			int			attnum;
  		}			assign_var;
  
  		/* for EEOP_ASSIGN_TMP[_MAKE_RO] */
  		struct
  		{
  			/* target index in ExprState->resultslot->tts_values/nulls */
  			int			resultnum;
  		}			assign_tmp;
  
  		/* for EEOP_CONST */
  		struct
  		{
  			/* constant's value */
  			Datum		value;
  			bool		isnull;
  		}			constval;
  
  		/* for EEOP_FUNCEXPR_* / NULLIF / DISTINCT */
  		struct
  		{
  			FmgrInfo   *finfo;	/* function's lookup data */
  			FunctionCallInfo fcinfo_data;	/* arguments etc */
  			/* faster to access without additional indirection: */
  			PGFunction	fn_addr;	/* actual call address */
  			int			nargs;	/* number of arguments */
  		}			func;
  
  		/* for EEOP_BOOL_*_STEP */
  		struct
  		{
  			bool	   *anynull;	/* track if any input was NULL */
  			int			jumpdone;	/* jump here if result determined */
  		}			boolexpr;
  
  		/* for EEOP_QUAL */
  		struct
  		{
  			int			jumpdone;	/* jump here on false or null */
  		}			qualexpr;
  
  		/* for EEOP_JUMP[_CONDITION] */
  		struct
  		{
  			int			jumpdone;	/* target instruction's index */
  		}			jump;
  
  		/* for EEOP_NULLTEST_ROWIS[NOT]NULL */
  		struct
  		{
  			/* cached tupdesc pointer - filled at runtime */
  			TupleDesc	argdesc;
  		}			nulltest_row;
  
  		/* for EEOP_PARAM_EXEC/EXTERN */
  		struct
  		{
  			int			paramid;	/* numeric ID for parameter */
  			Oid			paramtype;	/* OID of parameter's datatype */
  		}			param;
  
  		/* for EEOP_PARAM_CALLBACK */
  		struct
  		{
  			ExecEvalSubroutine paramfunc;	/* add-on evaluation subroutine */
  			void	   *paramarg;	/* private data for same */
  			int			paramid;	/* numeric ID for parameter */
  			Oid			paramtype;	/* OID of parameter's datatype */
  		}			cparam;
  
  		/* for EEOP_CASE_TESTVAL/DOMAIN_TESTVAL */
  		struct
  		{
  			Datum	   *value;	/* value to return */
  			bool	   *isnull;
  		}			casetest;
  
  		/* for EEOP_MAKE_READONLY */
  		struct
  		{
  			Datum	   *value;	/* value to coerce to read-only */
  			bool	   *isnull;
  		}			make_readonly;
  
  		/* for EEOP_IOCOERCE */
  		struct
  		{
  			/* lookup and call info for source type's output function */
  			FmgrInfo   *finfo_out;
  			FunctionCallInfo fcinfo_data_out;
  			/* lookup and call info for result type's input function */
  			FmgrInfo   *finfo_in;
  			FunctionCallInfo fcinfo_data_in;
  		}			iocoerce;
  
  		/* for EEOP_SQLVALUEFUNCTION */
  		struct
  		{
  			SQLValueFunction *svf;
  		}			sqlvaluefunction;
  
  		/* for EEOP_NEXTVALUEEXPR */
  		struct
  		{
  			Oid			seqid;
  			Oid			seqtypid;
  		}			nextvalueexpr;
  
  		/* for EEOP_ARRAYEXPR */
  		struct
  		{
  			Datum	   *elemvalues; /* element values get stored here */
  			bool	   *elemnulls;
  			int			nelems; /* length of the above arrays */
  			Oid			elemtype;	/* array element type */
  			int16		elemlength; /* typlen of the array element type */
  			bool		elembyval;	/* is the element type pass-by-value? */
  			char		elemalign;	/* typalign of the element type */
  			bool		multidims;	/* is array expression multi-D? */
  		}			arrayexpr;
  
  		/* for EEOP_ARRAYCOERCE */
  		struct
  		{
  			ExprState  *elemexprstate;	/* null if no per-element work */
  			Oid			resultelemtype; /* element type of result array */
  			struct ArrayMapState *amstate;	/* workspace for array_map */
  		}			arraycoerce;
  
  		/* for EEOP_ROW */
  		struct
  		{
  			TupleDesc	tupdesc;	/* descriptor for result tuples */
  			/* workspace for the values constituting the row: */
  			Datum	   *elemvalues;
  			bool	   *elemnulls;
  		}			row;
  
  		/* for EEOP_ROWCOMPARE_STEP */
  		struct
  		{
  			/* lookup and call data for column comparison function */
  			FmgrInfo   *finfo;
  			FunctionCallInfo fcinfo_data;
  			PGFunction	fn_addr;
  			/* target for comparison resulting in NULL */
  			int			jumpnull;
  			/* target for comparison yielding inequality */
  			int			jumpdone;
  		}			rowcompare_step;
  
  		/* for EEOP_ROWCOMPARE_FINAL */
  		struct
  		{
  			RowCompareType rctype;
  		}			rowcompare_final;
  
  		/* for EEOP_MINMAX */
  		struct
  		{
  			/* workspace for argument values */
  			Datum	   *values;
  			bool	   *nulls;
  			int			nelems;
  			/* is it GREATEST or LEAST? */
  			MinMaxOp	op;
  			/* lookup and call data for comparison function */
  			FmgrInfo   *finfo;
  			FunctionCallInfo fcinfo_data;
  		}			minmax;
  
  		/* for EEOP_FIELDSELECT */
  		struct
  		{
  			AttrNumber	fieldnum;	/* field number to extract */
  			Oid			resulttype; /* field's type */
  			/* cached tupdesc pointer - filled at runtime */
  			TupleDesc	argdesc;
  		}			fieldselect;
  
  		/* for EEOP_FIELDSTORE_DEFORM / FIELDSTORE_FORM */
  		struct
  		{
  			/* original expression node */
  			FieldStore *fstore;
  
  			/* cached tupdesc pointer - filled at runtime */
  			/* note that a DEFORM and FORM pair share the same tupdesc */
  			TupleDesc  *argdesc;
  
  			/* workspace for column values */
  			Datum	   *values;
  			bool	   *nulls;
  			int			ncolumns;
  		}			fieldstore;
  
  		/* for EEOP_SBSREF_SUBSCRIPT */
  		struct
  		{
  			/* too big to have inline */
  			struct SubscriptingRefState *state;
  			int			off;	/* 0-based index of this subscript */
  			bool		isupper;	/* is it upper or lower subscript? */
  			int			jumpdone;	/* jump here on null */
  		}			sbsref_subscript;
  
  		/* for EEOP_SBSREF_OLD / ASSIGN / FETCH */
  		struct
  		{
  			/* too big to have inline */
  			struct SubscriptingRefState *state;
  		}			sbsref;
  
  		/* for EEOP_DOMAIN_NOTNULL / DOMAIN_CHECK */
  		struct
  		{
  			/* name of constraint */
  			char	   *constraintname;
  			/* where the result of a CHECK constraint will be stored */
  			Datum	   *checkvalue;
  			bool	   *checknull;
  			/* OID of domain type */
  			Oid			resulttype;
  		}			domaincheck;
  
  		/* for EEOP_CONVERT_ROWTYPE */
  		struct
  		{
  			ConvertRowtypeExpr *convert;	/* original expression */
  			/* these three fields are filled at runtime: */
  			TupleDesc	indesc; /* tupdesc for input type */
  			TupleDesc	outdesc;	/* tupdesc for output type */
  			TupleConversionMap *map;	/* column mapping */
  			bool		initialized;	/* initialized for current types? */
  		}			convert_rowtype;
  
  		/* for EEOP_SCALARARRAYOP */
  		struct
  		{
  			/* element_type/typlen/typbyval/typalign are filled at runtime */
  			Oid			element_type;	/* InvalidOid if not yet filled */
  			bool		useOr;	/* use OR or AND semantics? */
  			int16		typlen; /* array element type storage info */
  			bool		typbyval;
  			char		typalign;
  			FmgrInfo   *finfo;	/* function's lookup data */
  			FunctionCallInfo fcinfo_data;	/* arguments etc */
  			/* faster to access without additional indirection: */
  			PGFunction	fn_addr;	/* actual call address */
  		}			scalararrayop;
  
  		/* for EEOP_XMLEXPR */
  		struct
  		{
  			XmlExpr    *xexpr;	/* original expression node */
  			/* workspace for evaluating named args, if any */
  			Datum	   *named_argvalue;
  			bool	   *named_argnull;
  			/* workspace for evaluating unnamed args, if any */
  			Datum	   *argvalue;
  			bool	   *argnull;
  		}			xmlexpr;
  
  		/* for EEOP_AGGREF */
  		struct
  		{
  			/* out-of-line state, modified by nodeAgg.c */
  			AggrefExprState *astate;
  		}			aggref;
  
  		/* for EEOP_GROUPING_FUNC */
  		struct
  		{
  			List	   *clauses;	/* integer list of column numbers */
  		}			grouping_func;
  
  		/* for EEOP_WINDOW_FUNC */
  		struct
  		{
  			/* out-of-line state, modified by nodeWindowAgg.c */
  			WindowFuncExprState *wfstate;
  		}			window_func;
  
  		/* for EEOP_SUBPLAN */
  		struct
  		{
  			/* out-of-line state, created by nodeSubplan.c */
  			SubPlanState *sstate;
  		}			subplan;
  
  		/* for EEOP_AGG_*DESERIALIZE */
  		struct
  		{
  			FunctionCallInfo fcinfo_data;
  			int			jumpnull;
  		}			agg_deserialize;
  
  		/* for EEOP_AGG_STRICT_INPUT_CHECK_NULLS / STRICT_INPUT_CHECK_ARGS */
  		struct
  		{
  			/*
  			 * For EEOP_AGG_STRICT_INPUT_CHECK_ARGS args contains pointers to
  			 * the NullableDatums that need to be checked for NULLs.
  			 *
  			 * For EEOP_AGG_STRICT_INPUT_CHECK_NULLS nulls contains pointers
  			 * to booleans that need to be checked for NULLs.
  			 *
  			 * Both cases currently need to exist because sometimes the
  			 * to-be-checked nulls are in TupleTableSlot.isnull array, and
  			 * sometimes in FunctionCallInfoBaseData.args[i].isnull.
  			 */
  			NullableDatum *args;
  			bool	   *nulls;
  			int			nargs;
  			int			jumpnull;
  		}			agg_strict_input_check;
  
  		/* for EEOP_AGG_PLAIN_PERGROUP_NULLCHECK */
  		struct
  		{
  			int			setoff;
  			int			jumpnull;
  		}			agg_plain_pergroup_nullcheck;
  
  		/* for EEOP_AGG_PLAIN_TRANS_[INIT_][STRICT_]{BYVAL,BYREF} */
  		/* for EEOP_AGG_ORDERED_TRANS_{DATUM,TUPLE} */
  		struct
  		{
  			AggStatePerTrans pertrans;
  			ExprContext *aggcontext;
  			int			setno;
  			int			transno;
  			int			setoff;
  		}			agg_trans;
  	}			d;
  } ExprEvalStep;
  
  
  /* Non-inline data for container operations */
  typedef struct SubscriptingRefState
  {
  	bool		isassignment;	/* is it assignment, or just fetch? */
  
  	Oid			refelemtype;	/* OID of the container element type */
  	int16		refattrlength;	/* typlen of container type */
  	int16		refelemlength;	/* typlen of the container element type */
  	bool		refelembyval;	/* is the element type pass-by-value? */
  	char		refelemalign;	/* typalign of the element type */
  
  	/* numupper and upperprovided[] are filled at compile time */
  	/* at runtime, extracted subscript datums get stored in upperindex[] */
  	int			numupper;
  	bool		upperprovided[MAXDIM];
  	int			upperindex[MAXDIM];
  
  	/* similarly for lower indexes, if any */
  	int			numlower;
  	bool		lowerprovided[MAXDIM];
  	int			lowerindex[MAXDIM];
  
  	/* subscript expressions get evaluated into here */
  	Datum		subscriptvalue;
  	bool		subscriptnull;
  
  	/* for assignment, new value to assign is evaluated into here */
  	Datum		replacevalue;
  	bool		replacenull;
  
  	/* if we have a nested assignment, SBSREF_OLD puts old value here */
  	Datum		prevvalue;
  	bool		prevnull;
  } SubscriptingRefState;
  
  
  /* functions in execExpr.c */
  extern void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s);
  
  /* functions in execExprInterp.c */
  extern void ExecReadyInterpretedExpr(ExprState *state);
  extern ExprEvalOp ExecEvalStepOp(ExprState *state, ExprEvalStep *op);
  
  extern Datum ExecInterpExprStillValid(ExprState *state, ExprContext *econtext, bool *isNull);
  extern void CheckExprStillValid(ExprState *state, ExprContext *econtext);
  
  /*
   * Non fast-path execution functions. These are externs instead of statics in
   * execExprInterp.c, because that allows them to be used by other methods of
   * expression evaluation, reducing code duplication.
   */
  extern void ExecEvalFuncExprFusage(ExprState *state, ExprEvalStep *op,
  								   ExprContext *econtext);
  extern void ExecEvalFuncExprStrictFusage(ExprState *state, ExprEvalStep *op,
  										 ExprContext *econtext);
  extern void ExecEvalParamExec(ExprState *state, ExprEvalStep *op,
  							  ExprContext *econtext);
  extern void ExecEvalParamExtern(ExprState *state, ExprEvalStep *op,
  								ExprContext *econtext);
  extern void ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op);
  extern void ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op);
  extern void ExecEvalNextValueExpr(ExprState *state, ExprEvalStep *op);
  extern void ExecEvalRowNull(ExprState *state, ExprEvalStep *op,
  							ExprContext *econtext);
  extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op,
  							   ExprContext *econtext);
  extern void ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op);
  extern void ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op,
  								ExprContext *econtext);
  extern void ExecEvalRow(ExprState *state, ExprEvalStep *op);
  extern void ExecEvalMinMax(ExprState *state, ExprEvalStep *op);
  extern void ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op,
  								ExprContext *econtext);
  extern void ExecEvalFieldStoreDeForm(ExprState *state, ExprEvalStep *op,
  									 ExprContext *econtext);
  extern void ExecEvalFieldStoreForm(ExprState *state, ExprEvalStep *op,
  								   ExprContext *econtext);
  extern bool ExecEvalSubscriptingRef(ExprState *state, ExprEvalStep *op);
  extern void ExecEvalSubscriptingRefFetch(ExprState *state, ExprEvalStep *op);
  extern void ExecEvalSubscriptingRefOld(ExprState *state, ExprEvalStep *op);
  extern void ExecEvalSubscriptingRefAssign(ExprState *state, ExprEvalStep *op);
  extern void ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op,
  								   ExprContext *econtext);
  extern void ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op);
  extern void ExecEvalConstraintNotNull(ExprState *state, ExprEvalStep *op);
  extern void ExecEvalConstraintCheck(ExprState *state, ExprEvalStep *op);
  extern void ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op);
  extern void ExecEvalGroupingFunc(ExprState *state, ExprEvalStep *op);
  extern void ExecEvalSubPlan(ExprState *state, ExprEvalStep *op,
  							ExprContext *econtext);
  extern void ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op,
  								ExprContext *econtext);
  extern void ExecEvalSysVar(ExprState *state, ExprEvalStep *op,
  						   ExprContext *econtext, TupleTableSlot *slot);
  
  extern void ExecAggInitGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup,
  							 ExprContext *aggcontext);
  extern Datum ExecAggTransReparent(AggState *aggstate, AggStatePerTrans pertrans,
  								  Datum newValue, bool newValueIsNull,
  								  Datum oldValue, bool oldValueIsNull);
  extern void ExecEvalAggOrderedTransDatum(ExprState *state, ExprEvalStep *op,
  										 ExprContext *econtext);
  extern void ExecEvalAggOrderedTransTuple(ExprState *state, ExprEvalStep *op,
  										 ExprContext *econtext);
  
  #endif							/* EXEC_EXPR_H */
  