PostgreSQL Source Code  git master
execExpr.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * execExpr.c
4  * Expression evaluation infrastructure.
5  *
6  * During executor startup, we compile each expression tree (which has
7  * previously been processed by the parser and planner) into an ExprState,
8  * using ExecInitExpr() et al. This converts the tree into a flat array
9  * of ExprEvalSteps, which may be thought of as instructions in a program.
10  * At runtime, we'll execute steps, starting with the first, until we reach
11  * an EEOP_DONE opcode.
12  *
13  * This file contains the "compilation" logic. It is independent of the
14  * specific execution technology we use (switch statement, computed goto,
15  * JIT compilation, etc).
16  *
17  * See src/backend/executor/README for some background, specifically the
18  * "Expression Trees and ExprState nodes", "Expression Initialization",
19  * and "Expression Evaluation" sections.
20  *
21  *
22  * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
23  * Portions Copyright (c) 1994, Regents of the University of California
24  *
25  *
26  * IDENTIFICATION
27  * src/backend/executor/execExpr.c
28  *
29  *-------------------------------------------------------------------------
30  */
31 #include "postgres.h"
32 
33 #include "access/nbtree.h"
34 #include "catalog/objectaccess.h"
35 #include "catalog/pg_type.h"
36 #include "executor/execExpr.h"
37 #include "executor/nodeSubplan.h"
38 #include "funcapi.h"
39 #include "jit/jit.h"
40 #include "miscadmin.h"
41 #include "nodes/makefuncs.h"
42 #include "nodes/nodeFuncs.h"
43 #include "optimizer/optimizer.h"
44 #include "pgstat.h"
45 #include "utils/array.h"
46 #include "utils/builtins.h"
47 #include "utils/datum.h"
48 #include "utils/lsyscache.h"
49 #include "utils/typcache.h"
50 
51 
52 typedef struct LastAttnumInfo
53 {
58 
59 static void ExecReadyExpr(ExprState *state);
60 static void ExecInitExprRec(Expr *node, ExprState *state,
61  Datum *resv, bool *resnull);
62 static void ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args,
63  Oid funcid, Oid inputcollid,
64  ExprState *state);
65 static void ExecInitExprSlots(ExprState *state, Node *node);
66 static void ExecPushExprSlots(ExprState *state, LastAttnumInfo *info);
67 static bool get_last_attnums_walker(Node *node, LastAttnumInfo *info);
69 static void ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable,
70  ExprState *state);
71 static void ExecInitSubscriptingRef(ExprEvalStep *scratch,
72  SubscriptingRef *sbsref,
74  Datum *resv, bool *resnull);
75 static bool isAssignmentIndirectionExpr(Expr *expr);
76 static void ExecInitCoerceToDomain(ExprEvalStep *scratch, CoerceToDomain *ctest,
78  Datum *resv, bool *resnull);
79 static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
80  ExprEvalStep *scratch,
81  FunctionCallInfo fcinfo, AggStatePerTrans pertrans,
82  int transno, int setno, int setoff, bool ishash);
83 
84 
85 /*
86  * ExecInitExpr: prepare an expression tree for execution
87  *
88  * This function builds and returns an ExprState implementing the given
89  * Expr node tree. The return ExprState can then be handed to ExecEvalExpr
90  * for execution. Because the Expr tree itself is read-only as far as
91  * ExecInitExpr and ExecEvalExpr are concerned, several different executions
92  * of the same plan tree can occur concurrently. (But note that an ExprState
93  * does mutate at runtime, so it can't be re-used concurrently.)
94  *
95  * This must be called in a memory context that will last as long as repeated
96  * executions of the expression are needed. Typically the context will be
97  * the same as the per-query context of the associated ExprContext.
98  *
99  * Any Aggref, WindowFunc, or SubPlan nodes found in the tree are added to
100  * the lists of such nodes held by the parent PlanState (or more accurately,
101  * the AggrefExprState etc. nodes created for them are added).
102  *
103  * Note: there is no ExecEndExpr function; we assume that any resource
104  * cleanup needed will be handled by just releasing the memory context
105  * in which the state tree is built. Functions that require additional
106  * cleanup work can register a shutdown callback in the ExprContext.
107  *
108  * 'node' is the root of the expression tree to compile.
109  * 'parent' is the PlanState node that owns the expression.
110  *
111  * 'parent' may be NULL if we are preparing an expression that is not
112  * associated with a plan tree. (If so, it can't have aggs or subplans.)
113  * Such cases should usually come through ExecPrepareExpr, not directly here.
114  *
115  * Also, if 'node' is NULL, we just return NULL. This is convenient for some
116  * callers that may or may not have an expression that needs to be compiled.
117  * Note that a NULL ExprState pointer *cannot* be handed to ExecEvalExpr,
118  * although ExecQual and ExecCheck will accept one (and treat it as "true").
119  */
120 ExprState *
121 ExecInitExpr(Expr *node, PlanState *parent)
122 {
123  ExprState *state;
124  ExprEvalStep scratch = {0};
125 
126  /* Special case: NULL expression produces a NULL ExprState pointer */
127  if (node == NULL)
128  return NULL;
129 
130  /* Initialize ExprState with empty step list */
131  state = makeNode(ExprState);
132  state->expr = node;
133  state->parent = parent;
134  state->ext_params = NULL;
135 
136  /* Insert EEOP_*_FETCHSOME steps as needed */
137  ExecInitExprSlots(state, (Node *) node);
138 
139  /* Compile the expression proper */
140  ExecInitExprRec(node, state, &state->resvalue, &state->resnull);
141 
142  /* Finally, append a DONE step */
143  scratch.opcode = EEOP_DONE;
144  ExprEvalPushStep(state, &scratch);
145 
146  ExecReadyExpr(state);
147 
148  return state;
149 }
150 
151 /*
152  * ExecInitExprWithParams: prepare a standalone expression tree for execution
153  *
154  * This is the same as ExecInitExpr, except that there is no parent PlanState,
155  * and instead we may have a ParamListInfo describing PARAM_EXTERN Params.
156  */
157 ExprState *
159 {
160  ExprState *state;
161  ExprEvalStep scratch = {0};
162 
163  /* Special case: NULL expression produces a NULL ExprState pointer */
164  if (node == NULL)
165  return NULL;
166 
167  /* Initialize ExprState with empty step list */
168  state = makeNode(ExprState);
169  state->expr = node;
170  state->parent = NULL;
171  state->ext_params = ext_params;
172 
173  /* Insert EEOP_*_FETCHSOME steps as needed */
174  ExecInitExprSlots(state, (Node *) node);
175 
176  /* Compile the expression proper */
177  ExecInitExprRec(node, state, &state->resvalue, &state->resnull);
178 
179  /* Finally, append a DONE step */
180  scratch.opcode = EEOP_DONE;
181  ExprEvalPushStep(state, &scratch);
182 
183  ExecReadyExpr(state);
184 
185  return state;
186 }
187 
188 /*
189  * ExecInitQual: prepare a qual for execution by ExecQual
190  *
191  * Prepares for the evaluation of a conjunctive boolean expression (qual list
192  * with implicit AND semantics) that returns true if none of the
193  * subexpressions are false.
194  *
195  * We must return true if the list is empty. Since that's a very common case,
196  * we optimize it a bit further by translating to a NULL ExprState pointer
197  * rather than setting up an ExprState that computes constant TRUE. (Some
198  * especially hot-spot callers of ExecQual detect this and avoid calling
199  * ExecQual at all.)
200  *
201  * If any of the subexpressions yield NULL, then the result of the conjunction
202  * is false. This makes ExecQual primarily useful for evaluating WHERE
203  * clauses, since SQL specifies that tuples with null WHERE results do not
204  * get selected.
205  */
206 ExprState *
207 ExecInitQual(List *qual, PlanState *parent)
208 {
209  ExprState *state;
210  ExprEvalStep scratch = {0};
211  List *adjust_jumps = NIL;
212  ListCell *lc;
213 
214  /* short-circuit (here and in ExecQual) for empty restriction list */
215  if (qual == NIL)
216  return NULL;
217 
218  Assert(IsA(qual, List));
219 
220  state = makeNode(ExprState);
221  state->expr = (Expr *) qual;
222  state->parent = parent;
223  state->ext_params = NULL;
224 
225  /* mark expression as to be used with ExecQual() */
226  state->flags = EEO_FLAG_IS_QUAL;
227 
228  /* Insert EEOP_*_FETCHSOME steps as needed */
229  ExecInitExprSlots(state, (Node *) qual);
230 
231  /*
232  * ExecQual() needs to return false for an expression returning NULL. That
233  * allows us to short-circuit the evaluation the first time a NULL is
234  * encountered. As qual evaluation is a hot-path this warrants using a
235  * special opcode for qual evaluation that's simpler than BOOL_AND (which
236  * has more complex NULL handling).
237  */
238  scratch.opcode = EEOP_QUAL;
239 
240  /*
241  * We can use ExprState's resvalue/resnull as target for each qual expr.
242  */
243  scratch.resvalue = &state->resvalue;
244  scratch.resnull = &state->resnull;
245 
246  foreach(lc, qual)
247  {
248  Expr *node = (Expr *) lfirst(lc);
249 
250  /* first evaluate expression */
251  ExecInitExprRec(node, state, &state->resvalue, &state->resnull);
252 
253  /* then emit EEOP_QUAL to detect if it's false (or null) */
254  scratch.d.qualexpr.jumpdone = -1;
255  ExprEvalPushStep(state, &scratch);
256  adjust_jumps = lappend_int(adjust_jumps,
257  state->steps_len - 1);
258  }
259 
260  /* adjust jump targets */
261  foreach(lc, adjust_jumps)
262  {
263  ExprEvalStep *as = &state->steps[lfirst_int(lc)];
264 
265  Assert(as->opcode == EEOP_QUAL);
266  Assert(as->d.qualexpr.jumpdone == -1);
267  as->d.qualexpr.jumpdone = state->steps_len;
268  }
269 
270  /*
271  * At the end, we don't need to do anything more. The last qual expr must
272  * have yielded TRUE, and since its result is stored in the desired output
273  * location, we're done.
274  */
275  scratch.opcode = EEOP_DONE;
276  ExprEvalPushStep(state, &scratch);
277 
278  ExecReadyExpr(state);
279 
280  return state;
281 }
282 
283 /*
284  * ExecInitCheck: prepare a check constraint for execution by ExecCheck
285  *
286  * This is much like ExecInitQual/ExecQual, except that a null result from
287  * the conjunction is treated as TRUE. This behavior is appropriate for
288  * evaluating CHECK constraints, since SQL specifies that NULL constraint
289  * conditions are not failures.
290  *
291  * Note that like ExecInitQual, this expects input in implicit-AND format.
292  * Users of ExecCheck that have expressions in normal explicit-AND format
293  * can just apply ExecInitExpr to produce suitable input for ExecCheck.
294  */
295 ExprState *
296 ExecInitCheck(List *qual, PlanState *parent)
297 {
298  /* short-circuit (here and in ExecCheck) for empty restriction list */
299  if (qual == NIL)
300  return NULL;
301 
302  Assert(IsA(qual, List));
303 
304  /*
305  * Just convert the implicit-AND list to an explicit AND (if there's more
306  * than one entry), and compile normally. Unlike ExecQual, we can't
307  * short-circuit on NULL results, so the regular AND behavior is needed.
308  */
309  return ExecInitExpr(make_ands_explicit(qual), parent);
310 }
311 
312 /*
313  * Call ExecInitExpr() on a list of expressions, return a list of ExprStates.
314  */
315 List *
317 {
318  List *result = NIL;
319  ListCell *lc;
320 
321  foreach(lc, nodes)
322  {
323  Expr *e = lfirst(lc);
324 
325  result = lappend(result, ExecInitExpr(e, parent));
326  }
327 
328  return result;
329 }
330 
331 /*
332  * ExecBuildProjectionInfo
333  *
334  * Build a ProjectionInfo node for evaluating the given tlist in the given
335  * econtext, and storing the result into the tuple slot. (Caller must have
336  * ensured that tuple slot has a descriptor matching the tlist!)
337  *
338  * inputDesc can be NULL, but if it is not, we check to see whether simple
339  * Vars in the tlist match the descriptor. It is important to provide
340  * inputDesc for relation-scan plan nodes, as a cross check that the relation
341  * hasn't been changed since the plan was made. At higher levels of a plan,
342  * there is no need to recheck.
343  *
344  * This is implemented by internally building an ExprState that performs the
345  * whole projection in one go.
346  *
347  * Caution: before PG v10, the targetList was a list of ExprStates; now it
348  * should be the planner-created targetlist, since we do the compilation here.
349  */
352  ExprContext *econtext,
353  TupleTableSlot *slot,
354  PlanState *parent,
355  TupleDesc inputDesc)
356 {
358  ExprState *state;
359  ExprEvalStep scratch = {0};
360  ListCell *lc;
361 
362  projInfo->pi_exprContext = econtext;
363  /* We embed ExprState into ProjectionInfo instead of doing extra palloc */
364  projInfo->pi_state.tag = T_ExprState;
365  state = &projInfo->pi_state;
366  state->expr = (Expr *) targetList;
367  state->parent = parent;
368  state->ext_params = NULL;
369 
370  state->resultslot = slot;
371 
372  /* Insert EEOP_*_FETCHSOME steps as needed */
373  ExecInitExprSlots(state, (Node *) targetList);
374 
375  /* Now compile each tlist column */
376  foreach(lc, targetList)
377  {
378  TargetEntry *tle = lfirst_node(TargetEntry, lc);
379  Var *variable = NULL;
380  AttrNumber attnum = 0;
381  bool isSafeVar = false;
382 
383  /*
384  * If tlist expression is a safe non-system Var, use the fast-path
385  * ASSIGN_*_VAR opcodes. "Safe" means that we don't need to apply
386  * CheckVarSlotCompatibility() during plan startup. If a source slot
387  * was provided, we make the equivalent tests here; if a slot was not
388  * provided, we assume that no check is needed because we're dealing
389  * with a non-relation-scan-level expression.
390  */
391  if (tle->expr != NULL &&
392  IsA(tle->expr, Var) &&
393  ((Var *) tle->expr)->varattno > 0)
394  {
395  /* Non-system Var, but how safe is it? */
396  variable = (Var *) tle->expr;
397  attnum = variable->varattno;
398 
399  if (inputDesc == NULL)
400  isSafeVar = true; /* can't check, just assume OK */
401  else if (attnum <= inputDesc->natts)
402  {
403  Form_pg_attribute attr = TupleDescAttr(inputDesc, attnum - 1);
404 
405  /*
406  * If user attribute is dropped or has a type mismatch, don't
407  * use ASSIGN_*_VAR. Instead let the normal expression
408  * machinery handle it (which'll possibly error out).
409  */
410  if (!attr->attisdropped && variable->vartype == attr->atttypid)
411  {
412  isSafeVar = true;
413  }
414  }
415  }
416 
417  if (isSafeVar)
418  {
419  /* Fast-path: just generate an EEOP_ASSIGN_*_VAR step */
420  switch (variable->varno)
421  {
422  case INNER_VAR:
423  /* get the tuple from the inner node */
424  scratch.opcode = EEOP_ASSIGN_INNER_VAR;
425  break;
426 
427  case OUTER_VAR:
428  /* get the tuple from the outer node */
429  scratch.opcode = EEOP_ASSIGN_OUTER_VAR;
430  break;
431 
432  /* INDEX_VAR is handled by default case */
433 
434  default:
435  /* get the tuple from the relation being scanned */
436  scratch.opcode = EEOP_ASSIGN_SCAN_VAR;
437  break;
438  }
439 
440  scratch.d.assign_var.attnum = attnum - 1;
441  scratch.d.assign_var.resultnum = tle->resno - 1;
442  ExprEvalPushStep(state, &scratch);
443  }
444  else
445  {
446  /*
447  * Otherwise, compile the column expression normally.
448  *
449  * We can't tell the expression to evaluate directly into the
450  * result slot, as the result slot (and the exprstate for that
451  * matter) can change between executions. We instead evaluate
452  * into the ExprState's resvalue/resnull and then move.
453  */
454  ExecInitExprRec(tle->expr, state,
455  &state->resvalue, &state->resnull);
456 
457  /*
458  * Column might be referenced multiple times in upper nodes, so
459  * force value to R/O - but only if it could be an expanded datum.
460  */
461  if (get_typlen(exprType((Node *) tle->expr)) == -1)
463  else
464  scratch.opcode = EEOP_ASSIGN_TMP;
465  scratch.d.assign_tmp.resultnum = tle->resno - 1;
466  ExprEvalPushStep(state, &scratch);
467  }
468  }
469 
470  scratch.opcode = EEOP_DONE;
471  ExprEvalPushStep(state, &scratch);
472 
473  ExecReadyExpr(state);
474 
475  return projInfo;
476 }
477 
478 /*
479  * ExecPrepareExpr --- initialize for expression execution outside a normal
480  * Plan tree context.
481  *
482  * This differs from ExecInitExpr in that we don't assume the caller is
483  * already running in the EState's per-query context. Also, we run the
484  * passed expression tree through expression_planner() to prepare it for
485  * execution. (In ordinary Plan trees the regular planning process will have
486  * made the appropriate transformations on expressions, but for standalone
487  * expressions this won't have happened.)
488  */
489 ExprState *
490 ExecPrepareExpr(Expr *node, EState *estate)
491 {
492  ExprState *result;
493  MemoryContext oldcontext;
494 
495  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
496 
497  node = expression_planner(node);
498 
499  result = ExecInitExpr(node, NULL);
500 
501  MemoryContextSwitchTo(oldcontext);
502 
503  return result;
504 }
505 
506 /*
507  * ExecPrepareQual --- initialize for qual execution outside a normal
508  * Plan tree context.
509  *
510  * This differs from ExecInitQual in that we don't assume the caller is
511  * already running in the EState's per-query context. Also, we run the
512  * passed expression tree through expression_planner() to prepare it for
513  * execution. (In ordinary Plan trees the regular planning process will have
514  * made the appropriate transformations on expressions, but for standalone
515  * expressions this won't have happened.)
516  */
517 ExprState *
518 ExecPrepareQual(List *qual, EState *estate)
519 {
520  ExprState *result;
521  MemoryContext oldcontext;
522 
523  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
524 
525  qual = (List *) expression_planner((Expr *) qual);
526 
527  result = ExecInitQual(qual, NULL);
528 
529  MemoryContextSwitchTo(oldcontext);
530 
531  return result;
532 }
533 
534 /*
535  * ExecPrepareCheck -- initialize check constraint for execution outside a
536  * normal Plan tree context.
537  *
538  * See ExecPrepareExpr() and ExecInitCheck() for details.
539  */
540 ExprState *
541 ExecPrepareCheck(List *qual, EState *estate)
542 {
543  ExprState *result;
544  MemoryContext oldcontext;
545 
546  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
547 
548  qual = (List *) expression_planner((Expr *) qual);
549 
550  result = ExecInitCheck(qual, NULL);
551 
552  MemoryContextSwitchTo(oldcontext);
553 
554  return result;
555 }
556 
557 /*
558  * Call ExecPrepareExpr() on each member of a list of Exprs, and return
559  * a list of ExprStates.
560  *
561  * See ExecPrepareExpr() for details.
562  */
563 List *
565 {
566  List *result = NIL;
567  MemoryContext oldcontext;
568  ListCell *lc;
569 
570  /* Ensure that the list cell nodes are in the right context too */
571  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
572 
573  foreach(lc, nodes)
574  {
575  Expr *e = (Expr *) lfirst(lc);
576 
577  result = lappend(result, ExecPrepareExpr(e, estate));
578  }
579 
580  MemoryContextSwitchTo(oldcontext);
581 
582  return result;
583 }
584 
585 /*
586  * ExecCheck - evaluate a check constraint
587  *
588  * For check constraints, a null result is taken as TRUE, ie the constraint
589  * passes.
590  *
591  * The check constraint may have been prepared with ExecInitCheck
592  * (possibly via ExecPrepareCheck) if the caller had it in implicit-AND
593  * format, but a regular boolean expression prepared with ExecInitExpr or
594  * ExecPrepareExpr works too.
595  */
596 bool
598 {
599  Datum ret;
600  bool isnull;
601 
602  /* short-circuit (here and in ExecInitCheck) for empty restriction list */
603  if (state == NULL)
604  return true;
605 
606  /* verify that expression was not compiled using ExecInitQual */
607  Assert(!(state->flags & EEO_FLAG_IS_QUAL));
608 
609  ret = ExecEvalExprSwitchContext(state, econtext, &isnull);
610 
611  if (isnull)
612  return true;
613 
614  return DatumGetBool(ret);
615 }
616 
617 /*
618  * Prepare a compiled expression for execution. This has to be called for
619  * every ExprState before it can be executed.
620  *
621  * NB: While this currently only calls ExecReadyInterpretedExpr(),
622  * this will likely get extended to further expression evaluation methods.
623  * Therefore this should be used instead of directly calling
624  * ExecReadyInterpretedExpr().
625  */
626 static void
628 {
629  if (jit_compile_expr(state))
630  return;
631 
633 }
634 
635 /*
636  * Append the steps necessary for the evaluation of node to ExprState->steps,
637  * possibly recursing into sub-expressions of node.
638  *
639  * node - expression to evaluate
640  * state - ExprState to whose ->steps to append the necessary operations
641  * resv / resnull - where to store the result of the node into
642  */
643 static void
645  Datum *resv, bool *resnull)
646 {
647  ExprEvalStep scratch = {0};
648 
649  /* Guard against stack overflow due to overly complex expressions */
651 
652  /* Step's output location is always what the caller gave us */
653  Assert(resv != NULL && resnull != NULL);
654  scratch.resvalue = resv;
655  scratch.resnull = resnull;
656 
657  /* cases should be ordered as they are in enum NodeTag */
658  switch (nodeTag(node))
659  {
660  case T_Var:
661  {
662  Var *variable = (Var *) node;
663 
664  if (variable->varattno == InvalidAttrNumber)
665  {
666  /* whole-row Var */
667  ExecInitWholeRowVar(&scratch, variable, state);
668  }
669  else if (variable->varattno <= 0)
670  {
671  /* system column */
672  scratch.d.var.attnum = variable->varattno;
673  scratch.d.var.vartype = variable->vartype;
674  switch (variable->varno)
675  {
676  case INNER_VAR:
677  scratch.opcode = EEOP_INNER_SYSVAR;
678  break;
679  case OUTER_VAR:
680  scratch.opcode = EEOP_OUTER_SYSVAR;
681  break;
682 
683  /* INDEX_VAR is handled by default case */
684 
685  default:
686  scratch.opcode = EEOP_SCAN_SYSVAR;
687  break;
688  }
689  }
690  else
691  {
692  /* regular user column */
693  scratch.d.var.attnum = variable->varattno - 1;
694  scratch.d.var.vartype = variable->vartype;
695  switch (variable->varno)
696  {
697  case INNER_VAR:
698  scratch.opcode = EEOP_INNER_VAR;
699  break;
700  case OUTER_VAR:
701  scratch.opcode = EEOP_OUTER_VAR;
702  break;
703 
704  /* INDEX_VAR is handled by default case */
705 
706  default:
707  scratch.opcode = EEOP_SCAN_VAR;
708  break;
709  }
710  }
711 
712  ExprEvalPushStep(state, &scratch);
713  break;
714  }
715 
716  case T_Const:
717  {
718  Const *con = (Const *) node;
719 
720  scratch.opcode = EEOP_CONST;
721  scratch.d.constval.value = con->constvalue;
722  scratch.d.constval.isnull = con->constisnull;
723 
724  ExprEvalPushStep(state, &scratch);
725  break;
726  }
727 
728  case T_Param:
729  {
730  Param *param = (Param *) node;
731  ParamListInfo params;
732 
733  switch (param->paramkind)
734  {
735  case PARAM_EXEC:
736  scratch.opcode = EEOP_PARAM_EXEC;
737  scratch.d.param.paramid = param->paramid;
738  scratch.d.param.paramtype = param->paramtype;
739  ExprEvalPushStep(state, &scratch);
740  break;
741  case PARAM_EXTERN:
742 
743  /*
744  * If we have a relevant ParamCompileHook, use it;
745  * otherwise compile a standard EEOP_PARAM_EXTERN
746  * step. ext_params, if supplied, takes precedence
747  * over info from the parent node's EState (if any).
748  */
749  if (state->ext_params)
750  params = state->ext_params;
751  else if (state->parent &&
752  state->parent->state)
753  params = state->parent->state->es_param_list_info;
754  else
755  params = NULL;
756  if (params && params->paramCompile)
757  {
758  params->paramCompile(params, param, state,
759  resv, resnull);
760  }
761  else
762  {
763  scratch.opcode = EEOP_PARAM_EXTERN;
764  scratch.d.param.paramid = param->paramid;
765  scratch.d.param.paramtype = param->paramtype;
766  ExprEvalPushStep(state, &scratch);
767  }
768  break;
769  default:
770  elog(ERROR, "unrecognized paramkind: %d",
771  (int) param->paramkind);
772  break;
773  }
774  break;
775  }
776 
777  case T_Aggref:
778  {
779  Aggref *aggref = (Aggref *) node;
781 
782  scratch.opcode = EEOP_AGGREF;
783  scratch.d.aggref.astate = astate;
784  astate->aggref = aggref;
785 
786  if (state->parent && IsA(state->parent, AggState))
787  {
788  AggState *aggstate = (AggState *) state->parent;
789 
790  aggstate->aggs = lappend(aggstate->aggs, astate);
791  aggstate->numaggs++;
792  }
793  else
794  {
795  /* planner messed up */
796  elog(ERROR, "Aggref found in non-Agg plan node");
797  }
798 
799  ExprEvalPushStep(state, &scratch);
800  break;
801  }
802 
803  case T_GroupingFunc:
804  {
805  GroupingFunc *grp_node = (GroupingFunc *) node;
806  Agg *agg;
807 
808  if (!state->parent || !IsA(state->parent, AggState) ||
809  !IsA(state->parent->plan, Agg))
810  elog(ERROR, "GroupingFunc found in non-Agg plan node");
811 
812  scratch.opcode = EEOP_GROUPING_FUNC;
813  scratch.d.grouping_func.parent = (AggState *) state->parent;
814 
815  agg = (Agg *) (state->parent->plan);
816 
817  if (agg->groupingSets)
818  scratch.d.grouping_func.clauses = grp_node->cols;
819  else
820  scratch.d.grouping_func.clauses = NIL;
821 
822  ExprEvalPushStep(state, &scratch);
823  break;
824  }
825 
826  case T_WindowFunc:
827  {
828  WindowFunc *wfunc = (WindowFunc *) node;
830 
831  wfstate->wfunc = wfunc;
832 
833  if (state->parent && IsA(state->parent, WindowAggState))
834  {
835  WindowAggState *winstate = (WindowAggState *) state->parent;
836  int nfuncs;
837 
838  winstate->funcs = lappend(winstate->funcs, wfstate);
839  nfuncs = ++winstate->numfuncs;
840  if (wfunc->winagg)
841  winstate->numaggs++;
842 
843  /* for now initialize agg using old style expressions */
844  wfstate->args = ExecInitExprList(wfunc->args,
845  state->parent);
846  wfstate->aggfilter = ExecInitExpr(wfunc->aggfilter,
847  state->parent);
848 
849  /*
850  * Complain if the windowfunc's arguments contain any
851  * windowfuncs; nested window functions are semantically
852  * nonsensical. (This should have been caught earlier,
853  * but we defend against it here anyway.)
854  */
855  if (nfuncs != winstate->numfuncs)
856  ereport(ERROR,
857  (errcode(ERRCODE_WINDOWING_ERROR),
858  errmsg("window function calls cannot be nested")));
859  }
860  else
861  {
862  /* planner messed up */
863  elog(ERROR, "WindowFunc found in non-WindowAgg plan node");
864  }
865 
866  scratch.opcode = EEOP_WINDOW_FUNC;
867  scratch.d.window_func.wfstate = wfstate;
868  ExprEvalPushStep(state, &scratch);
869  break;
870  }
871 
872  case T_SubscriptingRef:
873  {
874  SubscriptingRef *sbsref = (SubscriptingRef *) node;
875 
876  ExecInitSubscriptingRef(&scratch, sbsref, state, resv, resnull);
877  break;
878  }
879 
880  case T_FuncExpr:
881  {
882  FuncExpr *func = (FuncExpr *) node;
883 
884  ExecInitFunc(&scratch, node,
885  func->args, func->funcid, func->inputcollid,
886  state);
887  ExprEvalPushStep(state, &scratch);
888  break;
889  }
890 
891  case T_OpExpr:
892  {
893  OpExpr *op = (OpExpr *) node;
894 
895  ExecInitFunc(&scratch, node,
896  op->args, op->opfuncid, op->inputcollid,
897  state);
898  ExprEvalPushStep(state, &scratch);
899  break;
900  }
901 
902  case T_DistinctExpr:
903  {
904  DistinctExpr *op = (DistinctExpr *) node;
905 
906  ExecInitFunc(&scratch, node,
907  op->args, op->opfuncid, op->inputcollid,
908  state);
909 
910  /*
911  * Change opcode of call instruction to EEOP_DISTINCT.
912  *
913  * XXX: historically we've not called the function usage
914  * pgstat infrastructure - that seems inconsistent given that
915  * we do so for normal function *and* operator evaluation. If
916  * we decided to do that here, we'd probably want separate
917  * opcodes for FUSAGE or not.
918  */
919  scratch.opcode = EEOP_DISTINCT;
920  ExprEvalPushStep(state, &scratch);
921  break;
922  }
923 
924  case T_NullIfExpr:
925  {
926  NullIfExpr *op = (NullIfExpr *) node;
927 
928  ExecInitFunc(&scratch, node,
929  op->args, op->opfuncid, op->inputcollid,
930  state);
931 
932  /*
933  * Change opcode of call instruction to EEOP_NULLIF.
934  *
935  * XXX: historically we've not called the function usage
936  * pgstat infrastructure - that seems inconsistent given that
937  * we do so for normal function *and* operator evaluation. If
938  * we decided to do that here, we'd probably want separate
939  * opcodes for FUSAGE or not.
940  */
941  scratch.opcode = EEOP_NULLIF;
942  ExprEvalPushStep(state, &scratch);
943  break;
944  }
945 
946  case T_ScalarArrayOpExpr:
947  {
948  ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
949  Expr *scalararg;
950  Expr *arrayarg;
951  FmgrInfo *finfo;
952  FunctionCallInfo fcinfo;
953  AclResult aclresult;
954 
955  Assert(list_length(opexpr->args) == 2);
956  scalararg = (Expr *) linitial(opexpr->args);
957  arrayarg = (Expr *) lsecond(opexpr->args);
958 
959  /* Check permission to call function */
960  aclresult = pg_proc_aclcheck(opexpr->opfuncid,
961  GetUserId(),
962  ACL_EXECUTE);
963  if (aclresult != ACLCHECK_OK)
964  aclcheck_error(aclresult, OBJECT_FUNCTION,
965  get_func_name(opexpr->opfuncid));
967 
968  /* Set up the primary fmgr lookup information */
969  finfo = palloc0(sizeof(FmgrInfo));
970  fcinfo = palloc0(SizeForFunctionCallInfo(2));
971  fmgr_info(opexpr->opfuncid, finfo);
972  fmgr_info_set_expr((Node *) node, finfo);
973  InitFunctionCallInfoData(*fcinfo, finfo, 2,
974  opexpr->inputcollid, NULL, NULL);
975 
976  /* Evaluate scalar directly into left function argument */
977  ExecInitExprRec(scalararg, state,
978  &fcinfo->args[0].value, &fcinfo->args[0].isnull);
979 
980  /*
981  * Evaluate array argument into our return value. There's no
982  * danger in that, because the return value is guaranteed to
983  * be overwritten by EEOP_SCALARARRAYOP, and will not be
984  * passed to any other expression.
985  */
986  ExecInitExprRec(arrayarg, state, resv, resnull);
987 
988  /* And perform the operation */
989  scratch.opcode = EEOP_SCALARARRAYOP;
990  scratch.d.scalararrayop.element_type = InvalidOid;
991  scratch.d.scalararrayop.useOr = opexpr->useOr;
992  scratch.d.scalararrayop.finfo = finfo;
993  scratch.d.scalararrayop.fcinfo_data = fcinfo;
994  scratch.d.scalararrayop.fn_addr = finfo->fn_addr;
995  ExprEvalPushStep(state, &scratch);
996  break;
997  }
998 
999  case T_BoolExpr:
1000  {
1001  BoolExpr *boolexpr = (BoolExpr *) node;
1002  int nargs = list_length(boolexpr->args);
1003  List *adjust_jumps = NIL;
1004  int off;
1005  ListCell *lc;
1006 
1007  /* allocate scratch memory used by all steps of AND/OR */
1008  if (boolexpr->boolop != NOT_EXPR)
1009  scratch.d.boolexpr.anynull = (bool *) palloc(sizeof(bool));
1010 
1011  /*
1012  * For each argument evaluate the argument itself, then
1013  * perform the bool operation's appropriate handling.
1014  *
1015  * We can evaluate each argument into our result area, since
1016  * the short-circuiting logic means we only need to remember
1017  * previous NULL values.
1018  *
1019  * AND/OR is split into separate STEP_FIRST (one) / STEP (zero
1020  * or more) / STEP_LAST (one) steps, as each of those has to
1021  * perform different work. The FIRST/LAST split is valid
1022  * because AND/OR have at least two arguments.
1023  */
1024  off = 0;
1025  foreach(lc, boolexpr->args)
1026  {
1027  Expr *arg = (Expr *) lfirst(lc);
1028 
1029  /* Evaluate argument into our output variable */
1030  ExecInitExprRec(arg, state, resv, resnull);
1031 
1032  /* Perform the appropriate step type */
1033  switch (boolexpr->boolop)
1034  {
1035  case AND_EXPR:
1036  Assert(nargs >= 2);
1037 
1038  if (off == 0)
1039  scratch.opcode = EEOP_BOOL_AND_STEP_FIRST;
1040  else if (off + 1 == nargs)
1041  scratch.opcode = EEOP_BOOL_AND_STEP_LAST;
1042  else
1043  scratch.opcode = EEOP_BOOL_AND_STEP;
1044  break;
1045  case OR_EXPR:
1046  Assert(nargs >= 2);
1047 
1048  if (off == 0)
1049  scratch.opcode = EEOP_BOOL_OR_STEP_FIRST;
1050  else if (off + 1 == nargs)
1051  scratch.opcode = EEOP_BOOL_OR_STEP_LAST;
1052  else
1053  scratch.opcode = EEOP_BOOL_OR_STEP;
1054  break;
1055  case NOT_EXPR:
1056  Assert(nargs == 1);
1057 
1058  scratch.opcode = EEOP_BOOL_NOT_STEP;
1059  break;
1060  default:
1061  elog(ERROR, "unrecognized boolop: %d",
1062  (int) boolexpr->boolop);
1063  break;
1064  }
1065 
1066  scratch.d.boolexpr.jumpdone = -1;
1067  ExprEvalPushStep(state, &scratch);
1068  adjust_jumps = lappend_int(adjust_jumps,
1069  state->steps_len - 1);
1070  off++;
1071  }
1072 
1073  /* adjust jump targets */
1074  foreach(lc, adjust_jumps)
1075  {
1076  ExprEvalStep *as = &state->steps[lfirst_int(lc)];
1077 
1078  Assert(as->d.boolexpr.jumpdone == -1);
1079  as->d.boolexpr.jumpdone = state->steps_len;
1080  }
1081 
1082  break;
1083  }
1084 
1085  case T_SubPlan:
1086  {
1087  SubPlan *subplan = (SubPlan *) node;
1088  SubPlanState *sstate;
1089 
1090  if (!state->parent)
1091  elog(ERROR, "SubPlan found with no parent plan");
1092 
1093  sstate = ExecInitSubPlan(subplan, state->parent);
1094 
1095  /* add SubPlanState nodes to state->parent->subPlan */
1096  state->parent->subPlan = lappend(state->parent->subPlan,
1097  sstate);
1098 
1099  scratch.opcode = EEOP_SUBPLAN;
1100  scratch.d.subplan.sstate = sstate;
1101 
1102  ExprEvalPushStep(state, &scratch);
1103  break;
1104  }
1105 
1106  case T_AlternativeSubPlan:
1107  {
1108  AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
1109  AlternativeSubPlanState *asstate;
1110 
1111  if (!state->parent)
1112  elog(ERROR, "AlternativeSubPlan found with no parent plan");
1113 
1114  asstate = ExecInitAlternativeSubPlan(asplan, state->parent);
1115 
1116  scratch.opcode = EEOP_ALTERNATIVE_SUBPLAN;
1117  scratch.d.alternative_subplan.asstate = asstate;
1118 
1119  ExprEvalPushStep(state, &scratch);
1120  break;
1121  }
1122 
1123  case T_FieldSelect:
1124  {
1125  FieldSelect *fselect = (FieldSelect *) node;
1126 
1127  /* evaluate row/record argument into result area */
1128  ExecInitExprRec(fselect->arg, state, resv, resnull);
1129 
1130  /* and extract field */
1131  scratch.opcode = EEOP_FIELDSELECT;
1132  scratch.d.fieldselect.fieldnum = fselect->fieldnum;
1133  scratch.d.fieldselect.resulttype = fselect->resulttype;
1134  scratch.d.fieldselect.argdesc = NULL;
1135 
1136  ExprEvalPushStep(state, &scratch);
1137  break;
1138  }
1139 
1140  case T_FieldStore:
1141  {
1142  FieldStore *fstore = (FieldStore *) node;
1143  TupleDesc tupDesc;
1144  TupleDesc *descp;
1145  Datum *values;
1146  bool *nulls;
1147  int ncolumns;
1148  ListCell *l1,
1149  *l2;
1150 
1151  /* find out the number of columns in the composite type */
1152  tupDesc = lookup_rowtype_tupdesc(fstore->resulttype, -1);
1153  ncolumns = tupDesc->natts;
1154  DecrTupleDescRefCount(tupDesc);
1155 
1156  /* create workspace for column values */
1157  values = (Datum *) palloc(sizeof(Datum) * ncolumns);
1158  nulls = (bool *) palloc(sizeof(bool) * ncolumns);
1159 
1160  /* create workspace for runtime tupdesc cache */
1161  descp = (TupleDesc *) palloc(sizeof(TupleDesc));
1162  *descp = NULL;
1163 
1164  /* emit code to evaluate the composite input value */
1165  ExecInitExprRec(fstore->arg, state, resv, resnull);
1166 
1167  /* next, deform the input tuple into our workspace */
1168  scratch.opcode = EEOP_FIELDSTORE_DEFORM;
1169  scratch.d.fieldstore.fstore = fstore;
1170  scratch.d.fieldstore.argdesc = descp;
1171  scratch.d.fieldstore.values = values;
1172  scratch.d.fieldstore.nulls = nulls;
1173  scratch.d.fieldstore.ncolumns = ncolumns;
1174  ExprEvalPushStep(state, &scratch);
1175 
1176  /* evaluate new field values, store in workspace columns */
1177  forboth(l1, fstore->newvals, l2, fstore->fieldnums)
1178  {
1179  Expr *e = (Expr *) lfirst(l1);
1180  AttrNumber fieldnum = lfirst_int(l2);
1181  Datum *save_innermost_caseval;
1182  bool *save_innermost_casenull;
1183 
1184  if (fieldnum <= 0 || fieldnum > ncolumns)
1185  elog(ERROR, "field number %d is out of range in FieldStore",
1186  fieldnum);
1187 
1188  /*
1189  * Use the CaseTestExpr mechanism to pass down the old
1190  * value of the field being replaced; this is needed in
1191  * case the newval is itself a FieldStore or
1192  * SubscriptingRef that has to obtain and modify the old
1193  * value. It's safe to reuse the CASE mechanism because
1194  * there cannot be a CASE between here and where the value
1195  * would be needed, and a field assignment can't be within
1196  * a CASE either. (So saving and restoring
1197  * innermost_caseval is just paranoia, but let's do it
1198  * anyway.)
1199  *
1200  * Another non-obvious point is that it's safe to use the
1201  * field's values[]/nulls[] entries as both the caseval
1202  * source and the result address for this subexpression.
1203  * That's okay only because (1) both FieldStore and
1204  * SubscriptingRef evaluate their arg or refexpr inputs
1205  * first, and (2) any such CaseTestExpr is directly the
1206  * arg or refexpr input. So any read of the caseval will
1207  * occur before there's a chance to overwrite it. Also,
1208  * if multiple entries in the newvals/fieldnums lists
1209  * target the same field, they'll effectively be applied
1210  * left-to-right which is what we want.
1211  */
1212  save_innermost_caseval = state->innermost_caseval;
1213  save_innermost_casenull = state->innermost_casenull;
1214  state->innermost_caseval = &values[fieldnum - 1];
1215  state->innermost_casenull = &nulls[fieldnum - 1];
1216 
1217  ExecInitExprRec(e, state,
1218  &values[fieldnum - 1],
1219  &nulls[fieldnum - 1]);
1220 
1221  state->innermost_caseval = save_innermost_caseval;
1222  state->innermost_casenull = save_innermost_casenull;
1223  }
1224 
1225  /* finally, form result tuple */
1226  scratch.opcode = EEOP_FIELDSTORE_FORM;
1227  scratch.d.fieldstore.fstore = fstore;
1228  scratch.d.fieldstore.argdesc = descp;
1229  scratch.d.fieldstore.values = values;
1230  scratch.d.fieldstore.nulls = nulls;
1231  scratch.d.fieldstore.ncolumns = ncolumns;
1232  ExprEvalPushStep(state, &scratch);
1233  break;
1234  }
1235 
1236  case T_RelabelType:
1237  {
1238  /* relabel doesn't need to do anything at runtime */
1239  RelabelType *relabel = (RelabelType *) node;
1240 
1241  ExecInitExprRec(relabel->arg, state, resv, resnull);
1242  break;
1243  }
1244 
1245  case T_CoerceViaIO:
1246  {
1247  CoerceViaIO *iocoerce = (CoerceViaIO *) node;
1248  Oid iofunc;
1249  bool typisvarlena;
1250  Oid typioparam;
1251  FunctionCallInfo fcinfo_in;
1252 
1253  /* evaluate argument into step's result area */
1254  ExecInitExprRec(iocoerce->arg, state, resv, resnull);
1255 
1256  /*
1257  * Prepare both output and input function calls, to be
1258  * evaluated inside a single evaluation step for speed - this
1259  * can be a very common operation.
1260  *
1261  * We don't check permissions here as a type's input/output
1262  * function are assumed to be executable by everyone.
1263  */
1264  scratch.opcode = EEOP_IOCOERCE;
1265 
1266  /* lookup the source type's output function */
1267  scratch.d.iocoerce.finfo_out = palloc0(sizeof(FmgrInfo));
1268  scratch.d.iocoerce.fcinfo_data_out = palloc0(SizeForFunctionCallInfo(1));
1269 
1270  getTypeOutputInfo(exprType((Node *) iocoerce->arg),
1271  &iofunc, &typisvarlena);
1272  fmgr_info(iofunc, scratch.d.iocoerce.finfo_out);
1273  fmgr_info_set_expr((Node *) node, scratch.d.iocoerce.finfo_out);
1274  InitFunctionCallInfoData(*scratch.d.iocoerce.fcinfo_data_out,
1275  scratch.d.iocoerce.finfo_out,
1276  1, InvalidOid, NULL, NULL);
1277 
1278  /* lookup the result type's input function */
1279  scratch.d.iocoerce.finfo_in = palloc0(sizeof(FmgrInfo));
1280  scratch.d.iocoerce.fcinfo_data_in = palloc0(SizeForFunctionCallInfo(3));
1281 
1282  getTypeInputInfo(iocoerce->resulttype,
1283  &iofunc, &typioparam);
1284  fmgr_info(iofunc, scratch.d.iocoerce.finfo_in);
1285  fmgr_info_set_expr((Node *) node, scratch.d.iocoerce.finfo_in);
1286  InitFunctionCallInfoData(*scratch.d.iocoerce.fcinfo_data_in,
1287  scratch.d.iocoerce.finfo_in,
1288  3, InvalidOid, NULL, NULL);
1289 
1290  /*
1291  * We can preload the second and third arguments for the input
1292  * function, since they're constants.
1293  */
1294  fcinfo_in = scratch.d.iocoerce.fcinfo_data_in;
1295  fcinfo_in->args[1].value = ObjectIdGetDatum(typioparam);
1296  fcinfo_in->args[1].isnull = false;
1297  fcinfo_in->args[2].value = Int32GetDatum(-1);
1298  fcinfo_in->args[2].isnull = false;
1299 
1300  ExprEvalPushStep(state, &scratch);
1301  break;
1302  }
1303 
1304  case T_ArrayCoerceExpr:
1305  {
1306  ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
1307  Oid resultelemtype;
1308  ExprState *elemstate;
1309 
1310  /* evaluate argument into step's result area */
1311  ExecInitExprRec(acoerce->arg, state, resv, resnull);
1312 
1313  resultelemtype = get_element_type(acoerce->resulttype);
1314  if (!OidIsValid(resultelemtype))
1315  ereport(ERROR,
1316  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1317  errmsg("target type is not an array")));
1318 
1319  /*
1320  * Construct a sub-expression for the per-element expression;
1321  * but don't ready it until after we check it for triviality.
1322  * We assume it hasn't any Var references, but does have a
1323  * CaseTestExpr representing the source array element values.
1324  */
1325  elemstate = makeNode(ExprState);
1326  elemstate->expr = acoerce->elemexpr;
1327  elemstate->parent = state->parent;
1328  elemstate->ext_params = state->ext_params;
1329 
1330  elemstate->innermost_caseval = (Datum *) palloc(sizeof(Datum));
1331  elemstate->innermost_casenull = (bool *) palloc(sizeof(bool));
1332 
1333  ExecInitExprRec(acoerce->elemexpr, elemstate,
1334  &elemstate->resvalue, &elemstate->resnull);
1335 
1336  if (elemstate->steps_len == 1 &&
1337  elemstate->steps[0].opcode == EEOP_CASE_TESTVAL)
1338  {
1339  /* Trivial, so we need no per-element work at runtime */
1340  elemstate = NULL;
1341  }
1342  else
1343  {
1344  /* Not trivial, so append a DONE step */
1345  scratch.opcode = EEOP_DONE;
1346  ExprEvalPushStep(elemstate, &scratch);
1347  /* and ready the subexpression */
1348  ExecReadyExpr(elemstate);
1349  }
1350 
1351  scratch.opcode = EEOP_ARRAYCOERCE;
1352  scratch.d.arraycoerce.elemexprstate = elemstate;
1353  scratch.d.arraycoerce.resultelemtype = resultelemtype;
1354 
1355  if (elemstate)
1356  {
1357  /* Set up workspace for array_map */
1358  scratch.d.arraycoerce.amstate =
1359  (ArrayMapState *) palloc0(sizeof(ArrayMapState));
1360  }
1361  else
1362  {
1363  /* Don't need workspace if there's no subexpression */
1364  scratch.d.arraycoerce.amstate = NULL;
1365  }
1366 
1367  ExprEvalPushStep(state, &scratch);
1368  break;
1369  }
1370 
1371  case T_ConvertRowtypeExpr:
1372  {
1374 
1375  /* evaluate argument into step's result area */
1376  ExecInitExprRec(convert->arg, state, resv, resnull);
1377 
1378  /* and push conversion step */
1379  scratch.opcode = EEOP_CONVERT_ROWTYPE;
1380  scratch.d.convert_rowtype.convert = convert;
1381  scratch.d.convert_rowtype.indesc = NULL;
1382  scratch.d.convert_rowtype.outdesc = NULL;
1383  scratch.d.convert_rowtype.map = NULL;
1384  scratch.d.convert_rowtype.initialized = false;
1385 
1386  ExprEvalPushStep(state, &scratch);
1387  break;
1388  }
1389 
1390  /* note that CaseWhen expressions are handled within this block */
1391  case T_CaseExpr:
1392  {
1393  CaseExpr *caseExpr = (CaseExpr *) node;
1394  List *adjust_jumps = NIL;
1395  Datum *caseval = NULL;
1396  bool *casenull = NULL;
1397  ListCell *lc;
1398 
1399  /*
1400  * If there's a test expression, we have to evaluate it and
1401  * save the value where the CaseTestExpr placeholders can find
1402  * it.
1403  */
1404  if (caseExpr->arg != NULL)
1405  {
1406  /* Evaluate testexpr into caseval/casenull workspace */
1407  caseval = palloc(sizeof(Datum));
1408  casenull = palloc(sizeof(bool));
1409 
1410  ExecInitExprRec(caseExpr->arg, state,
1411  caseval, casenull);
1412 
1413  /*
1414  * Since value might be read multiple times, force to R/O
1415  * - but only if it could be an expanded datum.
1416  */
1417  if (get_typlen(exprType((Node *) caseExpr->arg)) == -1)
1418  {
1419  /* change caseval in-place */
1420  scratch.opcode = EEOP_MAKE_READONLY;
1421  scratch.resvalue = caseval;
1422  scratch.resnull = casenull;
1423  scratch.d.make_readonly.value = caseval;
1424  scratch.d.make_readonly.isnull = casenull;
1425  ExprEvalPushStep(state, &scratch);
1426  /* restore normal settings of scratch fields */
1427  scratch.resvalue = resv;
1428  scratch.resnull = resnull;
1429  }
1430  }
1431 
1432  /*
1433  * Prepare to evaluate each of the WHEN clauses in turn; as
1434  * soon as one is true we return the value of the
1435  * corresponding THEN clause. If none are true then we return
1436  * the value of the ELSE clause, or NULL if there is none.
1437  */
1438  foreach(lc, caseExpr->args)
1439  {
1440  CaseWhen *when = (CaseWhen *) lfirst(lc);
1441  Datum *save_innermost_caseval;
1442  bool *save_innermost_casenull;
1443  int whenstep;
1444 
1445  /*
1446  * Make testexpr result available to CaseTestExpr nodes
1447  * within the condition. We must save and restore prior
1448  * setting of innermost_caseval fields, in case this node
1449  * is itself within a larger CASE.
1450  *
1451  * If there's no test expression, we don't actually need
1452  * to save and restore these fields; but it's less code to
1453  * just do so unconditionally.
1454  */
1455  save_innermost_caseval = state->innermost_caseval;
1456  save_innermost_casenull = state->innermost_casenull;
1457  state->innermost_caseval = caseval;
1458  state->innermost_casenull = casenull;
1459 
1460  /* evaluate condition into CASE's result variables */
1461  ExecInitExprRec(when->expr, state, resv, resnull);
1462 
1463  state->innermost_caseval = save_innermost_caseval;
1464  state->innermost_casenull = save_innermost_casenull;
1465 
1466  /* If WHEN result isn't true, jump to next CASE arm */
1467  scratch.opcode = EEOP_JUMP_IF_NOT_TRUE;
1468  scratch.d.jump.jumpdone = -1; /* computed later */
1469  ExprEvalPushStep(state, &scratch);
1470  whenstep = state->steps_len - 1;
1471 
1472  /*
1473  * If WHEN result is true, evaluate THEN result, storing
1474  * it into the CASE's result variables.
1475  */
1476  ExecInitExprRec(when->result, state, resv, resnull);
1477 
1478  /* Emit JUMP step to jump to end of CASE's code */
1479  scratch.opcode = EEOP_JUMP;
1480  scratch.d.jump.jumpdone = -1; /* computed later */
1481  ExprEvalPushStep(state, &scratch);
1482 
1483  /*
1484  * Don't know address for that jump yet, compute once the
1485  * whole CASE expression is built.
1486  */
1487  adjust_jumps = lappend_int(adjust_jumps,
1488  state->steps_len - 1);
1489 
1490  /*
1491  * But we can set WHEN test's jump target now, to make it
1492  * jump to the next WHEN subexpression or the ELSE.
1493  */
1494  state->steps[whenstep].d.jump.jumpdone = state->steps_len;
1495  }
1496 
1497  /* transformCaseExpr always adds a default */
1498  Assert(caseExpr->defresult);
1499 
1500  /* evaluate ELSE expr into CASE's result variables */
1501  ExecInitExprRec(caseExpr->defresult, state,
1502  resv, resnull);
1503 
1504  /* adjust jump targets */
1505  foreach(lc, adjust_jumps)
1506  {
1507  ExprEvalStep *as = &state->steps[lfirst_int(lc)];
1508 
1509  Assert(as->opcode == EEOP_JUMP);
1510  Assert(as->d.jump.jumpdone == -1);
1511  as->d.jump.jumpdone = state->steps_len;
1512  }
1513 
1514  break;
1515  }
1516 
1517  case T_CaseTestExpr:
1518  {
1519  /*
1520  * Read from location identified by innermost_caseval. Note
1521  * that innermost_caseval could be NULL, if this node isn't
1522  * actually within a CaseExpr, ArrayCoerceExpr, etc structure.
1523  * That can happen because some parts of the system abuse
1524  * CaseTestExpr to cause a read of a value externally supplied
1525  * in econtext->caseValue_datum. We'll take care of that
1526  * scenario at runtime.
1527  */
1528  scratch.opcode = EEOP_CASE_TESTVAL;
1529  scratch.d.casetest.value = state->innermost_caseval;
1530  scratch.d.casetest.isnull = state->innermost_casenull;
1531 
1532  ExprEvalPushStep(state, &scratch);
1533  break;
1534  }
1535 
1536  case T_ArrayExpr:
1537  {
1538  ArrayExpr *arrayexpr = (ArrayExpr *) node;
1539  int nelems = list_length(arrayexpr->elements);
1540  ListCell *lc;
1541  int elemoff;
1542 
1543  /*
1544  * Evaluate by computing each element, and then forming the
1545  * array. Elements are computed into scratch arrays
1546  * associated with the ARRAYEXPR step.
1547  */
1548  scratch.opcode = EEOP_ARRAYEXPR;
1549  scratch.d.arrayexpr.elemvalues =
1550  (Datum *) palloc(sizeof(Datum) * nelems);
1551  scratch.d.arrayexpr.elemnulls =
1552  (bool *) palloc(sizeof(bool) * nelems);
1553  scratch.d.arrayexpr.nelems = nelems;
1554 
1555  /* fill remaining fields of step */
1556  scratch.d.arrayexpr.multidims = arrayexpr->multidims;
1557  scratch.d.arrayexpr.elemtype = arrayexpr->element_typeid;
1558 
1559  /* do one-time catalog lookup for type info */
1561  &scratch.d.arrayexpr.elemlength,
1562  &scratch.d.arrayexpr.elembyval,
1563  &scratch.d.arrayexpr.elemalign);
1564 
1565  /* prepare to evaluate all arguments */
1566  elemoff = 0;
1567  foreach(lc, arrayexpr->elements)
1568  {
1569  Expr *e = (Expr *) lfirst(lc);
1570 
1571  ExecInitExprRec(e, state,
1572  &scratch.d.arrayexpr.elemvalues[elemoff],
1573  &scratch.d.arrayexpr.elemnulls[elemoff]);
1574  elemoff++;
1575  }
1576 
1577  /* and then collect all into an array */
1578  ExprEvalPushStep(state, &scratch);
1579  break;
1580  }
1581 
1582  case T_RowExpr:
1583  {
1584  RowExpr *rowexpr = (RowExpr *) node;
1585  int nelems = list_length(rowexpr->args);
1586  TupleDesc tupdesc;
1587  int i;
1588  ListCell *l;
1589 
1590  /* Build tupdesc to describe result tuples */
1591  if (rowexpr->row_typeid == RECORDOID)
1592  {
1593  /* generic record, use types of given expressions */
1594  tupdesc = ExecTypeFromExprList(rowexpr->args);
1595  }
1596  else
1597  {
1598  /* it's been cast to a named type, use that */
1599  tupdesc = lookup_rowtype_tupdesc_copy(rowexpr->row_typeid, -1);
1600  }
1601  /* In either case, adopt RowExpr's column aliases */
1602  ExecTypeSetColNames(tupdesc, rowexpr->colnames);
1603  /* Bless the tupdesc in case it's now of type RECORD */
1604  BlessTupleDesc(tupdesc);
1605 
1606  /*
1607  * In the named-type case, the tupdesc could have more columns
1608  * than are in the args list, since the type might have had
1609  * columns added since the ROW() was parsed. We want those
1610  * extra columns to go to nulls, so we make sure that the
1611  * workspace arrays are large enough and then initialize any
1612  * extra columns to read as NULLs.
1613  */
1614  Assert(nelems <= tupdesc->natts);
1615  nelems = Max(nelems, tupdesc->natts);
1616 
1617  /*
1618  * Evaluate by first building datums for each field, and then
1619  * a final step forming the composite datum.
1620  */
1621  scratch.opcode = EEOP_ROW;
1622  scratch.d.row.tupdesc = tupdesc;
1623 
1624  /* space for the individual field datums */
1625  scratch.d.row.elemvalues =
1626  (Datum *) palloc(sizeof(Datum) * nelems);
1627  scratch.d.row.elemnulls =
1628  (bool *) palloc(sizeof(bool) * nelems);
1629  /* as explained above, make sure any extra columns are null */
1630  memset(scratch.d.row.elemnulls, true, sizeof(bool) * nelems);
1631 
1632  /* Set up evaluation, skipping any deleted columns */
1633  i = 0;
1634  foreach(l, rowexpr->args)
1635  {
1636  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
1637  Expr *e = (Expr *) lfirst(l);
1638 
1639  if (!att->attisdropped)
1640  {
1641  /*
1642  * Guard against ALTER COLUMN TYPE on rowtype since
1643  * the RowExpr was created. XXX should we check
1644  * typmod too? Not sure we can be sure it'll be the
1645  * same.
1646  */
1647  if (exprType((Node *) e) != att->atttypid)
1648  ereport(ERROR,
1649  (errcode(ERRCODE_DATATYPE_MISMATCH),
1650  errmsg("ROW() column has type %s instead of type %s",
1651  format_type_be(exprType((Node *) e)),
1652  format_type_be(att->atttypid))));
1653  }
1654  else
1655  {
1656  /*
1657  * Ignore original expression and insert a NULL. We
1658  * don't really care what type of NULL it is, so
1659  * always make an int4 NULL.
1660  */
1661  e = (Expr *) makeNullConst(INT4OID, -1, InvalidOid);
1662  }
1663 
1664  /* Evaluate column expr into appropriate workspace slot */
1665  ExecInitExprRec(e, state,
1666  &scratch.d.row.elemvalues[i],
1667  &scratch.d.row.elemnulls[i]);
1668  i++;
1669  }
1670 
1671  /* And finally build the row value */
1672  ExprEvalPushStep(state, &scratch);
1673  break;
1674  }
1675 
1676  case T_RowCompareExpr:
1677  {
1678  RowCompareExpr *rcexpr = (RowCompareExpr *) node;
1679  int nopers = list_length(rcexpr->opnos);
1680  List *adjust_jumps = NIL;
1681  ListCell *l_left_expr,
1682  *l_right_expr,
1683  *l_opno,
1684  *l_opfamily,
1685  *l_inputcollid;
1686  ListCell *lc;
1687 
1688  /*
1689  * Iterate over each field, prepare comparisons. To handle
1690  * NULL results, prepare jumps to after the expression. If a
1691  * comparison yields a != 0 result, jump to the final step.
1692  */
1693  Assert(list_length(rcexpr->largs) == nopers);
1694  Assert(list_length(rcexpr->rargs) == nopers);
1695  Assert(list_length(rcexpr->opfamilies) == nopers);
1696  Assert(list_length(rcexpr->inputcollids) == nopers);
1697 
1698  forfive(l_left_expr, rcexpr->largs,
1699  l_right_expr, rcexpr->rargs,
1700  l_opno, rcexpr->opnos,
1701  l_opfamily, rcexpr->opfamilies,
1702  l_inputcollid, rcexpr->inputcollids)
1703  {
1704  Expr *left_expr = (Expr *) lfirst(l_left_expr);
1705  Expr *right_expr = (Expr *) lfirst(l_right_expr);
1706  Oid opno = lfirst_oid(l_opno);
1707  Oid opfamily = lfirst_oid(l_opfamily);
1708  Oid inputcollid = lfirst_oid(l_inputcollid);
1709  int strategy;
1710  Oid lefttype;
1711  Oid righttype;
1712  Oid proc;
1713  FmgrInfo *finfo;
1714  FunctionCallInfo fcinfo;
1715 
1716  get_op_opfamily_properties(opno, opfamily, false,
1717  &strategy,
1718  &lefttype,
1719  &righttype);
1720  proc = get_opfamily_proc(opfamily,
1721  lefttype,
1722  righttype,
1723  BTORDER_PROC);
1724  if (!OidIsValid(proc))
1725  elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
1726  BTORDER_PROC, lefttype, righttype, opfamily);
1727 
1728  /* Set up the primary fmgr lookup information */
1729  finfo = palloc0(sizeof(FmgrInfo));
1730  fcinfo = palloc0(SizeForFunctionCallInfo(2));
1731  fmgr_info(proc, finfo);
1732  fmgr_info_set_expr((Node *) node, finfo);
1733  InitFunctionCallInfoData(*fcinfo, finfo, 2,
1734  inputcollid, NULL, NULL);
1735 
1736  /*
1737  * If we enforced permissions checks on index support
1738  * functions, we'd need to make a check here. But the
1739  * index support machinery doesn't do that, and thus
1740  * neither does this code.
1741  */
1742 
1743  /* evaluate left and right args directly into fcinfo */
1744  ExecInitExprRec(left_expr, state,
1745  &fcinfo->args[0].value, &fcinfo->args[0].isnull);
1746  ExecInitExprRec(right_expr, state,
1747  &fcinfo->args[1].value, &fcinfo->args[1].isnull);
1748 
1749  scratch.opcode = EEOP_ROWCOMPARE_STEP;
1750  scratch.d.rowcompare_step.finfo = finfo;
1751  scratch.d.rowcompare_step.fcinfo_data = fcinfo;
1752  scratch.d.rowcompare_step.fn_addr = finfo->fn_addr;
1753  /* jump targets filled below */
1754  scratch.d.rowcompare_step.jumpnull = -1;
1755  scratch.d.rowcompare_step.jumpdone = -1;
1756 
1757  ExprEvalPushStep(state, &scratch);
1758  adjust_jumps = lappend_int(adjust_jumps,
1759  state->steps_len - 1);
1760  }
1761 
1762  /*
1763  * We could have a zero-column rowtype, in which case the rows
1764  * necessarily compare equal.
1765  */
1766  if (nopers == 0)
1767  {
1768  scratch.opcode = EEOP_CONST;
1769  scratch.d.constval.value = Int32GetDatum(0);
1770  scratch.d.constval.isnull = false;
1771  ExprEvalPushStep(state, &scratch);
1772  }
1773 
1774  /* Finally, examine the last comparison result */
1775  scratch.opcode = EEOP_ROWCOMPARE_FINAL;
1776  scratch.d.rowcompare_final.rctype = rcexpr->rctype;
1777  ExprEvalPushStep(state, &scratch);
1778 
1779  /* adjust jump targets */
1780  foreach(lc, adjust_jumps)
1781  {
1782  ExprEvalStep *as = &state->steps[lfirst_int(lc)];
1783 
1785  Assert(as->d.rowcompare_step.jumpdone == -1);
1786  Assert(as->d.rowcompare_step.jumpnull == -1);
1787 
1788  /* jump to comparison evaluation */
1789  as->d.rowcompare_step.jumpdone = state->steps_len - 1;
1790  /* jump to the following expression */
1791  as->d.rowcompare_step.jumpnull = state->steps_len;
1792  }
1793 
1794  break;
1795  }
1796 
1797  case T_CoalesceExpr:
1798  {
1799  CoalesceExpr *coalesce = (CoalesceExpr *) node;
1800  List *adjust_jumps = NIL;
1801  ListCell *lc;
1802 
1803  /* We assume there's at least one arg */
1804  Assert(coalesce->args != NIL);
1805 
1806  /*
1807  * Prepare evaluation of all coalesced arguments, after each
1808  * one push a step that short-circuits if not null.
1809  */
1810  foreach(lc, coalesce->args)
1811  {
1812  Expr *e = (Expr *) lfirst(lc);
1813 
1814  /* evaluate argument, directly into result datum */
1815  ExecInitExprRec(e, state, resv, resnull);
1816 
1817  /* if it's not null, skip to end of COALESCE expr */
1818  scratch.opcode = EEOP_JUMP_IF_NOT_NULL;
1819  scratch.d.jump.jumpdone = -1; /* adjust later */
1820  ExprEvalPushStep(state, &scratch);
1821 
1822  adjust_jumps = lappend_int(adjust_jumps,
1823  state->steps_len - 1);
1824  }
1825 
1826  /*
1827  * No need to add a constant NULL return - we only can get to
1828  * the end of the expression if a NULL already is being
1829  * returned.
1830  */
1831 
1832  /* adjust jump targets */
1833  foreach(lc, adjust_jumps)
1834  {
1835  ExprEvalStep *as = &state->steps[lfirst_int(lc)];
1836 
1838  Assert(as->d.jump.jumpdone == -1);
1839  as->d.jump.jumpdone = state->steps_len;
1840  }
1841 
1842  break;
1843  }
1844 
1845  case T_MinMaxExpr:
1846  {
1847  MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
1848  int nelems = list_length(minmaxexpr->args);
1849  TypeCacheEntry *typentry;
1850  FmgrInfo *finfo;
1851  FunctionCallInfo fcinfo;
1852  ListCell *lc;
1853  int off;
1854 
1855  /* Look up the btree comparison function for the datatype */
1856  typentry = lookup_type_cache(minmaxexpr->minmaxtype,
1858  if (!OidIsValid(typentry->cmp_proc))
1859  ereport(ERROR,
1860  (errcode(ERRCODE_UNDEFINED_FUNCTION),
1861  errmsg("could not identify a comparison function for type %s",
1862  format_type_be(minmaxexpr->minmaxtype))));
1863 
1864  /*
1865  * If we enforced permissions checks on index support
1866  * functions, we'd need to make a check here. But the index
1867  * support machinery doesn't do that, and thus neither does
1868  * this code.
1869  */
1870 
1871  /* Perform function lookup */
1872  finfo = palloc0(sizeof(FmgrInfo));
1873  fcinfo = palloc0(SizeForFunctionCallInfo(2));
1874  fmgr_info(typentry->cmp_proc, finfo);
1875  fmgr_info_set_expr((Node *) node, finfo);
1876  InitFunctionCallInfoData(*fcinfo, finfo, 2,
1877  minmaxexpr->inputcollid, NULL, NULL);
1878 
1879  scratch.opcode = EEOP_MINMAX;
1880  /* allocate space to store arguments */
1881  scratch.d.minmax.values =
1882  (Datum *) palloc(sizeof(Datum) * nelems);
1883  scratch.d.minmax.nulls =
1884  (bool *) palloc(sizeof(bool) * nelems);
1885  scratch.d.minmax.nelems = nelems;
1886 
1887  scratch.d.minmax.op = minmaxexpr->op;
1888  scratch.d.minmax.finfo = finfo;
1889  scratch.d.minmax.fcinfo_data = fcinfo;
1890 
1891  /* evaluate expressions into minmax->values/nulls */
1892  off = 0;
1893  foreach(lc, minmaxexpr->args)
1894  {
1895  Expr *e = (Expr *) lfirst(lc);
1896 
1897  ExecInitExprRec(e, state,
1898  &scratch.d.minmax.values[off],
1899  &scratch.d.minmax.nulls[off]);
1900  off++;
1901  }
1902 
1903  /* and push the final comparison */
1904  ExprEvalPushStep(state, &scratch);
1905  break;
1906  }
1907 
1908  case T_SQLValueFunction:
1909  {
1910  SQLValueFunction *svf = (SQLValueFunction *) node;
1911 
1912  scratch.opcode = EEOP_SQLVALUEFUNCTION;
1913  scratch.d.sqlvaluefunction.svf = svf;
1914 
1915  ExprEvalPushStep(state, &scratch);
1916  break;
1917  }
1918 
1919  case T_XmlExpr:
1920  {
1921  XmlExpr *xexpr = (XmlExpr *) node;
1922  int nnamed = list_length(xexpr->named_args);
1923  int nargs = list_length(xexpr->args);
1924  int off;
1925  ListCell *arg;
1926 
1927  scratch.opcode = EEOP_XMLEXPR;
1928  scratch.d.xmlexpr.xexpr = xexpr;
1929 
1930  /* allocate space for storing all the arguments */
1931  if (nnamed)
1932  {
1933  scratch.d.xmlexpr.named_argvalue =
1934  (Datum *) palloc(sizeof(Datum) * nnamed);
1935  scratch.d.xmlexpr.named_argnull =
1936  (bool *) palloc(sizeof(bool) * nnamed);
1937  }
1938  else
1939  {
1940  scratch.d.xmlexpr.named_argvalue = NULL;
1941  scratch.d.xmlexpr.named_argnull = NULL;
1942  }
1943 
1944  if (nargs)
1945  {
1946  scratch.d.xmlexpr.argvalue =
1947  (Datum *) palloc(sizeof(Datum) * nargs);
1948  scratch.d.xmlexpr.argnull =
1949  (bool *) palloc(sizeof(bool) * nargs);
1950  }
1951  else
1952  {
1953  scratch.d.xmlexpr.argvalue = NULL;
1954  scratch.d.xmlexpr.argnull = NULL;
1955  }
1956 
1957  /* prepare argument execution */
1958  off = 0;
1959  foreach(arg, xexpr->named_args)
1960  {
1961  Expr *e = (Expr *) lfirst(arg);
1962 
1963  ExecInitExprRec(e, state,
1964  &scratch.d.xmlexpr.named_argvalue[off],
1965  &scratch.d.xmlexpr.named_argnull[off]);
1966  off++;
1967  }
1968 
1969  off = 0;
1970  foreach(arg, xexpr->args)
1971  {
1972  Expr *e = (Expr *) lfirst(arg);
1973 
1974  ExecInitExprRec(e, state,
1975  &scratch.d.xmlexpr.argvalue[off],
1976  &scratch.d.xmlexpr.argnull[off]);
1977  off++;
1978  }
1979 
1980  /* and evaluate the actual XML expression */
1981  ExprEvalPushStep(state, &scratch);
1982  break;
1983  }
1984 
1985  case T_NullTest:
1986  {
1987  NullTest *ntest = (NullTest *) node;
1988 
1989  if (ntest->nulltesttype == IS_NULL)
1990  {
1991  if (ntest->argisrow)
1992  scratch.opcode = EEOP_NULLTEST_ROWISNULL;
1993  else
1994  scratch.opcode = EEOP_NULLTEST_ISNULL;
1995  }
1996  else if (ntest->nulltesttype == IS_NOT_NULL)
1997  {
1998  if (ntest->argisrow)
2000  else
2001  scratch.opcode = EEOP_NULLTEST_ISNOTNULL;
2002  }
2003  else
2004  {
2005  elog(ERROR, "unrecognized nulltesttype: %d",
2006  (int) ntest->nulltesttype);
2007  }
2008  /* initialize cache in case it's a row test */
2009  scratch.d.nulltest_row.argdesc = NULL;
2010 
2011  /* first evaluate argument into result variable */
2012  ExecInitExprRec(ntest->arg, state,
2013  resv, resnull);
2014 
2015  /* then push the test of that argument */
2016  ExprEvalPushStep(state, &scratch);
2017  break;
2018  }
2019 
2020  case T_BooleanTest:
2021  {
2022  BooleanTest *btest = (BooleanTest *) node;
2023 
2024  /*
2025  * Evaluate argument, directly into result datum. That's ok,
2026  * because resv/resnull is definitely not used anywhere else,
2027  * and will get overwritten by the below EEOP_BOOLTEST_IS_*
2028  * step.
2029  */
2030  ExecInitExprRec(btest->arg, state, resv, resnull);
2031 
2032  switch (btest->booltesttype)
2033  {
2034  case IS_TRUE:
2035  scratch.opcode = EEOP_BOOLTEST_IS_TRUE;
2036  break;
2037  case IS_NOT_TRUE:
2039  break;
2040  case IS_FALSE:
2041  scratch.opcode = EEOP_BOOLTEST_IS_FALSE;
2042  break;
2043  case IS_NOT_FALSE:
2045  break;
2046  case IS_UNKNOWN:
2047  /* Same as scalar IS NULL test */
2048  scratch.opcode = EEOP_NULLTEST_ISNULL;
2049  break;
2050  case IS_NOT_UNKNOWN:
2051  /* Same as scalar IS NOT NULL test */
2052  scratch.opcode = EEOP_NULLTEST_ISNOTNULL;
2053  break;
2054  default:
2055  elog(ERROR, "unrecognized booltesttype: %d",
2056  (int) btest->booltesttype);
2057  }
2058 
2059  ExprEvalPushStep(state, &scratch);
2060  break;
2061  }
2062 
2063  case T_CoerceToDomain:
2064  {
2065  CoerceToDomain *ctest = (CoerceToDomain *) node;
2066 
2067  ExecInitCoerceToDomain(&scratch, ctest, state,
2068  resv, resnull);
2069  break;
2070  }
2071 
2072  case T_CoerceToDomainValue:
2073  {
2074  /*
2075  * Read from location identified by innermost_domainval. Note
2076  * that innermost_domainval could be NULL, if we're compiling
2077  * a standalone domain check rather than one embedded in a
2078  * larger expression. In that case we must read from
2079  * econtext->domainValue_datum. We'll take care of that
2080  * scenario at runtime.
2081  */
2082  scratch.opcode = EEOP_DOMAIN_TESTVAL;
2083  /* we share instruction union variant with case testval */
2084  scratch.d.casetest.value = state->innermost_domainval;
2085  scratch.d.casetest.isnull = state->innermost_domainnull;
2086 
2087  ExprEvalPushStep(state, &scratch);
2088  break;
2089  }
2090 
2091  case T_CurrentOfExpr:
2092  {
2093  scratch.opcode = EEOP_CURRENTOFEXPR;
2094  ExprEvalPushStep(state, &scratch);
2095  break;
2096  }
2097 
2098  case T_NextValueExpr:
2099  {
2100  NextValueExpr *nve = (NextValueExpr *) node;
2101 
2102  scratch.opcode = EEOP_NEXTVALUEEXPR;
2103  scratch.d.nextvalueexpr.seqid = nve->seqid;
2104  scratch.d.nextvalueexpr.seqtypid = nve->typeId;
2105 
2106  ExprEvalPushStep(state, &scratch);
2107  break;
2108  }
2109 
2110  default:
2111  elog(ERROR, "unrecognized node type: %d",
2112  (int) nodeTag(node));
2113  break;
2114  }
2115 }
2116 
2117 /*
2118  * Add another expression evaluation step to ExprState->steps.
2119  *
2120  * Note that this potentially re-allocates es->steps, therefore no pointer
2121  * into that array may be used while the expression is still being built.
2122  */
2123 void
2125 {
2126  if (es->steps_alloc == 0)
2127  {
2128  es->steps_alloc = 16;
2129  es->steps = palloc(sizeof(ExprEvalStep) * es->steps_alloc);
2130  }
2131  else if (es->steps_alloc == es->steps_len)
2132  {
2133  es->steps_alloc *= 2;
2134  es->steps = repalloc(es->steps,
2135  sizeof(ExprEvalStep) * es->steps_alloc);
2136  }
2137 
2138  memcpy(&es->steps[es->steps_len++], s, sizeof(ExprEvalStep));
2139 }
2140 
2141 /*
2142  * Perform setup necessary for the evaluation of a function-like expression,
2143  * appending argument evaluation steps to the steps list in *state, and
2144  * setting up *scratch so it is ready to be pushed.
2145  *
2146  * *scratch is not pushed here, so that callers may override the opcode,
2147  * which is useful for function-like cases like DISTINCT.
2148  */
2149 static void
2150 ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args, Oid funcid,
2151  Oid inputcollid, ExprState *state)
2152 {
2153  int nargs = list_length(args);
2154  AclResult aclresult;
2155  FmgrInfo *flinfo;
2156  FunctionCallInfo fcinfo;
2157  int argno;
2158  ListCell *lc;
2159 
2160  /* Check permission to call function */
2161  aclresult = pg_proc_aclcheck(funcid, GetUserId(), ACL_EXECUTE);
2162  if (aclresult != ACLCHECK_OK)
2163  aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(funcid));
2164  InvokeFunctionExecuteHook(funcid);
2165 
2166  /*
2167  * Safety check on nargs. Under normal circumstances this should never
2168  * fail, as parser should check sooner. But possibly it might fail if
2169  * server has been compiled with FUNC_MAX_ARGS smaller than some functions
2170  * declared in pg_proc?
2171  */
2172  if (nargs > FUNC_MAX_ARGS)
2173  ereport(ERROR,
2174  (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
2175  errmsg_plural("cannot pass more than %d argument to a function",
2176  "cannot pass more than %d arguments to a function",
2177  FUNC_MAX_ARGS,
2178  FUNC_MAX_ARGS)));
2179 
2180  /* Allocate function lookup data and parameter workspace for this call */
2181  scratch->d.func.finfo = palloc0(sizeof(FmgrInfo));
2182  scratch->d.func.fcinfo_data = palloc0(SizeForFunctionCallInfo(nargs));
2183  flinfo = scratch->d.func.finfo;
2184  fcinfo = scratch->d.func.fcinfo_data;
2185 
2186  /* Set up the primary fmgr lookup information */
2187  fmgr_info(funcid, flinfo);
2188  fmgr_info_set_expr((Node *) node, flinfo);
2189 
2190  /* Initialize function call parameter structure too */
2191  InitFunctionCallInfoData(*fcinfo, flinfo,
2192  nargs, inputcollid, NULL, NULL);
2193 
2194  /* Keep extra copies of this info to save an indirection at runtime */
2195  scratch->d.func.fn_addr = flinfo->fn_addr;
2196  scratch->d.func.nargs = nargs;
2197 
2198  /* We only support non-set functions here */
2199  if (flinfo->fn_retset)
2200  ereport(ERROR,
2201  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2202  errmsg("set-valued function called in context that cannot accept a set"),
2203  state->parent ?
2205  exprLocation((Node *) node)) : 0));
2206 
2207  /* Build code to evaluate arguments directly into the fcinfo struct */
2208  argno = 0;
2209  foreach(lc, args)
2210  {
2211  Expr *arg = (Expr *) lfirst(lc);
2212 
2213  if (IsA(arg, Const))
2214  {
2215  /*
2216  * Don't evaluate const arguments every round; especially
2217  * interesting for constants in comparisons.
2218  */
2219  Const *con = (Const *) arg;
2220 
2221  fcinfo->args[argno].value = con->constvalue;
2222  fcinfo->args[argno].isnull = con->constisnull;
2223  }
2224  else
2225  {
2226  ExecInitExprRec(arg, state,
2227  &fcinfo->args[argno].value,
2228  &fcinfo->args[argno].isnull);
2229  }
2230  argno++;
2231  }
2232 
2233  /* Insert appropriate opcode depending on strictness and stats level */
2234  if (pgstat_track_functions <= flinfo->fn_stats)
2235  {
2236  if (flinfo->fn_strict && nargs > 0)
2237  scratch->opcode = EEOP_FUNCEXPR_STRICT;
2238  else
2239  scratch->opcode = EEOP_FUNCEXPR;
2240  }
2241  else
2242  {
2243  if (flinfo->fn_strict && nargs > 0)
2245  else
2246  scratch->opcode = EEOP_FUNCEXPR_FUSAGE;
2247  }
2248 }
2249 
2250 /*
2251  * Add expression steps deforming the ExprState's inner/outer/scan slots
2252  * as much as required by the expression.
2253  */
2254 static void
2256 {
2257  LastAttnumInfo info = {0, 0, 0};
2258 
2259  /*
2260  * Figure out which attributes we're going to need.
2261  */
2262  get_last_attnums_walker(node, &info);
2263 
2264  ExecPushExprSlots(state, &info);
2265 }
2266 
2267 /*
2268  * Add steps deforming the ExprState's inner/out/scan slots as much as
2269  * indicated by info. This is useful when building an ExprState covering more
2270  * than one expression.
2271  */
2272 static void
2274 {
2275  ExprEvalStep scratch = {0};
2276 
2277  scratch.resvalue = NULL;
2278  scratch.resnull = NULL;
2279 
2280  /* Emit steps as needed */
2281  if (info->last_inner > 0)
2282  {
2283  scratch.opcode = EEOP_INNER_FETCHSOME;
2284  scratch.d.fetch.last_var = info->last_inner;
2285  scratch.d.fetch.fixed = false;
2286  scratch.d.fetch.kind = NULL;
2287  scratch.d.fetch.known_desc = NULL;
2288  if (ExecComputeSlotInfo(state, &scratch))
2289  ExprEvalPushStep(state, &scratch);
2290  }
2291  if (info->last_outer > 0)
2292  {
2293  scratch.opcode = EEOP_OUTER_FETCHSOME;
2294  scratch.d.fetch.last_var = info->last_outer;
2295  scratch.d.fetch.fixed = false;
2296  scratch.d.fetch.kind = NULL;
2297  scratch.d.fetch.known_desc = NULL;
2298  if (ExecComputeSlotInfo(state, &scratch))
2299  ExprEvalPushStep(state, &scratch);
2300  }
2301  if (info->last_scan > 0)
2302  {
2303  scratch.opcode = EEOP_SCAN_FETCHSOME;
2304  scratch.d.fetch.last_var = info->last_scan;
2305  scratch.d.fetch.fixed = false;
2306  scratch.d.fetch.kind = NULL;
2307  scratch.d.fetch.known_desc = NULL;
2308  if (ExecComputeSlotInfo(state, &scratch))
2309  ExprEvalPushStep(state, &scratch);
2310  }
2311 }
2312 
2313 /*
2314  * get_last_attnums_walker: expression walker for ExecInitExprSlots
2315  */
2316 static bool
2318 {
2319  if (node == NULL)
2320  return false;
2321  if (IsA(node, Var))
2322  {
2323  Var *variable = (Var *) node;
2324  AttrNumber attnum = variable->varattno;
2325 
2326  switch (variable->varno)
2327  {
2328  case INNER_VAR:
2329  info->last_inner = Max(info->last_inner, attnum);
2330  break;
2331 
2332  case OUTER_VAR:
2333  info->last_outer = Max(info->last_outer, attnum);
2334  break;
2335 
2336  /* INDEX_VAR is handled by default case */
2337 
2338  default:
2339  info->last_scan = Max(info->last_scan, attnum);
2340  break;
2341  }
2342  return false;
2343  }
2344 
2345  /*
2346  * Don't examine the arguments or filters of Aggrefs or WindowFuncs,
2347  * because those do not represent expressions to be evaluated within the
2348  * calling expression's econtext. GroupingFunc arguments are never
2349  * evaluated at all.
2350  */
2351  if (IsA(node, Aggref))
2352  return false;
2353  if (IsA(node, WindowFunc))
2354  return false;
2355  if (IsA(node, GroupingFunc))
2356  return false;
2358  (void *) info);
2359 }
2360 
2361 /*
2362  * Compute additional information for EEOP_*_FETCHSOME ops.
2363  *
2364  * The goal is to determine whether a slot is 'fixed', that is, every
2365  * evaluation of the expression will have the same type of slot, with an
2366  * equivalent descriptor.
2367  *
2368  * Returns true if the the deforming step is required, false otherwise.
2369  */
2370 static bool
2372 {
2373  PlanState *parent = state->parent;
2374  TupleDesc desc = NULL;
2375  const TupleTableSlotOps *tts_ops = NULL;
2376  bool isfixed = false;
2377  ExprEvalOp opcode = op->opcode;
2378 
2379  Assert(opcode == EEOP_INNER_FETCHSOME ||
2380  opcode == EEOP_OUTER_FETCHSOME ||
2381  opcode == EEOP_SCAN_FETCHSOME);
2382 
2383  if (op->d.fetch.known_desc != NULL)
2384  {
2385  desc = op->d.fetch.known_desc;
2386  tts_ops = op->d.fetch.kind;
2387  isfixed = op->d.fetch.kind != NULL;
2388  }
2389  else if (!parent)
2390  {
2391  isfixed = false;
2392  }
2393  else if (opcode == EEOP_INNER_FETCHSOME)
2394  {
2395  PlanState *is = innerPlanState(parent);
2396 
2397  if (parent->inneropsset && !parent->inneropsfixed)
2398  {
2399  isfixed = false;
2400  }
2401  else if (parent->inneropsset && parent->innerops)
2402  {
2403  isfixed = true;
2404  tts_ops = parent->innerops;
2405  desc = ExecGetResultType(is);
2406  }
2407  else if (is)
2408  {
2409  tts_ops = ExecGetResultSlotOps(is, &isfixed);
2410  desc = ExecGetResultType(is);
2411  }
2412  }
2413  else if (opcode == EEOP_OUTER_FETCHSOME)
2414  {
2415  PlanState *os = outerPlanState(parent);
2416 
2417  if (parent->outeropsset && !parent->outeropsfixed)
2418  {
2419  isfixed = false;
2420  }
2421  else if (parent->outeropsset && parent->outerops)
2422  {
2423  isfixed = true;
2424  tts_ops = parent->outerops;
2425  desc = ExecGetResultType(os);
2426  }
2427  else if (os)
2428  {
2429  tts_ops = ExecGetResultSlotOps(os, &isfixed);
2430  desc = ExecGetResultType(os);
2431  }
2432  }
2433  else if (opcode == EEOP_SCAN_FETCHSOME)
2434  {
2435  desc = parent->scandesc;
2436 
2437  if (parent && parent->scanops)
2438  tts_ops = parent->scanops;
2439 
2440  if (parent->scanopsset)
2441  isfixed = parent->scanopsfixed;
2442  }
2443 
2444  if (isfixed && desc != NULL && tts_ops != NULL)
2445  {
2446  op->d.fetch.fixed = true;
2447  op->d.fetch.kind = tts_ops;
2448  op->d.fetch.known_desc = desc;
2449  }
2450  else
2451  {
2452  op->d.fetch.fixed = false;
2453  op->d.fetch.kind = NULL;
2454  op->d.fetch.known_desc = NULL;
2455  }
2456 
2457  /* if the slot is known to always virtual we never need to deform */
2458  if (op->d.fetch.fixed && op->d.fetch.kind == &TTSOpsVirtual)
2459  return false;
2460 
2461  return true;
2462 }
2463 
2464 /*
2465  * Prepare step for the evaluation of a whole-row variable.
2466  * The caller still has to push the step.
2467  */
2468 static void
2470 {
2471  PlanState *parent = state->parent;
2472 
2473  /* fill in all but the target */
2474  scratch->opcode = EEOP_WHOLEROW;
2475  scratch->d.wholerow.var = variable;
2476  scratch->d.wholerow.first = true;
2477  scratch->d.wholerow.slow = false;
2478  scratch->d.wholerow.tupdesc = NULL; /* filled at runtime */
2479  scratch->d.wholerow.junkFilter = NULL;
2480 
2481  /*
2482  * If the input tuple came from a subquery, it might contain "resjunk"
2483  * columns (such as GROUP BY or ORDER BY columns), which we don't want to
2484  * keep in the whole-row result. We can get rid of such columns by
2485  * passing the tuple through a JunkFilter --- but to make one, we have to
2486  * lay our hands on the subquery's targetlist. Fortunately, there are not
2487  * very many cases where this can happen, and we can identify all of them
2488  * by examining our parent PlanState. We assume this is not an issue in
2489  * standalone expressions that don't have parent plans. (Whole-row Vars
2490  * can occur in such expressions, but they will always be referencing
2491  * table rows.)
2492  */
2493  if (parent)
2494  {
2495  PlanState *subplan = NULL;
2496 
2497  switch (nodeTag(parent))
2498  {
2499  case T_SubqueryScanState:
2500  subplan = ((SubqueryScanState *) parent)->subplan;
2501  break;
2502  case T_CteScanState:
2503  subplan = ((CteScanState *) parent)->cteplanstate;
2504  break;
2505  default:
2506  break;
2507  }
2508 
2509  if (subplan)
2510  {
2511  bool junk_filter_needed = false;
2512  ListCell *tlist;
2513 
2514  /* Detect whether subplan tlist actually has any junk columns */
2515  foreach(tlist, subplan->plan->targetlist)
2516  {
2517  TargetEntry *tle = (TargetEntry *) lfirst(tlist);
2518 
2519  if (tle->resjunk)
2520  {
2521  junk_filter_needed = true;
2522  break;
2523  }
2524  }
2525 
2526  /* If so, build the junkfilter now */
2527  if (junk_filter_needed)
2528  {
2529  scratch->d.wholerow.junkFilter =
2531  ExecInitExtraTupleSlot(parent->state, NULL,
2532  &TTSOpsVirtual));
2533  }
2534  }
2535  }
2536 }
2537 
2538 /*
2539  * Prepare evaluation of a SubscriptingRef expression.
2540  */
2541 static void
2543  ExprState *state, Datum *resv, bool *resnull)
2544 {
2545  bool isAssignment = (sbsref->refassgnexpr != NULL);
2546  SubscriptingRefState *sbsrefstate = palloc0(sizeof(SubscriptingRefState));
2547  List *adjust_jumps = NIL;
2548  ListCell *lc;
2549  int i;
2550 
2551  /* Fill constant fields of SubscriptingRefState */
2552  sbsrefstate->isassignment = isAssignment;
2553  sbsrefstate->refelemtype = sbsref->refelemtype;
2554  sbsrefstate->refattrlength = get_typlen(sbsref->refcontainertype);
2556  &sbsrefstate->refelemlength,
2557  &sbsrefstate->refelembyval,
2558  &sbsrefstate->refelemalign);
2559 
2560  /*
2561  * Evaluate array input. It's safe to do so into resv/resnull, because we
2562  * won't use that as target for any of the other subexpressions, and it'll
2563  * be overwritten by the final EEOP_SBSREF_FETCH/ASSIGN step, which is
2564  * pushed last.
2565  */
2566  ExecInitExprRec(sbsref->refexpr, state, resv, resnull);
2567 
2568  /*
2569  * If refexpr yields NULL, and it's a fetch, then result is NULL. We can
2570  * implement this with just JUMP_IF_NULL, since we evaluated the array
2571  * into the desired target location.
2572  */
2573  if (!isAssignment)
2574  {
2575  scratch->opcode = EEOP_JUMP_IF_NULL;
2576  scratch->d.jump.jumpdone = -1; /* adjust later */
2577  ExprEvalPushStep(state, scratch);
2578  adjust_jumps = lappend_int(adjust_jumps,
2579  state->steps_len - 1);
2580  }
2581 
2582  /* Verify subscript list lengths are within limit */
2583  if (list_length(sbsref->refupperindexpr) > MAXDIM)
2584  ereport(ERROR,
2585  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2586  errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
2587  list_length(sbsref->refupperindexpr), MAXDIM)));
2588 
2589  if (list_length(sbsref->reflowerindexpr) > MAXDIM)
2590  ereport(ERROR,
2591  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2592  errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
2593  list_length(sbsref->reflowerindexpr), MAXDIM)));
2594 
2595  /* Evaluate upper subscripts */
2596  i = 0;
2597  foreach(lc, sbsref->refupperindexpr)
2598  {
2599  Expr *e = (Expr *) lfirst(lc);
2600 
2601  /* When slicing, individual subscript bounds can be omitted */
2602  if (!e)
2603  {
2604  sbsrefstate->upperprovided[i] = false;
2605  i++;
2606  continue;
2607  }
2608 
2609  sbsrefstate->upperprovided[i] = true;
2610 
2611  /* Each subscript is evaluated into subscriptvalue/subscriptnull */
2612  ExecInitExprRec(e, state,
2613  &sbsrefstate->subscriptvalue, &sbsrefstate->subscriptnull);
2614 
2615  /* ... and then SBSREF_SUBSCRIPT saves it into step's workspace */
2616  scratch->opcode = EEOP_SBSREF_SUBSCRIPT;
2617  scratch->d.sbsref_subscript.state = sbsrefstate;
2618  scratch->d.sbsref_subscript.off = i;
2619  scratch->d.sbsref_subscript.isupper = true;
2620  scratch->d.sbsref_subscript.jumpdone = -1; /* adjust later */
2621  ExprEvalPushStep(state, scratch);
2622  adjust_jumps = lappend_int(adjust_jumps,
2623  state->steps_len - 1);
2624  i++;
2625  }
2626  sbsrefstate->numupper = i;
2627 
2628  /* Evaluate lower subscripts similarly */
2629  i = 0;
2630  foreach(lc, sbsref->reflowerindexpr)
2631  {
2632  Expr *e = (Expr *) lfirst(lc);
2633 
2634  /* When slicing, individual subscript bounds can be omitted */
2635  if (!e)
2636  {
2637  sbsrefstate->lowerprovided[i] = false;
2638  i++;
2639  continue;
2640  }
2641 
2642  sbsrefstate->lowerprovided[i] = true;
2643 
2644  /* Each subscript is evaluated into subscriptvalue/subscriptnull */
2645  ExecInitExprRec(e, state,
2646  &sbsrefstate->subscriptvalue, &sbsrefstate->subscriptnull);
2647 
2648  /* ... and then SBSREF_SUBSCRIPT saves it into step's workspace */
2649  scratch->opcode = EEOP_SBSREF_SUBSCRIPT;
2650  scratch->d.sbsref_subscript.state = sbsrefstate;
2651  scratch->d.sbsref_subscript.off = i;
2652  scratch->d.sbsref_subscript.isupper = false;
2653  scratch->d.sbsref_subscript.jumpdone = -1; /* adjust later */
2654  ExprEvalPushStep(state, scratch);
2655  adjust_jumps = lappend_int(adjust_jumps,
2656  state->steps_len - 1);
2657  i++;
2658  }
2659  sbsrefstate->numlower = i;
2660 
2661  /* Should be impossible if parser is sane, but check anyway: */
2662  if (sbsrefstate->numlower != 0 &&
2663  sbsrefstate->numupper != sbsrefstate->numlower)
2664  elog(ERROR, "upper and lower index lists are not same length");
2665 
2666  if (isAssignment)
2667  {
2668  Datum *save_innermost_caseval;
2669  bool *save_innermost_casenull;
2670 
2671  /*
2672  * We might have a nested-assignment situation, in which the
2673  * refassgnexpr is itself a FieldStore or SubscriptingRef that needs
2674  * to obtain and modify the previous value of the array element or
2675  * slice being replaced. If so, we have to extract that value from
2676  * the array and pass it down via the CaseTestExpr mechanism. It's
2677  * safe to reuse the CASE mechanism because there cannot be a CASE
2678  * between here and where the value would be needed, and an array
2679  * assignment can't be within a CASE either. (So saving and restoring
2680  * innermost_caseval is just paranoia, but let's do it anyway.)
2681  *
2682  * Since fetching the old element might be a nontrivial expense, do it
2683  * only if the argument actually needs it.
2684  */
2686  {
2687  scratch->opcode = EEOP_SBSREF_OLD;
2688  scratch->d.sbsref.state = sbsrefstate;
2689  ExprEvalPushStep(state, scratch);
2690  }
2691 
2692  /* SBSREF_OLD puts extracted value into prevvalue/prevnull */
2693  save_innermost_caseval = state->innermost_caseval;
2694  save_innermost_casenull = state->innermost_casenull;
2695  state->innermost_caseval = &sbsrefstate->prevvalue;
2696  state->innermost_casenull = &sbsrefstate->prevnull;
2697 
2698  /* evaluate replacement value into replacevalue/replacenull */
2699  ExecInitExprRec(sbsref->refassgnexpr, state,
2700  &sbsrefstate->replacevalue, &sbsrefstate->replacenull);
2701 
2702  state->innermost_caseval = save_innermost_caseval;
2703  state->innermost_casenull = save_innermost_casenull;
2704 
2705  /* and perform the assignment */
2706  scratch->opcode = EEOP_SBSREF_ASSIGN;
2707  scratch->d.sbsref.state = sbsrefstate;
2708  ExprEvalPushStep(state, scratch);
2709 
2710  }
2711  else
2712  {
2713  /* array fetch is much simpler */
2714  scratch->opcode = EEOP_SBSREF_FETCH;
2715  scratch->d.sbsref.state = sbsrefstate;
2716  ExprEvalPushStep(state, scratch);
2717 
2718  }
2719 
2720  /* adjust jump targets */
2721  foreach(lc, adjust_jumps)
2722  {
2723  ExprEvalStep *as = &state->steps[lfirst_int(lc)];
2724 
2725  if (as->opcode == EEOP_SBSREF_SUBSCRIPT)
2726  {
2727  Assert(as->d.sbsref_subscript.jumpdone == -1);
2728  as->d.sbsref_subscript.jumpdone = state->steps_len;
2729  }
2730  else
2731  {
2733  Assert(as->d.jump.jumpdone == -1);
2734  as->d.jump.jumpdone = state->steps_len;
2735  }
2736  }
2737 }
2738 
2739 /*
2740  * Helper for preparing SubscriptingRef expressions for evaluation: is expr
2741  * a nested FieldStore or SubscriptingRef that needs the old element value
2742  * passed down?
2743  *
2744  * (We could use this in FieldStore too, but in that case passing the old
2745  * value is so cheap there's no need.)
2746  *
2747  * Note: it might seem that this needs to recurse, but it does not; the
2748  * CaseTestExpr, if any, will be directly the arg or refexpr of the top-level
2749  * node. Nested-assignment situations give rise to expression trees in which
2750  * each level of assignment has its own CaseTestExpr, and the recursive
2751  * structure appears within the newvals or refassgnexpr field.
2752  */
2753 static bool
2755 {
2756  if (expr == NULL)
2757  return false; /* just paranoia */
2758  if (IsA(expr, FieldStore))
2759  {
2760  FieldStore *fstore = (FieldStore *) expr;
2761 
2762  if (fstore->arg && IsA(fstore->arg, CaseTestExpr))
2763  return true;
2764  }
2765  else if (IsA(expr, SubscriptingRef))
2766  {
2767  SubscriptingRef *sbsRef = (SubscriptingRef *) expr;
2768 
2769  if (sbsRef->refexpr && IsA(sbsRef->refexpr, CaseTestExpr))
2770  return true;
2771  }
2772  return false;
2773 }
2774 
2775 /*
2776  * Prepare evaluation of a CoerceToDomain expression.
2777  */
2778 static void
2780  ExprState *state, Datum *resv, bool *resnull)
2781 {
2782  ExprEvalStep scratch2 = {0};
2783  DomainConstraintRef *constraint_ref;
2784  Datum *domainval = NULL;
2785  bool *domainnull = NULL;
2786  Datum *save_innermost_domainval;
2787  bool *save_innermost_domainnull;
2788  ListCell *l;
2789 
2790  scratch->d.domaincheck.resulttype = ctest->resulttype;
2791  /* we'll allocate workspace only if needed */
2792  scratch->d.domaincheck.checkvalue = NULL;
2793  scratch->d.domaincheck.checknull = NULL;
2794 
2795  /*
2796  * Evaluate argument - it's fine to directly store it into resv/resnull,
2797  * if there's constraint failures there'll be errors, otherwise it's what
2798  * needs to be returned.
2799  */
2800  ExecInitExprRec(ctest->arg, state, resv, resnull);
2801 
2802  /*
2803  * Note: if the argument is of varlena type, it could be a R/W expanded
2804  * object. We want to return the R/W pointer as the final result, but we
2805  * have to pass a R/O pointer as the value to be tested by any functions
2806  * in check expressions. We don't bother to emit a MAKE_READONLY step
2807  * unless there's actually at least one check expression, though. Until
2808  * we've tested that, domainval/domainnull are NULL.
2809  */
2810 
2811  /*
2812  * Collect the constraints associated with the domain.
2813  *
2814  * Note: before PG v10 we'd recheck the set of constraints during each
2815  * evaluation of the expression. Now we bake them into the ExprState
2816  * during executor initialization. That means we don't need typcache.c to
2817  * provide compiled exprs.
2818  */
2819  constraint_ref = (DomainConstraintRef *)
2820  palloc(sizeof(DomainConstraintRef));
2822  constraint_ref,
2824  false);
2825 
2826  /*
2827  * Compile code to check each domain constraint. NOTNULL constraints can
2828  * just be applied on the resv/resnull value, but for CHECK constraints we
2829  * need more pushups.
2830  */
2831  foreach(l, constraint_ref->constraints)
2832  {
2834 
2835  scratch->d.domaincheck.constraintname = con->name;
2836 
2837  switch (con->constrainttype)
2838  {
2840  scratch->opcode = EEOP_DOMAIN_NOTNULL;
2841  ExprEvalPushStep(state, scratch);
2842  break;
2843  case DOM_CONSTRAINT_CHECK:
2844  /* Allocate workspace for CHECK output if we didn't yet */
2845  if (scratch->d.domaincheck.checkvalue == NULL)
2846  {
2847  scratch->d.domaincheck.checkvalue =
2848  (Datum *) palloc(sizeof(Datum));
2849  scratch->d.domaincheck.checknull =
2850  (bool *) palloc(sizeof(bool));
2851  }
2852 
2853  /*
2854  * If first time through, determine where CoerceToDomainValue
2855  * nodes should read from.
2856  */
2857  if (domainval == NULL)
2858  {
2859  /*
2860  * Since value might be read multiple times, force to R/O
2861  * - but only if it could be an expanded datum.
2862  */
2863  if (get_typlen(ctest->resulttype) == -1)
2864  {
2865  /* Yes, so make output workspace for MAKE_READONLY */
2866  domainval = (Datum *) palloc(sizeof(Datum));
2867  domainnull = (bool *) palloc(sizeof(bool));
2868 
2869  /* Emit MAKE_READONLY */
2870  scratch2.opcode = EEOP_MAKE_READONLY;
2871  scratch2.resvalue = domainval;
2872  scratch2.resnull = domainnull;
2873  scratch2.d.make_readonly.value = resv;
2874  scratch2.d.make_readonly.isnull = resnull;
2875  ExprEvalPushStep(state, &scratch2);
2876  }
2877  else
2878  {
2879  /* No, so it's fine to read from resv/resnull */
2880  domainval = resv;
2881  domainnull = resnull;
2882  }
2883  }
2884 
2885  /*
2886  * Set up value to be returned by CoerceToDomainValue nodes.
2887  * We must save and restore innermost_domainval/null fields,
2888  * in case this node is itself within a check expression for
2889  * another domain.
2890  */
2891  save_innermost_domainval = state->innermost_domainval;
2892  save_innermost_domainnull = state->innermost_domainnull;
2893  state->innermost_domainval = domainval;
2894  state->innermost_domainnull = domainnull;
2895 
2896  /* evaluate check expression value */
2897  ExecInitExprRec(con->check_expr, state,
2898  scratch->d.domaincheck.checkvalue,
2899  scratch->d.domaincheck.checknull);
2900 
2901  state->innermost_domainval = save_innermost_domainval;
2902  state->innermost_domainnull = save_innermost_domainnull;
2903 
2904  /* now test result */
2905  scratch->opcode = EEOP_DOMAIN_CHECK;
2906  ExprEvalPushStep(state, scratch);
2907 
2908  break;
2909  default:
2910  elog(ERROR, "unrecognized constraint type: %d",
2911  (int) con->constrainttype);
2912  break;
2913  }
2914  }
2915 }
2916 
2917 /*
2918  * Build transition/combine function invocations for all aggregate transition
2919  * / combination function invocations in a grouping sets phase. This has to
2920  * invoke all sort based transitions in a phase (if doSort is true), all hash
2921  * based transitions (if doHash is true), or both (both true).
2922  *
2923  * The resulting expression will, for each set of transition values, first
2924  * check for filters, evaluate aggregate input, check that that input is not
2925  * NULL for a strict transition function, and then finally invoke the
2926  * transition for each of the concurrently computed grouping sets.
2927  */
2928 ExprState *
2930  bool doSort, bool doHash)
2931 {
2933  PlanState *parent = &aggstate->ss.ps;
2934  ExprEvalStep scratch = {0};
2935  int transno = 0;
2936  int setoff = 0;
2937  bool isCombine = DO_AGGSPLIT_COMBINE(aggstate->aggsplit);
2938  LastAttnumInfo deform = {0, 0, 0};
2939 
2940  state->expr = (Expr *) aggstate;
2941  state->parent = parent;
2942 
2943  scratch.resvalue = &state->resvalue;
2944  scratch.resnull = &state->resnull;
2945 
2946  /*
2947  * First figure out which slots, and how many columns from each, we're
2948  * going to need.
2949  */
2950  for (transno = 0; transno < aggstate->numtrans; transno++)
2951  {
2952  AggStatePerTrans pertrans = &aggstate->pertrans[transno];
2953 
2955  &deform);
2956  get_last_attnums_walker((Node *) pertrans->aggref->args,
2957  &deform);
2959  &deform);
2961  &deform);
2963  &deform);
2964  }
2965  ExecPushExprSlots(state, &deform);
2966 
2967  /*
2968  * Emit instructions for each transition value / grouping set combination.
2969  */
2970  for (transno = 0; transno < aggstate->numtrans; transno++)
2971  {
2972  AggStatePerTrans pertrans = &aggstate->pertrans[transno];
2973  int argno;
2974  int setno;
2975  FunctionCallInfo trans_fcinfo = pertrans->transfn_fcinfo;
2976  ListCell *arg;
2977  ListCell *bail;
2978  List *adjust_bailout = NIL;
2979  NullableDatum *strictargs = NULL;
2980  bool *strictnulls = NULL;
2981 
2982  /*
2983  * If filter present, emit. Do so before evaluating the input, to
2984  * avoid potentially unneeded computations, or even worse, unintended
2985  * side-effects. When combining, all the necessary filtering has
2986  * already been done.
2987  */
2988  if (pertrans->aggref->aggfilter && !isCombine)
2989  {
2990  /* evaluate filter expression */
2991  ExecInitExprRec(pertrans->aggref->aggfilter, state,
2992  &state->resvalue, &state->resnull);
2993  /* and jump out if false */
2994  scratch.opcode = EEOP_JUMP_IF_NOT_TRUE;
2995  scratch.d.jump.jumpdone = -1; /* adjust later */
2996  ExprEvalPushStep(state, &scratch);
2997  adjust_bailout = lappend_int(adjust_bailout,
2998  state->steps_len - 1);
2999  }
3000 
3001  /*
3002  * Evaluate arguments to aggregate/combine function.
3003  */
3004  argno = 0;
3005  if (isCombine)
3006  {
3007  /*
3008  * Combining two aggregate transition values. Instead of directly
3009  * coming from a tuple the input is a, potentially deserialized,
3010  * transition value.
3011  */
3012  TargetEntry *source_tle;
3013 
3014  Assert(pertrans->numSortCols == 0);
3015  Assert(list_length(pertrans->aggref->args) == 1);
3016 
3017  strictargs = trans_fcinfo->args + 1;
3018  source_tle = (TargetEntry *) linitial(pertrans->aggref->args);
3019 
3020  /*
3021  * deserialfn_oid will be set if we must deserialize the input
3022  * state before calling the combine function.
3023  */
3024  if (!OidIsValid(pertrans->deserialfn_oid))
3025  {
3026  /*
3027  * Start from 1, since the 0th arg will be the transition
3028  * value
3029  */
3030  ExecInitExprRec(source_tle->expr, state,
3031  &trans_fcinfo->args[argno + 1].value,
3032  &trans_fcinfo->args[argno + 1].isnull);
3033  }
3034  else
3035  {
3036  FunctionCallInfo ds_fcinfo = pertrans->deserialfn_fcinfo;
3037 
3038  /* evaluate argument */
3039  ExecInitExprRec(source_tle->expr, state,
3040  &ds_fcinfo->args[0].value,
3041  &ds_fcinfo->args[0].isnull);
3042 
3043  /* Dummy second argument for type-safety reasons */
3044  ds_fcinfo->args[1].value = PointerGetDatum(NULL);
3045  ds_fcinfo->args[1].isnull = false;
3046 
3047  /*
3048  * Don't call a strict deserialization function with NULL
3049  * input
3050  */
3051  if (pertrans->deserialfn.fn_strict)
3053  else
3054  scratch.opcode = EEOP_AGG_DESERIALIZE;
3055 
3056  scratch.d.agg_deserialize.aggstate = aggstate;
3057  scratch.d.agg_deserialize.fcinfo_data = ds_fcinfo;
3058  scratch.d.agg_deserialize.jumpnull = -1; /* adjust later */
3059  scratch.resvalue = &trans_fcinfo->args[argno + 1].value;
3060  scratch.resnull = &trans_fcinfo->args[argno + 1].isnull;
3061 
3062  ExprEvalPushStep(state, &scratch);
3063  adjust_bailout = lappend_int(adjust_bailout,
3064  state->steps_len - 1);
3065 
3066  /* restore normal settings of scratch fields */
3067  scratch.resvalue = &state->resvalue;
3068  scratch.resnull = &state->resnull;
3069  }
3070  argno++;
3071  }
3072  else if (pertrans->numSortCols == 0)
3073  {
3074  /*
3075  * Normal transition function without ORDER BY / DISTINCT.
3076  */
3077  strictargs = trans_fcinfo->args + 1;
3078 
3079  foreach(arg, pertrans->aggref->args)
3080  {
3081  TargetEntry *source_tle = (TargetEntry *) lfirst(arg);
3082 
3083  /*
3084  * Start from 1, since the 0th arg will be the transition
3085  * value
3086  */
3087  ExecInitExprRec(source_tle->expr, state,
3088  &trans_fcinfo->args[argno + 1].value,
3089  &trans_fcinfo->args[argno + 1].isnull);
3090  argno++;
3091  }
3092  }
3093  else if (pertrans->numInputs == 1)
3094  {
3095  /*
3096  * DISTINCT and/or ORDER BY case, with a single column sorted on.
3097  */
3098  TargetEntry *source_tle =
3099  (TargetEntry *) linitial(pertrans->aggref->args);
3100 
3101  Assert(list_length(pertrans->aggref->args) == 1);
3102 
3103  ExecInitExprRec(source_tle->expr, state,
3104  &state->resvalue,
3105  &state->resnull);
3106  strictnulls = &state->resnull;
3107  argno++;
3108  }
3109  else
3110  {
3111  /*
3112  * DISTINCT and/or ORDER BY case, with multiple columns sorted on.
3113  */
3114  Datum *values = pertrans->sortslot->tts_values;
3115  bool *nulls = pertrans->sortslot->tts_isnull;
3116 
3117  strictnulls = nulls;
3118 
3119  foreach(arg, pertrans->aggref->args)
3120  {
3121  TargetEntry *source_tle = (TargetEntry *) lfirst(arg);
3122 
3123  ExecInitExprRec(source_tle->expr, state,
3124  &values[argno], &nulls[argno]);
3125  argno++;
3126  }
3127  }
3128  Assert(pertrans->numInputs == argno);
3129 
3130  /*
3131  * For a strict transfn, nothing happens when there's a NULL input; we
3132  * just keep the prior transValue. This is true for both plain and
3133  * sorted/distinct aggregates.
3134  */
3135  if (trans_fcinfo->flinfo->fn_strict && pertrans->numTransInputs > 0)
3136  {
3137  if (strictnulls)
3139  else
3141  scratch.d.agg_strict_input_check.nulls = strictnulls;
3142  scratch.d.agg_strict_input_check.args = strictargs;
3143  scratch.d.agg_strict_input_check.jumpnull = -1; /* adjust later */
3144  scratch.d.agg_strict_input_check.nargs = pertrans->numTransInputs;
3145  ExprEvalPushStep(state, &scratch);
3146  adjust_bailout = lappend_int(adjust_bailout,
3147  state->steps_len - 1);
3148  }
3149 
3150  /*
3151  * Call transition function (once for each concurrently evaluated
3152  * grouping set). Do so for both sort and hash based computations, as
3153  * applicable.
3154  */
3155  setoff = 0;
3156  if (doSort)
3157  {
3158  int processGroupingSets = Max(phase->numsets, 1);
3159 
3160  for (setno = 0; setno < processGroupingSets; setno++)
3161  {
3162  ExecBuildAggTransCall(state, aggstate, &scratch, trans_fcinfo,
3163  pertrans, transno, setno, setoff, false);
3164  setoff++;
3165  }
3166  }
3167 
3168  if (doHash)
3169  {
3170  int numHashes = aggstate->num_hashes;
3171 
3172  /* in MIXED mode, there'll be preceding transition values */
3173  if (aggstate->aggstrategy != AGG_HASHED)
3174  setoff = aggstate->maxsets;
3175  else
3176  setoff = 0;
3177 
3178  for (setno = 0; setno < numHashes; setno++)
3179  {
3180  ExecBuildAggTransCall(state, aggstate, &scratch, trans_fcinfo,
3181  pertrans, transno, setno, setoff, true);
3182  setoff++;
3183  }
3184  }
3185 
3186  /* adjust early bail out jump target(s) */
3187  foreach(bail, adjust_bailout)
3188  {
3189  ExprEvalStep *as = &state->steps[lfirst_int(bail)];
3190 
3191  if (as->opcode == EEOP_JUMP_IF_NOT_TRUE)
3192  {
3193  Assert(as->d.jump.jumpdone == -1);
3194  as->d.jump.jumpdone = state->steps_len;
3195  }
3196  else if (as->opcode == EEOP_AGG_STRICT_INPUT_CHECK_ARGS ||
3198  {
3199  Assert(as->d.agg_strict_input_check.jumpnull == -1);
3200  as->d.agg_strict_input_check.jumpnull = state->steps_len;
3201  }
3202  else if (as->opcode == EEOP_AGG_STRICT_DESERIALIZE)
3203  {
3204  Assert(as->d.agg_deserialize.jumpnull == -1);
3205  as->d.agg_deserialize.jumpnull = state->steps_len;
3206  }
3207  }
3208  }
3209 
3210  scratch.resvalue = NULL;
3211  scratch.resnull = NULL;
3212  scratch.opcode = EEOP_DONE;
3213  ExprEvalPushStep(state, &scratch);
3214 
3215  ExecReadyExpr(state);
3216 
3217  return state;
3218 }
3219 
3220 /*
3221  * Build transition/combine function invocation for a single transition
3222  * value. This is separated from ExecBuildAggTrans() because there are
3223  * multiple callsites (hash and sort in some grouping set cases).
3224  */
3225 static void
3227  ExprEvalStep *scratch,
3228  FunctionCallInfo fcinfo, AggStatePerTrans pertrans,
3229  int transno, int setno, int setoff, bool ishash)
3230 {
3231  int adjust_init_jumpnull = -1;
3232  int adjust_strict_jumpnull = -1;
3233  ExprContext *aggcontext;
3234 
3235  if (ishash)
3236  aggcontext = aggstate->hashcontext;
3237  else
3238  aggcontext = aggstate->aggcontexts[setno];
3239 
3240  /*
3241  * If the initial value for the transition state doesn't exist in the
3242  * pg_aggregate table then we will let the first non-NULL value returned
3243  * from the outer procNode become the initial value. (This is useful for
3244  * aggregates like max() and min().) The noTransValue flag signals that we
3245  * still need to do this.
3246  */
3247  if (pertrans->numSortCols == 0 &&
3248  fcinfo->flinfo->fn_strict &&
3249  pertrans->initValueIsNull)
3250  {
3251  scratch->opcode = EEOP_AGG_INIT_TRANS;
3252  scratch->d.agg_init_trans.aggstate = aggstate;
3253  scratch->d.agg_init_trans.pertrans = pertrans;
3254  scratch->d.agg_init_trans.setno = setno;
3255  scratch->d.agg_init_trans.setoff = setoff;
3256  scratch->d.agg_init_trans.transno = transno;
3257  scratch->d.agg_init_trans.aggcontext = aggcontext;
3258  scratch->d.agg_init_trans.jumpnull = -1; /* adjust later */
3259  ExprEvalPushStep(state, scratch);
3260 
3261  /* see comment about jumping out below */
3262  adjust_init_jumpnull = state->steps_len - 1;
3263  }
3264 
3265  if (pertrans->numSortCols == 0 &&
3266  fcinfo->flinfo->fn_strict)
3267  {
3269  scratch->d.agg_strict_trans_check.aggstate = aggstate;
3270  scratch->d.agg_strict_trans_check.setno = setno;
3271  scratch->d.agg_strict_trans_check.setoff = setoff;
3272  scratch->d.agg_strict_trans_check.transno = transno;
3273  scratch->d.agg_strict_trans_check.jumpnull = -1; /* adjust later */
3274  ExprEvalPushStep(state, scratch);
3275 
3276  /*
3277  * Note, we don't push into adjust_bailout here - those jump to the
3278  * end of all transition value computations. Here a single transition
3279  * value is NULL, so just skip processing the individual value.
3280  */
3281  adjust_strict_jumpnull = state->steps_len - 1;
3282  }
3283 
3284  /* invoke appropriate transition implementation */
3285  if (pertrans->numSortCols == 0 && pertrans->transtypeByVal)
3287  else if (pertrans->numSortCols == 0)
3288  scratch->opcode = EEOP_AGG_PLAIN_TRANS;
3289  else if (pertrans->numInputs == 1)
3291  else
3293 
3294  scratch->d.agg_trans.aggstate = aggstate;
3295  scratch->d.agg_trans.pertrans = pertrans;
3296  scratch->d.agg_trans.setno = setno;
3297  scratch->d.agg_trans.setoff = setoff;
3298  scratch->d.agg_trans.transno = transno;
3299  scratch->d.agg_trans.aggcontext = aggcontext;
3300  ExprEvalPushStep(state, scratch);
3301 
3302  /* adjust jumps so they jump till after transition invocation */
3303  if (adjust_init_jumpnull != -1)
3304  {
3305  ExprEvalStep *as = &state->steps[adjust_init_jumpnull];
3306 
3307  Assert(as->d.agg_init_trans.jumpnull == -1);
3308  as->d.agg_init_trans.jumpnull = state->steps_len;
3309  }
3310  if (adjust_strict_jumpnull != -1)
3311  {
3312  ExprEvalStep *as = &state->steps[adjust_strict_jumpnull];
3313 
3314  Assert(as->d.agg_strict_trans_check.jumpnull == -1);
3315  as->d.agg_strict_trans_check.jumpnull = state->steps_len;
3316  }
3317 }
3318 
3319 /*
3320  * Build equality expression that can be evaluated using ExecQual(), returning
3321  * true if the expression context's inner/outer tuple are NOT DISTINCT. I.e
3322  * two nulls match, a null and a not-null don't match.
3323  *
3324  * desc: tuple descriptor of the to-be-compared tuples
3325  * numCols: the number of attributes to be examined
3326  * keyColIdx: array of attribute column numbers
3327  * eqFunctions: array of function oids of the equality functions to use
3328  * parent: parent executor node
3329  */
3330 ExprState *
3332  const TupleTableSlotOps *lops, const TupleTableSlotOps *rops,
3333  int numCols,
3334  const AttrNumber *keyColIdx,
3335  const Oid *eqfunctions,
3336  const Oid *collations,
3337  PlanState *parent)
3338 {
3340  ExprEvalStep scratch = {0};
3341  int natt;
3342  int maxatt = -1;
3343  List *adjust_jumps = NIL;
3344  ListCell *lc;
3345 
3346  /*
3347  * When no columns are actually compared, the result's always true. See
3348  * special case in ExecQual().
3349  */
3350  if (numCols == 0)
3351  return NULL;
3352 
3353  state->expr = NULL;
3354  state->flags = EEO_FLAG_IS_QUAL;
3355  state->parent = parent;
3356 
3357  scratch.resvalue = &state->resvalue;
3358  scratch.resnull = &state->resnull;
3359 
3360  /* compute max needed attribute */
3361  for (natt = 0; natt < numCols; natt++)
3362  {
3363  int attno = keyColIdx[natt];
3364 
3365  if (attno > maxatt)
3366  maxatt = attno;
3367  }
3368  Assert(maxatt >= 0);
3369 
3370  /* push deform steps */
3371  scratch.opcode = EEOP_INNER_FETCHSOME;
3372  scratch.d.fetch.last_var = maxatt;
3373  scratch.d.fetch.fixed = false;
3374  scratch.d.fetch.known_desc = ldesc;
3375  scratch.d.fetch.kind = lops;
3376  if (ExecComputeSlotInfo(state, &scratch))
3377  ExprEvalPushStep(state, &scratch);
3378 
3379  scratch.opcode = EEOP_OUTER_FETCHSOME;
3380  scratch.d.fetch.last_var = maxatt;
3381  scratch.d.fetch.fixed = false;
3382  scratch.d.fetch.known_desc = rdesc;
3383  scratch.d.fetch.kind = rops;
3384  if (ExecComputeSlotInfo(state, &scratch))
3385  ExprEvalPushStep(state, &scratch);
3386 
3387  /*
3388  * Start comparing at the last field (least significant sort key). That's
3389  * the most likely to be different if we are dealing with sorted input.
3390  */
3391  for (natt = numCols; --natt >= 0;)
3392  {
3393  int attno = keyColIdx[natt];
3394  Form_pg_attribute latt = TupleDescAttr(ldesc, attno - 1);
3395  Form_pg_attribute ratt = TupleDescAttr(rdesc, attno - 1);
3396  Oid foid = eqfunctions[natt];
3397  Oid collid = collations[natt];
3398  FmgrInfo *finfo;
3399  FunctionCallInfo fcinfo;
3400  AclResult aclresult;
3401 
3402  /* Check permission to call function */
3403  aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
3404  if (aclresult != ACLCHECK_OK)
3405  aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(foid));
3406 
3408 
3409  /* Set up the primary fmgr lookup information */
3410  finfo = palloc0(sizeof(FmgrInfo));
3411  fcinfo = palloc0(SizeForFunctionCallInfo(2));
3412  fmgr_info(foid, finfo);
3413  fmgr_info_set_expr(NULL, finfo);
3414  InitFunctionCallInfoData(*fcinfo, finfo, 2,
3415  collid, NULL, NULL);
3416 
3417  /* left arg */
3418  scratch.opcode = EEOP_INNER_VAR;
3419  scratch.d.var.attnum = attno - 1;
3420  scratch.d.var.vartype = latt->atttypid;
3421  scratch.resvalue = &fcinfo->args[0].value;
3422  scratch.resnull = &fcinfo->args[0].isnull;
3423  ExprEvalPushStep(state, &scratch);
3424 
3425  /* right arg */
3426  scratch.opcode = EEOP_OUTER_VAR;
3427  scratch.d.var.attnum = attno - 1;
3428  scratch.d.var.vartype = ratt->atttypid;
3429  scratch.resvalue = &fcinfo->args[1].value;
3430  scratch.resnull = &fcinfo->args[1].isnull;
3431  ExprEvalPushStep(state, &scratch);
3432 
3433  /* evaluate distinctness */
3434  scratch.opcode = EEOP_NOT_DISTINCT;
3435  scratch.d.func.finfo = finfo;
3436  scratch.d.func.fcinfo_data = fcinfo;
3437  scratch.d.func.fn_addr = finfo->fn_addr;
3438  scratch.d.func.nargs = 2;
3439  scratch.resvalue = &state->resvalue;
3440  scratch.resnull = &state->resnull;
3441  ExprEvalPushStep(state, &scratch);
3442 
3443  /* then emit EEOP_QUAL to detect if result is false (or null) */
3444  scratch.opcode = EEOP_QUAL;
3445  scratch.d.qualexpr.jumpdone = -1;
3446  scratch.resvalue = &state->resvalue;
3447  scratch.resnull = &state->resnull;
3448  ExprEvalPushStep(state, &scratch);
3449  adjust_jumps = lappend_int(adjust_jumps,
3450  state->steps_len - 1);
3451  }
3452 
3453  /* adjust jump targets */
3454  foreach(lc, adjust_jumps)
3455  {
3456  ExprEvalStep *as = &state->steps[lfirst_int(lc)];
3457 
3458  Assert(as->opcode == EEOP_QUAL);
3459  Assert(as->d.qualexpr.jumpdone == -1);
3460  as->d.qualexpr.jumpdone = state->steps_len;
3461  }
3462 
3463  scratch.resvalue = NULL;
3464  scratch.resnull = NULL;
3465  scratch.opcode = EEOP_DONE;
3466  ExprEvalPushStep(state, &scratch);
3467 
3468  ExecReadyExpr(state);
3469 
3470  return state;
3471 }
Datum constvalue
Definition: primnodes.h:200
List * aggdistinct
Definition: primnodes.h:307
Oid minmaxtype
Definition: primnodes.h:1088
bool multidims
Definition: primnodes.h:978
#define NIL
Definition: pg_list.h:65
static void ExecInitCoerceToDomain(ExprEvalStep *scratch, CoerceToDomain *ctest, ExprState *state, Datum *resv, bool *resnull)
Definition: execExpr.c:2779
NodeTag tag
Definition: execnodes.h:64
Definition: fmgr.h:56
struct ExprEvalStep::@52::@94 agg_trans
struct ExprEvalStep::@52::@80 sbsref
List * args
Definition: primnodes.h:1092
List * args
Definition: primnodes.h:1008
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
static void ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable, ExprState *state)
Definition: execExpr.c:2469
#define BTORDER_PROC
Definition: nbtree.h:392
struct ExprEvalStep::@52::@84 xmlexpr
const TupleTableSlotOps * innerops
Definition: execnodes.h:1014
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:300
Expr * arg
Definition: primnodes.h:777
struct PlanState * parent
Definition: execnodes.h:108
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:419
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2674
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1796
ExprState * aggfilter
Definition: execnodes.h:760
struct ExprEvalStep::@52::@88 subplan
ExprState * ExecInitCheck(List *qual, PlanState *parent)
Definition: execExpr.c:296
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1192
struct ExprEvalStep::@52::@54 var
List * args
Definition: primnodes.h:363
List * args
Definition: primnodes.h:463
const TupleTableSlotOps * ExecGetResultSlotOps(PlanState *planstate, bool *isfixed)
Definition: execUtils.c:463
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1652
Datum * resvalue
Definition: execExpr.h:250
#define MAXDIM
Definition: c.h:529
int numaggs
Definition: execnodes.h:2038
Oid GetUserId(void)
Definition: miscinit.c:380
DomainConstraintType constrainttype
Definition: execnodes.h:904
ExprState * ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc, const TupleTableSlotOps *lops, const TupleTableSlotOps *rops, int numCols, const AttrNumber *keyColIdx, const Oid *eqfunctions, const Oid *collations, PlanState *parent)
Definition: execExpr.c:3331
Oid resulttype
Definition: primnodes.h:750
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:837
PGFunction fn_addr
Definition: fmgr.h:58
struct ExprEvalStep::@52::@92 agg_init_trans
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2526
ExprState * ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase, bool doSort, bool doHash)
Definition: execExpr.c:2929
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2049
#define PointerGetDatum(X)
Definition: postgres.h:556
struct ExprEvalStep * steps
Definition: execnodes.h:86
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
ScanState ss
Definition: execnodes.h:2036
void ExecReadyInterpretedExpr(ExprState *state)
bool * innermost_casenull
Definition: execnodes.h:112
ExprState * ExecPrepareCheck(List *qual, EState *estate)
Definition: execExpr.c:541
bool inneropsset
Definition: execnodes.h:1022
struct ExprEvalStep::@52::@85 aggref
Oid resulttype
Definition: primnodes.h:821
#define SizeForFunctionCallInfo(nargs)
Definition: fmgr.h:102
RowCompareType rctype
Definition: primnodes.h:1056
List * opfamilies
Definition: primnodes.h:1058
static bool isAssignmentIndirectionExpr(Expr *expr)
Definition: execExpr.c:2754
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:84
Expr * expression_planner(Expr *expr)
Definition: planner.c:6046
bool * resnull
Definition: execExpr.h:251
List * subPlan
Definition: execnodes.h:967
ParamListInfo ext_params
Definition: execnodes.h:109
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
ExprEvalOp
Definition: execExpr.h:44
Expr * arg
Definition: primnodes.h:800
ParamKind paramkind
Definition: primnodes.h:248
Definition: nodes.h:525
AggSplit aggsplit
Definition: execnodes.h:2041
int errcode(int sqlerrcode)
Definition: elog.c:570
List * args
Definition: primnodes.h:305
AttrNumber varattno
Definition: primnodes.h:172
char * format_type_be(Oid type_oid)
Definition: format_type.c:326
Expr * arg
Definition: primnodes.h:748
Datum * tts_values
Definition: tuptable.h:126
bool inneropsfixed
Definition: execnodes.h:1018
Datum * innermost_domainval
Definition: execnodes.h:114
AggStatePerTrans pertrans
Definition: execnodes.h:2046
EState * state
Definition: execnodes.h:942
TupleTableSlot * resultslot
Definition: execnodes.h:81
unsigned int Oid
Definition: postgres_ext.h:31
union ExprEvalStep::@52 d
Definition: primnodes.h:167
List * refupperindexpr
Definition: primnodes.h:408
#define OidIsValid(objectId)
Definition: c.h:638
ExprState * ExecPrepareExpr(Expr *node, EState *estate)
Definition: execExpr.c:490
#define DO_AGGSPLIT_COMBINE(as)
Definition: nodes.h:787
FunctionCallInfo transfn_fcinfo
Definition: nodeAgg.h:161
struct ExprEvalStep::@52::@61 qualexpr
int numtrans
Definition: execnodes.h:2039
#define lsecond(l)
Definition: pg_list.h:200
bool * innermost_domainnull
Definition: execnodes.h:115
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:207
struct ExprEvalStep::@52::@81 domaincheck
SubPlanState * ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
Definition: nodeSubplan.c:790
struct ExprEvalStep::@52::@90 agg_deserialize
Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
Definition: makefuncs.c:335
#define FUNC_MAX_ARGS
Aggref * aggref
Definition: nodeAgg.h:43
PlanState ps
Definition: execnodes.h:1331
int maxsets
Definition: execnodes.h:2063
static void ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref, ExprState *state, Datum *resv, bool *resnull)
Definition: execExpr.c:2542
ParamCompileHook paramCompile
Definition: params.h:114
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3353
struct ExprEvalStep::@52::@86 grouping_func
MemoryContext es_query_cxt
Definition: execnodes.h:550
bool fn_retset
Definition: fmgr.h:62
static void convert(const int32 val, char *const buf)
Definition: zic.c:1959
struct ExprEvalStep::@52::@73 row
bool resjunk
Definition: primnodes.h:1400
#define linitial(l)
Definition: pg_list.h:195
struct ExprEvalStep::@52::@63 nulltest_row
AggStrategy aggstrategy
Definition: execnodes.h:2040
struct ExprEvalStep::@52::@53 fetch
Oid funcid
Definition: primnodes.h:455
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
List * colnames
Definition: primnodes.h:1024
bool fn_strict
Definition: fmgr.h:61
bool resnull
Definition: execnodes.h:73
Expr * expr
Definition: execnodes.h:95
#define lfirst_int(lc)
Definition: pg_list.h:191
char * get_func_name(Oid funcid)
Definition: lsyscache.c:1410
Oid vartype
Definition: primnodes.h:174
List * args
Definition: primnodes.h:1072
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
Definition: fmgr.h:95
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:124
struct ExprEvalStep::@52::@67 make_readonly
BoolExprType boolop
Definition: primnodes.h:568
static void ExecInitExprSlots(ExprState *state, Node *node)
Definition: execExpr.c:2255
Expr * arg
Definition: primnodes.h:1205
struct ExprEvalStep::@52::@78 fieldstore
struct ExprEvalStep::@52::@72 arraycoerce
#define lfirst_node(type, lc)
Definition: pg_list.h:193
#define outerPlanState(node)
Definition: execnodes.h:1034
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2048
struct ExprEvalStep::@52::@89 alternative_subplan
AttrNumber last_scan
Definition: execExpr.c:56
Aggref * aggref
Definition: execnodes.h:747
const TupleTableSlotOps * scanops
Definition: execnodes.h:1012
bool * tts_isnull
Definition: tuptable.h:128
void check_stack_depth(void)
Definition: postgres.c:3262
struct ExprEvalStep::@52::@66 casetest
#define EEO_FLAG_IS_QUAL
Definition: execnodes.h:60
ExprState * ExecInitExprWithParams(Expr *node, ParamListInfo ext_params)
Definition: execExpr.c:158
List * aggorder
Definition: primnodes.h:306
Expr * arg
Definition: primnodes.h:1228
#define fmgr_info_set_expr(expr, finfo)
Definition: fmgr.h:135
AttrNumber resno
Definition: primnodes.h:1394
#define DatumGetBool(X)
Definition: postgres.h:393
bool upperprovided[MAXDIM]
Definition: execExpr.h:675
List * ExecInitExprList(List *nodes, PlanState *parent)
Definition: execExpr.c:316
AttrNumber last_inner
Definition: execExpr.c:54
AttrNumber last_outer
Definition: execExpr.c:55
struct ExprEvalStep::@52::@58 constval
ExprState * ExecPrepareQual(List *qual, EState *estate)
Definition: execExpr.c:518
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
List * aggdirectargs
Definition: primnodes.h:304
Oid resulttype
Definition: primnodes.h:780
Expr * arg
Definition: primnodes.h:820
List * elements
Definition: primnodes.h:977
bool outeropsset
Definition: execnodes.h:1021
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
Expr * elemexpr
Definition: primnodes.h:845
Definition: type.h:82
struct ExprEvalStep::@52::@60 boolexpr
Datum * innermost_caseval
Definition: execnodes.h:111
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2641
#define ereport(elevel, rest)
Definition: elog.h:141
Datum value
Definition: postgres.h:378
struct ExprEvalStep::@52::@71 arrayexpr
struct ExprEvalStep::@52::@64 param
List * lappend_int(List *list, int datum)
Definition: list.c:340
List * newvals
Definition: primnodes.h:778
#define InvokeFunctionExecuteHook(objectId)
Definition: objectaccess.h:179
List * cols
Definition: primnodes.h:348
List * ExecPrepareExprList(List *nodes, EState *estate)
Definition: execExpr.c:564
Definition: nodes.h:152
List * lappend(List *list, void *datum)
Definition: list.c:322
static void ExecPushExprSlots(ExprState *state, LastAttnumInfo *info)
Definition: execExpr.c:2273
struct ExprEvalStep::@52::@93 agg_strict_trans_check
Index varno
Definition: primnodes.h:170
int num_hashes
Definition: execnodes.h:2074
Definition: nodes.h:151
static void ExecInitExprRec(Expr *node, ExprState *state, Datum *resv, bool *resnull)
Definition: execExpr.c:644
ExprContext * hashcontext
Definition: execnodes.h:2047
struct ExprEvalStep::@52::@87 window_func
List * args
Definition: primnodes.h:919
void * palloc0(Size size)
Definition: mcxt.c:980
AclResult
Definition: acl.h:177
BoolTestType booltesttype
Definition: primnodes.h:1229
static bool ExecComputeSlotInfo(ExprState *state, ExprEvalStep *op)
Definition: execExpr.c:2371
uintptr_t Datum
Definition: postgres.h:367
FmgrInfo * flinfo
Definition: fmgr.h:87
Expr * make_ands_explicit(List *andclauses)
Definition: makefuncs.c:705
void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s)
Definition: execExpr.c:2124
TupleDesc scandesc
Definition: execnodes.h:987
static void ExecReadyExpr(ExprState *state)
Definition: execExpr.c:627
bool jit_compile_expr(struct ExprState *state)
Definition: jit.c:156
bool lowerprovided[MAXDIM]
Definition: execExpr.h:680
Oid opfuncid
Definition: primnodes.h:503
FmgrInfo deserialfn
Definition: nodeAgg.h:86
List * groupingSets
Definition: plannodes.h:814
NullTestType nulltesttype
Definition: primnodes.h:1206
Plan * plan
Definition: execnodes.h:940
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:322
#define InvalidOid
Definition: postgres_ext.h:36
struct ExprEvalStep::@52::@62 jump
int16 attnum
Definition: pg_attribute.h:79
List * named_args
Definition: primnodes.h:1169
struct ExprEvalStep::@52::@56 assign_var
struct ExprEvalStep::@52::@82 convert_rowtype
#define INNER_VAR
Definition: primnodes.h:157
List * args
Definition: primnodes.h:1171
struct ExprEvalStep::@52::@59 func
int executor_errposition(EState *estate, int location)
Definition: execUtils.c:836
bool scanopsfixed
Definition: execnodes.h:1016
#define TYPECACHE_CMP_PROC
Definition: typcache.h:131
#define Max(x, y)
Definition: c.h:898
struct ExprEvalStep::@52::@74 rowcompare_step
ExprContext ** aggcontexts
Definition: execnodes.h:2048
#define makeNode(_type_)
Definition: nodes.h:573
AlternativeSubPlanState * ExecInitAlternativeSubPlan(AlternativeSubPlan *asplan, PlanState *parent)
Definition: nodeSubplan.c:1315
Oid inputcollid
Definition: primnodes.h:462
#define Assert(condition)
Definition: c.h:732
#define lfirst(lc)
Definition: pg_list.h:190
FunctionCallInfo deserialfn_fcinfo
Definition: nodeAgg.h:166
Definition: regguts.h:298
intptr_t opcode
Definition: execExpr.h:247
Expr * aggfilter
Definition: primnodes.h:364
void DecrTupleDescRefCount(TupleDesc tupdesc)
Definition: tupdesc.c:393
Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
Definition: lsyscache.c:744
Expr * expr
Definition: primnodes.h:1393
int paramid
Definition: primnodes.h:249
void InitDomainConstraintRef(Oid type_id, DomainConstraintRef *ref, MemoryContext refctx, bool need_exprstate)
Definition: typcache.c:1202
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:150
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
struct ExprEvalStep::@52::@70 nextvalueexpr
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1840
Oid row_typeid
Definition: primnodes.h:1009
static int list_length(const List *l)
Definition: pg_list.h:169
struct ExprEvalStep::@52::@91 agg_strict_input_check
Oid inputcollid
Definition: primnodes.h:1090
Expr * aggfilter
Definition: primnodes.h:308
Oid inputcollid
Definition: primnodes.h:507
static void ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args, Oid funcid, Oid inputcollid, ExprState *state)
Definition: execExpr.c:2150
bool outeropsfixed
Definition: execnodes.h:1017
bool scanopsset
Definition: execnodes.h:1020
struct LastAttnumInfo LastAttnumInfo
List * args
Definition: primnodes.h:569
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:454
#define InvalidAttrNumber
Definition: attnum.h:23
#define nodeTag(nodeptr)
Definition: nodes.h:530
List * targetlist
Definition: plannodes.h:140
struct ExprEvalStep::@52::@76 minmax
Oid element_typeid
Definition: primnodes.h:976
static bool get_last_attnums_walker(Node *node, LastAttnumInfo *info)
Definition: execExpr.c:2317
static Datum values[MAXATTR]
Definition: bootstrap.c:167
struct ExprEvalStep::@52::@79 sbsref_subscript
Expr * refassgnexpr
Definition: primnodes.h:416
struct ExprEvalStep::@52::@69 sqlvaluefunction
#define Int32GetDatum(X)
Definition: postgres.h:479
e
Definition: preproc-init.c:82
void get_op_opfamily_properties(Oid opno, Oid opfamily, bool ordering_op, int *strategy, Oid *lefttype, Oid *righttype)
Definition: lsyscache.c:133
int16 get_typlen(Oid typid)
Definition: lsyscache.c:1975
TupleDesc ExecTypeFromExprList(List *exprList)
Definition: execTuples.c:1963
int steps_alloc
Definition: execnodes.h:106
void * palloc(Size size)
Definition: mcxt.c:949
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
Definition: execExpr.c:351
int errmsg(const char *fmt,...)
Definition: elog.c:784
int steps_len
Definition: execnodes.h:105
#define ACL_EXECUTE
Definition: parsenodes.h:81
List * fieldnums
Definition: primnodes.h:779
struct ExprEvalStep::@52::@68 iocoerce
List * reflowerindexpr
Definition: primnodes.h:410
bool winagg
Definition: primnodes.h:367
#define elog(elevel,...)
Definition: elog.h:226
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4655
#define forfive(cell1, list1, cell2, list2, cell3, list3, cell4, list4, cell5, list5)
Definition: pg_list.h:489
int i
uint8 flags
Definition: execnodes.h:66
ExprState pi_state
Definition: execnodes.h:331
void * arg
bool ExecCheck(ExprState *state, ExprContext *econtext)
Definition: execExpr.c:597
ParamListInfo es_param_list_info
Definition: execnodes.h:544
Oid refcontainertype
Definition: primnodes.h:404
struct ExprEvalStep::@52::@77 fieldselect
bool argisrow
Definition: primnodes.h:1207
MinMaxOp op
Definition: primnodes.h:1091
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition: execExpr.c:121
Expr * refexpr
Definition: primnodes.h:413
Expr * arg
Definition: primnodes.h:918
struct ExprEvalStep::@52::@83 scalararrayop
Definition: plannodes.h:802
WindowFunc * wfunc
Definition: execnodes.h:758
List * aggs
Definition: execnodes.h:2037
TupleTableSlot * sortslot
Definition: nodeAgg.h:135
struct ExprEvalStep::@52::@55 wholerow
Expr * result
Definition: primnodes.h:931
List * args
Definition: primnodes.h:508
#define innerPlanState(node)
Definition: execnodes.h:1033
List * inputcollids
Definition: primnodes.h:1059
Expr * defresult
Definition: primnodes.h:920
Expr * expr
Definition: primnodes.h:930
ExprContext * pi_exprContext
Definition: execnodes.h:333
Definition: pg_list.h:50
Datum resvalue
Definition: execnodes.h:75
int16 AttrNumber
Definition: attnum.h:21
#define OUTER_VAR
Definition: primnodes.h:158
void ExecTypeSetColNames(TupleDesc typeInfo, List *namesList)
Definition: execTuples.c:2002
JunkFilter * ExecInitJunkFilter(List *targetList, TupleTableSlot *slot)
Definition: execJunk.c:60
Oid paramtype
Definition: primnodes.h:250
bool constisnull
Definition: primnodes.h:201
static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate, ExprEvalStep *scratch, FunctionCallInfo fcinfo, AggStatePerTrans pertrans, int transno, int setno, int setoff, bool ishash)
Definition: execExpr.c:3226
#define lfirst_oid(lc)
Definition: pg_list.h:192
const TupleTableSlotOps * outerops
Definition: execnodes.h:1013
struct ExprEvalStep::@52::@75 rowcompare_final
TupleDesc lookup_rowtype_tupdesc_copy(Oid type_id, int32 typmod)
Definition: typcache.c:1686
Definition: nodes.h:153
AttrNumber fieldnum
Definition: primnodes.h:749
struct ExprEvalStep::@52::@57 assign_tmp