1 | /*------------------------------------------------------------------------- |
2 | * |
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 | /* |
36 | * Discriminator for ExprEvalSteps. |
37 | * |
38 | * Identifies the operation to be executed and which member in the |
39 | * ExprEvalStep->d union is valid. |
40 | * |
41 | * The order of entries needs to be kept in sync with the dispatch_table[] |
42 | * array in execExprInterp.c:ExecInterpExpr(). |
43 | */ |
44 | typedef enum ExprEvalOp |
45 | { |
46 | /* entire expression has been evaluated completely, return */ |
47 | EEOP_DONE, |
48 | |
49 | /* apply slot_getsomeattrs on corresponding tuple slot */ |
50 | EEOP_INNER_FETCHSOME, |
51 | EEOP_OUTER_FETCHSOME, |
52 | EEOP_SCAN_FETCHSOME, |
53 | |
54 | /* compute non-system Var value */ |
55 | EEOP_INNER_VAR, |
56 | EEOP_OUTER_VAR, |
57 | EEOP_SCAN_VAR, |
58 | |
59 | /* compute system Var value */ |
60 | EEOP_INNER_SYSVAR, |
61 | EEOP_OUTER_SYSVAR, |
62 | EEOP_SCAN_SYSVAR, |
63 | |
64 | /* compute wholerow Var */ |
65 | EEOP_WHOLEROW, |
66 | |
67 | /* |
68 | * Compute non-system Var value, assign it into ExprState's resultslot. |
69 | * These are not used if a CheckVarSlotCompatibility() check would be |
70 | * needed. |
71 | */ |
72 | EEOP_ASSIGN_INNER_VAR, |
73 | EEOP_ASSIGN_OUTER_VAR, |
74 | EEOP_ASSIGN_SCAN_VAR, |
75 | |
76 | /* assign ExprState's resvalue/resnull to a column of its resultslot */ |
77 | EEOP_ASSIGN_TMP, |
78 | /* ditto, applying MakeExpandedObjectReadOnly() */ |
79 | EEOP_ASSIGN_TMP_MAKE_RO, |
80 | |
81 | /* evaluate Const value */ |
82 | EEOP_CONST, |
83 | |
84 | /* |
85 | * Evaluate function call (including OpExprs etc). For speed, we |
86 | * distinguish in the opcode whether the function is strict and/or |
87 | * requires usage stats tracking. |
88 | */ |
89 | EEOP_FUNCEXPR, |
90 | EEOP_FUNCEXPR_STRICT, |
91 | EEOP_FUNCEXPR_FUSAGE, |
92 | EEOP_FUNCEXPR_STRICT_FUSAGE, |
93 | |
94 | /* |
95 | * Evaluate boolean AND expression, one step per subexpression. FIRST/LAST |
96 | * subexpressions are special-cased for performance. Since AND always has |
97 | * at least two subexpressions, FIRST and LAST never apply to the same |
98 | * subexpression. |
99 | */ |
100 | EEOP_BOOL_AND_STEP_FIRST, |
101 | EEOP_BOOL_AND_STEP, |
102 | EEOP_BOOL_AND_STEP_LAST, |
103 | |
104 | /* similarly for boolean OR expression */ |
105 | EEOP_BOOL_OR_STEP_FIRST, |
106 | EEOP_BOOL_OR_STEP, |
107 | EEOP_BOOL_OR_STEP_LAST, |
108 | |
109 | /* evaluate boolean NOT expression */ |
110 | EEOP_BOOL_NOT_STEP, |
111 | |
112 | /* simplified version of BOOL_AND_STEP for use by ExecQual() */ |
113 | EEOP_QUAL, |
114 | |
115 | /* unconditional jump to another step */ |
116 | EEOP_JUMP, |
117 | |
118 | /* conditional jumps based on current result value */ |
119 | EEOP_JUMP_IF_NULL, |
120 | EEOP_JUMP_IF_NOT_NULL, |
121 | EEOP_JUMP_IF_NOT_TRUE, |
122 | |
123 | /* perform NULL tests for scalar values */ |
124 | EEOP_NULLTEST_ISNULL, |
125 | EEOP_NULLTEST_ISNOTNULL, |
126 | |
127 | /* perform NULL tests for row values */ |
128 | EEOP_NULLTEST_ROWISNULL, |
129 | EEOP_NULLTEST_ROWISNOTNULL, |
130 | |
131 | /* evaluate a BooleanTest expression */ |
132 | EEOP_BOOLTEST_IS_TRUE, |
133 | EEOP_BOOLTEST_IS_NOT_TRUE, |
134 | EEOP_BOOLTEST_IS_FALSE, |
135 | EEOP_BOOLTEST_IS_NOT_FALSE, |
136 | |
137 | /* evaluate PARAM_EXEC/EXTERN parameters */ |
138 | EEOP_PARAM_EXEC, |
139 | EEOP_PARAM_EXTERN, |
140 | EEOP_PARAM_CALLBACK, |
141 | |
142 | /* return CaseTestExpr value */ |
143 | EEOP_CASE_TESTVAL, |
144 | |
145 | /* apply MakeExpandedObjectReadOnly() to target value */ |
146 | EEOP_MAKE_READONLY, |
147 | |
148 | /* evaluate assorted special-purpose expression types */ |
149 | EEOP_IOCOERCE, |
150 | EEOP_DISTINCT, |
151 | EEOP_NOT_DISTINCT, |
152 | EEOP_NULLIF, |
153 | EEOP_SQLVALUEFUNCTION, |
154 | EEOP_CURRENTOFEXPR, |
155 | EEOP_NEXTVALUEEXPR, |
156 | EEOP_ARRAYEXPR, |
157 | EEOP_ARRAYCOERCE, |
158 | EEOP_ROW, |
159 | |
160 | /* |
161 | * Compare two individual elements of each of two compared ROW() |
162 | * expressions. Skip to ROWCOMPARE_FINAL if elements are not equal. |
163 | */ |
164 | EEOP_ROWCOMPARE_STEP, |
165 | |
166 | /* evaluate boolean value based on previous ROWCOMPARE_STEP operations */ |
167 | EEOP_ROWCOMPARE_FINAL, |
168 | |
169 | /* evaluate GREATEST() or LEAST() */ |
170 | EEOP_MINMAX, |
171 | |
172 | /* evaluate FieldSelect expression */ |
173 | EEOP_FIELDSELECT, |
174 | |
175 | /* |
176 | * Deform tuple before evaluating new values for individual fields in a |
177 | * FieldStore expression. |
178 | */ |
179 | EEOP_FIELDSTORE_DEFORM, |
180 | |
181 | /* |
182 | * Form the new tuple for a FieldStore expression. Individual fields will |
183 | * have been evaluated into columns of the tuple deformed by the preceding |
184 | * DEFORM step. |
185 | */ |
186 | EEOP_FIELDSTORE_FORM, |
187 | |
188 | /* Process a container subscript; short-circuit expression to NULL if NULL */ |
189 | EEOP_SBSREF_SUBSCRIPT, |
190 | |
191 | /* |
192 | * Compute old container element/slice when a SubscriptingRef assignment |
193 | * expression contains SubscriptingRef/FieldStore subexpressions. Value is |
194 | * accessed using the CaseTest mechanism. |
195 | */ |
196 | EEOP_SBSREF_OLD, |
197 | |
198 | /* compute new value for SubscriptingRef assignment expression */ |
199 | EEOP_SBSREF_ASSIGN, |
200 | |
201 | /* compute element/slice for SubscriptingRef fetch expression */ |
202 | EEOP_SBSREF_FETCH, |
203 | |
204 | /* evaluate value for CoerceToDomainValue */ |
205 | EEOP_DOMAIN_TESTVAL, |
206 | |
207 | /* evaluate a domain's NOT NULL constraint */ |
208 | EEOP_DOMAIN_NOTNULL, |
209 | |
210 | /* evaluate a single domain CHECK constraint */ |
211 | EEOP_DOMAIN_CHECK, |
212 | |
213 | /* evaluate assorted special-purpose expression types */ |
214 | EEOP_CONVERT_ROWTYPE, |
215 | EEOP_SCALARARRAYOP, |
216 | EEOP_XMLEXPR, |
217 | EEOP_AGGREF, |
218 | EEOP_GROUPING_FUNC, |
219 | EEOP_WINDOW_FUNC, |
220 | EEOP_SUBPLAN, |
221 | EEOP_ALTERNATIVE_SUBPLAN, |
222 | |
223 | /* aggregation related nodes */ |
224 | EEOP_AGG_STRICT_DESERIALIZE, |
225 | EEOP_AGG_DESERIALIZE, |
226 | EEOP_AGG_STRICT_INPUT_CHECK_ARGS, |
227 | EEOP_AGG_STRICT_INPUT_CHECK_NULLS, |
228 | EEOP_AGG_INIT_TRANS, |
229 | EEOP_AGG_STRICT_TRANS_CHECK, |
230 | EEOP_AGG_PLAIN_TRANS_BYVAL, |
231 | EEOP_AGG_PLAIN_TRANS, |
232 | EEOP_AGG_ORDERED_TRANS_DATUM, |
233 | EEOP_AGG_ORDERED_TRANS_TUPLE, |
234 | |
235 | /* non-existent operation, used e.g. to check array lengths */ |
236 | EEOP_LAST |
237 | } ExprEvalOp; |
238 | |
239 | |
240 | typedef struct ExprEvalStep |
241 | { |
242 | /* |
243 | * Instruction to be executed. During instruction preparation this is an |
244 | * enum ExprEvalOp, but later it can be changed to some other type, e.g. a |
245 | * pointer for computed goto (that's why it's an intptr_t). |
246 | */ |
247 | intptr_t opcode; |
248 | |
249 | /* where to store the result of this step */ |
250 | Datum *resvalue; |
251 | bool *resnull; |
252 | |
253 | /* |
254 | * Inline data for the operation. Inline data is faster to access, but |
255 | * also bloats the size of all instructions. The union should be kept to |
256 | * no more than 40 bytes on 64-bit systems (so that the entire struct is |
257 | * no more than 64 bytes, a single cacheline on common systems). |
258 | */ |
259 | union |
260 | { |
261 | /* for EEOP_INNER/OUTER/SCAN_FETCHSOME */ |
262 | struct |
263 | { |
264 | /* attribute number up to which to fetch (inclusive) */ |
265 | int last_var; |
266 | /* will the type of slot be the same for every invocation */ |
267 | bool fixed; |
268 | /* tuple descriptor, if known */ |
269 | TupleDesc known_desc; |
270 | /* type of slot, can only be relied upon if fixed is set */ |
271 | const TupleTableSlotOps *kind; |
272 | } fetch; |
273 | |
274 | /* for EEOP_INNER/OUTER/SCAN_[SYS]VAR[_FIRST] */ |
275 | struct |
276 | { |
277 | /* attnum is attr number - 1 for regular VAR ... */ |
278 | /* but it's just the normal (negative) attr number for SYSVAR */ |
279 | int attnum; |
280 | Oid vartype; /* type OID of variable */ |
281 | } var; |
282 | |
283 | /* for EEOP_WHOLEROW */ |
284 | struct |
285 | { |
286 | Var *var; /* original Var node in plan tree */ |
287 | bool first; /* first time through, need to initialize? */ |
288 | bool slow; /* need runtime check for nulls? */ |
289 | TupleDesc tupdesc; /* descriptor for resulting tuples */ |
290 | JunkFilter *junkFilter; /* JunkFilter to remove resjunk cols */ |
291 | } wholerow; |
292 | |
293 | /* for EEOP_ASSIGN_*_VAR */ |
294 | struct |
295 | { |
296 | /* target index in ExprState->resultslot->tts_values/nulls */ |
297 | int resultnum; |
298 | /* source attribute number - 1 */ |
299 | int attnum; |
300 | } assign_var; |
301 | |
302 | /* for EEOP_ASSIGN_TMP[_MAKE_RO] */ |
303 | struct |
304 | { |
305 | /* target index in ExprState->resultslot->tts_values/nulls */ |
306 | int resultnum; |
307 | } assign_tmp; |
308 | |
309 | /* for EEOP_CONST */ |
310 | struct |
311 | { |
312 | /* constant's value */ |
313 | Datum value; |
314 | bool isnull; |
315 | } constval; |
316 | |
317 | /* for EEOP_FUNCEXPR_* / NULLIF / DISTINCT */ |
318 | struct |
319 | { |
320 | FmgrInfo *finfo; /* function's lookup data */ |
321 | FunctionCallInfo fcinfo_data; /* arguments etc */ |
322 | /* faster to access without additional indirection: */ |
323 | PGFunction fn_addr; /* actual call address */ |
324 | int nargs; /* number of arguments */ |
325 | } func; |
326 | |
327 | /* for EEOP_BOOL_*_STEP */ |
328 | struct |
329 | { |
330 | bool *anynull; /* track if any input was NULL */ |
331 | int jumpdone; /* jump here if result determined */ |
332 | } boolexpr; |
333 | |
334 | /* for EEOP_QUAL */ |
335 | struct |
336 | { |
337 | int jumpdone; /* jump here on false or null */ |
338 | } qualexpr; |
339 | |
340 | /* for EEOP_JUMP[_CONDITION] */ |
341 | struct |
342 | { |
343 | int jumpdone; /* target instruction's index */ |
344 | } jump; |
345 | |
346 | /* for EEOP_NULLTEST_ROWIS[NOT]NULL */ |
347 | struct |
348 | { |
349 | /* cached tupdesc pointer - filled at runtime */ |
350 | TupleDesc argdesc; |
351 | } nulltest_row; |
352 | |
353 | /* for EEOP_PARAM_EXEC/EXTERN */ |
354 | struct |
355 | { |
356 | int paramid; /* numeric ID for parameter */ |
357 | Oid paramtype; /* OID of parameter's datatype */ |
358 | } param; |
359 | |
360 | /* for EEOP_PARAM_CALLBACK */ |
361 | struct |
362 | { |
363 | ExecEvalSubroutine paramfunc; /* add-on evaluation subroutine */ |
364 | void *paramarg; /* private data for same */ |
365 | int paramid; /* numeric ID for parameter */ |
366 | Oid paramtype; /* OID of parameter's datatype */ |
367 | } cparam; |
368 | |
369 | /* for EEOP_CASE_TESTVAL/DOMAIN_TESTVAL */ |
370 | struct |
371 | { |
372 | Datum *value; /* value to return */ |
373 | bool *isnull; |
374 | } casetest; |
375 | |
376 | /* for EEOP_MAKE_READONLY */ |
377 | struct |
378 | { |
379 | Datum *value; /* value to coerce to read-only */ |
380 | bool *isnull; |
381 | } make_readonly; |
382 | |
383 | /* for EEOP_IOCOERCE */ |
384 | struct |
385 | { |
386 | /* lookup and call info for source type's output function */ |
387 | FmgrInfo *finfo_out; |
388 | FunctionCallInfo fcinfo_data_out; |
389 | /* lookup and call info for result type's input function */ |
390 | FmgrInfo *finfo_in; |
391 | FunctionCallInfo fcinfo_data_in; |
392 | } iocoerce; |
393 | |
394 | /* for EEOP_SQLVALUEFUNCTION */ |
395 | struct |
396 | { |
397 | SQLValueFunction *svf; |
398 | } sqlvaluefunction; |
399 | |
400 | /* for EEOP_NEXTVALUEEXPR */ |
401 | struct |
402 | { |
403 | Oid seqid; |
404 | Oid seqtypid; |
405 | } nextvalueexpr; |
406 | |
407 | /* for EEOP_ARRAYEXPR */ |
408 | struct |
409 | { |
410 | Datum *elemvalues; /* element values get stored here */ |
411 | bool *elemnulls; |
412 | int nelems; /* length of the above arrays */ |
413 | Oid elemtype; /* array element type */ |
414 | int16 elemlength; /* typlen of the array element type */ |
415 | bool elembyval; /* is the element type pass-by-value? */ |
416 | char elemalign; /* typalign of the element type */ |
417 | bool multidims; /* is array expression multi-D? */ |
418 | } arrayexpr; |
419 | |
420 | /* for EEOP_ARRAYCOERCE */ |
421 | struct |
422 | { |
423 | ExprState *elemexprstate; /* null if no per-element work */ |
424 | Oid resultelemtype; /* element type of result array */ |
425 | struct ArrayMapState *amstate; /* workspace for array_map */ |
426 | } arraycoerce; |
427 | |
428 | /* for EEOP_ROW */ |
429 | struct |
430 | { |
431 | TupleDesc tupdesc; /* descriptor for result tuples */ |
432 | /* workspace for the values constituting the row: */ |
433 | Datum *elemvalues; |
434 | bool *elemnulls; |
435 | } row; |
436 | |
437 | /* for EEOP_ROWCOMPARE_STEP */ |
438 | struct |
439 | { |
440 | /* lookup and call data for column comparison function */ |
441 | FmgrInfo *finfo; |
442 | FunctionCallInfo fcinfo_data; |
443 | PGFunction fn_addr; |
444 | /* target for comparison resulting in NULL */ |
445 | int jumpnull; |
446 | /* target for comparison yielding inequality */ |
447 | int jumpdone; |
448 | } rowcompare_step; |
449 | |
450 | /* for EEOP_ROWCOMPARE_FINAL */ |
451 | struct |
452 | { |
453 | RowCompareType rctype; |
454 | } rowcompare_final; |
455 | |
456 | /* for EEOP_MINMAX */ |
457 | struct |
458 | { |
459 | /* workspace for argument values */ |
460 | Datum *values; |
461 | bool *nulls; |
462 | int nelems; |
463 | /* is it GREATEST or LEAST? */ |
464 | MinMaxOp op; |
465 | /* lookup and call data for comparison function */ |
466 | FmgrInfo *finfo; |
467 | FunctionCallInfo fcinfo_data; |
468 | } minmax; |
469 | |
470 | /* for EEOP_FIELDSELECT */ |
471 | struct |
472 | { |
473 | AttrNumber fieldnum; /* field number to extract */ |
474 | Oid resulttype; /* field's type */ |
475 | /* cached tupdesc pointer - filled at runtime */ |
476 | TupleDesc argdesc; |
477 | } fieldselect; |
478 | |
479 | /* for EEOP_FIELDSTORE_DEFORM / FIELDSTORE_FORM */ |
480 | struct |
481 | { |
482 | /* original expression node */ |
483 | FieldStore *fstore; |
484 | |
485 | /* cached tupdesc pointer - filled at runtime */ |
486 | /* note that a DEFORM and FORM pair share the same tupdesc */ |
487 | TupleDesc *argdesc; |
488 | |
489 | /* workspace for column values */ |
490 | Datum *values; |
491 | bool *nulls; |
492 | int ncolumns; |
493 | } fieldstore; |
494 | |
495 | /* for EEOP_SBSREF_SUBSCRIPT */ |
496 | struct |
497 | { |
498 | /* too big to have inline */ |
499 | struct SubscriptingRefState *state; |
500 | int off; /* 0-based index of this subscript */ |
501 | bool isupper; /* is it upper or lower subscript? */ |
502 | int jumpdone; /* jump here on null */ |
503 | } sbsref_subscript; |
504 | |
505 | /* for EEOP_SBSREF_OLD / ASSIGN / FETCH */ |
506 | struct |
507 | { |
508 | /* too big to have inline */ |
509 | struct SubscriptingRefState *state; |
510 | } sbsref; |
511 | |
512 | /* for EEOP_DOMAIN_NOTNULL / DOMAIN_CHECK */ |
513 | struct |
514 | { |
515 | /* name of constraint */ |
516 | char *constraintname; |
517 | /* where the result of a CHECK constraint will be stored */ |
518 | Datum *checkvalue; |
519 | bool *checknull; |
520 | /* OID of domain type */ |
521 | Oid resulttype; |
522 | } domaincheck; |
523 | |
524 | /* for EEOP_CONVERT_ROWTYPE */ |
525 | struct |
526 | { |
527 | ConvertRowtypeExpr *convert; /* original expression */ |
528 | /* these three fields are filled at runtime: */ |
529 | TupleDesc indesc; /* tupdesc for input type */ |
530 | TupleDesc outdesc; /* tupdesc for output type */ |
531 | TupleConversionMap *map; /* column mapping */ |
532 | bool initialized; /* initialized for current types? */ |
533 | } convert_rowtype; |
534 | |
535 | /* for EEOP_SCALARARRAYOP */ |
536 | struct |
537 | { |
538 | /* element_type/typlen/typbyval/typalign are filled at runtime */ |
539 | Oid element_type; /* InvalidOid if not yet filled */ |
540 | bool useOr; /* use OR or AND semantics? */ |
541 | int16 typlen; /* array element type storage info */ |
542 | bool typbyval; |
543 | char typalign; |
544 | FmgrInfo *finfo; /* function's lookup data */ |
545 | FunctionCallInfo fcinfo_data; /* arguments etc */ |
546 | /* faster to access without additional indirection: */ |
547 | PGFunction fn_addr; /* actual call address */ |
548 | } scalararrayop; |
549 | |
550 | /* for EEOP_XMLEXPR */ |
551 | struct |
552 | { |
553 | XmlExpr *xexpr; /* original expression node */ |
554 | /* workspace for evaluating named args, if any */ |
555 | Datum *named_argvalue; |
556 | bool *named_argnull; |
557 | /* workspace for evaluating unnamed args, if any */ |
558 | Datum *argvalue; |
559 | bool *argnull; |
560 | } xmlexpr; |
561 | |
562 | /* for EEOP_AGGREF */ |
563 | struct |
564 | { |
565 | /* out-of-line state, modified by nodeAgg.c */ |
566 | AggrefExprState *astate; |
567 | } aggref; |
568 | |
569 | /* for EEOP_GROUPING_FUNC */ |
570 | struct |
571 | { |
572 | AggState *parent; /* parent Agg */ |
573 | List *clauses; /* integer list of column numbers */ |
574 | } grouping_func; |
575 | |
576 | /* for EEOP_WINDOW_FUNC */ |
577 | struct |
578 | { |
579 | /* out-of-line state, modified by nodeWindowFunc.c */ |
580 | WindowFuncExprState *wfstate; |
581 | } window_func; |
582 | |
583 | /* for EEOP_SUBPLAN */ |
584 | struct |
585 | { |
586 | /* out-of-line state, created by nodeSubplan.c */ |
587 | SubPlanState *sstate; |
588 | } subplan; |
589 | |
590 | /* for EEOP_ALTERNATIVE_SUBPLAN */ |
591 | struct |
592 | { |
593 | /* out-of-line state, created by nodeSubplan.c */ |
594 | AlternativeSubPlanState *asstate; |
595 | } alternative_subplan; |
596 | |
597 | /* for EEOP_AGG_*DESERIALIZE */ |
598 | struct |
599 | { |
600 | AggState *aggstate; |
601 | FunctionCallInfo fcinfo_data; |
602 | int jumpnull; |
603 | } agg_deserialize; |
604 | |
605 | /* for EEOP_AGG_STRICT_INPUT_CHECK_NULLS / STRICT_INPUT_CHECK_ARGS */ |
606 | struct |
607 | { |
608 | /* |
609 | * For EEOP_AGG_STRICT_INPUT_CHECK_ARGS args contains pointers to |
610 | * the NullableDatums that need to be checked for NULLs. |
611 | * |
612 | * For EEOP_AGG_STRICT_INPUT_CHECK_NULLS nulls contains pointers |
613 | * to booleans that need to be checked for NULLs. |
614 | * |
615 | * Both cases currently need to exist because sometimes the |
616 | * to-be-checked nulls are in TupleTableSlot.isnull array, and |
617 | * sometimes in FunctionCallInfoBaseData.args[i].isnull. |
618 | */ |
619 | NullableDatum *args; |
620 | bool *nulls; |
621 | int nargs; |
622 | int jumpnull; |
623 | } agg_strict_input_check; |
624 | |
625 | /* for EEOP_AGG_INIT_TRANS */ |
626 | struct |
627 | { |
628 | AggState *aggstate; |
629 | AggStatePerTrans pertrans; |
630 | ExprContext *aggcontext; |
631 | int setno; |
632 | int transno; |
633 | int setoff; |
634 | int jumpnull; |
635 | } agg_init_trans; |
636 | |
637 | /* for EEOP_AGG_STRICT_TRANS_CHECK */ |
638 | struct |
639 | { |
640 | AggState *aggstate; |
641 | int setno; |
642 | int transno; |
643 | int setoff; |
644 | int jumpnull; |
645 | } agg_strict_trans_check; |
646 | |
647 | /* for EEOP_AGG_{PLAIN,ORDERED}_TRANS* */ |
648 | struct |
649 | { |
650 | AggState *aggstate; |
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 | extern Datum ExecAggTransReparent(AggState *aggstate, AggStatePerTrans pertrans, |
760 | Datum newValue, bool newValueIsNull, |
761 | Datum oldValue, bool oldValueIsNull); |
762 | extern void ExecEvalAggOrderedTransDatum(ExprState *state, ExprEvalStep *op, |
763 | ExprContext *econtext); |
764 | extern void ExecEvalAggOrderedTransTuple(ExprState *state, ExprEvalStep *op, |
765 | ExprContext *econtext); |
766 | |
767 | #endif /* EXEC_EXPR_H */ |
768 | |