1 /*-------------------------------------------------------------------------
2  *
dbd_strlower(char * in)3  * execExpr.h
4  *	  Low level infrastructure related to expression evaluation
5  *
6  *
7  * Portions Copyright (c) 1996-2019, 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,
dbd_register(lua_State * L,const char * name,const luaL_Reg * methods,const luaL_Reg * class_methods,lua_CFunction gc,lua_CFunction tostring)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_INIT_TRANS,
243 	EEOP_AGG_STRICT_TRANS_CHECK,
244 	EEOP_AGG_PLAIN_TRANS_BYVAL,
245 	EEOP_AGG_PLAIN_TRANS,
246 	EEOP_AGG_ORDERED_TRANS_DATUM,
247 	EEOP_AGG_ORDERED_TRANS_TUPLE,
248 
249 	/* non-existent operation, used e.g. to check array lengths */
250 	EEOP_LAST
251 } ExprEvalOp;
252 
253 
254 typedef struct ExprEvalStep
255 {
256 	/*
257 	 * Instruction to be executed.  During instruction preparation this is an
258 	 * enum ExprEvalOp, but later it can be changed to some other type, e.g. a
259 	 * pointer for computed goto (that's why it's an intptr_t).
260 	 */
261 	intptr_t	opcode;
262 
263 	/* where to store the result of this step */
264 	Datum	   *resvalue;
265 	bool	   *resnull;
266 
267 	/*
268 	 * Inline data for the operation.  Inline data is faster to access, but
269 	 * also bloats the size of all instructions.  The union should be kept to
270 	 * no more than 40 bytes on 64-bit systems (so that the entire struct is
271 	 * no more than 64 bytes, a single cacheline on common systems).
272 	 */
273 	union
274 	{
275 		/* for EEOP_INNER/OUTER/SCAN_FETCHSOME */
276 		struct
277 		{
278 			/* attribute number up to which to fetch (inclusive) */
279 			int			last_var;
280 			/* will the type of slot be the same for every invocation */
281 			bool		fixed;
282 			/* tuple descriptor, if known */
283 			TupleDesc	known_desc;
284 			/* type of slot, can only be relied upon if fixed is set */
285 			const TupleTableSlotOps *kind;
286 		}			fetch;
287 
288 		/* for EEOP_INNER/OUTER/SCAN_[SYS]VAR[_FIRST] */
289 		struct
290 		{
291 			/* attnum is attr number - 1 for regular VAR ... */
292 			/* but it's just the normal (negative) attr number for SYSVAR */
293 			int			attnum;
294 			Oid			vartype;	/* type OID of variable */
295 		}			var;
296 
297 		/* for EEOP_WHOLEROW */
298 		struct
299 		{
300 			Var		   *var;	/* original Var node in plan tree */
301 			bool		first;	/* first time through, need to initialize? */
302 			bool		slow;	/* need runtime check for nulls? */
303 			TupleDesc	tupdesc;	/* descriptor for resulting tuples */
304 			JunkFilter *junkFilter; /* JunkFilter to remove resjunk cols */
305 		}			wholerow;
306 
307 		/* for EEOP_ASSIGN_*_VAR */
308 		struct
309 		{
310 			/* target index in ExprState->resultslot->tts_values/nulls */
311 			int			resultnum;
312 			/* source attribute number - 1 */
313 			int			attnum;
314 		}			assign_var;
315 
316 		/* for EEOP_ASSIGN_TMP[_MAKE_RO] */
317 		struct
318 		{
319 			/* target index in ExprState->resultslot->tts_values/nulls */
320 			int			resultnum;
321 		}			assign_tmp;
322 
323 		/* for EEOP_CONST */
324 		struct
325 		{
326 			/* constant's value */
327 			Datum		value;
328 			bool		isnull;
329 		}			constval;
330 
331 		/* for EEOP_FUNCEXPR_* / NULLIF / DISTINCT */
332 		struct
333 		{
334 			FmgrInfo   *finfo;	/* function's lookup data */
335 			FunctionCallInfo fcinfo_data;	/* arguments etc */
336 			/* faster to access without additional indirection: */
337 			PGFunction	fn_addr;	/* actual call address */
338 			int			nargs;	/* number of arguments */
339 		}			func;
340 
341 		/* for EEOP_BOOL_*_STEP */
342 		struct
343 		{
344 			bool	   *anynull;	/* track if any input was NULL */
345 			int			jumpdone;	/* jump here if result determined */
346 		}			boolexpr;
347 
348 		/* for EEOP_QUAL */
349 		struct
350 		{
351 			int			jumpdone;	/* jump here on false or null */
352 		}			qualexpr;
353 
354 		/* for EEOP_JUMP[_CONDITION] */
355 		struct
356 		{
357 			int			jumpdone;	/* target instruction's index */
358 		}			jump;
359 
360 		/* for EEOP_NULLTEST_ROWIS[NOT]NULL */
361 		struct
362 		{
363 			/* cached descriptor for composite type - filled at runtime */
364 			ExprEvalRowtypeCache rowcache;
365 		}			nulltest_row;
366 
367 		/* for EEOP_PARAM_EXEC/EXTERN */
368 		struct
369 		{
370 			int			paramid;	/* numeric ID for parameter */
371 			Oid			paramtype;	/* OID of parameter's datatype */
372 		}			param;
373 
374 		/* for EEOP_PARAM_CALLBACK */
375 		struct
376 		{
377 			ExecEvalSubroutine paramfunc;	/* add-on evaluation subroutine */
378 			void	   *paramarg;	/* private data for same */
379 			int			paramid;	/* numeric ID for parameter */
380 			Oid			paramtype;	/* OID of parameter's datatype */
381 		}			cparam;
382 
383 		/* for EEOP_CASE_TESTVAL/DOMAIN_TESTVAL */
384 		struct
385 		{
386 			Datum	   *value;	/* value to return */
387 			bool	   *isnull;
388 		}			casetest;
389 
390 		/* for EEOP_MAKE_READONLY */
391 		struct
392 		{
393 			Datum	   *value;	/* value to coerce to read-only */
394 			bool	   *isnull;
395 		}			make_readonly;
396 
397 		/* for EEOP_IOCOERCE */
398 		struct
399 		{
400 			/* lookup and call info for source type's output function */
401 			FmgrInfo   *finfo_out;
402 			FunctionCallInfo fcinfo_data_out;
403 			/* lookup and call info for result type's input function */
404 			FmgrInfo   *finfo_in;
405 			FunctionCallInfo fcinfo_data_in;
406 		}			iocoerce;
407 
408 		/* for EEOP_SQLVALUEFUNCTION */
409 		struct
410 		{
411 			SQLValueFunction *svf;
412 		}			sqlvaluefunction;
413 
414 		/* for EEOP_NEXTVALUEEXPR */
415 		struct
416 		{
417 			Oid			seqid;
418 			Oid			seqtypid;
419 		}			nextvalueexpr;
420 
421 		/* for EEOP_ARRAYEXPR */
422 		struct
423 		{
424 			Datum	   *elemvalues; /* element values get stored here */
425 			bool	   *elemnulls;
426 			int			nelems; /* length of the above arrays */
427 			Oid			elemtype;	/* array element type */
428 			int16		elemlength; /* typlen of the array element type */
429 			bool		elembyval;	/* is the element type pass-by-value? */
430 			char		elemalign;	/* typalign of the element type */
431 			bool		multidims;	/* is array expression multi-D? */
432 		}			arrayexpr;
433 
434 		/* for EEOP_ARRAYCOERCE */
435 		struct
436 		{
437 			ExprState  *elemexprstate;	/* null if no per-element work */
438 			Oid			resultelemtype; /* element type of result array */
439 			struct ArrayMapState *amstate;	/* workspace for array_map */
440 		}			arraycoerce;
441 
442 		/* for EEOP_ROW */
443 		struct
444 		{
445 			TupleDesc	tupdesc;	/* descriptor for result tuples */
446 			/* workspace for the values constituting the row: */
447 			Datum	   *elemvalues;
448 			bool	   *elemnulls;
449 		}			row;
450 
451 		/* for EEOP_ROWCOMPARE_STEP */
452 		struct
453 		{
454 			/* lookup and call data for column comparison function */
455 			FmgrInfo   *finfo;
456 			FunctionCallInfo fcinfo_data;
457 			PGFunction	fn_addr;
458 			/* target for comparison resulting in NULL */
459 			int			jumpnull;
460 			/* target for comparison yielding inequality */
461 			int			jumpdone;
462 		}			rowcompare_step;
463 
464 		/* for EEOP_ROWCOMPARE_FINAL */
465 		struct
466 		{
467 			RowCompareType rctype;
468 		}			rowcompare_final;
469 
470 		/* for EEOP_MINMAX */
471 		struct
472 		{
473 			/* workspace for argument values */
474 			Datum	   *values;
475 			bool	   *nulls;
476 			int			nelems;
477 			/* is it GREATEST or LEAST? */
478 			MinMaxOp	op;
479 			/* lookup and call data for comparison function */
480 			FmgrInfo   *finfo;
481 			FunctionCallInfo fcinfo_data;
482 		}			minmax;
483 
484 		/* for EEOP_FIELDSELECT */
485 		struct
486 		{
487 			AttrNumber	fieldnum;	/* field number to extract */
488 			Oid			resulttype; /* field's type */
489 			/* cached descriptor for composite type - filled at runtime */
490 			ExprEvalRowtypeCache rowcache;
491 		}			fieldselect;
492 
493 		/* for EEOP_FIELDSTORE_DEFORM / FIELDSTORE_FORM */
494 		struct
495 		{
496 			/* original expression node */
497 			FieldStore *fstore;
498 
499 			/* cached descriptor for composite type - filled at runtime */
500 			/* note that a DEFORM and FORM pair share the same cache */
501 			ExprEvalRowtypeCache *rowcache;
502 
503 			/* workspace for column values */
504 			Datum	   *values;
505 			bool	   *nulls;
506 			int			ncolumns;
507 		}			fieldstore;
508 
509 		/* for EEOP_SBSREF_SUBSCRIPT */
510 		struct
511 		{
512 			/* too big to have inline */
513 			struct SubscriptingRefState *state;
514 			int			off;	/* 0-based index of this subscript */
515 			bool		isupper;	/* is it upper or lower subscript? */
516 			int			jumpdone;	/* jump here on null */
517 		}			sbsref_subscript;
518 
519 		/* for EEOP_SBSREF_OLD / ASSIGN / FETCH */
520 		struct
521 		{
522 			/* too big to have inline */
523 			struct SubscriptingRefState *state;
524 		}			sbsref;
525 
526 		/* for EEOP_DOMAIN_NOTNULL / DOMAIN_CHECK */
527 		struct
528 		{
529 			/* name of constraint */
530 			char	   *constraintname;
531 			/* where the result of a CHECK constraint will be stored */
532 			Datum	   *checkvalue;
533 			bool	   *checknull;
534 			/* OID of domain type */
535 			Oid			resulttype;
536 		}			domaincheck;
537 
538 		/* for EEOP_CONVERT_ROWTYPE */
539 		struct
540 		{
541 			Oid			inputtype;	/* input composite type */
542 			Oid			outputtype; /* output composite type */
543 			/* these three fields are filled at runtime: */
544 			ExprEvalRowtypeCache *incache;	/* cache for input type */
545 			ExprEvalRowtypeCache *outcache; /* cache for output type */
546 			TupleConversionMap *map;	/* column mapping */
547 		}			convert_rowtype;
548 
549 		/* for EEOP_SCALARARRAYOP */
550 		struct
551 		{
552 			/* element_type/typlen/typbyval/typalign are filled at runtime */
553 			Oid			element_type;	/* InvalidOid if not yet filled */
554 			bool		useOr;	/* use OR or AND semantics? */
555 			int16		typlen; /* array element type storage info */
556 			bool		typbyval;
557 			char		typalign;
558 			FmgrInfo   *finfo;	/* function's lookup data */
559 			FunctionCallInfo fcinfo_data;	/* arguments etc */
560 			/* faster to access without additional indirection: */
561 			PGFunction	fn_addr;	/* actual call address */
562 		}			scalararrayop;
563 
564 		/* for EEOP_XMLEXPR */
565 		struct
566 		{
567 			XmlExpr    *xexpr;	/* original expression node */
568 			/* workspace for evaluating named args, if any */
569 			Datum	   *named_argvalue;
570 			bool	   *named_argnull;
571 			/* workspace for evaluating unnamed args, if any */
572 			Datum	   *argvalue;
573 			bool	   *argnull;
574 		}			xmlexpr;
575 
576 		/* for EEOP_AGGREF */
577 		struct
578 		{
579 			/* out-of-line state, modified by nodeAgg.c */
580 			AggrefExprState *astate;
581 		}			aggref;
582 
583 		/* for EEOP_GROUPING_FUNC */
584 		struct
585 		{
586 			AggState   *parent; /* parent Agg */
587 			List	   *clauses;	/* integer list of column numbers */
588 		}			grouping_func;
589 
590 		/* for EEOP_WINDOW_FUNC */
591 		struct
592 		{
593 			/* out-of-line state, modified by nodeWindowFunc.c */
594 			WindowFuncExprState *wfstate;
595 		}			window_func;
596 
597 		/* for EEOP_SUBPLAN */
598 		struct
599 		{
600 			/* out-of-line state, created by nodeSubplan.c */
601 			SubPlanState *sstate;
602 		}			subplan;
603 
604 		/* for EEOP_ALTERNATIVE_SUBPLAN */
605 		struct
606 		{
607 			/* out-of-line state, created by nodeSubplan.c */
608 			AlternativeSubPlanState *asstate;
609 		}			alternative_subplan;
610 
611 		/* for EEOP_AGG_*DESERIALIZE */
612 		struct
613 		{
614 			AggState   *aggstate;
615 			FunctionCallInfo fcinfo_data;
616 			int			jumpnull;
617 		}			agg_deserialize;
618 
619 		/* for EEOP_AGG_STRICT_INPUT_CHECK_NULLS / STRICT_INPUT_CHECK_ARGS */
620 		struct
621 		{
622 			/*
623 			 * For EEOP_AGG_STRICT_INPUT_CHECK_ARGS args contains pointers to
624 			 * the NullableDatums that need to be checked for NULLs.
625 			 *
626 			 * For EEOP_AGG_STRICT_INPUT_CHECK_NULLS nulls contains pointers
627 			 * to booleans that need to be checked for NULLs.
628 			 *
629 			 * Both cases currently need to exist because sometimes the
630 			 * to-be-checked nulls are in TupleTableSlot.isnull array, and
631 			 * sometimes in FunctionCallInfoBaseData.args[i].isnull.
632 			 */
633 			NullableDatum *args;
634 			bool	   *nulls;
635 			int			nargs;
636 			int			jumpnull;
637 		}			agg_strict_input_check;
638 
639 		/* for EEOP_AGG_INIT_TRANS */
640 		struct
641 		{
642 			AggState   *aggstate;
643 			AggStatePerTrans pertrans;
644 			ExprContext *aggcontext;
645 			int			setno;
646 			int			transno;
647 			int			setoff;
648 			int			jumpnull;
649 		}			agg_init_trans;
650 
651 		/* for EEOP_AGG_STRICT_TRANS_CHECK */
652 		struct
653 		{
654 			AggState   *aggstate;
655 			int			setno;
656 			int			transno;
657 			int			setoff;
658 			int			jumpnull;
659 		}			agg_strict_trans_check;
660 
661 		/* for EEOP_AGG_{PLAIN,ORDERED}_TRANS* */
662 		struct
663 		{
664 			AggState   *aggstate;
665 			AggStatePerTrans pertrans;
666 			ExprContext *aggcontext;
667 			int			setno;
668 			int			transno;
669 			int			setoff;
670 		}			agg_trans;
671 	}			d;
672 } ExprEvalStep;
673 
674 
675 /* Non-inline data for container operations */
676 typedef struct SubscriptingRefState
677 {
678 	bool		isassignment;	/* is it assignment, or just fetch? */
679 
680 	Oid			refelemtype;	/* OID of the container element type */
681 	int16		refattrlength;	/* typlen of container type */
682 	int16		refelemlength;	/* typlen of the container element type */
683 	bool		refelembyval;	/* is the element type pass-by-value? */
684 	char		refelemalign;	/* typalign of the element type */
685 
686 	/* numupper and upperprovided[] are filled at compile time */
687 	/* at runtime, extracted subscript datums get stored in upperindex[] */
688 	int			numupper;
689 	bool		upperprovided[MAXDIM];
690 	int			upperindex[MAXDIM];
691 
692 	/* similarly for lower indexes, if any */
693 	int			numlower;
694 	bool		lowerprovided[MAXDIM];
695 	int			lowerindex[MAXDIM];
696 
697 	/* subscript expressions get evaluated into here */
698 	Datum		subscriptvalue;
699 	bool		subscriptnull;
700 
701 	/* for assignment, new value to assign is evaluated into here */
702 	Datum		replacevalue;
703 	bool		replacenull;
704 
705 	/* if we have a nested assignment, SBSREF_OLD puts old value here */
706 	Datum		prevvalue;
707 	bool		prevnull;
708 } SubscriptingRefState;
709 
710 
711 /* functions in execExpr.c */
712 extern void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s);
713 
714 /* functions in execExprInterp.c */
715 extern void ExecReadyInterpretedExpr(ExprState *state);
716 extern ExprEvalOp ExecEvalStepOp(ExprState *state, ExprEvalStep *op);
717 
718 extern Datum ExecInterpExprStillValid(ExprState *state, ExprContext *econtext, bool *isNull);
719 extern void CheckExprStillValid(ExprState *state, ExprContext *econtext);
720 
721 /*
722  * Non fast-path execution functions. These are externs instead of statics in
723  * execExprInterp.c, because that allows them to be used by other methods of
724  * expression evaluation, reducing code duplication.
725  */
726 extern void ExecEvalFuncExprFusage(ExprState *state, ExprEvalStep *op,
727 								   ExprContext *econtext);
728 extern void ExecEvalFuncExprStrictFusage(ExprState *state, ExprEvalStep *op,
729 										 ExprContext *econtext);
730 extern void ExecEvalParamExec(ExprState *state, ExprEvalStep *op,
731 							  ExprContext *econtext);
732 extern void ExecEvalParamExtern(ExprState *state, ExprEvalStep *op,
733 								ExprContext *econtext);
734 extern void ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op);
735 extern void ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op);
736 extern void ExecEvalNextValueExpr(ExprState *state, ExprEvalStep *op);
737 extern void ExecEvalRowNull(ExprState *state, ExprEvalStep *op,
738 							ExprContext *econtext);
739 extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op,
740 							   ExprContext *econtext);
741 extern void ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op);
742 extern void ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op,
743 								ExprContext *econtext);
744 extern void ExecEvalRow(ExprState *state, ExprEvalStep *op);
745 extern void ExecEvalMinMax(ExprState *state, ExprEvalStep *op);
746 extern void ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op,
747 								ExprContext *econtext);
748 extern void ExecEvalFieldStoreDeForm(ExprState *state, ExprEvalStep *op,
749 									 ExprContext *econtext);
750 extern void ExecEvalFieldStoreForm(ExprState *state, ExprEvalStep *op,
751 								   ExprContext *econtext);
752 extern bool ExecEvalSubscriptingRef(ExprState *state, ExprEvalStep *op);
753 extern void ExecEvalSubscriptingRefFetch(ExprState *state, ExprEvalStep *op);
754 extern void ExecEvalSubscriptingRefOld(ExprState *state, ExprEvalStep *op);
755 extern void ExecEvalSubscriptingRefAssign(ExprState *state, ExprEvalStep *op);
756 extern void ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op,
757 								   ExprContext *econtext);
758 extern void ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op);
759 extern void ExecEvalConstraintNotNull(ExprState *state, ExprEvalStep *op);
760 extern void ExecEvalConstraintCheck(ExprState *state, ExprEvalStep *op);
761 extern void ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op);
762 extern void ExecEvalGroupingFunc(ExprState *state, ExprEvalStep *op);
763 extern void ExecEvalSubPlan(ExprState *state, ExprEvalStep *op,
764 							ExprContext *econtext);
765 extern void ExecEvalAlternativeSubPlan(ExprState *state, ExprEvalStep *op,
766 									   ExprContext *econtext);
767 extern void ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op,
768 								ExprContext *econtext);
769 extern void ExecEvalSysVar(ExprState *state, ExprEvalStep *op,
770 						   ExprContext *econtext, TupleTableSlot *slot);
771 
772 extern void ExecAggInitGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup);
773 extern Datum ExecAggTransReparent(AggState *aggstate, AggStatePerTrans pertrans,
774 								  Datum newValue, bool newValueIsNull,
775 								  Datum oldValue, bool oldValueIsNull);
776 extern void ExecEvalAggOrderedTransDatum(ExprState *state, ExprEvalStep *op,
777 										 ExprContext *econtext);
778 extern void ExecEvalAggOrderedTransTuple(ExprState *state, ExprEvalStep *op,
779 										 ExprContext *econtext);
780 
781 #endif							/* EXEC_EXPR_H */
782