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