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