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