1 /*-------------------------------------------------------------------------
2  *
3  * execExpr.h
4  *	  Low level infrastructure related to expression evaluation
5  *
6  *
7  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * src/include/executor/execExpr.h
11  *
12  *-------------------------------------------------------------------------
13  */
14 #ifndef EXEC_EXPR_H
15 #define EXEC_EXPR_H
16 
17 #include "executor/nodeAgg.h"
18 #include "nodes/execnodes.h"
19 
20 /* forward references to avoid circularity */
21 struct ExprEvalStep;
22 struct SubscriptingRefState;
23 
24 /* Bits in ExprState->flags (see also execnodes.h for public flag bits): */
25 /* expression's interpreter has been initialized */
26 #define EEO_FLAG_INTERPRETER_INITIALIZED	(1 << 1)
27 /* jump-threading is in use */
28 #define EEO_FLAG_DIRECT_THREADED			(1 << 2)
29 
30 /* Typical API for out-of-line evaluation subroutines */
31 typedef void (*ExecEvalSubroutine) (ExprState *state,
32 									struct ExprEvalStep *op,
33 									ExprContext *econtext);
34 
35 /* ExprEvalSteps that cache a composite type's tupdesc need one of these */
36 /* (it fits in-line in some step types, otherwise allocate out-of-line) */
37 typedef struct ExprEvalRowtypeCache
38 {
39 	/*
40 	 * cacheptr points to composite type's TypeCacheEntry if tupdesc_id is not
41 	 * 0; or for an anonymous RECORD type, it points directly at the cached
42 	 * tupdesc for the type, and tupdesc_id is 0.  (We'd use separate fields
43 	 * if space were not at a premium.)  Initial state is cacheptr == NULL.
44 	 */
45 	void	   *cacheptr;
46 	uint64		tupdesc_id;		/* last-seen tupdesc identifier, or 0 */
47 } ExprEvalRowtypeCache;
48 
49 /*
50  * Discriminator for ExprEvalSteps.
51  *
52  * Identifies the operation to be executed and which member in the
53  * ExprEvalStep->d union is valid.
54  *
55  * The order of entries needs to be kept in sync with the dispatch_table[]
56  * array in execExprInterp.c:ExecInterpExpr().
57  */
58 typedef enum ExprEvalOp
59 {
60 	/* entire expression has been evaluated completely, return */
61 	EEOP_DONE,
62 
63 	/* apply slot_getsomeattrs on corresponding tuple slot */
64 	EEOP_INNER_FETCHSOME,
65 	EEOP_OUTER_FETCHSOME,
66 	EEOP_SCAN_FETCHSOME,
67 
68 	/* compute non-system Var value */
69 	EEOP_INNER_VAR,
70 	EEOP_OUTER_VAR,
71 	EEOP_SCAN_VAR,
72 
73 	/* compute system Var value */
74 	EEOP_INNER_SYSVAR,
75 	EEOP_OUTER_SYSVAR,
76 	EEOP_SCAN_SYSVAR,
77 
78 	/* compute wholerow Var */
79 	EEOP_WHOLEROW,
80 
81 	/*
82 	 * Compute non-system Var value, assign it into ExprState's resultslot.
83 	 * These are not used if a CheckVarSlotCompatibility() check would be
84 	 * needed.
85 	 */
86 	EEOP_ASSIGN_INNER_VAR,
87 	EEOP_ASSIGN_OUTER_VAR,
88 	EEOP_ASSIGN_SCAN_VAR,
89 
90 	/* assign ExprState's resvalue/resnull to a column of its resultslot */
91 	EEOP_ASSIGN_TMP,
92 	/* ditto, applying MakeExpandedObjectReadOnly() */
93 	EEOP_ASSIGN_TMP_MAKE_RO,
94 
95 	/* evaluate Const value */
96 	EEOP_CONST,
97 
98 	/*
99 	 * Evaluate function call (including OpExprs etc).  For speed, we
100 	 * distinguish in the opcode whether the function is strict and/or
101 	 * requires usage stats tracking.
102 	 */
103 	EEOP_FUNCEXPR,
104 	EEOP_FUNCEXPR_STRICT,
105 	EEOP_FUNCEXPR_FUSAGE,
106 	EEOP_FUNCEXPR_STRICT_FUSAGE,
107 
108 	/*
109 	 * Evaluate boolean AND expression, one step per subexpression. FIRST/LAST
110 	 * subexpressions are special-cased for performance.  Since AND always has
111 	 * at least two subexpressions, FIRST and LAST never apply to the same
112 	 * subexpression.
113 	 */
114 	EEOP_BOOL_AND_STEP_FIRST,
115 	EEOP_BOOL_AND_STEP,
116 	EEOP_BOOL_AND_STEP_LAST,
117 
118 	/* similarly for boolean OR expression */
119 	EEOP_BOOL_OR_STEP_FIRST,
120 	EEOP_BOOL_OR_STEP,
121 	EEOP_BOOL_OR_STEP_LAST,
122 
123 	/* evaluate boolean NOT expression */
124 	EEOP_BOOL_NOT_STEP,
125 
126 	/* simplified version of BOOL_AND_STEP for use by ExecQual() */
127 	EEOP_QUAL,
128 
129 	/* unconditional jump to another step */
130 	EEOP_JUMP,
131 
132 	/* conditional jumps based on current result value */
133 	EEOP_JUMP_IF_NULL,
134 	EEOP_JUMP_IF_NOT_NULL,
135 	EEOP_JUMP_IF_NOT_TRUE,
136 
137 	/* perform NULL tests for scalar values */
138 	EEOP_NULLTEST_ISNULL,
139 	EEOP_NULLTEST_ISNOTNULL,
140 
141 	/* perform NULL tests for row values */
142 	EEOP_NULLTEST_ROWISNULL,
143 	EEOP_NULLTEST_ROWISNOTNULL,
144 
145 	/* evaluate a BooleanTest expression */
146 	EEOP_BOOLTEST_IS_TRUE,
147 	EEOP_BOOLTEST_IS_NOT_TRUE,
148 	EEOP_BOOLTEST_IS_FALSE,
149 	EEOP_BOOLTEST_IS_NOT_FALSE,
150 
151 	/* evaluate PARAM_EXEC/EXTERN parameters */
152 	EEOP_PARAM_EXEC,
153 	EEOP_PARAM_EXTERN,
154 	EEOP_PARAM_CALLBACK,
155 
156 	/* return CaseTestExpr value */
157 	EEOP_CASE_TESTVAL,
158 
159 	/* apply MakeExpandedObjectReadOnly() to target value */
160 	EEOP_MAKE_READONLY,
161 
162 	/* evaluate assorted special-purpose expression types */
163 	EEOP_IOCOERCE,
164 	EEOP_DISTINCT,
165 	EEOP_NOT_DISTINCT,
166 	EEOP_NULLIF,
167 	EEOP_SQLVALUEFUNCTION,
168 	EEOP_CURRENTOFEXPR,
169 	EEOP_NEXTVALUEEXPR,
170 	EEOP_ARRAYEXPR,
171 	EEOP_ARRAYCOERCE,
172 	EEOP_ROW,
173 
174 	/*
175 	 * Compare two individual elements of each of two compared ROW()
176 	 * expressions.  Skip to ROWCOMPARE_FINAL if elements are not equal.
177 	 */
178 	EEOP_ROWCOMPARE_STEP,
179 
180 	/* evaluate boolean value based on previous ROWCOMPARE_STEP operations */
181 	EEOP_ROWCOMPARE_FINAL,
182 
183 	/* evaluate GREATEST() or LEAST() */
184 	EEOP_MINMAX,
185 
186 	/* evaluate FieldSelect expression */
187 	EEOP_FIELDSELECT,
188 
189 	/*
190 	 * Deform tuple before evaluating new values for individual fields in a
191 	 * FieldStore expression.
192 	 */
193 	EEOP_FIELDSTORE_DEFORM,
194 
195 	/*
196 	 * Form the new tuple for a FieldStore expression.  Individual fields will
197 	 * have been evaluated into columns of the tuple deformed by the preceding
198 	 * DEFORM step.
199 	 */
200 	EEOP_FIELDSTORE_FORM,
201 
202 	/* Process a container subscript; short-circuit expression to NULL if NULL */
203 	EEOP_SBSREF_SUBSCRIPT,
204 
205 	/*
206 	 * Compute old container element/slice when a SubscriptingRef assignment
207 	 * expression contains SubscriptingRef/FieldStore subexpressions. Value is
208 	 * accessed using the CaseTest mechanism.
209 	 */
210 	EEOP_SBSREF_OLD,
211 
212 	/* compute new value for SubscriptingRef assignment expression */
213 	EEOP_SBSREF_ASSIGN,
214 
215 	/* compute element/slice for SubscriptingRef fetch expression */
216 	EEOP_SBSREF_FETCH,
217 
218 	/* evaluate value for CoerceToDomainValue */
219 	EEOP_DOMAIN_TESTVAL,
220 
221 	/* evaluate a domain's NOT NULL constraint */
222 	EEOP_DOMAIN_NOTNULL,
223 
224 	/* evaluate a single domain CHECK constraint */
225 	EEOP_DOMAIN_CHECK,
226 
227 	/* evaluate assorted special-purpose expression types */
228 	EEOP_CONVERT_ROWTYPE,
229 	EEOP_SCALARARRAYOP,
230 	EEOP_XMLEXPR,
231 	EEOP_AGGREF,
232 	EEOP_GROUPING_FUNC,
233 	EEOP_WINDOW_FUNC,
234 	EEOP_SUBPLAN,
235 	EEOP_ALTERNATIVE_SUBPLAN,
236 
237 	/* aggregation related nodes */
238 	EEOP_AGG_STRICT_DESERIALIZE,
239 	EEOP_AGG_DESERIALIZE,
240 	EEOP_AGG_STRICT_INPUT_CHECK_ARGS,
241 	EEOP_AGG_STRICT_INPUT_CHECK_NULLS,
242 	EEOP_AGG_PLAIN_PERGROUP_NULLCHECK,
243 	EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL,
244 	EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL,
245 	EEOP_AGG_PLAIN_TRANS_BYVAL,
246 	EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF,
247 	EEOP_AGG_PLAIN_TRANS_STRICT_BYREF,
248 	EEOP_AGG_PLAIN_TRANS_BYREF,
249 	EEOP_AGG_ORDERED_TRANS_DATUM,
250 	EEOP_AGG_ORDERED_TRANS_TUPLE,
251 
252 	/* non-existent operation, used e.g. to check array lengths */
253 	EEOP_LAST
254 } ExprEvalOp;
255 
256 
257 typedef struct ExprEvalStep
258 {
259 	/*
260 	 * Instruction to be executed.  During instruction preparation this is an
261 	 * enum ExprEvalOp, but later it can be changed to some other type, e.g. a
262 	 * pointer for computed goto (that's why it's an intptr_t).
263 	 */
264 	intptr_t	opcode;
265 
266 	/* where to store the result of this step */
267 	Datum	   *resvalue;
268 	bool	   *resnull;
269 
270 	/*
271 	 * Inline data for the operation.  Inline data is faster to access, but
272 	 * also bloats the size of all instructions.  The union should be kept to
273 	 * no more than 40 bytes on 64-bit systems (so that the entire struct is
274 	 * no more than 64 bytes, a single cacheline on common systems).
275 	 */
276 	union
277 	{
278 		/* for EEOP_INNER/OUTER/SCAN_FETCHSOME */
279 		struct
280 		{
281 			/* attribute number up to which to fetch (inclusive) */
282 			int			last_var;
283 			/* will the type of slot be the same for every invocation */
284 			bool		fixed;
285 			/* tuple descriptor, if known */
286 			TupleDesc	known_desc;
287 			/* type of slot, can only be relied upon if fixed is set */
288 			const TupleTableSlotOps *kind;
289 		}			fetch;
290 
291 		/* for EEOP_INNER/OUTER/SCAN_[SYS]VAR[_FIRST] */
292 		struct
293 		{
294 			/* attnum is attr number - 1 for regular VAR ... */
295 			/* but it's just the normal (negative) attr number for SYSVAR */
296 			int			attnum;
297 			Oid			vartype;	/* type OID of variable */
298 		}			var;
299 
300 		/* for EEOP_WHOLEROW */
301 		struct
302 		{
303 			Var		   *var;	/* original Var node in plan tree */
304 			bool		first;	/* first time through, need to initialize? */
305 			bool		slow;	/* need runtime check for nulls? */
306 			TupleDesc	tupdesc;	/* descriptor for resulting tuples */
307 			JunkFilter *junkFilter; /* JunkFilter to remove resjunk cols */
308 		}			wholerow;
309 
310 		/* for EEOP_ASSIGN_*_VAR */
311 		struct
312 		{
313 			/* target index in ExprState->resultslot->tts_values/nulls */
314 			int			resultnum;
315 			/* source attribute number - 1 */
316 			int			attnum;
317 		}			assign_var;
318 
319 		/* for EEOP_ASSIGN_TMP[_MAKE_RO] */
320 		struct
321 		{
322 			/* target index in ExprState->resultslot->tts_values/nulls */
323 			int			resultnum;
324 		}			assign_tmp;
325 
326 		/* for EEOP_CONST */
327 		struct
328 		{
329 			/* constant's value */
330 			Datum		value;
331 			bool		isnull;
332 		}			constval;
333 
334 		/* for EEOP_FUNCEXPR_* / NULLIF / DISTINCT */
335 		struct
336 		{
337 			FmgrInfo   *finfo;	/* function's lookup data */
338 			FunctionCallInfo fcinfo_data;	/* arguments etc */
339 			/* faster to access without additional indirection: */
340 			PGFunction	fn_addr;	/* actual call address */
341 			int			nargs;	/* number of arguments */
342 		}			func;
343 
344 		/* for EEOP_BOOL_*_STEP */
345 		struct
346 		{
347 			bool	   *anynull;	/* track if any input was NULL */
348 			int			jumpdone;	/* jump here if result determined */
349 		}			boolexpr;
350 
351 		/* for EEOP_QUAL */
352 		struct
353 		{
354 			int			jumpdone;	/* jump here on false or null */
355 		}			qualexpr;
356 
357 		/* for EEOP_JUMP[_CONDITION] */
358 		struct
359 		{
360 			int			jumpdone;	/* target instruction's index */
361 		}			jump;
362 
363 		/* for EEOP_NULLTEST_ROWIS[NOT]NULL */
364 		struct
365 		{
366 			/* cached descriptor for composite type - filled at runtime */
367 			ExprEvalRowtypeCache rowcache;
368 		}			nulltest_row;
369 
370 		/* for EEOP_PARAM_EXEC/EXTERN */
371 		struct
372 		{
373 			int			paramid;	/* numeric ID for parameter */
374 			Oid			paramtype;	/* OID of parameter's datatype */
375 		}			param;
376 
377 		/* for EEOP_PARAM_CALLBACK */
378 		struct
379 		{
380 			ExecEvalSubroutine paramfunc;	/* add-on evaluation subroutine */
381 			void	   *paramarg;	/* private data for same */
382 			int			paramid;	/* numeric ID for parameter */
383 			Oid			paramtype;	/* OID of parameter's datatype */
384 		}			cparam;
385 
386 		/* for EEOP_CASE_TESTVAL/DOMAIN_TESTVAL */
387 		struct
388 		{
389 			Datum	   *value;	/* value to return */
390 			bool	   *isnull;
391 		}			casetest;
392 
393 		/* for EEOP_MAKE_READONLY */
394 		struct
395 		{
396 			Datum	   *value;	/* value to coerce to read-only */
397 			bool	   *isnull;
398 		}			make_readonly;
399 
400 		/* for EEOP_IOCOERCE */
401 		struct
402 		{
403 			/* lookup and call info for source type's output function */
404 			FmgrInfo   *finfo_out;
405 			FunctionCallInfo fcinfo_data_out;
406 			/* lookup and call info for result type's input function */
407 			FmgrInfo   *finfo_in;
408 			FunctionCallInfo fcinfo_data_in;
409 		}			iocoerce;
410 
411 		/* for EEOP_SQLVALUEFUNCTION */
412 		struct
413 		{
414 			SQLValueFunction *svf;
415 		}			sqlvaluefunction;
416 
417 		/* for EEOP_NEXTVALUEEXPR */
418 		struct
419 		{
420 			Oid			seqid;
421 			Oid			seqtypid;
422 		}			nextvalueexpr;
423 
424 		/* for EEOP_ARRAYEXPR */
425 		struct
426 		{
427 			Datum	   *elemvalues; /* element values get stored here */
428 			bool	   *elemnulls;
429 			int			nelems; /* length of the above arrays */
430 			Oid			elemtype;	/* array element type */
431 			int16		elemlength; /* typlen of the array element type */
432 			bool		elembyval;	/* is the element type pass-by-value? */
433 			char		elemalign;	/* typalign of the element type */
434 			bool		multidims;	/* is array expression multi-D? */
435 		}			arrayexpr;
436 
437 		/* for EEOP_ARRAYCOERCE */
438 		struct
439 		{
440 			ExprState  *elemexprstate;	/* null if no per-element work */
441 			Oid			resultelemtype; /* element type of result array */
442 			struct ArrayMapState *amstate;	/* workspace for array_map */
443 		}			arraycoerce;
444 
445 		/* for EEOP_ROW */
446 		struct
447 		{
448 			TupleDesc	tupdesc;	/* descriptor for result tuples */
449 			/* workspace for the values constituting the row: */
450 			Datum	   *elemvalues;
451 			bool	   *elemnulls;
452 		}			row;
453 
454 		/* for EEOP_ROWCOMPARE_STEP */
455 		struct
456 		{
457 			/* lookup and call data for column comparison function */
458 			FmgrInfo   *finfo;
459 			FunctionCallInfo fcinfo_data;
460 			PGFunction	fn_addr;
461 			/* target for comparison resulting in NULL */
462 			int			jumpnull;
463 			/* target for comparison yielding inequality */
464 			int			jumpdone;
465 		}			rowcompare_step;
466 
467 		/* for EEOP_ROWCOMPARE_FINAL */
468 		struct
469 		{
470 			RowCompareType rctype;
471 		}			rowcompare_final;
472 
473 		/* for EEOP_MINMAX */
474 		struct
475 		{
476 			/* workspace for argument values */
477 			Datum	   *values;
478 			bool	   *nulls;
479 			int			nelems;
480 			/* is it GREATEST or LEAST? */
481 			MinMaxOp	op;
482 			/* lookup and call data for comparison function */
483 			FmgrInfo   *finfo;
484 			FunctionCallInfo fcinfo_data;
485 		}			minmax;
486 
487 		/* for EEOP_FIELDSELECT */
488 		struct
489 		{
490 			AttrNumber	fieldnum;	/* field number to extract */
491 			Oid			resulttype; /* field's type */
492 			/* cached descriptor for composite type - filled at runtime */
493 			ExprEvalRowtypeCache rowcache;
494 		}			fieldselect;
495 
496 		/* for EEOP_FIELDSTORE_DEFORM / FIELDSTORE_FORM */
497 		struct
498 		{
499 			/* original expression node */
500 			FieldStore *fstore;
501 
502 			/* cached descriptor for composite type - filled at runtime */
503 			/* note that a DEFORM and FORM pair share the same cache */
504 			ExprEvalRowtypeCache *rowcache;
505 
506 			/* workspace for column values */
507 			Datum	   *values;
508 			bool	   *nulls;
509 			int			ncolumns;
510 		}			fieldstore;
511 
512 		/* for EEOP_SBSREF_SUBSCRIPT */
513 		struct
514 		{
515 			/* too big to have inline */
516 			struct SubscriptingRefState *state;
517 			int			off;	/* 0-based index of this subscript */
518 			bool		isupper;	/* is it upper or lower subscript? */
519 			int			jumpdone;	/* jump here on null */
520 		}			sbsref_subscript;
521 
522 		/* for EEOP_SBSREF_OLD / ASSIGN / FETCH */
523 		struct
524 		{
525 			/* too big to have inline */
526 			struct SubscriptingRefState *state;
527 		}			sbsref;
528 
529 		/* for EEOP_DOMAIN_NOTNULL / DOMAIN_CHECK */
530 		struct
531 		{
532 			/* name of constraint */
533 			char	   *constraintname;
534 			/* where the result of a CHECK constraint will be stored */
535 			Datum	   *checkvalue;
536 			bool	   *checknull;
537 			/* OID of domain type */
538 			Oid			resulttype;
539 		}			domaincheck;
540 
541 		/* for EEOP_CONVERT_ROWTYPE */
542 		struct
543 		{
544 			Oid			inputtype;	/* input composite type */
545 			Oid			outputtype; /* output composite type */
546 			/* these three fields are filled at runtime: */
547 			ExprEvalRowtypeCache *incache;	/* cache for input type */
548 			ExprEvalRowtypeCache *outcache; /* cache for output type */
549 			TupleConversionMap *map;	/* column mapping */
550 		}			convert_rowtype;
551 
552 		/* for EEOP_SCALARARRAYOP */
553 		struct
554 		{
555 			/* element_type/typlen/typbyval/typalign are filled at runtime */
556 			Oid			element_type;	/* InvalidOid if not yet filled */
557 			bool		useOr;	/* use OR or AND semantics? */
558 			int16		typlen; /* array element type storage info */
559 			bool		typbyval;
560 			char		typalign;
561 			FmgrInfo   *finfo;	/* function's lookup data */
562 			FunctionCallInfo fcinfo_data;	/* arguments etc */
563 			/* faster to access without additional indirection: */
564 			PGFunction	fn_addr;	/* actual call address */
565 		}			scalararrayop;
566 
567 		/* for EEOP_XMLEXPR */
568 		struct
569 		{
570 			XmlExpr    *xexpr;	/* original expression node */
571 			/* workspace for evaluating named args, if any */
572 			Datum	   *named_argvalue;
573 			bool	   *named_argnull;
574 			/* workspace for evaluating unnamed args, if any */
575 			Datum	   *argvalue;
576 			bool	   *argnull;
577 		}			xmlexpr;
578 
579 		/* for EEOP_AGGREF */
580 		struct
581 		{
582 			/* out-of-line state, modified by nodeAgg.c */
583 			AggrefExprState *astate;
584 		}			aggref;
585 
586 		/* for EEOP_GROUPING_FUNC */
587 		struct
588 		{
589 			List	   *clauses;	/* integer list of column numbers */
590 		}			grouping_func;
591 
592 		/* for EEOP_WINDOW_FUNC */
593 		struct
594 		{
595 			/* out-of-line state, modified by nodeWindowAgg.c */
596 			WindowFuncExprState *wfstate;
597 		}			window_func;
598 
599 		/* for EEOP_SUBPLAN */
600 		struct
601 		{
602 			/* out-of-line state, created by nodeSubplan.c */
603 			SubPlanState *sstate;
604 		}			subplan;
605 
606 		/* for EEOP_ALTERNATIVE_SUBPLAN */
607 		struct
608 		{
609 			/* out-of-line state, created by nodeSubplan.c */
610 			AlternativeSubPlanState *asstate;
611 		}			alternative_subplan;
612 
613 		/* for EEOP_AGG_*DESERIALIZE */
614 		struct
615 		{
616 			FunctionCallInfo fcinfo_data;
617 			int			jumpnull;
618 		}			agg_deserialize;
619 
620 		/* for EEOP_AGG_STRICT_INPUT_CHECK_NULLS / STRICT_INPUT_CHECK_ARGS */
621 		struct
622 		{
623 			/*
624 			 * For EEOP_AGG_STRICT_INPUT_CHECK_ARGS args contains pointers to
625 			 * the NullableDatums that need to be checked for NULLs.
626 			 *
627 			 * For EEOP_AGG_STRICT_INPUT_CHECK_NULLS nulls contains pointers
628 			 * to booleans that need to be checked for NULLs.
629 			 *
630 			 * Both cases currently need to exist because sometimes the
631 			 * to-be-checked nulls are in TupleTableSlot.isnull array, and
632 			 * sometimes in FunctionCallInfoBaseData.args[i].isnull.
633 			 */
634 			NullableDatum *args;
635 			bool	   *nulls;
636 			int			nargs;
637 			int			jumpnull;
638 		}			agg_strict_input_check;
639 
640 		/* for EEOP_AGG_PLAIN_PERGROUP_NULLCHECK */
641 		struct
642 		{
643 			int			setoff;
644 			int			jumpnull;
645 		}			agg_plain_pergroup_nullcheck;
646 
647 		/* for EEOP_AGG_PLAIN_TRANS_[INIT_][STRICT_]{BYVAL,BYREF} */
648 		/* for EEOP_AGG_ORDERED_TRANS_{DATUM,TUPLE} */
649 		struct
650 		{
651 			AggStatePerTrans pertrans;
652 			ExprContext *aggcontext;
653 			int			setno;
654 			int			transno;
655 			int			setoff;
656 		}			agg_trans;
657 	}			d;
658 } ExprEvalStep;
659 
660 
661 /* Non-inline data for container operations */
662 typedef struct SubscriptingRefState
663 {
664 	bool		isassignment;	/* is it assignment, or just fetch? */
665 
666 	Oid			refelemtype;	/* OID of the container element type */
667 	int16		refattrlength;	/* typlen of container type */
668 	int16		refelemlength;	/* typlen of the container element type */
669 	bool		refelembyval;	/* is the element type pass-by-value? */
670 	char		refelemalign;	/* typalign of the element type */
671 
672 	/* numupper and upperprovided[] are filled at compile time */
673 	/* at runtime, extracted subscript datums get stored in upperindex[] */
674 	int			numupper;
675 	bool		upperprovided[MAXDIM];
676 	int			upperindex[MAXDIM];
677 
678 	/* similarly for lower indexes, if any */
679 	int			numlower;
680 	bool		lowerprovided[MAXDIM];
681 	int			lowerindex[MAXDIM];
682 
683 	/* subscript expressions get evaluated into here */
684 	Datum		subscriptvalue;
685 	bool		subscriptnull;
686 
687 	/* for assignment, new value to assign is evaluated into here */
688 	Datum		replacevalue;
689 	bool		replacenull;
690 
691 	/* if we have a nested assignment, SBSREF_OLD puts old value here */
692 	Datum		prevvalue;
693 	bool		prevnull;
694 } SubscriptingRefState;
695 
696 
697 /* functions in execExpr.c */
698 extern void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s);
699 
700 /* functions in execExprInterp.c */
701 extern void ExecReadyInterpretedExpr(ExprState *state);
702 extern ExprEvalOp ExecEvalStepOp(ExprState *state, ExprEvalStep *op);
703 
704 extern Datum ExecInterpExprStillValid(ExprState *state, ExprContext *econtext, bool *isNull);
705 extern void CheckExprStillValid(ExprState *state, ExprContext *econtext);
706 
707 /*
708  * Non fast-path execution functions. These are externs instead of statics in
709  * execExprInterp.c, because that allows them to be used by other methods of
710  * expression evaluation, reducing code duplication.
711  */
712 extern void ExecEvalFuncExprFusage(ExprState *state, ExprEvalStep *op,
713 								   ExprContext *econtext);
714 extern void ExecEvalFuncExprStrictFusage(ExprState *state, ExprEvalStep *op,
715 										 ExprContext *econtext);
716 extern void ExecEvalParamExec(ExprState *state, ExprEvalStep *op,
717 							  ExprContext *econtext);
718 extern void ExecEvalParamExtern(ExprState *state, ExprEvalStep *op,
719 								ExprContext *econtext);
720 extern void ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op);
721 extern void ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op);
722 extern void ExecEvalNextValueExpr(ExprState *state, ExprEvalStep *op);
723 extern void ExecEvalRowNull(ExprState *state, ExprEvalStep *op,
724 							ExprContext *econtext);
725 extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op,
726 							   ExprContext *econtext);
727 extern void ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op);
728 extern void ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op,
729 								ExprContext *econtext);
730 extern void ExecEvalRow(ExprState *state, ExprEvalStep *op);
731 extern void ExecEvalMinMax(ExprState *state, ExprEvalStep *op);
732 extern void ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op,
733 								ExprContext *econtext);
734 extern void ExecEvalFieldStoreDeForm(ExprState *state, ExprEvalStep *op,
735 									 ExprContext *econtext);
736 extern void ExecEvalFieldStoreForm(ExprState *state, ExprEvalStep *op,
737 								   ExprContext *econtext);
738 extern bool ExecEvalSubscriptingRef(ExprState *state, ExprEvalStep *op);
739 extern void ExecEvalSubscriptingRefFetch(ExprState *state, ExprEvalStep *op);
740 extern void ExecEvalSubscriptingRefOld(ExprState *state, ExprEvalStep *op);
741 extern void ExecEvalSubscriptingRefAssign(ExprState *state, ExprEvalStep *op);
742 extern void ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op,
743 								   ExprContext *econtext);
744 extern void ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op);
745 extern void ExecEvalConstraintNotNull(ExprState *state, ExprEvalStep *op);
746 extern void ExecEvalConstraintCheck(ExprState *state, ExprEvalStep *op);
747 extern void ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op);
748 extern void ExecEvalGroupingFunc(ExprState *state, ExprEvalStep *op);
749 extern void ExecEvalSubPlan(ExprState *state, ExprEvalStep *op,
750 							ExprContext *econtext);
751 extern void ExecEvalAlternativeSubPlan(ExprState *state, ExprEvalStep *op,
752 									   ExprContext *econtext);
753 extern void ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op,
754 								ExprContext *econtext);
755 extern void ExecEvalSysVar(ExprState *state, ExprEvalStep *op,
756 						   ExprContext *econtext, TupleTableSlot *slot);
757 
758 extern void ExecAggInitGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup,
759 							 ExprContext *aggcontext);
760 extern Datum ExecAggTransReparent(AggState *aggstate, AggStatePerTrans pertrans,
761 								  Datum newValue, bool newValueIsNull,
762 								  Datum oldValue, bool oldValueIsNull);
763 extern void ExecEvalAggOrderedTransDatum(ExprState *state, ExprEvalStep *op,
764 										 ExprContext *econtext);
765 extern void ExecEvalAggOrderedTransTuple(ExprState *state, ExprEvalStep *op,
766 										 ExprContext *econtext);
767 
768 #endif							/* EXEC_EXPR_H */
769