PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
execQual.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * execQual.c
4  * Routines to evaluate qualification and targetlist expressions
5  *
6  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/executor/execQual.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 /*
16  * INTERFACE ROUTINES
17  * ExecEvalExpr - (now a macro) evaluate an expression, return a datum
18  * ExecEvalExprSwitchContext - same, but switch into eval memory context
19  * ExecQual - return true/false if qualification is satisfied
20  * ExecProject - form a new tuple by projecting the given tuple
21  *
22  * NOTES
23  * The more heavily used ExecEvalExpr routines, such as ExecEvalScalarVar,
24  * are hotspots. Making these faster will speed up the entire system.
25  *
26  * ExecProject() is used to make tuple projections. Rather then
27  * trying to speed it up, the execution plan should be pre-processed
28  * to facilitate attribute sharing between nodes wherever possible,
29  * instead of doing needless copying. -cim 5/31/91
30  *
31  * During expression evaluation, we check_stack_depth only in
32  * ExecMakeFunctionResultSet/ExecMakeFunctionResultNoSets rather than at
33  * every single node. This is a compromise that trades off precision of
34  * the stack limit setting to gain speed.
35  */
36 
37 #include "postgres.h"
38 
39 #include "access/htup_details.h"
40 #include "access/nbtree.h"
41 #include "access/tupconvert.h"
42 #include "catalog/objectaccess.h"
43 #include "catalog/pg_type.h"
44 #include "executor/execdebug.h"
45 #include "executor/nodeSubplan.h"
46 #include "funcapi.h"
47 #include "miscadmin.h"
48 #include "nodes/makefuncs.h"
49 #include "nodes/nodeFuncs.h"
50 #include "optimizer/planner.h"
51 #include "parser/parse_coerce.h"
52 #include "parser/parsetree.h"
53 #include "pgstat.h"
54 #include "utils/acl.h"
55 #include "utils/builtins.h"
56 #include "utils/date.h"
57 #include "utils/lsyscache.h"
58 #include "utils/memutils.h"
59 #include "utils/timestamp.h"
60 #include "utils/typcache.h"
61 #include "utils/xml.h"
62 
63 
64 /* static function decls */
66  ExprContext *econtext,
67  bool *isNull);
68 static bool isAssignmentIndirectionExpr(ExprState *exprstate);
69 static Datum ExecEvalAggref(AggrefExprState *aggref,
70  ExprContext *econtext,
71  bool *isNull);
73  ExprContext *econtext,
74  bool *isNull);
75 static Datum ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
76  bool *isNull);
77 static Datum ExecEvalScalarVarFast(ExprState *exprstate, ExprContext *econtext,
78  bool *isNull);
80  ExprContext *econtext,
81  bool *isNull);
83  ExprContext *econtext,
84  bool *isNull);
86  ExprContext *econtext,
87  bool *isNull);
88 static Datum ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
89  bool *isNull);
90 static Datum ExecEvalParamExec(ExprState *exprstate, ExprContext *econtext,
91  bool *isNull);
92 static Datum ExecEvalParamExtern(ExprState *exprstate, ExprContext *econtext,
93  bool *isNull);
94 static void init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache,
95  MemoryContext fcacheCxt, bool allowSRF, bool needDescForSRF);
96 static void ShutdownFuncExpr(Datum arg);
97 static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod,
98  TupleDesc *cache_field, ExprContext *econtext);
99 static void ShutdownTupleDescRef(Datum arg);
100 static void ExecEvalFuncArgs(FunctionCallInfo fcinfo,
101  List *argList, ExprContext *econtext);
102 static void ExecPrepareTuplestoreResult(FuncExprState *fcache,
103  ExprContext *econtext,
104  Tuplestorestate *resultStore,
105  TupleDesc resultDesc);
106 static void tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc);
108  ExprContext *econtext,
109  bool *isNull);
110 static Datum ExecEvalFunc(FuncExprState *fcache, ExprContext *econtext,
111  bool *isNull);
112 static Datum ExecEvalOper(FuncExprState *fcache, ExprContext *econtext,
113  bool *isNull);
114 static Datum ExecEvalDistinct(FuncExprState *fcache, ExprContext *econtext,
115  bool *isNull);
117  ExprContext *econtext,
118  bool *isNull);
119 static Datum ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
120  bool *isNull);
121 static Datum ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
122  bool *isNull);
123 static Datum ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
124  bool *isNull);
126  ExprContext *econtext,
127  bool *isNull);
128 static Datum ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
129  bool *isNull);
130 static Datum ExecEvalCaseTestExpr(ExprState *exprstate,
131  ExprContext *econtext,
132  bool *isNull);
133 static Datum ExecEvalArray(ArrayExprState *astate,
134  ExprContext *econtext,
135  bool *isNull);
136 static Datum ExecEvalRow(RowExprState *rstate,
137  ExprContext *econtext,
138  bool *isNull);
140  ExprContext *econtext,
141  bool *isNull);
142 static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr,
143  ExprContext *econtext,
144  bool *isNull);
145 static Datum ExecEvalMinMax(MinMaxExprState *minmaxExpr,
146  ExprContext *econtext,
147  bool *isNull);
149  ExprContext *econtext,
150  bool *isNull);
151 static Datum ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
152  bool *isNull);
153 static Datum ExecEvalNullIf(FuncExprState *nullIfExpr,
154  ExprContext *econtext,
155  bool *isNull);
156 static Datum ExecEvalNullTest(NullTestState *nstate,
157  ExprContext *econtext,
158  bool *isNull);
160  ExprContext *econtext,
161  bool *isNull);
163  ExprContext *econtext,
164  bool *isNull);
166  ExprContext *econtext,
167  bool *isNull);
169  ExprContext *econtext,
170  bool *isNull);
172  ExprContext *econtext,
173  bool *isNull);
174 static Datum ExecEvalRelabelType(GenericExprState *exprstate,
175  ExprContext *econtext,
176  bool *isNull);
178  ExprContext *econtext,
179  bool *isNull);
181  ExprContext *econtext,
182  bool *isNull);
183 static Datum ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
184  bool *isNull);
186  ExprContext *econtext,
187  bool *isNull);
188 
189 
190 /* ----------------------------------------------------------------
191  * ExecEvalExpr routines
192  *
193  * Recursively evaluate a targetlist or qualification expression.
194  *
195  * Each of the following routines having the signature
196  * Datum ExecEvalFoo(ExprState *expression,
197  * ExprContext *econtext,
198  * bool *isNull);
199  * is responsible for evaluating one type or subtype of ExprState node.
200  * They are normally called via the ExecEvalExpr macro, which makes use of
201  * the function pointer set up when the ExprState node was built by
202  * ExecInitExpr. (In some cases, we change this pointer later to avoid
203  * re-executing one-time overhead.)
204  *
205  * Note: for notational simplicity we declare these functions as taking the
206  * specific type of ExprState that they work on. This requires casting when
207  * assigning the function pointer in ExecInitExpr. Be careful that the
208  * function signature is declared correctly, because the cast suppresses
209  * automatic checking!
210  *
211  *
212  * All these functions share this calling convention:
213  *
214  * Inputs:
215  * expression: the expression state tree to evaluate
216  * econtext: evaluation context information
217  *
218  * Outputs:
219  * return value: Datum value of result
220  * *isNull: set to TRUE if result is NULL (actual return value is
221  * meaningless if so); set to FALSE if non-null result
222  *
223  * The caller should already have switched into the temporary memory
224  * context econtext->ecxt_per_tuple_memory. The convenience entry point
225  * ExecEvalExprSwitchContext() is provided for callers who don't prefer to
226  * do the switch in an outer loop. We do not do the switch in these routines
227  * because it'd be a waste of cycles during nested expression evaluation.
228  * ----------------------------------------------------------------
229  */
230 
231 
232 /*----------
233  * ExecEvalArrayRef
234  *
235  * This function takes an ArrayRef and returns the extracted Datum
236  * if it's a simple reference, or the modified array value if it's
237  * an array assignment (i.e., array element or slice insertion).
238  *
239  * NOTE: if we get a NULL result from a subscript expression, we return NULL
240  * when it's an array reference, or raise an error when it's an assignment.
241  *----------
242  */
243 static Datum
245  ExprContext *econtext,
246  bool *isNull)
247 {
248  ArrayRef *arrayRef = (ArrayRef *) astate->xprstate.expr;
249  Datum array_source;
250  bool isAssignment = (arrayRef->refassgnexpr != NULL);
251  bool eisnull;
252  ListCell *l;
253  int i = 0,
254  j = 0;
255  IntArray upper,
256  lower;
257  bool upperProvided[MAXDIM],
258  lowerProvided[MAXDIM];
259  int *lIndex;
260 
261  array_source = ExecEvalExpr(astate->refexpr,
262  econtext,
263  isNull);
264 
265  /*
266  * If refexpr yields NULL, and it's a fetch, then result is NULL. In the
267  * assignment case, we'll cons up something below.
268  */
269  if (*isNull)
270  {
271  if (!isAssignment)
272  return (Datum) NULL;
273  }
274 
275  foreach(l, astate->refupperindexpr)
276  {
277  ExprState *eltstate = (ExprState *) lfirst(l);
278 
279  if (i >= MAXDIM)
280  ereport(ERROR,
281  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
282  errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
283  i + 1, MAXDIM)));
284 
285  if (eltstate == NULL)
286  {
287  /* Slice bound is omitted, so use array's upper bound */
288  Assert(astate->reflowerindexpr != NIL);
289  upperProvided[i++] = false;
290  continue;
291  }
292  upperProvided[i] = true;
293 
294  upper.indx[i++] = DatumGetInt32(ExecEvalExpr(eltstate,
295  econtext,
296  &eisnull));
297  /* If any index expr yields NULL, result is NULL or error */
298  if (eisnull)
299  {
300  if (isAssignment)
301  ereport(ERROR,
302  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
303  errmsg("array subscript in assignment must not be null")));
304  *isNull = true;
305  return (Datum) NULL;
306  }
307  }
308 
309  if (astate->reflowerindexpr != NIL)
310  {
311  foreach(l, astate->reflowerindexpr)
312  {
313  ExprState *eltstate = (ExprState *) lfirst(l);
314 
315  if (j >= MAXDIM)
316  ereport(ERROR,
317  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
318  errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
319  j + 1, MAXDIM)));
320 
321  if (eltstate == NULL)
322  {
323  /* Slice bound is omitted, so use array's lower bound */
324  lowerProvided[j++] = false;
325  continue;
326  }
327  lowerProvided[j] = true;
328 
329  lower.indx[j++] = DatumGetInt32(ExecEvalExpr(eltstate,
330  econtext,
331  &eisnull));
332  /* If any index expr yields NULL, result is NULL or error */
333  if (eisnull)
334  {
335  if (isAssignment)
336  ereport(ERROR,
337  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
338  errmsg("array subscript in assignment must not be null")));
339  *isNull = true;
340  return (Datum) NULL;
341  }
342  }
343  /* this can't happen unless parser messed up */
344  if (i != j)
345  elog(ERROR, "upper and lower index lists are not same length");
346  lIndex = lower.indx;
347  }
348  else
349  lIndex = NULL;
350 
351  if (isAssignment)
352  {
353  Datum sourceData;
354  Datum save_datum;
355  bool save_isNull;
356 
357  /*
358  * We might have a nested-assignment situation, in which the
359  * refassgnexpr is itself a FieldStore or ArrayRef that needs to
360  * obtain and modify the previous value of the array element or slice
361  * being replaced. If so, we have to extract that value from the
362  * array and pass it down via the econtext's caseValue. It's safe to
363  * reuse the CASE mechanism because there cannot be a CASE between
364  * here and where the value would be needed, and an array assignment
365  * can't be within a CASE either. (So saving and restoring the
366  * caseValue is just paranoia, but let's do it anyway.)
367  *
368  * Since fetching the old element might be a nontrivial expense, do it
369  * only if the argument appears to actually need it.
370  */
371  save_datum = econtext->caseValue_datum;
372  save_isNull = econtext->caseValue_isNull;
373 
375  {
376  if (*isNull)
377  {
378  /* whole array is null, so any element or slice is too */
379  econtext->caseValue_datum = (Datum) 0;
380  econtext->caseValue_isNull = true;
381  }
382  else if (lIndex == NULL)
383  {
384  econtext->caseValue_datum =
385  array_get_element(array_source, i,
386  upper.indx,
387  astate->refattrlength,
388  astate->refelemlength,
389  astate->refelembyval,
390  astate->refelemalign,
391  &econtext->caseValue_isNull);
392  }
393  else
394  {
395  /* this is currently unreachable */
396  econtext->caseValue_datum =
397  array_get_slice(array_source, i,
398  upper.indx, lower.indx,
399  upperProvided, lowerProvided,
400  astate->refattrlength,
401  astate->refelemlength,
402  astate->refelembyval,
403  astate->refelemalign);
404  econtext->caseValue_isNull = false;
405  }
406  }
407  else
408  {
409  /* argument shouldn't need caseValue, but for safety set it null */
410  econtext->caseValue_datum = (Datum) 0;
411  econtext->caseValue_isNull = true;
412  }
413 
414  /*
415  * Evaluate the value to be assigned into the array.
416  */
417  sourceData = ExecEvalExpr(astate->refassgnexpr,
418  econtext,
419  &eisnull);
420 
421  econtext->caseValue_datum = save_datum;
422  econtext->caseValue_isNull = save_isNull;
423 
424  /*
425  * For an assignment to a fixed-length array type, both the original
426  * array and the value to be assigned into it must be non-NULL, else
427  * we punt and return the original array.
428  */
429  if (astate->refattrlength > 0) /* fixed-length array? */
430  if (eisnull || *isNull)
431  return array_source;
432 
433  /*
434  * For assignment to varlena arrays, we handle a NULL original array
435  * by substituting an empty (zero-dimensional) array; insertion of the
436  * new element will result in a singleton array value. It does not
437  * matter whether the new element is NULL.
438  */
439  if (*isNull)
440  {
441  array_source = PointerGetDatum(construct_empty_array(arrayRef->refelemtype));
442  *isNull = false;
443  }
444 
445  if (lIndex == NULL)
446  return array_set_element(array_source, i,
447  upper.indx,
448  sourceData,
449  eisnull,
450  astate->refattrlength,
451  astate->refelemlength,
452  astate->refelembyval,
453  astate->refelemalign);
454  else
455  return array_set_slice(array_source, i,
456  upper.indx, lower.indx,
457  upperProvided, lowerProvided,
458  sourceData,
459  eisnull,
460  astate->refattrlength,
461  astate->refelemlength,
462  astate->refelembyval,
463  astate->refelemalign);
464  }
465 
466  if (lIndex == NULL)
467  return array_get_element(array_source, i,
468  upper.indx,
469  astate->refattrlength,
470  astate->refelemlength,
471  astate->refelembyval,
472  astate->refelemalign,
473  isNull);
474  else
475  return array_get_slice(array_source, i,
476  upper.indx, lower.indx,
477  upperProvided, lowerProvided,
478  astate->refattrlength,
479  astate->refelemlength,
480  astate->refelembyval,
481  astate->refelemalign);
482 }
483 
484 /*
485  * Helper for ExecEvalArrayRef: is expr a nested FieldStore or ArrayRef
486  * that might need the old element value passed down?
487  *
488  * (We could use this in ExecEvalFieldStore too, but in that case passing
489  * the old value is so cheap there's no need.)
490  */
491 static bool
493 {
494  if (exprstate == NULL)
495  return false; /* just paranoia */
496  if (IsA(exprstate, FieldStoreState))
497  {
498  FieldStore *fstore = (FieldStore *) exprstate->expr;
499 
500  if (fstore->arg && IsA(fstore->arg, CaseTestExpr))
501  return true;
502  }
503  else if (IsA(exprstate, ArrayRefExprState))
504  {
505  ArrayRef *arrayRef = (ArrayRef *) exprstate->expr;
506 
507  if (arrayRef->refexpr && IsA(arrayRef->refexpr, CaseTestExpr))
508  return true;
509  }
510  return false;
511 }
512 
513 /* ----------------------------------------------------------------
514  * ExecEvalAggref
515  *
516  * Returns a Datum whose value is the value of the precomputed
517  * aggregate found in the given expression context.
518  * ----------------------------------------------------------------
519  */
520 static Datum
522  bool *isNull)
523 {
524  if (econtext->ecxt_aggvalues == NULL) /* safety check */
525  elog(ERROR, "no aggregates in this expression context");
526 
527  *isNull = econtext->ecxt_aggnulls[aggref->aggno];
528  return econtext->ecxt_aggvalues[aggref->aggno];
529 }
530 
531 /* ----------------------------------------------------------------
532  * ExecEvalWindowFunc
533  *
534  * Returns a Datum whose value is the value of the precomputed
535  * window function found in the given expression context.
536  * ----------------------------------------------------------------
537  */
538 static Datum
540  bool *isNull)
541 {
542  if (econtext->ecxt_aggvalues == NULL) /* safety check */
543  elog(ERROR, "no window functions in this expression context");
544 
545  *isNull = econtext->ecxt_aggnulls[wfunc->wfuncno];
546  return econtext->ecxt_aggvalues[wfunc->wfuncno];
547 }
548 
549 /* ----------------------------------------------------------------
550  * ExecEvalScalarVar
551  *
552  * Returns a Datum whose value is the value of a scalar (not whole-row)
553  * range variable with respect to given expression context.
554  *
555  * Note: ExecEvalScalarVar is executed only the first time through in a given
556  * plan; it changes the ExprState's function pointer to pass control directly
557  * to ExecEvalScalarVarFast after making one-time checks.
558  * ----------------------------------------------------------------
559  */
560 static Datum
562  bool *isNull)
563 {
564  Var *variable = (Var *) exprstate->expr;
565  TupleTableSlot *slot;
566  AttrNumber attnum;
567 
568  /* Get the input slot and attribute number we want */
569  switch (variable->varno)
570  {
571  case INNER_VAR: /* get the tuple from the inner node */
572  slot = econtext->ecxt_innertuple;
573  break;
574 
575  case OUTER_VAR: /* get the tuple from the outer node */
576  slot = econtext->ecxt_outertuple;
577  break;
578 
579  /* INDEX_VAR is handled by default case */
580 
581  default: /* get the tuple from the relation being
582  * scanned */
583  slot = econtext->ecxt_scantuple;
584  break;
585  }
586 
587  attnum = variable->varattno;
588 
589  /* This was checked by ExecInitExpr */
590  Assert(attnum != InvalidAttrNumber);
591 
592  /*
593  * If it's a user attribute, check validity (bogus system attnums will be
594  * caught inside slot_getattr). What we have to check for here is the
595  * possibility of an attribute having been changed in type since the plan
596  * tree was created. Ideally the plan will get invalidated and not
597  * re-used, but just in case, we keep these defenses. Fortunately it's
598  * sufficient to check once on the first time through.
599  *
600  * Note: we allow a reference to a dropped attribute. slot_getattr will
601  * force a NULL result in such cases.
602  *
603  * Note: ideally we'd check typmod as well as typid, but that seems
604  * impractical at the moment: in many cases the tupdesc will have been
605  * generated by ExecTypeFromTL(), and that can't guarantee to generate an
606  * accurate typmod in all cases, because some expression node types don't
607  * carry typmod.
608  */
609  if (attnum > 0)
610  {
611  TupleDesc slot_tupdesc = slot->tts_tupleDescriptor;
612  Form_pg_attribute attr;
613 
614  if (attnum > slot_tupdesc->natts) /* should never happen */
615  elog(ERROR, "attribute number %d exceeds number of columns %d",
616  attnum, slot_tupdesc->natts);
617 
618  attr = slot_tupdesc->attrs[attnum - 1];
619 
620  /* can't check type if dropped, since atttypid is probably 0 */
621  if (!attr->attisdropped)
622  {
623  if (variable->vartype != attr->atttypid)
624  ereport(ERROR,
625  (errcode(ERRCODE_DATATYPE_MISMATCH),
626  errmsg("attribute %d has wrong type", attnum),
627  errdetail("Table has type %s, but query expects %s.",
628  format_type_be(attr->atttypid),
629  format_type_be(variable->vartype))));
630  }
631  }
632 
633  /* Skip the checking on future executions of node */
634  exprstate->evalfunc = ExecEvalScalarVarFast;
635 
636  /* Fetch the value from the slot */
637  return slot_getattr(slot, attnum, isNull);
638 }
639 
640 /* ----------------------------------------------------------------
641  * ExecEvalScalarVarFast
642  *
643  * Returns a Datum for a scalar variable.
644  * ----------------------------------------------------------------
645  */
646 static Datum
648  bool *isNull)
649 {
650  Var *variable = (Var *) exprstate->expr;
651  TupleTableSlot *slot;
652  AttrNumber attnum;
653 
654  /* Get the input slot and attribute number we want */
655  switch (variable->varno)
656  {
657  case INNER_VAR: /* get the tuple from the inner node */
658  slot = econtext->ecxt_innertuple;
659  break;
660 
661  case OUTER_VAR: /* get the tuple from the outer node */
662  slot = econtext->ecxt_outertuple;
663  break;
664 
665  /* INDEX_VAR is handled by default case */
666 
667  default: /* get the tuple from the relation being
668  * scanned */
669  slot = econtext->ecxt_scantuple;
670  break;
671  }
672 
673  attnum = variable->varattno;
674 
675  /* Fetch the value from the slot */
676  return slot_getattr(slot, attnum, isNull);
677 }
678 
679 /* ----------------------------------------------------------------
680  * ExecEvalWholeRowVar
681  *
682  * Returns a Datum whose value is the value of a whole-row range
683  * variable with respect to given expression context.
684  *
685  * Note: ExecEvalWholeRowVar is executed only the first time through in a
686  * given plan; it changes the ExprState's function pointer to pass control
687  * directly to ExecEvalWholeRowFast or ExecEvalWholeRowSlow after making
688  * one-time checks.
689  * ----------------------------------------------------------------
690  */
691 static Datum
693  bool *isNull)
694 {
695  Var *variable = (Var *) wrvstate->xprstate.expr;
696  TupleTableSlot *slot;
697  TupleDesc output_tupdesc;
698  MemoryContext oldcontext;
699  bool needslow = false;
700 
701  /* This was checked by ExecInitExpr */
702  Assert(variable->varattno == InvalidAttrNumber);
703 
704  /* Get the input slot we want */
705  switch (variable->varno)
706  {
707  case INNER_VAR: /* get the tuple from the inner node */
708  slot = econtext->ecxt_innertuple;
709  break;
710 
711  case OUTER_VAR: /* get the tuple from the outer node */
712  slot = econtext->ecxt_outertuple;
713  break;
714 
715  /* INDEX_VAR is handled by default case */
716 
717  default: /* get the tuple from the relation being
718  * scanned */
719  slot = econtext->ecxt_scantuple;
720  break;
721  }
722 
723  /*
724  * If the input tuple came from a subquery, it might contain "resjunk"
725  * columns (such as GROUP BY or ORDER BY columns), which we don't want to
726  * keep in the whole-row result. We can get rid of such columns by
727  * passing the tuple through a JunkFilter --- but to make one, we have to
728  * lay our hands on the subquery's targetlist. Fortunately, there are not
729  * very many cases where this can happen, and we can identify all of them
730  * by examining our parent PlanState. We assume this is not an issue in
731  * standalone expressions that don't have parent plans. (Whole-row Vars
732  * can occur in such expressions, but they will always be referencing
733  * table rows.)
734  */
735  if (wrvstate->parent)
736  {
737  PlanState *subplan = NULL;
738 
739  switch (nodeTag(wrvstate->parent))
740  {
741  case T_SubqueryScanState:
742  subplan = ((SubqueryScanState *) wrvstate->parent)->subplan;
743  break;
744  case T_CteScanState:
745  subplan = ((CteScanState *) wrvstate->parent)->cteplanstate;
746  break;
747  default:
748  break;
749  }
750 
751  if (subplan)
752  {
753  bool junk_filter_needed = false;
754  ListCell *tlist;
755 
756  /* Detect whether subplan tlist actually has any junk columns */
757  foreach(tlist, subplan->plan->targetlist)
758  {
759  TargetEntry *tle = (TargetEntry *) lfirst(tlist);
760 
761  if (tle->resjunk)
762  {
763  junk_filter_needed = true;
764  break;
765  }
766  }
767 
768  /* If so, build the junkfilter in the query memory context */
769  if (junk_filter_needed)
770  {
771  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
772  wrvstate->wrv_junkFilter =
774  ExecGetResultType(subplan)->tdhasoid,
775  ExecInitExtraTupleSlot(wrvstate->parent->state));
776  MemoryContextSwitchTo(oldcontext);
777  }
778  }
779  }
780 
781  /* Apply the junkfilter if any */
782  if (wrvstate->wrv_junkFilter != NULL)
783  slot = ExecFilterJunk(wrvstate->wrv_junkFilter, slot);
784 
785  /*
786  * If the Var identifies a named composite type, we must check that the
787  * actual tuple type is compatible with it.
788  */
789  if (variable->vartype != RECORDOID)
790  {
791  TupleDesc var_tupdesc;
792  TupleDesc slot_tupdesc;
793  int i;
794 
795  /*
796  * We really only care about numbers of attributes and data types.
797  * Also, we can ignore type mismatch on columns that are dropped in
798  * the destination type, so long as (1) the physical storage matches
799  * or (2) the actual column value is NULL. Case (1) is helpful in
800  * some cases involving out-of-date cached plans, while case (2) is
801  * expected behavior in situations such as an INSERT into a table with
802  * dropped columns (the planner typically generates an INT4 NULL
803  * regardless of the dropped column type). If we find a dropped
804  * column and cannot verify that case (1) holds, we have to use
805  * ExecEvalWholeRowSlow to check (2) for each row.
806  */
807  var_tupdesc = lookup_rowtype_tupdesc(variable->vartype, -1);
808 
809  slot_tupdesc = slot->tts_tupleDescriptor;
810 
811  if (var_tupdesc->natts != slot_tupdesc->natts)
812  ereport(ERROR,
813  (errcode(ERRCODE_DATATYPE_MISMATCH),
814  errmsg("table row type and query-specified row type do not match"),
815  errdetail_plural("Table row contains %d attribute, but query expects %d.",
816  "Table row contains %d attributes, but query expects %d.",
817  slot_tupdesc->natts,
818  slot_tupdesc->natts,
819  var_tupdesc->natts)));
820 
821  for (i = 0; i < var_tupdesc->natts; i++)
822  {
823  Form_pg_attribute vattr = var_tupdesc->attrs[i];
824  Form_pg_attribute sattr = slot_tupdesc->attrs[i];
825 
826  if (vattr->atttypid == sattr->atttypid)
827  continue; /* no worries */
828  if (!vattr->attisdropped)
829  ereport(ERROR,
830  (errcode(ERRCODE_DATATYPE_MISMATCH),
831  errmsg("table row type and query-specified row type do not match"),
832  errdetail("Table has type %s at ordinal position %d, but query expects %s.",
833  format_type_be(sattr->atttypid),
834  i + 1,
835  format_type_be(vattr->atttypid))));
836 
837  if (vattr->attlen != sattr->attlen ||
838  vattr->attalign != sattr->attalign)
839  needslow = true; /* need runtime check for null */
840  }
841 
842  /*
843  * Use the variable's declared rowtype as the descriptor for the
844  * output values, modulo possibly assigning new column names below. In
845  * particular, we *must* absorb any attisdropped markings.
846  */
847  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
848  output_tupdesc = CreateTupleDescCopy(var_tupdesc);
849  MemoryContextSwitchTo(oldcontext);
850 
851  ReleaseTupleDesc(var_tupdesc);
852  }
853  else
854  {
855  /*
856  * In the RECORD case, we use the input slot's rowtype as the
857  * descriptor for the output values, modulo possibly assigning new
858  * column names below.
859  */
860  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
861  output_tupdesc = CreateTupleDescCopy(slot->tts_tupleDescriptor);
862  MemoryContextSwitchTo(oldcontext);
863  }
864 
865  /*
866  * Construct a tuple descriptor for the composite values we'll produce,
867  * and make sure its record type is "blessed". The main reason to do this
868  * is to be sure that operations such as row_to_json() will see the
869  * desired column names when they look up the descriptor from the type
870  * information embedded in the composite values.
871  *
872  * We already got the correct physical datatype info above, but now we
873  * should try to find the source RTE and adopt its column aliases, in case
874  * they are different from the original rowtype's names. For example, in
875  * "SELECT foo(t) FROM tab t(x,y)", the first two columns in the composite
876  * output should be named "x" and "y" regardless of tab's column names.
877  *
878  * If we can't locate the RTE, assume the column names we've got are OK.
879  * (As of this writing, the only cases where we can't locate the RTE are
880  * in execution of trigger WHEN clauses, and then the Var will have the
881  * trigger's relation's rowtype, so its names are fine.) Also, if the
882  * creator of the RTE didn't bother to fill in an eref field, assume our
883  * column names are OK. (This happens in COPY, and perhaps other places.)
884  */
885  if (econtext->ecxt_estate &&
886  variable->varno <= list_length(econtext->ecxt_estate->es_range_table))
887  {
888  RangeTblEntry *rte = rt_fetch(variable->varno,
889  econtext->ecxt_estate->es_range_table);
890 
891  if (rte->eref)
892  ExecTypeSetColNames(output_tupdesc, rte->eref->colnames);
893  }
894 
895  /* Bless the tupdesc if needed, and save it in the execution state */
896  wrvstate->wrv_tupdesc = BlessTupleDesc(output_tupdesc);
897 
898  /* Skip all the above on future executions of node */
899  if (needslow)
901  else
903 
904  /* Fetch the value */
905  return (*wrvstate->xprstate.evalfunc) ((ExprState *) wrvstate, econtext,
906  isNull);
907 }
908 
909 /* ----------------------------------------------------------------
910  * ExecEvalWholeRowFast
911  *
912  * Returns a Datum for a whole-row variable.
913  * ----------------------------------------------------------------
914  */
915 static Datum
917  bool *isNull)
918 {
919  Var *variable = (Var *) wrvstate->xprstate.expr;
920  TupleTableSlot *slot;
921  HeapTupleHeader dtuple;
922 
923  *isNull = false;
924 
925  /* Get the input slot we want */
926  switch (variable->varno)
927  {
928  case INNER_VAR: /* get the tuple from the inner node */
929  slot = econtext->ecxt_innertuple;
930  break;
931 
932  case OUTER_VAR: /* get the tuple from the outer node */
933  slot = econtext->ecxt_outertuple;
934  break;
935 
936  /* INDEX_VAR is handled by default case */
937 
938  default: /* get the tuple from the relation being
939  * scanned */
940  slot = econtext->ecxt_scantuple;
941  break;
942  }
943 
944  /* Apply the junkfilter if any */
945  if (wrvstate->wrv_junkFilter != NULL)
946  slot = ExecFilterJunk(wrvstate->wrv_junkFilter, slot);
947 
948  /*
949  * Copy the slot tuple and make sure any toasted fields get detoasted.
950  */
952 
953  /*
954  * Label the datum with the composite type info we identified before.
955  */
956  HeapTupleHeaderSetTypeId(dtuple, wrvstate->wrv_tupdesc->tdtypeid);
957  HeapTupleHeaderSetTypMod(dtuple, wrvstate->wrv_tupdesc->tdtypmod);
958 
959  return PointerGetDatum(dtuple);
960 }
961 
962 /* ----------------------------------------------------------------
963  * ExecEvalWholeRowSlow
964  *
965  * Returns a Datum for a whole-row variable, in the "slow" case where
966  * we can't just copy the subplan's output.
967  * ----------------------------------------------------------------
968  */
969 static Datum
971  bool *isNull)
972 {
973  Var *variable = (Var *) wrvstate->xprstate.expr;
974  TupleTableSlot *slot;
975  HeapTuple tuple;
977  TupleDesc var_tupdesc;
978  HeapTupleHeader dtuple;
979  int i;
980 
981  *isNull = false;
982 
983  /* Get the input slot we want */
984  switch (variable->varno)
985  {
986  case INNER_VAR: /* get the tuple from the inner node */
987  slot = econtext->ecxt_innertuple;
988  break;
989 
990  case OUTER_VAR: /* get the tuple from the outer node */
991  slot = econtext->ecxt_outertuple;
992  break;
993 
994  /* INDEX_VAR is handled by default case */
995 
996  default: /* get the tuple from the relation being
997  * scanned */
998  slot = econtext->ecxt_scantuple;
999  break;
1000  }
1001 
1002  /* Apply the junkfilter if any */
1003  if (wrvstate->wrv_junkFilter != NULL)
1004  slot = ExecFilterJunk(wrvstate->wrv_junkFilter, slot);
1005 
1006  tuple = ExecFetchSlotTuple(slot);
1007  tupleDesc = slot->tts_tupleDescriptor;
1008 
1009  /* wrv_tupdesc is a good enough representation of the Var's rowtype */
1010  Assert(variable->vartype != RECORDOID);
1011  var_tupdesc = wrvstate->wrv_tupdesc;
1012 
1013  /* Check to see if any dropped attributes are non-null */
1014  for (i = 0; i < var_tupdesc->natts; i++)
1015  {
1016  Form_pg_attribute vattr = var_tupdesc->attrs[i];
1017  Form_pg_attribute sattr = tupleDesc->attrs[i];
1018 
1019  if (!vattr->attisdropped)
1020  continue; /* already checked non-dropped cols */
1021  if (heap_attisnull(tuple, i + 1))
1022  continue; /* null is always okay */
1023  if (vattr->attlen != sattr->attlen ||
1024  vattr->attalign != sattr->attalign)
1025  ereport(ERROR,
1026  (errcode(ERRCODE_DATATYPE_MISMATCH),
1027  errmsg("table row type and query-specified row type do not match"),
1028  errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
1029  i + 1)));
1030  }
1031 
1032  /*
1033  * Copy the slot tuple and make sure any toasted fields get detoasted.
1034  */
1036 
1037  /*
1038  * Label the datum with the composite type info we identified before.
1039  */
1040  HeapTupleHeaderSetTypeId(dtuple, wrvstate->wrv_tupdesc->tdtypeid);
1041  HeapTupleHeaderSetTypMod(dtuple, wrvstate->wrv_tupdesc->tdtypmod);
1042 
1043  return PointerGetDatum(dtuple);
1044 }
1045 
1046 /* ----------------------------------------------------------------
1047  * ExecEvalConst
1048  *
1049  * Returns the value of a constant.
1050  *
1051  * Note that for pass-by-ref datatypes, we return a pointer to the
1052  * actual constant node. This is one of the reasons why functions
1053  * must treat their input arguments as read-only.
1054  * ----------------------------------------------------------------
1055  */
1056 static Datum
1057 ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
1058  bool *isNull)
1059 {
1060  Const *con = (Const *) exprstate->expr;
1061 
1062  *isNull = con->constisnull;
1063  return con->constvalue;
1064 }
1065 
1066 /* ----------------------------------------------------------------
1067  * ExecEvalParamExec
1068  *
1069  * Returns the value of a PARAM_EXEC parameter.
1070  * ----------------------------------------------------------------
1071  */
1072 static Datum
1074  bool *isNull)
1075 {
1076  Param *expression = (Param *) exprstate->expr;
1077  int thisParamId = expression->paramid;
1078  ParamExecData *prm;
1079 
1080  /*
1081  * PARAM_EXEC params (internal executor parameters) are stored in the
1082  * ecxt_param_exec_vals array, and can be accessed by array index.
1083  */
1084  prm = &(econtext->ecxt_param_exec_vals[thisParamId]);
1085  if (prm->execPlan != NULL)
1086  {
1087  /* Parameter not evaluated yet, so go do it */
1088  ExecSetParamPlan(prm->execPlan, econtext);
1089  /* ExecSetParamPlan should have processed this param... */
1090  Assert(prm->execPlan == NULL);
1091  }
1092  *isNull = prm->isnull;
1093  return prm->value;
1094 }
1095 
1096 /* ----------------------------------------------------------------
1097  * ExecEvalParamExtern
1098  *
1099  * Returns the value of a PARAM_EXTERN parameter.
1100  * ----------------------------------------------------------------
1101  */
1102 static Datum
1104  bool *isNull)
1105 {
1106  Param *expression = (Param *) exprstate->expr;
1107  int thisParamId = expression->paramid;
1108  ParamListInfo paramInfo = econtext->ecxt_param_list_info;
1109 
1110  /*
1111  * PARAM_EXTERN parameters must be sought in ecxt_param_list_info.
1112  */
1113  if (paramInfo &&
1114  thisParamId > 0 && thisParamId <= paramInfo->numParams)
1115  {
1116  ParamExternData *prm = &paramInfo->params[thisParamId - 1];
1117 
1118  /* give hook a chance in case parameter is dynamic */
1119  if (!OidIsValid(prm->ptype) && paramInfo->paramFetch != NULL)
1120  (*paramInfo->paramFetch) (paramInfo, thisParamId);
1121 
1122  if (OidIsValid(prm->ptype))
1123  {
1124  /* safety check in case hook did something unexpected */
1125  if (prm->ptype != expression->paramtype)
1126  ereport(ERROR,
1127  (errcode(ERRCODE_DATATYPE_MISMATCH),
1128  errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
1129  thisParamId,
1130  format_type_be(prm->ptype),
1131  format_type_be(expression->paramtype))));
1132 
1133  *isNull = prm->isnull;
1134  return prm->value;
1135  }
1136  }
1137 
1138  ereport(ERROR,
1139  (errcode(ERRCODE_UNDEFINED_OBJECT),
1140  errmsg("no value found for parameter %d", thisParamId)));
1141  return (Datum) 0; /* keep compiler quiet */
1142 }
1143 
1144 
1145 /* ----------------------------------------------------------------
1146  * ExecEvalOper / ExecEvalFunc support routines
1147  * ----------------------------------------------------------------
1148  */
1149 
1150 /*
1151  * GetAttributeByName
1152  * GetAttributeByNum
1153  *
1154  * These functions return the value of the requested attribute
1155  * out of the given tuple Datum.
1156  * C functions which take a tuple as an argument are expected
1157  * to use these. Ex: overpaid(EMP) might call GetAttributeByNum().
1158  * Note: these are actually rather slow because they do a typcache
1159  * lookup on each call.
1160  */
1161 Datum
1163  AttrNumber attrno,
1164  bool *isNull)
1165 {
1166  Datum result;
1167  Oid tupType;
1168  int32 tupTypmod;
1169  TupleDesc tupDesc;
1170  HeapTupleData tmptup;
1171 
1172  if (!AttributeNumberIsValid(attrno))
1173  elog(ERROR, "invalid attribute number %d", attrno);
1174 
1175  if (isNull == NULL)
1176  elog(ERROR, "a NULL isNull pointer was passed");
1177 
1178  if (tuple == NULL)
1179  {
1180  /* Kinda bogus but compatible with old behavior... */
1181  *isNull = true;
1182  return (Datum) 0;
1183  }
1184 
1185  tupType = HeapTupleHeaderGetTypeId(tuple);
1186  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1187  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1188 
1189  /*
1190  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1191  * the fields in the struct just in case user tries to inspect system
1192  * columns.
1193  */
1194  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1195  ItemPointerSetInvalid(&(tmptup.t_self));
1196  tmptup.t_tableOid = InvalidOid;
1197  tmptup.t_data = tuple;
1198 
1199  result = heap_getattr(&tmptup,
1200  attrno,
1201  tupDesc,
1202  isNull);
1203 
1204  ReleaseTupleDesc(tupDesc);
1205 
1206  return result;
1207 }
1208 
1209 Datum
1210 GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
1211 {
1212  AttrNumber attrno;
1213  Datum result;
1214  Oid tupType;
1215  int32 tupTypmod;
1216  TupleDesc tupDesc;
1217  HeapTupleData tmptup;
1218  int i;
1219 
1220  if (attname == NULL)
1221  elog(ERROR, "invalid attribute name");
1222 
1223  if (isNull == NULL)
1224  elog(ERROR, "a NULL isNull pointer was passed");
1225 
1226  if (tuple == NULL)
1227  {
1228  /* Kinda bogus but compatible with old behavior... */
1229  *isNull = true;
1230  return (Datum) 0;
1231  }
1232 
1233  tupType = HeapTupleHeaderGetTypeId(tuple);
1234  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
1235  tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1236 
1237  attrno = InvalidAttrNumber;
1238  for (i = 0; i < tupDesc->natts; i++)
1239  {
1240  if (namestrcmp(&(tupDesc->attrs[i]->attname), attname) == 0)
1241  {
1242  attrno = tupDesc->attrs[i]->attnum;
1243  break;
1244  }
1245  }
1246 
1247  if (attrno == InvalidAttrNumber)
1248  elog(ERROR, "attribute \"%s\" does not exist", attname);
1249 
1250  /*
1251  * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1252  * the fields in the struct just in case user tries to inspect system
1253  * columns.
1254  */
1255  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1256  ItemPointerSetInvalid(&(tmptup.t_self));
1257  tmptup.t_tableOid = InvalidOid;
1258  tmptup.t_data = tuple;
1259 
1260  result = heap_getattr(&tmptup,
1261  attrno,
1262  tupDesc,
1263  isNull);
1264 
1265  ReleaseTupleDesc(tupDesc);
1266 
1267  return result;
1268 }
1269 
1270 /*
1271  * init_fcache - initialize a FuncExprState node during first use
1272  */
1273 static void
1274 init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache,
1275  MemoryContext fcacheCxt, bool allowSRF, bool needDescForSRF)
1276 {
1277  AclResult aclresult;
1278 
1279  /* Check permission to call function */
1280  aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
1281  if (aclresult != ACLCHECK_OK)
1282  aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(foid));
1284 
1285  /*
1286  * Safety check on nargs. Under normal circumstances this should never
1287  * fail, as parser should check sooner. But possibly it might fail if
1288  * server has been compiled with FUNC_MAX_ARGS smaller than some functions
1289  * declared in pg_proc?
1290  */
1291  if (list_length(fcache->args) > FUNC_MAX_ARGS)
1292  ereport(ERROR,
1293  (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
1294  errmsg_plural("cannot pass more than %d argument to a function",
1295  "cannot pass more than %d arguments to a function",
1296  FUNC_MAX_ARGS,
1297  FUNC_MAX_ARGS)));
1298 
1299  /* Set up the primary fmgr lookup information */
1300  fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
1301  fmgr_info_set_expr((Node *) fcache->xprstate.expr, &(fcache->func));
1302 
1303  /* Initialize the function call parameter struct as well */
1304  InitFunctionCallInfoData(fcache->fcinfo_data, &(fcache->func),
1305  list_length(fcache->args),
1306  input_collation, NULL, NULL);
1307 
1308  /* If function returns set, check if that's allowed by caller */
1309  if (fcache->func.fn_retset && !allowSRF)
1310  ereport(ERROR,
1311  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1312  errmsg("set-valued function called in context that cannot accept a set")));
1313 
1314  /* Otherwise, ExecInitExpr should have marked the fcache correctly */
1315  Assert(fcache->func.fn_retset == fcache->funcReturnsSet);
1316 
1317  /* If function returns set, prepare expected tuple descriptor */
1318  if (fcache->func.fn_retset && needDescForSRF)
1319  {
1320  TypeFuncClass functypclass;
1321  Oid funcrettype;
1322  TupleDesc tupdesc;
1323  MemoryContext oldcontext;
1324 
1325  functypclass = get_expr_result_type(fcache->func.fn_expr,
1326  &funcrettype,
1327  &tupdesc);
1328 
1329  /* Must save tupdesc in fcache's context */
1330  oldcontext = MemoryContextSwitchTo(fcacheCxt);
1331 
1332  if (functypclass == TYPEFUNC_COMPOSITE)
1333  {
1334  /* Composite data type, e.g. a table's row type */
1335  Assert(tupdesc);
1336  /* Must copy it out of typcache for safety */
1337  fcache->funcResultDesc = CreateTupleDescCopy(tupdesc);
1338  fcache->funcReturnsTuple = true;
1339  }
1340  else if (functypclass == TYPEFUNC_SCALAR)
1341  {
1342  /* Base data type, i.e. scalar */
1343  tupdesc = CreateTemplateTupleDesc(1, false);
1344  TupleDescInitEntry(tupdesc,
1345  (AttrNumber) 1,
1346  NULL,
1347  funcrettype,
1348  -1,
1349  0);
1350  fcache->funcResultDesc = tupdesc;
1351  fcache->funcReturnsTuple = false;
1352  }
1353  else if (functypclass == TYPEFUNC_RECORD)
1354  {
1355  /* This will work if function doesn't need an expectedDesc */
1356  fcache->funcResultDesc = NULL;
1357  fcache->funcReturnsTuple = true;
1358  }
1359  else
1360  {
1361  /* Else, we will fail if function needs an expectedDesc */
1362  fcache->funcResultDesc = NULL;
1363  }
1364 
1365  MemoryContextSwitchTo(oldcontext);
1366  }
1367  else
1368  fcache->funcResultDesc = NULL;
1369 
1370  /* Initialize additional state */
1371  fcache->funcResultStore = NULL;
1372  fcache->funcResultSlot = NULL;
1373  fcache->shutdown_reg = false;
1374 }
1375 
1376 /*
1377  * callback function in case a FuncExpr returning a set needs to be shut down
1378  * before it has been run to completion
1379  */
1380 static void
1382 {
1383  FuncExprState *fcache = (FuncExprState *) DatumGetPointer(arg);
1384 
1385  /* If we have a slot, make sure it's let go of any tuplestore pointer */
1386  if (fcache->funcResultSlot)
1387  ExecClearTuple(fcache->funcResultSlot);
1388 
1389  /* Release any open tuplestore */
1390  if (fcache->funcResultStore)
1392  fcache->funcResultStore = NULL;
1393 
1394  /* Clear any active set-argument state */
1395  fcache->setArgsValid = false;
1396 
1397  /* execUtils will deregister the callback... */
1398  fcache->shutdown_reg = false;
1399 }
1400 
1401 /*
1402  * get_cached_rowtype: utility function to lookup a rowtype tupdesc
1403  *
1404  * type_id, typmod: identity of the rowtype
1405  * cache_field: where to cache the TupleDesc pointer in expression state node
1406  * (field must be initialized to NULL)
1407  * econtext: expression context we are executing in
1408  *
1409  * NOTE: because the shutdown callback will be called during plan rescan,
1410  * must be prepared to re-do this during any node execution; cannot call
1411  * just once during expression initialization
1412  */
1413 static TupleDesc
1414 get_cached_rowtype(Oid type_id, int32 typmod,
1415  TupleDesc *cache_field, ExprContext *econtext)
1416 {
1417  TupleDesc tupDesc = *cache_field;
1418 
1419  /* Do lookup if no cached value or if requested type changed */
1420  if (tupDesc == NULL ||
1421  type_id != tupDesc->tdtypeid ||
1422  typmod != tupDesc->tdtypmod)
1423  {
1424  tupDesc = lookup_rowtype_tupdesc(type_id, typmod);
1425 
1426  if (*cache_field)
1427  {
1428  /* Release old tupdesc; but callback is already registered */
1429  ReleaseTupleDesc(*cache_field);
1430  }
1431  else
1432  {
1433  /* Need to register shutdown callback to release tupdesc */
1434  RegisterExprContextCallback(econtext,
1436  PointerGetDatum(cache_field));
1437  }
1438  *cache_field = tupDesc;
1439  }
1440  return tupDesc;
1441 }
1442 
1443 /*
1444  * Callback function to release a tupdesc refcount at expression tree shutdown
1445  */
1446 static void
1448 {
1449  TupleDesc *cache_field = (TupleDesc *) DatumGetPointer(arg);
1450 
1451  if (*cache_field)
1452  ReleaseTupleDesc(*cache_field);
1453  *cache_field = NULL;
1454 }
1455 
1456 /*
1457  * Evaluate arguments for a function.
1458  */
1459 static void
1461  List *argList,
1462  ExprContext *econtext)
1463 {
1464  int i;
1465  ListCell *arg;
1466 
1467  i = 0;
1468  foreach(arg, argList)
1469  {
1470  ExprState *argstate = (ExprState *) lfirst(arg);
1471 
1472  fcinfo->arg[i] = ExecEvalExpr(argstate,
1473  econtext,
1474  &fcinfo->argnull[i]);
1475  i++;
1476  }
1477 
1478  Assert(i == fcinfo->nargs);
1479 }
1480 
1481 /*
1482  * ExecPrepareTuplestoreResult
1483  *
1484  * Subroutine for ExecMakeFunctionResultSet: prepare to extract rows from a
1485  * tuplestore function result. We must set up a funcResultSlot (unless
1486  * already done in a previous call cycle) and verify that the function
1487  * returned the expected tuple descriptor.
1488  */
1489 static void
1491  ExprContext *econtext,
1492  Tuplestorestate *resultStore,
1493  TupleDesc resultDesc)
1494 {
1495  fcache->funcResultStore = resultStore;
1496 
1497  if (fcache->funcResultSlot == NULL)
1498  {
1499  /* Create a slot so we can read data out of the tuplestore */
1500  TupleDesc slotDesc;
1501  MemoryContext oldcontext;
1502 
1503  oldcontext = MemoryContextSwitchTo(fcache->func.fn_mcxt);
1504 
1505  /*
1506  * If we were not able to determine the result rowtype from context,
1507  * and the function didn't return a tupdesc, we have to fail.
1508  */
1509  if (fcache->funcResultDesc)
1510  slotDesc = fcache->funcResultDesc;
1511  else if (resultDesc)
1512  {
1513  /* don't assume resultDesc is long-lived */
1514  slotDesc = CreateTupleDescCopy(resultDesc);
1515  }
1516  else
1517  {
1518  ereport(ERROR,
1519  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1520  errmsg("function returning setof record called in "
1521  "context that cannot accept type record")));
1522  slotDesc = NULL; /* keep compiler quiet */
1523  }
1524 
1525  fcache->funcResultSlot = MakeSingleTupleTableSlot(slotDesc);
1526  MemoryContextSwitchTo(oldcontext);
1527  }
1528 
1529  /*
1530  * If function provided a tupdesc, cross-check it. We only really need to
1531  * do this for functions returning RECORD, but might as well do it always.
1532  */
1533  if (resultDesc)
1534  {
1535  if (fcache->funcResultDesc)
1536  tupledesc_match(fcache->funcResultDesc, resultDesc);
1537 
1538  /*
1539  * If it is a dynamically-allocated TupleDesc, free it: it is
1540  * typically allocated in a per-query context, so we must avoid
1541  * leaking it across multiple usages.
1542  */
1543  if (resultDesc->tdrefcount == -1)
1544  FreeTupleDesc(resultDesc);
1545  }
1546 
1547  /* Register cleanup callback if we didn't already */
1548  if (!fcache->shutdown_reg)
1549  {
1550  RegisterExprContextCallback(econtext,
1552  PointerGetDatum(fcache));
1553  fcache->shutdown_reg = true;
1554  }
1555 }
1556 
1557 /*
1558  * Check that function result tuple type (src_tupdesc) matches or can
1559  * be considered to match what the query expects (dst_tupdesc). If
1560  * they don't match, ereport.
1561  *
1562  * We really only care about number of attributes and data type.
1563  * Also, we can ignore type mismatch on columns that are dropped in the
1564  * destination type, so long as the physical storage matches. This is
1565  * helpful in some cases involving out-of-date cached plans.
1566  */
1567 static void
1568 tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc)
1569 {
1570  int i;
1571 
1572  if (dst_tupdesc->natts != src_tupdesc->natts)
1573  ereport(ERROR,
1574  (errcode(ERRCODE_DATATYPE_MISMATCH),
1575  errmsg("function return row and query-specified return row do not match"),
1576  errdetail_plural("Returned row contains %d attribute, but query expects %d.",
1577  "Returned row contains %d attributes, but query expects %d.",
1578  src_tupdesc->natts,
1579  src_tupdesc->natts, dst_tupdesc->natts)));
1580 
1581  for (i = 0; i < dst_tupdesc->natts; i++)
1582  {
1583  Form_pg_attribute dattr = dst_tupdesc->attrs[i];
1584  Form_pg_attribute sattr = src_tupdesc->attrs[i];
1585 
1586  if (IsBinaryCoercible(sattr->atttypid, dattr->atttypid))
1587  continue; /* no worries */
1588  if (!dattr->attisdropped)
1589  ereport(ERROR,
1590  (errcode(ERRCODE_DATATYPE_MISMATCH),
1591  errmsg("function return row and query-specified return row do not match"),
1592  errdetail("Returned type %s at ordinal position %d, but query expects %s.",
1593  format_type_be(sattr->atttypid),
1594  i + 1,
1595  format_type_be(dattr->atttypid))));
1596 
1597  if (dattr->attlen != sattr->attlen ||
1598  dattr->attalign != sattr->attalign)
1599  ereport(ERROR,
1600  (errcode(ERRCODE_DATATYPE_MISMATCH),
1601  errmsg("function return row and query-specified return row do not match"),
1602  errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
1603  i + 1)));
1604  }
1605 }
1606 
1607 /*
1608  * ExecMakeFunctionResultSet
1609  *
1610  * Evaluate the arguments to a set-returning function and then call the
1611  * function itself. The argument expressions may not contain set-returning
1612  * functions (the planner is supposed to have separated evaluation for those).
1613  */
1614 Datum
1616  ExprContext *econtext,
1617  bool *isNull,
1618  ExprDoneCond *isDone)
1619 {
1620  List *arguments;
1621  Datum result;
1622  FunctionCallInfo fcinfo;
1623  PgStat_FunctionCallUsage fcusage;
1624  ReturnSetInfo rsinfo;
1625  bool callit;
1626  int i;
1627 
1628 restart:
1629 
1630  /* Guard against stack overflow due to overly complex expressions */
1632 
1633  /*
1634  * Initialize function cache if first time through. The expression node
1635  * could be either a FuncExpr or an OpExpr.
1636  */
1637  if (fcache->func.fn_oid == InvalidOid)
1638  {
1639  if (IsA(fcache->xprstate.expr, FuncExpr))
1640  {
1641  FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
1642 
1643  init_fcache(func->funcid, func->inputcollid, fcache,
1644  econtext->ecxt_per_query_memory, true, true);
1645  }
1646  else if (IsA(fcache->xprstate.expr, OpExpr))
1647  {
1648  OpExpr *op = (OpExpr *) fcache->xprstate.expr;
1649 
1650  init_fcache(op->opfuncid, op->inputcollid, fcache,
1651  econtext->ecxt_per_query_memory, true, true);
1652  }
1653  else
1654  elog(ERROR, "unrecognized node type: %d",
1655  (int) nodeTag(fcache->xprstate.expr));
1656 
1657  /* shouldn't get here otherwise */
1658  Assert(fcache->func.fn_retset);
1659  }
1660 
1661  /*
1662  * If a previous call of the function returned a set result in the form of
1663  * a tuplestore, continue reading rows from the tuplestore until it's
1664  * empty.
1665  */
1666  if (fcache->funcResultStore)
1667  {
1668  if (tuplestore_gettupleslot(fcache->funcResultStore, true, false,
1669  fcache->funcResultSlot))
1670  {
1671  *isDone = ExprMultipleResult;
1672  if (fcache->funcReturnsTuple)
1673  {
1674  /* We must return the whole tuple as a Datum. */
1675  *isNull = false;
1676  return ExecFetchSlotTupleDatum(fcache->funcResultSlot);
1677  }
1678  else
1679  {
1680  /* Extract the first column and return it as a scalar. */
1681  return slot_getattr(fcache->funcResultSlot, 1, isNull);
1682  }
1683  }
1684  /* Exhausted the tuplestore, so clean up */
1686  fcache->funcResultStore = NULL;
1687  *isDone = ExprEndResult;
1688  *isNull = true;
1689  return (Datum) 0;
1690  }
1691 
1692  /*
1693  * arguments is a list of expressions to evaluate before passing to the
1694  * function manager. We skip the evaluation if it was already done in the
1695  * previous call (ie, we are continuing the evaluation of a set-valued
1696  * function). Otherwise, collect the current argument values into fcinfo.
1697  */
1698  fcinfo = &fcache->fcinfo_data;
1699  arguments = fcache->args;
1700  if (!fcache->setArgsValid)
1701  ExecEvalFuncArgs(fcinfo, arguments, econtext);
1702  else
1703  {
1704  /* Reset flag (we may set it again below) */
1705  fcache->setArgsValid = false;
1706  }
1707 
1708  /*
1709  * Now call the function, passing the evaluated parameter values.
1710  */
1711 
1712  /* Prepare a resultinfo node for communication. */
1713  fcinfo->resultinfo = (Node *) &rsinfo;
1714  rsinfo.type = T_ReturnSetInfo;
1715  rsinfo.econtext = econtext;
1716  rsinfo.expectedDesc = fcache->funcResultDesc;
1717  rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
1718  /* note we do not set SFRM_Materialize_Random or _Preferred */
1719  rsinfo.returnMode = SFRM_ValuePerCall;
1720  /* isDone is filled below */
1721  rsinfo.setResult = NULL;
1722  rsinfo.setDesc = NULL;
1723 
1724  /*
1725  * If function is strict, and there are any NULL arguments, skip calling
1726  * the function.
1727  */
1728  callit = true;
1729  if (fcache->func.fn_strict)
1730  {
1731  for (i = 0; i < fcinfo->nargs; i++)
1732  {
1733  if (fcinfo->argnull[i])
1734  {
1735  callit = false;
1736  break;
1737  }
1738  }
1739  }
1740 
1741  if (callit)
1742  {
1743  pgstat_init_function_usage(fcinfo, &fcusage);
1744 
1745  fcinfo->isnull = false;
1746  rsinfo.isDone = ExprSingleResult;
1747  result = FunctionCallInvoke(fcinfo);
1748  *isNull = fcinfo->isnull;
1749  *isDone = rsinfo.isDone;
1750 
1751  pgstat_end_function_usage(&fcusage,
1752  rsinfo.isDone != ExprMultipleResult);
1753  }
1754  else
1755  {
1756  /* for a strict SRF, result for NULL is an empty set */
1757  result = (Datum) 0;
1758  *isNull = true;
1759  *isDone = ExprEndResult;
1760  }
1761 
1762  /* Which protocol does function want to use? */
1763  if (rsinfo.returnMode == SFRM_ValuePerCall)
1764  {
1765  if (*isDone != ExprEndResult)
1766  {
1767  /*
1768  * Save the current argument values to re-use on the next call.
1769  */
1770  if (*isDone == ExprMultipleResult)
1771  {
1772  fcache->setArgsValid = true;
1773  /* Register cleanup callback if we didn't already */
1774  if (!fcache->shutdown_reg)
1775  {
1776  RegisterExprContextCallback(econtext,
1778  PointerGetDatum(fcache));
1779  fcache->shutdown_reg = true;
1780  }
1781  }
1782  }
1783  }
1784  else if (rsinfo.returnMode == SFRM_Materialize)
1785  {
1786  /* check we're on the same page as the function author */
1787  if (rsinfo.isDone != ExprSingleResult)
1788  ereport(ERROR,
1789  (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1790  errmsg("table-function protocol for materialize mode was not followed")));
1791  if (rsinfo.setResult != NULL)
1792  {
1793  /* prepare to return values from the tuplestore */
1794  ExecPrepareTuplestoreResult(fcache, econtext,
1795  rsinfo.setResult,
1796  rsinfo.setDesc);
1797  /* loop back to top to start returning from tuplestore */
1798  goto restart;
1799  }
1800  /* if setResult was left null, treat it as empty set */
1801  *isDone = ExprEndResult;
1802  *isNull = true;
1803  result = (Datum) 0;
1804  }
1805  else
1806  ereport(ERROR,
1807  (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1808  errmsg("unrecognized table-function returnMode: %d",
1809  (int) rsinfo.returnMode)));
1810 
1811  return result;
1812 }
1813 
1814 /*
1815  * ExecMakeFunctionResultNoSets
1816  *
1817  * Evaluate a function or operator node with a non-set-returning function.
1818  * Assumes init_fcache() already done. Hand-tuned for speed.
1819  */
1820 static Datum
1822  ExprContext *econtext,
1823  bool *isNull)
1824 {
1825  ListCell *arg;
1826  Datum result;
1827  FunctionCallInfo fcinfo;
1828  PgStat_FunctionCallUsage fcusage;
1829  int i;
1830 
1831  /* Guard against stack overflow due to overly complex expressions */
1833 
1834  /* inlined, simplified version of ExecEvalFuncArgs */
1835  fcinfo = &fcache->fcinfo_data;
1836  i = 0;
1837  foreach(arg, fcache->args)
1838  {
1839  ExprState *argstate = (ExprState *) lfirst(arg);
1840 
1841  fcinfo->arg[i] = ExecEvalExpr(argstate,
1842  econtext,
1843  &fcinfo->argnull[i]);
1844  i++;
1845  }
1846 
1847  /*
1848  * If function is strict, and there are any NULL arguments, skip calling
1849  * the function and return NULL.
1850  */
1851  if (fcache->func.fn_strict)
1852  {
1853  while (--i >= 0)
1854  {
1855  if (fcinfo->argnull[i])
1856  {
1857  *isNull = true;
1858  return (Datum) 0;
1859  }
1860  }
1861  }
1862 
1863  pgstat_init_function_usage(fcinfo, &fcusage);
1864 
1865  fcinfo->isnull = false;
1866  result = FunctionCallInvoke(fcinfo);
1867  *isNull = fcinfo->isnull;
1868 
1869  pgstat_end_function_usage(&fcusage, true);
1870 
1871  return result;
1872 }
1873 
1874 
1875 /*
1876  * ExecMakeTableFunctionResult
1877  *
1878  * Evaluate a table function, producing a materialized result in a Tuplestore
1879  * object.
1880  */
1883  ExprContext *econtext,
1884  MemoryContext argContext,
1885  TupleDesc expectedDesc,
1886  bool randomAccess)
1887 {
1888  Tuplestorestate *tupstore = NULL;
1889  TupleDesc tupdesc = NULL;
1890  Oid funcrettype;
1891  bool returnsTuple;
1892  bool returnsSet = false;
1893  FunctionCallInfoData fcinfo;
1894  PgStat_FunctionCallUsage fcusage;
1895  ReturnSetInfo rsinfo;
1896  HeapTupleData tmptup;
1897  MemoryContext callerContext;
1898  MemoryContext oldcontext;
1899  bool direct_function_call;
1900  bool first_time = true;
1901 
1902  callerContext = CurrentMemoryContext;
1903 
1904  funcrettype = exprType((Node *) funcexpr->expr);
1905 
1906  returnsTuple = type_is_rowtype(funcrettype);
1907 
1908  /*
1909  * Prepare a resultinfo node for communication. We always do this even if
1910  * not expecting a set result, so that we can pass expectedDesc. In the
1911  * generic-expression case, the expression doesn't actually get to see the
1912  * resultinfo, but set it up anyway because we use some of the fields as
1913  * our own state variables.
1914  */
1915  rsinfo.type = T_ReturnSetInfo;
1916  rsinfo.econtext = econtext;
1917  rsinfo.expectedDesc = expectedDesc;
1919  if (randomAccess)
1920  rsinfo.allowedModes |= (int) SFRM_Materialize_Random;
1921  rsinfo.returnMode = SFRM_ValuePerCall;
1922  /* isDone is filled below */
1923  rsinfo.setResult = NULL;
1924  rsinfo.setDesc = NULL;
1925 
1926  /*
1927  * Normally the passed expression tree will be a FuncExprState, since the
1928  * grammar only allows a function call at the top level of a table
1929  * function reference. However, if the function doesn't return set then
1930  * the planner might have replaced the function call via constant-folding
1931  * or inlining. So if we see any other kind of expression node, execute
1932  * it via the general ExecEvalExpr() code; the only difference is that we
1933  * don't get a chance to pass a special ReturnSetInfo to any functions
1934  * buried in the expression.
1935  */
1936  if (funcexpr && IsA(funcexpr, FuncExprState) &&
1937  IsA(funcexpr->expr, FuncExpr))
1938  {
1939  FuncExprState *fcache = (FuncExprState *) funcexpr;
1940 
1941  /*
1942  * This path is similar to ExecMakeFunctionResultSet.
1943  */
1944  direct_function_call = true;
1945 
1946  /*
1947  * Initialize function cache if first time through
1948  */
1949  if (fcache->func.fn_oid == InvalidOid)
1950  {
1951  FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
1952 
1953  init_fcache(func->funcid, func->inputcollid, fcache,
1954  econtext->ecxt_per_query_memory, true, false);
1955  }
1956  returnsSet = fcache->func.fn_retset;
1957  InitFunctionCallInfoData(fcinfo, &(fcache->func),
1958  list_length(fcache->args),
1959  fcache->fcinfo_data.fncollation,
1960  NULL, (Node *) &rsinfo);
1961 
1962  /*
1963  * Evaluate the function's argument list.
1964  *
1965  * We can't do this in the per-tuple context: the argument values
1966  * would disappear when we reset that context in the inner loop. And
1967  * the caller's CurrentMemoryContext is typically a query-lifespan
1968  * context, so we don't want to leak memory there. We require the
1969  * caller to pass a separate memory context that can be used for this,
1970  * and can be reset each time through to avoid bloat.
1971  */
1972  MemoryContextReset(argContext);
1973  oldcontext = MemoryContextSwitchTo(argContext);
1974  ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
1975  MemoryContextSwitchTo(oldcontext);
1976 
1977  /*
1978  * If function is strict, and there are any NULL arguments, skip
1979  * calling the function and act like it returned NULL (or an empty
1980  * set, in the returns-set case).
1981  */
1982  if (fcache->func.fn_strict)
1983  {
1984  int i;
1985 
1986  for (i = 0; i < fcinfo.nargs; i++)
1987  {
1988  if (fcinfo.argnull[i])
1989  goto no_function_result;
1990  }
1991  }
1992  }
1993  else
1994  {
1995  /* Treat funcexpr as a generic expression */
1996  direct_function_call = false;
1998  }
1999 
2000  /*
2001  * Switch to short-lived context for calling the function or expression.
2002  */
2004 
2005  /*
2006  * Loop to handle the ValuePerCall protocol (which is also the same
2007  * behavior needed in the generic ExecEvalExpr path).
2008  */
2009  for (;;)
2010  {
2011  Datum result;
2012 
2014 
2015  /*
2016  * reset per-tuple memory context before each call of the function or
2017  * expression. This cleans up any local memory the function may leak
2018  * when called.
2019  */
2020  ResetExprContext(econtext);
2021 
2022  /* Call the function or expression one time */
2023  if (direct_function_call)
2024  {
2025  pgstat_init_function_usage(&fcinfo, &fcusage);
2026 
2027  fcinfo.isnull = false;
2028  rsinfo.isDone = ExprSingleResult;
2029  result = FunctionCallInvoke(&fcinfo);
2030 
2031  pgstat_end_function_usage(&fcusage,
2032  rsinfo.isDone != ExprMultipleResult);
2033  }
2034  else
2035  {
2036  result = ExecEvalExpr(funcexpr, econtext, &fcinfo.isnull);
2037  rsinfo.isDone = ExprSingleResult;
2038  }
2039 
2040  /* Which protocol does function want to use? */
2041  if (rsinfo.returnMode == SFRM_ValuePerCall)
2042  {
2043  /*
2044  * Check for end of result set.
2045  */
2046  if (rsinfo.isDone == ExprEndResult)
2047  break;
2048 
2049  /*
2050  * If first time through, build tuplestore for result. For a
2051  * scalar function result type, also make a suitable tupdesc.
2052  */
2053  if (first_time)
2054  {
2055  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2056  tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
2057  rsinfo.setResult = tupstore;
2058  if (!returnsTuple)
2059  {
2060  tupdesc = CreateTemplateTupleDesc(1, false);
2061  TupleDescInitEntry(tupdesc,
2062  (AttrNumber) 1,
2063  "column",
2064  funcrettype,
2065  -1,
2066  0);
2067  rsinfo.setDesc = tupdesc;
2068  }
2069  MemoryContextSwitchTo(oldcontext);
2070  }
2071 
2072  /*
2073  * Store current resultset item.
2074  */
2075  if (returnsTuple)
2076  {
2077  if (!fcinfo.isnull)
2078  {
2080 
2081  if (tupdesc == NULL)
2082  {
2083  /*
2084  * This is the first non-NULL result from the
2085  * function. Use the type info embedded in the
2086  * rowtype Datum to look up the needed tupdesc. Make
2087  * a copy for the query.
2088  */
2089  oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2092  rsinfo.setDesc = tupdesc;
2093  MemoryContextSwitchTo(oldcontext);
2094  }
2095  else
2096  {
2097  /*
2098  * Verify all later returned rows have same subtype;
2099  * necessary in case the type is RECORD.
2100  */
2101  if (HeapTupleHeaderGetTypeId(td) != tupdesc->tdtypeid ||
2102  HeapTupleHeaderGetTypMod(td) != tupdesc->tdtypmod)
2103  ereport(ERROR,
2104  (errcode(ERRCODE_DATATYPE_MISMATCH),
2105  errmsg("rows returned by function are not all of the same row type")));
2106  }
2107 
2108  /*
2109  * tuplestore_puttuple needs a HeapTuple not a bare
2110  * HeapTupleHeader, but it doesn't need all the fields.
2111  */
2112  tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
2113  tmptup.t_data = td;
2114 
2115  tuplestore_puttuple(tupstore, &tmptup);
2116  }
2117  else
2118  {
2119  /*
2120  * NULL result from a tuple-returning function; expand it
2121  * to a row of all nulls. We rely on the expectedDesc to
2122  * form such rows. (Note: this would be problematic if
2123  * tuplestore_putvalues saved the tdtypeid/tdtypmod from
2124  * the provided descriptor, since that might not match
2125  * what we get from the function itself. But it doesn't.)
2126  */
2127  int natts = expectedDesc->natts;
2128  bool *nullflags;
2129 
2130  nullflags = (bool *) palloc(natts * sizeof(bool));
2131  memset(nullflags, true, natts * sizeof(bool));
2132  tuplestore_putvalues(tupstore, expectedDesc, NULL, nullflags);
2133  }
2134  }
2135  else
2136  {
2137  /* Scalar-type case: just store the function result */
2138  tuplestore_putvalues(tupstore, tupdesc, &result, &fcinfo.isnull);
2139  }
2140 
2141  /*
2142  * Are we done?
2143  */
2144  if (rsinfo.isDone != ExprMultipleResult)
2145  break;
2146  }
2147  else if (rsinfo.returnMode == SFRM_Materialize)
2148  {
2149  /* check we're on the same page as the function author */
2150  if (!first_time || rsinfo.isDone != ExprSingleResult)
2151  ereport(ERROR,
2152  (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
2153  errmsg("table-function protocol for materialize mode was not followed")));
2154  /* Done evaluating the set result */
2155  break;
2156  }
2157  else
2158  ereport(ERROR,
2159  (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
2160  errmsg("unrecognized table-function returnMode: %d",
2161  (int) rsinfo.returnMode)));
2162 
2163  first_time = false;
2164  }
2165 
2166 no_function_result:
2167 
2168  /*
2169  * If we got nothing from the function (ie, an empty-set or NULL result),
2170  * we have to create the tuplestore to return, and if it's a
2171  * non-set-returning function then insert a single all-nulls row. As
2172  * above, we depend on the expectedDesc to manufacture the dummy row.
2173  */
2174  if (rsinfo.setResult == NULL)
2175  {
2177  tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
2178  rsinfo.setResult = tupstore;
2179  if (!returnsSet)
2180  {
2181  int natts = expectedDesc->natts;
2182  bool *nullflags;
2183 
2185  nullflags = (bool *) palloc(natts * sizeof(bool));
2186  memset(nullflags, true, natts * sizeof(bool));
2187  tuplestore_putvalues(tupstore, expectedDesc, NULL, nullflags);
2188  }
2189  }
2190 
2191  /*
2192  * If function provided a tupdesc, cross-check it. We only really need to
2193  * do this for functions returning RECORD, but might as well do it always.
2194  */
2195  if (rsinfo.setDesc)
2196  {
2197  tupledesc_match(expectedDesc, rsinfo.setDesc);
2198 
2199  /*
2200  * If it is a dynamically-allocated TupleDesc, free it: it is
2201  * typically allocated in a per-query context, so we must avoid
2202  * leaking it across multiple usages.
2203  */
2204  if (rsinfo.setDesc->tdrefcount == -1)
2205  FreeTupleDesc(rsinfo.setDesc);
2206  }
2207 
2208  MemoryContextSwitchTo(callerContext);
2209 
2210  /* All done, pass back the tuplestore */
2211  return rsinfo.setResult;
2212 }
2213 
2214 
2215 /* ----------------------------------------------------------------
2216  * ExecEvalFunc
2217  * ExecEvalOper
2218  *
2219  * Evaluate the functional result of a list of arguments by calling the
2220  * function manager.
2221  * ----------------------------------------------------------------
2222  */
2223 
2224 /* ----------------------------------------------------------------
2225  * ExecEvalFunc
2226  * ----------------------------------------------------------------
2227  */
2228 static Datum
2230  ExprContext *econtext,
2231  bool *isNull)
2232 {
2233  /* This is called only the first time through */
2234  FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
2235 
2236  /* Initialize function lookup info */
2237  init_fcache(func->funcid, func->inputcollid, fcache,
2238  econtext->ecxt_per_query_memory, false, false);
2239 
2240  /* Change the evalfunc pointer to save a few cycles in additional calls */
2242  return ExecMakeFunctionResultNoSets(fcache, econtext, isNull);
2243 }
2244 
2245 /* ----------------------------------------------------------------
2246  * ExecEvalOper
2247  * ----------------------------------------------------------------
2248  */
2249 static Datum
2251  ExprContext *econtext,
2252  bool *isNull)
2253 {
2254  /* This is called only the first time through */
2255  OpExpr *op = (OpExpr *) fcache->xprstate.expr;
2256 
2257  /* Initialize function lookup info */
2258  init_fcache(op->opfuncid, op->inputcollid, fcache,
2259  econtext->ecxt_per_query_memory, false, false);
2260 
2261  /* Change the evalfunc pointer to save a few cycles in additional calls */
2263  return ExecMakeFunctionResultNoSets(fcache, econtext, isNull);
2264 }
2265 
2266 /* ----------------------------------------------------------------
2267  * ExecEvalDistinct
2268  *
2269  * IS DISTINCT FROM must evaluate arguments to determine whether
2270  * they are NULL; if either is NULL then the result is already
2271  * known. If neither is NULL, then proceed to evaluate the
2272  * function. Note that this is *always* derived from the equals
2273  * operator, but since we need special processing of the arguments
2274  * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
2275  * ----------------------------------------------------------------
2276  */
2277 static Datum
2279  ExprContext *econtext,
2280  bool *isNull)
2281 {
2282  Datum result;
2283  FunctionCallInfo fcinfo;
2284 
2285  /* Set non-null as default */
2286  *isNull = false;
2287 
2288  /*
2289  * Initialize function cache if first time through
2290  */
2291  if (fcache->func.fn_oid == InvalidOid)
2292  {
2293  DistinctExpr *op = (DistinctExpr *) fcache->xprstate.expr;
2294 
2295  init_fcache(op->opfuncid, op->inputcollid, fcache,
2296  econtext->ecxt_per_query_memory, false, false);
2297  }
2298 
2299  /*
2300  * Evaluate arguments
2301  */
2302  fcinfo = &fcache->fcinfo_data;
2303  ExecEvalFuncArgs(fcinfo, fcache->args, econtext);
2304  Assert(fcinfo->nargs == 2);
2305 
2306  if (fcinfo->argnull[0] && fcinfo->argnull[1])
2307  {
2308  /* Both NULL? Then is not distinct... */
2309  result = BoolGetDatum(FALSE);
2310  }
2311  else if (fcinfo->argnull[0] || fcinfo->argnull[1])
2312  {
2313  /* Only one is NULL? Then is distinct... */
2314  result = BoolGetDatum(TRUE);
2315  }
2316  else
2317  {
2318  fcinfo->isnull = false;
2319  result = FunctionCallInvoke(fcinfo);
2320  *isNull = fcinfo->isnull;
2321  /* Must invert result of "=" */
2322  result = BoolGetDatum(!DatumGetBool(result));
2323  }
2324 
2325  return result;
2326 }
2327 
2328 /*
2329  * ExecEvalScalarArrayOp
2330  *
2331  * Evaluate "scalar op ANY/ALL (array)". The operator always yields boolean,
2332  * and we combine the results across all array elements using OR and AND
2333  * (for ANY and ALL respectively). Of course we short-circuit as soon as
2334  * the result is known.
2335  */
2336 static Datum
2338  ExprContext *econtext,
2339  bool *isNull)
2340 {
2342  bool useOr = opexpr->useOr;
2343  ArrayType *arr;
2344  int nitems;
2345  Datum result;
2346  bool resultnull;
2347  FunctionCallInfo fcinfo;
2348  int i;
2349  int16 typlen;
2350  bool typbyval;
2351  char typalign;
2352  char *s;
2353  bits8 *bitmap;
2354  int bitmask;
2355 
2356  /* Set non-null as default */
2357  *isNull = false;
2358 
2359  /*
2360  * Initialize function cache if first time through
2361  */
2362  if (sstate->fxprstate.func.fn_oid == InvalidOid)
2363  {
2364  init_fcache(opexpr->opfuncid, opexpr->inputcollid, &sstate->fxprstate,
2365  econtext->ecxt_per_query_memory, false, false);
2366  }
2367 
2368  /*
2369  * Evaluate arguments
2370  */
2371  fcinfo = &sstate->fxprstate.fcinfo_data;
2372  ExecEvalFuncArgs(fcinfo, sstate->fxprstate.args, econtext);
2373  Assert(fcinfo->nargs == 2);
2374 
2375  /*
2376  * If the array is NULL then we return NULL --- it's not very meaningful
2377  * to do anything else, even if the operator isn't strict.
2378  */
2379  if (fcinfo->argnull[1])
2380  {
2381  *isNull = true;
2382  return (Datum) 0;
2383  }
2384  /* Else okay to fetch and detoast the array */
2385  arr = DatumGetArrayTypeP(fcinfo->arg[1]);
2386 
2387  /*
2388  * If the array is empty, we return either FALSE or TRUE per the useOr
2389  * flag. This is correct even if the scalar is NULL; since we would
2390  * evaluate the operator zero times, it matters not whether it would want
2391  * to return NULL.
2392  */
2393  nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
2394  if (nitems <= 0)
2395  return BoolGetDatum(!useOr);
2396 
2397  /*
2398  * If the scalar is NULL, and the function is strict, return NULL; no
2399  * point in iterating the loop.
2400  */
2401  if (fcinfo->argnull[0] && sstate->fxprstate.func.fn_strict)
2402  {
2403  *isNull = true;
2404  return (Datum) 0;
2405  }
2406 
2407  /*
2408  * We arrange to look up info about the element type only once per series
2409  * of calls, assuming the element type doesn't change underneath us.
2410  */
2411  if (sstate->element_type != ARR_ELEMTYPE(arr))
2412  {
2414  &sstate->typlen,
2415  &sstate->typbyval,
2416  &sstate->typalign);
2417  sstate->element_type = ARR_ELEMTYPE(arr);
2418  }
2419  typlen = sstate->typlen;
2420  typbyval = sstate->typbyval;
2421  typalign = sstate->typalign;
2422 
2423  result = BoolGetDatum(!useOr);
2424  resultnull = false;
2425 
2426  /* Loop over the array elements */
2427  s = (char *) ARR_DATA_PTR(arr);
2428  bitmap = ARR_NULLBITMAP(arr);
2429  bitmask = 1;
2430 
2431  for (i = 0; i < nitems; i++)
2432  {
2433  Datum elt;
2434  Datum thisresult;
2435 
2436  /* Get array element, checking for NULL */
2437  if (bitmap && (*bitmap & bitmask) == 0)
2438  {
2439  fcinfo->arg[1] = (Datum) 0;
2440  fcinfo->argnull[1] = true;
2441  }
2442  else
2443  {
2444  elt = fetch_att(s, typbyval, typlen);
2445  s = att_addlength_pointer(s, typlen, s);
2446  s = (char *) att_align_nominal(s, typalign);
2447  fcinfo->arg[1] = elt;
2448  fcinfo->argnull[1] = false;
2449  }
2450 
2451  /* Call comparison function */
2452  if (fcinfo->argnull[1] && sstate->fxprstate.func.fn_strict)
2453  {
2454  fcinfo->isnull = true;
2455  thisresult = (Datum) 0;
2456  }
2457  else
2458  {
2459  fcinfo->isnull = false;
2460  thisresult = FunctionCallInvoke(fcinfo);
2461  }
2462 
2463  /* Combine results per OR or AND semantics */
2464  if (fcinfo->isnull)
2465  resultnull = true;
2466  else if (useOr)
2467  {
2468  if (DatumGetBool(thisresult))
2469  {
2470  result = BoolGetDatum(true);
2471  resultnull = false;
2472  break; /* needn't look at any more elements */
2473  }
2474  }
2475  else
2476  {
2477  if (!DatumGetBool(thisresult))
2478  {
2479  result = BoolGetDatum(false);
2480  resultnull = false;
2481  break; /* needn't look at any more elements */
2482  }
2483  }
2484 
2485  /* advance bitmap pointer if any */
2486  if (bitmap)
2487  {
2488  bitmask <<= 1;
2489  if (bitmask == 0x100)
2490  {
2491  bitmap++;
2492  bitmask = 1;
2493  }
2494  }
2495  }
2496 
2497  *isNull = resultnull;
2498  return result;
2499 }
2500 
2501 /* ----------------------------------------------------------------
2502  * ExecEvalNot
2503  * ExecEvalOr
2504  * ExecEvalAnd
2505  *
2506  * Evaluate boolean expressions, with appropriate short-circuiting.
2507  *
2508  * The query planner reformulates clause expressions in the
2509  * qualification to conjunctive normal form. If we ever get
2510  * an AND to evaluate, we can be sure that it's not a top-level
2511  * clause in the qualification, but appears lower (as a function
2512  * argument, for example), or in the target list. Not that you
2513  * need to know this, mind you...
2514  * ----------------------------------------------------------------
2515  */
2516 static Datum
2517 ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
2518  bool *isNull)
2519 {
2520  ExprState *clause = linitial(notclause->args);
2521  Datum expr_value;
2522 
2523  expr_value = ExecEvalExpr(clause, econtext, isNull);
2524 
2525  /*
2526  * if the expression evaluates to null, then we just cascade the null back
2527  * to whoever called us.
2528  */
2529  if (*isNull)
2530  return expr_value;
2531 
2532  /*
2533  * evaluation of 'not' is simple.. expr is false, then return 'true' and
2534  * vice versa.
2535  */
2536  return BoolGetDatum(!DatumGetBool(expr_value));
2537 }
2538 
2539 /* ----------------------------------------------------------------
2540  * ExecEvalOr
2541  * ----------------------------------------------------------------
2542  */
2543 static Datum
2545  bool *isNull)
2546 {
2547  List *clauses = orExpr->args;
2548  ListCell *clause;
2549  bool AnyNull;
2550 
2551  AnyNull = false;
2552 
2553  /*
2554  * If any of the clauses is TRUE, the OR result is TRUE regardless of the
2555  * states of the rest of the clauses, so we can stop evaluating and return
2556  * TRUE immediately. If none are TRUE and one or more is NULL, we return
2557  * NULL; otherwise we return FALSE. This makes sense when you interpret
2558  * NULL as "don't know": if we have a TRUE then the OR is TRUE even if we
2559  * aren't sure about some of the other inputs. If all the known inputs are
2560  * FALSE, but we have one or more "don't knows", then we have to report
2561  * that we "don't know" what the OR's result should be --- perhaps one of
2562  * the "don't knows" would have been TRUE if we'd known its value. Only
2563  * when all the inputs are known to be FALSE can we state confidently that
2564  * the OR's result is FALSE.
2565  */
2566  foreach(clause, clauses)
2567  {
2568  ExprState *clausestate = (ExprState *) lfirst(clause);
2569  Datum clause_value;
2570 
2571  clause_value = ExecEvalExpr(clausestate, econtext, isNull);
2572 
2573  /*
2574  * if we have a non-null true result, then return it.
2575  */
2576  if (*isNull)
2577  AnyNull = true; /* remember we got a null */
2578  else if (DatumGetBool(clause_value))
2579  return clause_value;
2580  }
2581 
2582  /* AnyNull is true if at least one clause evaluated to NULL */
2583  *isNull = AnyNull;
2584  return BoolGetDatum(false);
2585 }
2586 
2587 /* ----------------------------------------------------------------
2588  * ExecEvalAnd
2589  * ----------------------------------------------------------------
2590  */
2591 static Datum
2593  bool *isNull)
2594 {
2595  List *clauses = andExpr->args;
2596  ListCell *clause;
2597  bool AnyNull;
2598 
2599  AnyNull = false;
2600 
2601  /*
2602  * If any of the clauses is FALSE, the AND result is FALSE regardless of
2603  * the states of the rest of the clauses, so we can stop evaluating and
2604  * return FALSE immediately. If none are FALSE and one or more is NULL,
2605  * we return NULL; otherwise we return TRUE. This makes sense when you
2606  * interpret NULL as "don't know", using the same sort of reasoning as for
2607  * OR, above.
2608  */
2609 
2610  foreach(clause, clauses)
2611  {
2612  ExprState *clausestate = (ExprState *) lfirst(clause);
2613  Datum clause_value;
2614 
2615  clause_value = ExecEvalExpr(clausestate, econtext, isNull);
2616 
2617  /*
2618  * if we have a non-null false result, then return it.
2619  */
2620  if (*isNull)
2621  AnyNull = true; /* remember we got a null */
2622  else if (!DatumGetBool(clause_value))
2623  return clause_value;
2624  }
2625 
2626  /* AnyNull is true if at least one clause evaluated to NULL */
2627  *isNull = AnyNull;
2628  return BoolGetDatum(!AnyNull);
2629 }
2630 
2631 /* ----------------------------------------------------------------
2632  * ExecEvalConvertRowtype
2633  *
2634  * Evaluate a rowtype coercion operation. This may require
2635  * rearranging field positions.
2636  * ----------------------------------------------------------------
2637  */
2638 static Datum
2640  ExprContext *econtext,
2641  bool *isNull)
2642 {
2644  HeapTuple result;
2645  Datum tupDatum;
2646  HeapTupleHeader tuple;
2647  HeapTupleData tmptup;
2648 
2649  tupDatum = ExecEvalExpr(cstate->arg, econtext, isNull);
2650 
2651  /* this test covers the isDone exception too: */
2652  if (*isNull)
2653  return tupDatum;
2654 
2655  tuple = DatumGetHeapTupleHeader(tupDatum);
2656 
2657  /* Lookup tupdescs if first time through or after rescan */
2658  if (cstate->indesc == NULL)
2659  {
2660  get_cached_rowtype(exprType((Node *) convert->arg), -1,
2661  &cstate->indesc, econtext);
2662  cstate->initialized = false;
2663  }
2664  if (cstate->outdesc == NULL)
2665  {
2666  get_cached_rowtype(convert->resulttype, -1,
2667  &cstate->outdesc, econtext);
2668  cstate->initialized = false;
2669  }
2670 
2671  /*
2672  * We used to be able to assert that incoming tuples are marked with
2673  * exactly the rowtype of cstate->indesc. However, now that
2674  * ExecEvalWholeRowVar might change the tuples' marking to plain RECORD
2675  * due to inserting aliases, we can only make this weak test:
2676  */
2677  Assert(HeapTupleHeaderGetTypeId(tuple) == cstate->indesc->tdtypeid ||
2679 
2680  /* if first time through, initialize conversion map */
2681  if (!cstate->initialized)
2682  {
2683  MemoryContext old_cxt;
2684 
2685  /* allocate map in long-lived memory context */
2686  old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2687 
2688  /* prepare map from old to new attribute numbers */
2689  cstate->map = convert_tuples_by_name(cstate->indesc,
2690  cstate->outdesc,
2691  gettext_noop("could not convert row type"));
2692  cstate->initialized = true;
2693 
2694  MemoryContextSwitchTo(old_cxt);
2695  }
2696 
2697  /*
2698  * No-op if no conversion needed (not clear this can happen here).
2699  */
2700  if (cstate->map == NULL)
2701  return tupDatum;
2702 
2703  /*
2704  * do_convert_tuple needs a HeapTuple not a bare HeapTupleHeader.
2705  */
2706  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2707  tmptup.t_data = tuple;
2708 
2709  result = do_convert_tuple(&tmptup, cstate->map);
2710 
2711  return HeapTupleGetDatum(result);
2712 }
2713 
2714 /* ----------------------------------------------------------------
2715  * ExecEvalCase
2716  *
2717  * Evaluate a CASE clause. Will have boolean expressions
2718  * inside the WHEN clauses, and will have expressions
2719  * for results.
2720  * - thomas 1998-11-09
2721  * ----------------------------------------------------------------
2722  */
2723 static Datum
2725  bool *isNull)
2726 {
2727  List *clauses = caseExpr->args;
2728  ListCell *clause;
2729  Datum save_datum;
2730  bool save_isNull;
2731 
2732  /*
2733  * If there's a test expression, we have to evaluate it and save the value
2734  * where the CaseTestExpr placeholders can find it. We must save and
2735  * restore prior setting of econtext's caseValue fields, in case this node
2736  * is itself within a larger CASE. Furthermore, don't assign to the
2737  * econtext fields until after returning from evaluation of the test
2738  * expression. We used to pass &econtext->caseValue_isNull to the
2739  * recursive call, but that leads to aliasing that variable within said
2740  * call, which can (and did) produce bugs when the test expression itself
2741  * contains a CASE.
2742  *
2743  * If there's no test expression, we don't actually need to save and
2744  * restore these fields; but it's less code to just do so unconditionally.
2745  */
2746  save_datum = econtext->caseValue_datum;
2747  save_isNull = econtext->caseValue_isNull;
2748 
2749  if (caseExpr->arg)
2750  {
2751  Datum arg_value;
2752  bool arg_isNull;
2753 
2754  arg_value = ExecEvalExpr(caseExpr->arg,
2755  econtext,
2756  &arg_isNull);
2757  /* Since caseValue_datum may be read multiple times, force to R/O */
2758  econtext->caseValue_datum =
2759  MakeExpandedObjectReadOnly(arg_value,
2760  arg_isNull,
2761  caseExpr->argtyplen);
2762  econtext->caseValue_isNull = arg_isNull;
2763  }
2764 
2765  /*
2766  * we evaluate each of the WHEN clauses in turn, as soon as one is true we
2767  * return the corresponding result. If none are true then we return the
2768  * value of the default clause, or NULL if there is none.
2769  */
2770  foreach(clause, clauses)
2771  {
2772  CaseWhenState *wclause = lfirst(clause);
2773  Datum clause_value;
2774  bool clause_isNull;
2775 
2776  clause_value = ExecEvalExpr(wclause->expr,
2777  econtext,
2778  &clause_isNull);
2779 
2780  /*
2781  * if we have a true test, then we return the result, since the case
2782  * statement is satisfied. A NULL result from the test is not
2783  * considered true.
2784  */
2785  if (DatumGetBool(clause_value) && !clause_isNull)
2786  {
2787  econtext->caseValue_datum = save_datum;
2788  econtext->caseValue_isNull = save_isNull;
2789  return ExecEvalExpr(wclause->result,
2790  econtext,
2791  isNull);
2792  }
2793  }
2794 
2795  econtext->caseValue_datum = save_datum;
2796  econtext->caseValue_isNull = save_isNull;
2797 
2798  if (caseExpr->defresult)
2799  {
2800  return ExecEvalExpr(caseExpr->defresult,
2801  econtext,
2802  isNull);
2803  }
2804 
2805  *isNull = true;
2806  return (Datum) 0;
2807 }
2808 
2809 /*
2810  * ExecEvalCaseTestExpr
2811  *
2812  * Return the value stored by CASE.
2813  */
2814 static Datum
2816  ExprContext *econtext,
2817  bool *isNull)
2818 {
2819  *isNull = econtext->caseValue_isNull;
2820  return econtext->caseValue_datum;
2821 }
2822 
2823 /*
2824  * ExecEvalGroupingFuncExpr
2825  *
2826  * Return a bitmask with a bit for each (unevaluated) argument expression
2827  * (rightmost arg is least significant bit).
2828  *
2829  * A bit is set if the corresponding expression is NOT part of the set of
2830  * grouping expressions in the current grouping set.
2831  */
2832 static Datum
2834  ExprContext *econtext,
2835  bool *isNull)
2836 {
2837  int result = 0;
2838  int attnum = 0;
2839  Bitmapset *grouped_cols = gstate->aggstate->grouped_cols;
2840  ListCell *lc;
2841 
2842  *isNull = false;
2843 
2844  foreach(lc, (gstate->clauses))
2845  {
2846  attnum = lfirst_int(lc);
2847 
2848  result = result << 1;
2849 
2850  if (!bms_is_member(attnum, grouped_cols))
2851  result = result | 1;
2852  }
2853 
2854  return (Datum) result;
2855 }
2856 
2857 /* ----------------------------------------------------------------
2858  * ExecEvalArray - ARRAY[] expressions
2859  * ----------------------------------------------------------------
2860  */
2861 static Datum
2863  bool *isNull)
2864 {
2865  ArrayExpr *arrayExpr = (ArrayExpr *) astate->xprstate.expr;
2866  ArrayType *result;
2867  ListCell *element;
2868  Oid element_type = arrayExpr->element_typeid;
2869  int ndims = 0;
2870  int dims[MAXDIM];
2871  int lbs[MAXDIM];
2872 
2873  /* Set non-null as default */
2874  *isNull = false;
2875 
2876  if (!arrayExpr->multidims)
2877  {
2878  /* Elements are presumably of scalar type */
2879  int nelems;
2880  Datum *dvalues;
2881  bool *dnulls;
2882  int i = 0;
2883 
2884  ndims = 1;
2885  nelems = list_length(astate->elements);
2886 
2887  /* Shouldn't happen here, but if length is 0, return empty array */
2888  if (nelems == 0)
2889  return PointerGetDatum(construct_empty_array(element_type));
2890 
2891  dvalues = (Datum *) palloc(nelems * sizeof(Datum));
2892  dnulls = (bool *) palloc(nelems * sizeof(bool));
2893 
2894  /* loop through and build array of datums */
2895  foreach(element, astate->elements)
2896  {
2898 
2899  dvalues[i] = ExecEvalExpr(e, econtext, &dnulls[i]);
2900  i++;
2901  }
2902 
2903  /* setup for 1-D array of the given length */
2904  dims[0] = nelems;
2905  lbs[0] = 1;
2906 
2907  result = construct_md_array(dvalues, dnulls, ndims, dims, lbs,
2908  element_type,
2909  astate->elemlength,
2910  astate->elembyval,
2911  astate->elemalign);
2912  }
2913  else
2914  {
2915  /* Must be nested array expressions */
2916  int nbytes = 0;
2917  int nitems = 0;
2918  int outer_nelems = 0;
2919  int elem_ndims = 0;
2920  int *elem_dims = NULL;
2921  int *elem_lbs = NULL;
2922  bool firstone = true;
2923  bool havenulls = false;
2924  bool haveempty = false;
2925  char **subdata;
2926  bits8 **subbitmaps;
2927  int *subbytes;
2928  int *subnitems;
2929  int i;
2930  int32 dataoffset;
2931  char *dat;
2932  int iitem;
2933 
2934  i = list_length(astate->elements);
2935  subdata = (char **) palloc(i * sizeof(char *));
2936  subbitmaps = (bits8 **) palloc(i * sizeof(bits8 *));
2937  subbytes = (int *) palloc(i * sizeof(int));
2938  subnitems = (int *) palloc(i * sizeof(int));
2939 
2940  /* loop through and get data area from each element */
2941  foreach(element, astate->elements)
2942  {
2944  bool eisnull;
2945  Datum arraydatum;
2946  ArrayType *array;
2947  int this_ndims;
2948 
2949  arraydatum = ExecEvalExpr(e, econtext, &eisnull);
2950  /* temporarily ignore null subarrays */
2951  if (eisnull)
2952  {
2953  haveempty = true;
2954  continue;
2955  }
2956 
2957  array = DatumGetArrayTypeP(arraydatum);
2958 
2959  /* run-time double-check on element type */
2960  if (element_type != ARR_ELEMTYPE(array))
2961  ereport(ERROR,
2962  (errcode(ERRCODE_DATATYPE_MISMATCH),
2963  errmsg("cannot merge incompatible arrays"),
2964  errdetail("Array with element type %s cannot be "
2965  "included in ARRAY construct with element type %s.",
2966  format_type_be(ARR_ELEMTYPE(array)),
2967  format_type_be(element_type))));
2968 
2969  this_ndims = ARR_NDIM(array);
2970  /* temporarily ignore zero-dimensional subarrays */
2971  if (this_ndims <= 0)
2972  {
2973  haveempty = true;
2974  continue;
2975  }
2976 
2977  if (firstone)
2978  {
2979  /* Get sub-array details from first member */
2980  elem_ndims = this_ndims;
2981  ndims = elem_ndims + 1;
2982  if (ndims <= 0 || ndims > MAXDIM)
2983  ereport(ERROR,
2984  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2985  errmsg("number of array dimensions (%d) exceeds " \
2986  "the maximum allowed (%d)", ndims, MAXDIM)));
2987 
2988  elem_dims = (int *) palloc(elem_ndims * sizeof(int));
2989  memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
2990  elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
2991  memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
2992 
2993  firstone = false;
2994  }
2995  else
2996  {
2997  /* Check other sub-arrays are compatible */
2998  if (elem_ndims != this_ndims ||
2999  memcmp(elem_dims, ARR_DIMS(array),
3000  elem_ndims * sizeof(int)) != 0 ||
3001  memcmp(elem_lbs, ARR_LBOUND(array),
3002  elem_ndims * sizeof(int)) != 0)
3003  ereport(ERROR,
3004  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3005  errmsg("multidimensional arrays must have array "
3006  "expressions with matching dimensions")));
3007  }
3008 
3009  subdata[outer_nelems] = ARR_DATA_PTR(array);
3010  subbitmaps[outer_nelems] = ARR_NULLBITMAP(array);
3011  subbytes[outer_nelems] = ARR_SIZE(array) - ARR_DATA_OFFSET(array);
3012  nbytes += subbytes[outer_nelems];
3013  subnitems[outer_nelems] = ArrayGetNItems(this_ndims,
3014  ARR_DIMS(array));
3015  nitems += subnitems[outer_nelems];
3016  havenulls |= ARR_HASNULL(array);
3017  outer_nelems++;
3018  }
3019 
3020  /*
3021  * If all items were null or empty arrays, return an empty array;
3022  * otherwise, if some were and some weren't, raise error. (Note: we
3023  * must special-case this somehow to avoid trying to generate a 1-D
3024  * array formed from empty arrays. It's not ideal...)
3025  */
3026  if (haveempty)
3027  {
3028  if (ndims == 0) /* didn't find any nonempty array */
3029  return PointerGetDatum(construct_empty_array(element_type));
3030  ereport(ERROR,
3031  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3032  errmsg("multidimensional arrays must have array "
3033  "expressions with matching dimensions")));
3034  }
3035 
3036  /* setup for multi-D array */
3037  dims[0] = outer_nelems;
3038  lbs[0] = 1;
3039  for (i = 1; i < ndims; i++)
3040  {
3041  dims[i] = elem_dims[i - 1];
3042  lbs[i] = elem_lbs[i - 1];
3043  }
3044 
3045  if (havenulls)
3046  {
3047  dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nitems);
3048  nbytes += dataoffset;
3049  }
3050  else
3051  {
3052  dataoffset = 0; /* marker for no null bitmap */
3053  nbytes += ARR_OVERHEAD_NONULLS(ndims);
3054  }
3055 
3056  result = (ArrayType *) palloc(nbytes);
3057  SET_VARSIZE(result, nbytes);
3058  result->ndim = ndims;
3059  result->dataoffset = dataoffset;
3060  result->elemtype = element_type;
3061  memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
3062  memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
3063 
3064  dat = ARR_DATA_PTR(result);
3065  iitem = 0;
3066  for (i = 0; i < outer_nelems; i++)
3067  {
3068  memcpy(dat, subdata[i], subbytes[i]);
3069  dat += subbytes[i];
3070  if (havenulls)
3071  array_bitmap_copy(ARR_NULLBITMAP(result), iitem,
3072  subbitmaps[i], 0,
3073  subnitems[i]);
3074  iitem += subnitems[i];
3075  }
3076  }
3077 
3078  return PointerGetDatum(result);
3079 }
3080 
3081 /* ----------------------------------------------------------------
3082  * ExecEvalRow - ROW() expressions
3083  * ----------------------------------------------------------------
3084  */
3085 static Datum
3087  ExprContext *econtext,
3088  bool *isNull)
3089 {
3090  HeapTuple tuple;
3091  Datum *values;
3092  bool *isnull;
3093  int natts;
3094  ListCell *arg;
3095  int i;
3096 
3097  /* Set non-null as default */
3098  *isNull = false;
3099 
3100  /* Allocate workspace */
3101  natts = rstate->tupdesc->natts;
3102  values = (Datum *) palloc0(natts * sizeof(Datum));
3103  isnull = (bool *) palloc(natts * sizeof(bool));
3104 
3105  /* preset to nulls in case rowtype has some later-added columns */
3106  memset(isnull, true, natts * sizeof(bool));
3107 
3108  /* Evaluate field values */
3109  i = 0;
3110  foreach(arg, rstate->args)
3111  {
3112  ExprState *e = (ExprState *) lfirst(arg);
3113 
3114  values[i] = ExecEvalExpr(e, econtext, &isnull[i]);
3115  i++;
3116  }
3117 
3118  tuple = heap_form_tuple(rstate->tupdesc, values, isnull);
3119 
3120  pfree(values);
3121  pfree(isnull);
3122 
3123  return HeapTupleGetDatum(tuple);
3124 }
3125 
3126 /* ----------------------------------------------------------------
3127  * ExecEvalRowCompare - ROW() comparison-op ROW()
3128  * ----------------------------------------------------------------
3129  */
3130 static Datum
3132  ExprContext *econtext,
3133  bool *isNull)
3134 {
3135  bool result;
3136  RowCompareType rctype = ((RowCompareExpr *) rstate->xprstate.expr)->rctype;
3137  int32 cmpresult = 0;
3138  ListCell *l;
3139  ListCell *r;
3140  int i;
3141 
3142  *isNull = true; /* until we get a result */
3143 
3144  i = 0;
3145  forboth(l, rstate->largs, r, rstate->rargs)
3146  {
3147  ExprState *le = (ExprState *) lfirst(l);
3148  ExprState *re = (ExprState *) lfirst(r);
3149  FunctionCallInfoData locfcinfo;
3150 
3151  InitFunctionCallInfoData(locfcinfo, &(rstate->funcs[i]), 2,
3152  rstate->collations[i],
3153  NULL, NULL);
3154  locfcinfo.arg[0] = ExecEvalExpr(le, econtext,
3155  &locfcinfo.argnull[0]);
3156  locfcinfo.arg[1] = ExecEvalExpr(re, econtext,
3157  &locfcinfo.argnull[1]);
3158  if (rstate->funcs[i].fn_strict &&
3159  (locfcinfo.argnull[0] || locfcinfo.argnull[1]))
3160  return (Datum) 0; /* force NULL result */
3161  locfcinfo.isnull = false;
3162  cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
3163  if (locfcinfo.isnull)
3164  return (Datum) 0; /* force NULL result */
3165  if (cmpresult != 0)
3166  break; /* no need to compare remaining columns */
3167  i++;
3168  }
3169 
3170  switch (rctype)
3171  {
3172  /* EQ and NE cases aren't allowed here */
3173  case ROWCOMPARE_LT:
3174  result = (cmpresult < 0);
3175  break;
3176  case ROWCOMPARE_LE:
3177  result = (cmpresult <= 0);
3178  break;
3179  case ROWCOMPARE_GE:
3180  result = (cmpresult >= 0);
3181  break;
3182  case ROWCOMPARE_GT:
3183  result = (cmpresult > 0);
3184  break;
3185  default:
3186  elog(ERROR, "unrecognized RowCompareType: %d", (int) rctype);
3187  result = 0; /* keep compiler quiet */
3188  break;
3189  }
3190 
3191  *isNull = false;
3192  return BoolGetDatum(result);
3193 }
3194 
3195 /* ----------------------------------------------------------------
3196  * ExecEvalCoalesce
3197  * ----------------------------------------------------------------
3198  */
3199 static Datum
3201  bool *isNull)
3202 {
3203  ListCell *arg;
3204 
3205  /* Simply loop through until something NOT NULL is found */
3206  foreach(arg, coalesceExpr->args)
3207  {
3208  ExprState *e = (ExprState *) lfirst(arg);
3209  Datum value;
3210 
3211  value = ExecEvalExpr(e, econtext, isNull);
3212  if (!*isNull)
3213  return value;
3214  }
3215 
3216  /* Else return NULL */
3217  *isNull = true;
3218  return (Datum) 0;
3219 }
3220 
3221 /* ----------------------------------------------------------------
3222  * ExecEvalMinMax
3223  * ----------------------------------------------------------------
3224  */
3225 static Datum
3227  bool *isNull)
3228 {
3229  Datum result = (Datum) 0;
3230  MinMaxExpr *minmax = (MinMaxExpr *) minmaxExpr->xprstate.expr;
3231  Oid collation = minmax->inputcollid;
3232  MinMaxOp op = minmax->op;
3233  FunctionCallInfoData locfcinfo;
3234  ListCell *arg;
3235 
3236  *isNull = true; /* until we get a result */
3237 
3238  InitFunctionCallInfoData(locfcinfo, &minmaxExpr->cfunc, 2,
3239  collation, NULL, NULL);
3240  locfcinfo.argnull[0] = false;
3241  locfcinfo.argnull[1] = false;
3242 
3243  foreach(arg, minmaxExpr->args)
3244  {
3245  ExprState *e = (ExprState *) lfirst(arg);
3246  Datum value;
3247  bool valueIsNull;
3248  int32 cmpresult;
3249 
3250  value = ExecEvalExpr(e, econtext, &valueIsNull);
3251  if (valueIsNull)
3252  continue; /* ignore NULL inputs */
3253 
3254  if (*isNull)
3255  {
3256  /* first nonnull input, adopt value */
3257  result = value;
3258  *isNull = false;
3259  }
3260  else
3261  {
3262  /* apply comparison function */
3263  locfcinfo.arg[0] = result;
3264  locfcinfo.arg[1] = value;
3265  locfcinfo.isnull = false;
3266  cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
3267  if (locfcinfo.isnull) /* probably should not happen */
3268  continue;
3269  if (cmpresult > 0 && op == IS_LEAST)
3270  result = value;
3271  else if (cmpresult < 0 && op == IS_GREATEST)
3272  result = value;
3273  }
3274  }
3275 
3276  return result;
3277 }
3278 
3279 /* ----------------------------------------------------------------
3280  * ExecEvalSQLValueFunction
3281  * ----------------------------------------------------------------
3282  */
3283 static Datum
3285  ExprContext *econtext,
3286  bool *isNull)
3287 {
3288  Datum result = (Datum) 0;
3289  SQLValueFunction *svf = (SQLValueFunction *) svfExpr->expr;
3290  FunctionCallInfoData fcinfo;
3291 
3292  *isNull = false;
3293 
3294  /*
3295  * Note: current_schema() can return NULL. current_user() etc currently
3296  * cannot, but might as well code those cases the same way for safety.
3297  */
3298  switch (svf->op)
3299  {
3300  case SVFOP_CURRENT_DATE:
3301  result = DateADTGetDatum(GetSQLCurrentDate());
3302  break;
3303  case SVFOP_CURRENT_TIME:
3304  case SVFOP_CURRENT_TIME_N:
3306  break;
3310  break;
3311  case SVFOP_LOCALTIME:
3312  case SVFOP_LOCALTIME_N:
3313  result = TimeADTGetDatum(GetSQLLocalTime(svf->typmod));
3314  break;
3315  case SVFOP_LOCALTIMESTAMP:
3318  break;
3319  case SVFOP_CURRENT_ROLE:
3320  case SVFOP_CURRENT_USER:
3321  case SVFOP_USER:
3323  result = current_user(&fcinfo);
3324  *isNull = fcinfo.isnull;
3325  break;
3326  case SVFOP_SESSION_USER:
3328  result = session_user(&fcinfo);
3329  *isNull = fcinfo.isnull;
3330  break;
3331  case SVFOP_CURRENT_CATALOG:
3333  result = current_database(&fcinfo);
3334  *isNull = fcinfo.isnull;
3335  break;
3336  case SVFOP_CURRENT_SCHEMA:
3338  result = current_schema(&fcinfo);
3339  *isNull = fcinfo.isnull;
3340  break;
3341  }
3342 
3343  return result;
3344 }
3345 
3346 /* ----------------------------------------------------------------
3347  * ExecEvalXml
3348  * ----------------------------------------------------------------
3349  */
3350 static Datum
3352  bool *isNull)
3353 {
3354  XmlExpr *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
3355  Datum value;
3356  bool isnull;
3357  ListCell *arg;
3358  ListCell *narg;
3359 
3360  *isNull = true; /* until we get a result */
3361 
3362  switch (xexpr->op)
3363  {
3364  case IS_XMLCONCAT:
3365  {
3366  List *values = NIL;
3367 
3368  foreach(arg, xmlExpr->args)
3369  {
3370  ExprState *e = (ExprState *) lfirst(arg);
3371 
3372  value = ExecEvalExpr(e, econtext, &isnull);
3373  if (!isnull)
3374  values = lappend(values, DatumGetPointer(value));
3375  }
3376 
3377  if (list_length(values) > 0)
3378  {
3379  *isNull = false;
3380  return PointerGetDatum(xmlconcat(values));
3381  }
3382  else
3383  return (Datum) 0;
3384  }
3385  break;
3386 
3387  case IS_XMLFOREST:
3388  {
3390 
3391  initStringInfo(&buf);
3392  forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
3393  {
3394  ExprState *e = (ExprState *) lfirst(arg);
3395  char *argname = strVal(lfirst(narg));
3396 
3397  value = ExecEvalExpr(e, econtext, &isnull);
3398  if (!isnull)
3399  {
3400  appendStringInfo(&buf, "<%s>%s</%s>",
3401  argname,
3403  argname);
3404  *isNull = false;
3405  }
3406  }
3407 
3408  if (*isNull)
3409  {
3410  pfree(buf.data);
3411  return (Datum) 0;
3412  }
3413  else
3414  {
3415  text *result;
3416 
3417  result = cstring_to_text_with_len(buf.data, buf.len);
3418  pfree(buf.data);
3419 
3420  return PointerGetDatum(result);
3421  }
3422  }
3423  break;
3424 
3425  case IS_XMLELEMENT:
3426  *isNull = false;
3427  return PointerGetDatum(xmlelement(xmlExpr, econtext));
3428  break;
3429 
3430  case IS_XMLPARSE:
3431  {
3432  ExprState *e;
3433  text *data;
3434  bool preserve_whitespace;
3435 
3436  /* arguments are known to be text, bool */
3437  Assert(list_length(xmlExpr->args) == 2);
3438 
3439  e = (ExprState *) linitial(xmlExpr->args);
3440  value = ExecEvalExpr(e, econtext, &isnull);
3441  if (isnull)
3442  return (Datum) 0;
3443  data = DatumGetTextPP(value);
3444 
3445  e = (ExprState *) lsecond(xmlExpr->args);
3446  value = ExecEvalExpr(e, econtext, &isnull);
3447  if (isnull) /* probably can't happen */
3448  return (Datum) 0;
3449  preserve_whitespace = DatumGetBool(value);
3450 
3451  *isNull = false;
3452 
3453  return PointerGetDatum(xmlparse(data,
3454  xexpr->xmloption,
3455  preserve_whitespace));
3456  }
3457  break;
3458 
3459  case IS_XMLPI:
3460  {
3461  ExprState *e;
3462  text *arg;
3463 
3464  /* optional argument is known to be text */
3465  Assert(list_length(xmlExpr->args) <= 1);
3466 
3467  if (xmlExpr->args)
3468  {
3469  e = (ExprState *) linitial(xmlExpr->args);
3470  value = ExecEvalExpr(e, econtext, &isnull);
3471  if (isnull)
3472  arg = NULL;
3473  else
3474  arg = DatumGetTextPP(value);
3475  }
3476  else
3477  {
3478  arg = NULL;
3479  isnull = false;
3480  }
3481 
3482  return PointerGetDatum(xmlpi(xexpr->name, arg, isnull, isNull));
3483  }
3484  break;
3485 
3486  case IS_XMLROOT:
3487  {
3488  ExprState *e;
3489  xmltype *data;
3490  text *version;
3491  int standalone;
3492 
3493  /* arguments are known to be xml, text, int */
3494  Assert(list_length(xmlExpr->args) == 3);
3495 
3496  e = (ExprState *) linitial(xmlExpr->args);
3497  value = ExecEvalExpr(e, econtext, &isnull);
3498  if (isnull)
3499  return (Datum) 0;
3500  data = DatumGetXmlP(value);
3501 
3502  e = (ExprState *) lsecond(xmlExpr->args);
3503  value = ExecEvalExpr(e, econtext, &isnull);
3504  if (isnull)
3505  version = NULL;
3506  else
3507  version = DatumGetTextPP(value);
3508 
3509  e = (ExprState *) lthird(xmlExpr->args);
3510  value = ExecEvalExpr(e, econtext, &isnull);
3511  standalone = DatumGetInt32(value);
3512 
3513  *isNull = false;
3514 
3515  return PointerGetDatum(xmlroot(data,
3516  version,
3517  standalone));
3518  }
3519  break;
3520 
3521  case IS_XMLSERIALIZE:
3522  {
3523  ExprState *e;
3524 
3525  /* argument type is known to be xml */
3526  Assert(list_length(xmlExpr->args) == 1);
3527 
3528  e = (ExprState *) linitial(xmlExpr->args);
3529  value = ExecEvalExpr(e, econtext, &isnull);
3530  if (isnull)
3531  return (Datum) 0;
3532 
3533  *isNull = false;
3534 
3536  }
3537  break;
3538 
3539  case IS_DOCUMENT:
3540  {
3541  ExprState *e;
3542 
3543  /* optional argument is known to be xml */
3544  Assert(list_length(xmlExpr->args) == 1);
3545 
3546  e = (ExprState *) linitial(xmlExpr->args);
3547  value = ExecEvalExpr(e, econtext, &isnull);
3548  if (isnull)
3549  return (Datum) 0;
3550  else
3551  {
3552  *isNull = false;
3554  }
3555  }
3556  break;
3557  }
3558 
3559  elog(ERROR, "unrecognized XML operation");
3560  return (Datum) 0;
3561 }
3562 
3563 /* ----------------------------------------------------------------
3564  * ExecEvalNullIf
3565  *
3566  * Note that this is *always* derived from the equals operator,
3567  * but since we need special processing of the arguments
3568  * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
3569  * ----------------------------------------------------------------
3570  */
3571 static Datum
3573  ExprContext *econtext,
3574  bool *isNull)
3575 {
3576  Datum result;
3577  FunctionCallInfo fcinfo;
3578 
3579  /*
3580  * Initialize function cache if first time through
3581  */
3582  if (nullIfExpr->func.fn_oid == InvalidOid)
3583  {
3584  NullIfExpr *op = (NullIfExpr *) nullIfExpr->xprstate.expr;
3585 
3586  init_fcache(op->opfuncid, op->inputcollid, nullIfExpr,
3587  econtext->ecxt_per_query_memory, false, false);
3588  }
3589 
3590  /*
3591  * Evaluate arguments
3592  */
3593  fcinfo = &nullIfExpr->fcinfo_data;
3594  ExecEvalFuncArgs(fcinfo, nullIfExpr->args, econtext);
3595  Assert(fcinfo->nargs == 2);
3596 
3597  /* if either argument is NULL they can't be equal */
3598  if (!fcinfo->argnull[0] && !fcinfo->argnull[1])
3599  {
3600  fcinfo->isnull = false;
3601  result = FunctionCallInvoke(fcinfo);
3602  /* if the arguments are equal return null */
3603  if (!fcinfo->isnull && DatumGetBool(result))
3604  {
3605  *isNull = true;
3606  return (Datum) 0;
3607  }
3608  }
3609 
3610  /* else return first argument */
3611  *isNull = fcinfo->argnull[0];
3612  return fcinfo->arg[0];
3613 }
3614 
3615 /* ----------------------------------------------------------------
3616  * ExecEvalNullTest
3617  *
3618  * Evaluate a NullTest node.
3619  * ----------------------------------------------------------------
3620  */
3621 static Datum
3623  ExprContext *econtext,
3624  bool *isNull)
3625 {
3626  NullTest *ntest = (NullTest *) nstate->xprstate.expr;
3627  Datum result;
3628 
3629  result = ExecEvalExpr(nstate->arg, econtext, isNull);
3630 
3631  if (ntest->argisrow && !(*isNull))
3632  {
3633  /*
3634  * The SQL standard defines IS [NOT] NULL for a non-null rowtype
3635  * argument as:
3636  *
3637  * "R IS NULL" is true if every field is the null value.
3638  *
3639  * "R IS NOT NULL" is true if no field is the null value.
3640  *
3641  * This definition is (apparently intentionally) not recursive; so our
3642  * tests on the fields are primitive attisnull tests, not recursive
3643  * checks to see if they are all-nulls or no-nulls rowtypes.
3644  *
3645  * The standard does not consider the possibility of zero-field rows,
3646  * but here we consider them to vacuously satisfy both predicates.
3647  */
3648  HeapTupleHeader tuple;
3649  Oid tupType;
3650  int32 tupTypmod;
3651  TupleDesc tupDesc;
3652  HeapTupleData tmptup;
3653  int att;
3654 
3655  tuple = DatumGetHeapTupleHeader(result);
3656 
3657  tupType = HeapTupleHeaderGetTypeId(tuple);
3658  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3659 
3660  /* Lookup tupdesc if first time through or if type changes */
3661  tupDesc = get_cached_rowtype(tupType, tupTypmod,
3662  &nstate->argdesc, econtext);
3663 
3664  /*
3665  * heap_attisnull needs a HeapTuple not a bare HeapTupleHeader.
3666  */
3667  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3668  tmptup.t_data = tuple;
3669 
3670  for (att = 1; att <= tupDesc->natts; att++)
3671  {
3672  /* ignore dropped columns */
3673  if (tupDesc->attrs[att - 1]->attisdropped)
3674  continue;
3675  if (heap_attisnull(&tmptup, att))
3676  {
3677  /* null field disproves IS NOT NULL */
3678  if (ntest->nulltesttype == IS_NOT_NULL)
3679  return BoolGetDatum(false);
3680  }
3681  else
3682  {
3683  /* non-null field disproves IS NULL */
3684  if (ntest->nulltesttype == IS_NULL)
3685  return BoolGetDatum(false);
3686  }
3687  }
3688 
3689  return BoolGetDatum(true);
3690  }
3691  else
3692  {
3693  /* Simple scalar-argument case, or a null rowtype datum */
3694  switch (ntest->nulltesttype)
3695  {
3696  case IS_NULL:
3697  if (*isNull)
3698  {
3699  *isNull = false;
3700  return BoolGetDatum(true);
3701  }
3702  else
3703  return BoolGetDatum(false);
3704  case IS_NOT_NULL:
3705  if (*isNull)
3706  {
3707  *isNull = false;
3708  return BoolGetDatum(false);
3709  }
3710  else
3711  return BoolGetDatum(true);
3712  default:
3713  elog(ERROR, "unrecognized nulltesttype: %d",
3714  (int) ntest->nulltesttype);
3715  return (Datum) 0; /* keep compiler quiet */
3716  }
3717  }
3718 }
3719 
3720 /* ----------------------------------------------------------------
3721  * ExecEvalBooleanTest
3722  *
3723  * Evaluate a BooleanTest node.
3724  * ----------------------------------------------------------------
3725  */
3726 static Datum
3728  ExprContext *econtext,
3729  bool *isNull)
3730 {
3731  BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;
3732  Datum result;
3733 
3734  result = ExecEvalExpr(bstate->arg, econtext, isNull);
3735 
3736  switch (btest->booltesttype)
3737  {
3738  case IS_TRUE:
3739  if (*isNull)
3740  {
3741  *isNull = false;
3742  return BoolGetDatum(false);
3743  }
3744  else if (DatumGetBool(result))
3745  return BoolGetDatum(true);
3746  else
3747  return BoolGetDatum(false);
3748  case IS_NOT_TRUE:
3749  if (*isNull)
3750  {
3751  *isNull = false;
3752  return BoolGetDatum(true);
3753  }
3754  else if (DatumGetBool(result))
3755  return BoolGetDatum(false);
3756  else
3757  return BoolGetDatum(true);
3758  case IS_FALSE:
3759  if (*isNull)
3760  {
3761  *isNull = false;
3762  return BoolGetDatum(false);
3763  }
3764  else if (DatumGetBool(result))
3765  return BoolGetDatum(false);
3766  else
3767  return BoolGetDatum(true);
3768  case IS_NOT_FALSE:
3769  if (*isNull)
3770  {
3771  *isNull = false;
3772  return BoolGetDatum(true);
3773  }
3774  else if (DatumGetBool(result))
3775  return BoolGetDatum(true);
3776  else
3777  return BoolGetDatum(false);
3778  case IS_UNKNOWN:
3779  if (*isNull)
3780  {
3781  *isNull = false;
3782  return BoolGetDatum(true);
3783  }
3784  else
3785  return BoolGetDatum(false);
3786  case IS_NOT_UNKNOWN:
3787  if (*isNull)
3788  {
3789  *isNull = false;
3790  return BoolGetDatum(false);
3791  }
3792  else
3793  return BoolGetDatum(true);
3794  default:
3795  elog(ERROR, "unrecognized booltesttype: %d",
3796  (int) btest->booltesttype);
3797  return (Datum) 0; /* keep compiler quiet */
3798  }
3799 }
3800 
3801 /*
3802  * ExecEvalCoerceToDomain
3803  *
3804  * Test the provided data against the domain constraint(s). If the data
3805  * passes the constraint specifications, pass it through (return the
3806  * datum) otherwise throw an error.
3807  */
3808 static Datum
3810  bool *isNull)
3811 {
3812  CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
3813  Datum result;
3814  ListCell *l;
3815 
3816  result = ExecEvalExpr(cstate->arg, econtext, isNull);
3817 
3818  /* Make sure we have up-to-date constraints */
3820 
3821  foreach(l, cstate->constraint_ref->constraints)
3822  {
3824 
3825  switch (con->constrainttype)
3826  {
3828  if (*isNull)
3829  ereport(ERROR,
3830  (errcode(ERRCODE_NOT_NULL_VIOLATION),
3831  errmsg("domain %s does not allow null values",
3832  format_type_be(ctest->resulttype)),
3833  errdatatype(ctest->resulttype)));
3834  break;
3835  case DOM_CONSTRAINT_CHECK:
3836  {
3837  Datum conResult;
3838  bool conIsNull;
3839  Datum save_datum;
3840  bool save_isNull;
3841 
3842  /*
3843  * Set up value to be returned by CoerceToDomainValue
3844  * nodes. We must save and restore prior setting of
3845  * econtext's domainValue fields, in case this node is
3846  * itself within a check expression for another domain.
3847  *
3848  * Also, if we are working with a read-write expanded
3849  * datum, be sure that what we pass to CHECK expressions
3850  * is a read-only pointer; else called functions might
3851  * modify or even delete the expanded object.
3852  */
3853  save_datum = econtext->domainValue_datum;
3854  save_isNull = econtext->domainValue_isNull;
3855 
3856  econtext->domainValue_datum =
3857  MakeExpandedObjectReadOnly(result, *isNull,
3858  cstate->constraint_ref->tcache->typlen);
3859  econtext->domainValue_isNull = *isNull;
3860 
3861  conResult = ExecEvalExpr(con->check_expr, econtext,
3862  &conIsNull);
3863 
3864  if (!conIsNull &&
3865  !DatumGetBool(conResult))
3866  ereport(ERROR,
3867  (errcode(ERRCODE_CHECK_VIOLATION),
3868  errmsg("value for domain %s violates check constraint \"%s\"",
3869  format_type_be(ctest->resulttype),
3870  con->name),
3872  con->name)));
3873  econtext->domainValue_datum = save_datum;
3874  econtext->domainValue_isNull = save_isNull;
3875 
3876  break;
3877  }
3878  default:
3879  elog(ERROR, "unrecognized constraint type: %d",
3880  (int) con->constrainttype);
3881  break;
3882  }
3883  }
3884 
3885  /* If all has gone well (constraints did not fail) return the datum */
3886  return result;
3887 }
3888 
3889 /*
3890  * ExecEvalCoerceToDomainValue
3891  *
3892  * Return the value stored by CoerceToDomain.
3893  */
3894 static Datum
3896  ExprContext *econtext,
3897  bool *isNull)
3898 {
3899  *isNull = econtext->domainValue_isNull;
3900  return econtext->domainValue_datum;
3901 }
3902 
3903 /* ----------------------------------------------------------------
3904  * ExecEvalFieldSelect
3905  *
3906  * Evaluate a FieldSelect node.
3907  * ----------------------------------------------------------------
3908  */
3909 static Datum
3911  ExprContext *econtext,
3912  bool *isNull)
3913 {
3914  FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
3915  AttrNumber fieldnum = fselect->fieldnum;
3916  Datum result;
3917  Datum tupDatum;
3918  HeapTupleHeader tuple;
3919  Oid tupType;
3920  int32 tupTypmod;
3921  TupleDesc tupDesc;
3922  Form_pg_attribute attr;
3923  HeapTupleData tmptup;
3924 
3925  tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull);
3926 
3927  if (*isNull)
3928  return tupDatum;
3929 
3930  tuple = DatumGetHeapTupleHeader(tupDatum);
3931 
3932  tupType = HeapTupleHeaderGetTypeId(tuple);
3933  tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3934 
3935  /* Lookup tupdesc if first time through or if type changes */
3936  tupDesc = get_cached_rowtype(tupType, tupTypmod,
3937  &fstate->argdesc, econtext);
3938 
3939  /*
3940  * Find field's attr record. Note we don't support system columns here: a
3941  * datum tuple doesn't have valid values for most of the interesting
3942  * system columns anyway.
3943  */
3944  if (fieldnum <= 0) /* should never happen */
3945  elog(ERROR, "unsupported reference to system column %d in FieldSelect",
3946  fieldnum);
3947  if (fieldnum > tupDesc->natts) /* should never happen */
3948  elog(ERROR, "attribute number %d exceeds number of columns %d",
3949  fieldnum, tupDesc->natts);
3950  attr = tupDesc->attrs[fieldnum - 1];
3951 
3952  /* Check for dropped column, and force a NULL result if so */
3953  if (attr->attisdropped)
3954  {
3955  *isNull = true;
3956  return (Datum) 0;
3957  }
3958 
3959  /* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
3960  /* As in ExecEvalScalarVar, we should but can't check typmod */
3961  if (fselect->resulttype != attr->atttypid)
3962  ereport(ERROR,
3963  (errcode(ERRCODE_DATATYPE_MISMATCH),
3964  errmsg("attribute %d has wrong type", fieldnum),
3965  errdetail("Table has type %s, but query expects %s.",
3966  format_type_be(attr->atttypid),
3967  format_type_be(fselect->resulttype))));
3968 
3969  /* heap_getattr needs a HeapTuple not a bare HeapTupleHeader */
3970  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3971  tmptup.t_data = tuple;
3972 
3973  result = heap_getattr(&tmptup,
3974  fieldnum,
3975  tupDesc,
3976  isNull);
3977  return result;
3978 }
3979 
3980 /* ----------------------------------------------------------------
3981  * ExecEvalFieldStore
3982  *
3983  * Evaluate a FieldStore node.
3984  * ----------------------------------------------------------------
3985  */
3986 static Datum
3988  ExprContext *econtext,
3989  bool *isNull)
3990 {
3991  FieldStore *fstore = (FieldStore *) fstate->xprstate.expr;
3992  HeapTuple tuple;
3993  Datum tupDatum;
3994  TupleDesc tupDesc;
3995  Datum *values;
3996  bool *isnull;
3997  Datum save_datum;
3998  bool save_isNull;
3999  ListCell *l1,
4000  *l2;
4001 
4002  tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull);
4003 
4004  /* Lookup tupdesc if first time through or after rescan */
4005  tupDesc = get_cached_rowtype(fstore->resulttype, -1,
4006  &fstate->argdesc, econtext);
4007 
4008  /* Allocate workspace */
4009  values = (Datum *) palloc(tupDesc->natts * sizeof(Datum));
4010  isnull = (bool *) palloc(tupDesc->natts * sizeof(bool));
4011 
4012  if (!*isNull)
4013  {
4014  /*
4015  * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader. We
4016  * set all the fields in the struct just in case.
4017  */
4018  HeapTupleHeader tuphdr;
4019  HeapTupleData tmptup;
4020 
4021  tuphdr = DatumGetHeapTupleHeader(tupDatum);
4022  tmptup.t_len = HeapTupleHeaderGetDatumLength(tuphdr);
4023  ItemPointerSetInvalid(&(tmptup.t_self));
4024  tmptup.t_tableOid = InvalidOid;
4025  tmptup.t_data = tuphdr;
4026 
4027  heap_deform_tuple(&tmptup, tupDesc, values, isnull);
4028  }
4029  else
4030  {
4031  /* Convert null input tuple into an all-nulls row */
4032  memset(isnull, true, tupDesc->natts * sizeof(bool));
4033  }
4034 
4035  /* Result is never null */
4036  *isNull = false;
4037 
4038  save_datum = econtext->caseValue_datum;
4039  save_isNull = econtext->caseValue_isNull;
4040 
4041  forboth(l1, fstate->newvals, l2, fstore->fieldnums)
4042  {
4043  ExprState *newval = (ExprState *) lfirst(l1);
4044  AttrNumber fieldnum = lfirst_int(l2);
4045 
4046  Assert(fieldnum > 0 && fieldnum <= tupDesc->natts);
4047 
4048  /*
4049  * Use the CaseTestExpr mechanism to pass down the old value of the
4050  * field being replaced; this is needed in case the newval is itself a
4051  * FieldStore or ArrayRef that has to obtain and modify the old value.
4052  * It's safe to reuse the CASE mechanism because there cannot be a
4053  * CASE between here and where the value would be needed, and a field
4054  * assignment can't be within a CASE either. (So saving and restoring
4055  * the caseValue is just paranoia, but let's do it anyway.)
4056  */
4057  econtext->caseValue_datum = values[fieldnum - 1];
4058  econtext->caseValue_isNull = isnull[fieldnum - 1];
4059 
4060  values[fieldnum - 1] = ExecEvalExpr(newval,
4061  econtext,
4062  &isnull[fieldnum - 1]);
4063  }
4064 
4065  econtext->caseValue_datum = save_datum;
4066  econtext->caseValue_isNull = save_isNull;
4067 
4068  tuple = heap_form_tuple(tupDesc, values, isnull);
4069 
4070  pfree(values);
4071  pfree(isnull);
4072 
4073  return HeapTupleGetDatum(tuple);
4074 }
4075 
4076 /* ----------------------------------------------------------------
4077  * ExecEvalRelabelType
4078  *
4079  * Evaluate a RelabelType node.
4080  * ----------------------------------------------------------------
4081  */
4082 static Datum
4084  ExprContext *econtext,
4085  bool *isNull)
4086 {
4087  return ExecEvalExpr(exprstate->arg, econtext, isNull);
4088 }
4089 
4090 /* ----------------------------------------------------------------
4091  * ExecEvalCoerceViaIO
4092  *
4093  * Evaluate a CoerceViaIO node.
4094  * ----------------------------------------------------------------
4095  */
4096 static Datum
4098  ExprContext *econtext,
4099  bool *isNull)
4100 {
4101  Datum result;
4102  Datum inputval;
4103  char *string;
4104 
4105  inputval = ExecEvalExpr(iostate->arg, econtext, isNull);
4106 
4107  if (*isNull)
4108  string = NULL; /* output functions are not called on nulls */
4109  else
4110  string = OutputFunctionCall(&iostate->outfunc, inputval);
4111 
4112  result = InputFunctionCall(&iostate->infunc,
4113  string,
4114  iostate->intypioparam,
4115  -1);
4116 
4117  /* The input function cannot change the null/not-null status */
4118  return result;
4119 }
4120 
4121 /* ----------------------------------------------------------------
4122  * ExecEvalArrayCoerceExpr
4123  *
4124  * Evaluate an ArrayCoerceExpr node.
4125  * ----------------------------------------------------------------
4126  */
4127 static Datum
4129  ExprContext *econtext,
4130  bool *isNull)
4131 {
4132  ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) astate->xprstate.expr;
4133  Datum result;
4134  FunctionCallInfoData locfcinfo;
4135 
4136  result = ExecEvalExpr(astate->arg, econtext, isNull);
4137 
4138  if (*isNull)
4139  return result; /* nothing to do */
4140 
4141  /*
4142  * If it's binary-compatible, modify the element type in the array header,
4143  * but otherwise leave the array as we received it.
4144  */
4145  if (!OidIsValid(acoerce->elemfuncid))
4146  {
4147  /* Detoast input array if necessary, and copy in any case */
4148  ArrayType *array = DatumGetArrayTypePCopy(result);
4149 
4150  ARR_ELEMTYPE(array) = astate->resultelemtype;
4151  PG_RETURN_ARRAYTYPE_P(array);
4152  }
4153 
4154  /* Initialize function cache if first time through */
4155  if (astate->elemfunc.fn_oid == InvalidOid)
4156  {
4157  AclResult aclresult;
4158 
4159  /* Check permission to call function */
4160  aclresult = pg_proc_aclcheck(acoerce->elemfuncid, GetUserId(),
4161  ACL_EXECUTE);
4162  if (aclresult != ACLCHECK_OK)
4163  aclcheck_error(aclresult, ACL_KIND_PROC,
4164  get_func_name(acoerce->elemfuncid));
4166 
4167  /* Set up the primary fmgr lookup information */
4168  fmgr_info_cxt(acoerce->elemfuncid, &(astate->elemfunc),
4169  econtext->ecxt_per_query_memory);
4170  fmgr_info_set_expr((Node *) acoerce, &(astate->elemfunc));
4171  }
4172 
4173  /*
4174  * Use array_map to apply the function to each array element.
4175  *
4176  * We pass on the desttypmod and isExplicit flags whether or not the
4177  * function wants them.
4178  *
4179  * Note: coercion functions are assumed to not use collation.
4180  */
4181  InitFunctionCallInfoData(locfcinfo, &(astate->elemfunc), 3,
4182  InvalidOid, NULL, NULL);
4183  locfcinfo.arg[0] = result;
4184  locfcinfo.arg[1] = Int32GetDatum(acoerce->resulttypmod);
4185  locfcinfo.arg[2] = BoolGetDatum(acoerce->isExplicit);
4186  locfcinfo.argnull[0] = false;
4187  locfcinfo.argnull[1] = false;
4188  locfcinfo.argnull[2] = false;
4189 
4190  return array_map(&locfcinfo, astate->resultelemtype, astate->amstate);
4191 }
4192 
4193 /* ----------------------------------------------------------------
4194  * ExecEvalCurrentOfExpr
4195  *
4196  * The planner should convert CURRENT OF into a TidScan qualification, or some
4197  * other special handling in a ForeignScan node. So we have to be able to do
4198  * ExecInitExpr on a CurrentOfExpr, but we shouldn't ever actually execute it.
4199  * If we get here, we suppose we must be dealing with CURRENT OF on a foreign
4200  * table whose FDW doesn't handle it, and complain accordingly.
4201  * ----------------------------------------------------------------
4202  */
4203 static Datum
4205  bool *isNull)
4206 {
4207  ereport(ERROR,
4208  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4209  errmsg("WHERE CURRENT OF is not supported for this table type")));
4210  return 0; /* keep compiler quiet */
4211 }
4212 
4213 
4214 /*
4215  * ExecEvalExprSwitchContext
4216  *
4217  * Same as ExecEvalExpr, but get into the right allocation context explicitly.
4218  */
4219 Datum
4221  ExprContext *econtext,
4222  bool *isNull)
4223 {
4224  Datum retDatum;
4225  MemoryContext oldContext;
4226 
4227  oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
4228  retDatum = ExecEvalExpr(expression, econtext, isNull);
4229  MemoryContextSwitchTo(oldContext);
4230  return retDatum;
4231 }
4232 
4233 
4234 /*
4235  * ExecInitExpr: prepare an expression tree for execution
4236  *
4237  * This function builds and returns an ExprState tree paralleling the given
4238  * Expr node tree. The ExprState tree can then be handed to ExecEvalExpr
4239  * for execution. Because the Expr tree itself is read-only as far as
4240  * ExecInitExpr and ExecEvalExpr are concerned, several different executions
4241  * of the same plan tree can occur concurrently.
4242  *
4243  * This must be called in a memory context that will last as long as repeated
4244  * executions of the expression are needed. Typically the context will be
4245  * the same as the per-query context of the associated ExprContext.
4246  *
4247  * Any Aggref, WindowFunc, or SubPlan nodes found in the tree are added to the
4248  * lists of such nodes held by the parent PlanState. Otherwise, we do very
4249  * little initialization here other than building the state-node tree. Any
4250  * nontrivial work associated with initializing runtime info for a node should
4251  * happen during the first actual evaluation of that node. (This policy lets
4252  * us avoid work if the node is never actually evaluated.)
4253  *
4254  * Note: there is no ExecEndExpr function; we assume that any resource
4255  * cleanup needed will be handled by just releasing the memory context
4256  * in which the state tree is built. Functions that require additional
4257  * cleanup work can register a shutdown callback in the ExprContext.
4258  *
4259  * 'node' is the root of the expression tree to examine
4260  * 'parent' is the PlanState node that owns the expression.
4261  *
4262  * 'parent' may be NULL if we are preparing an expression that is not
4263  * associated with a plan tree. (If so, it can't have aggs or subplans.)
4264  * This case should usually come through ExecPrepareExpr, not directly here.
4265  */
4266 ExprState *
4267 ExecInitExpr(Expr *node, PlanState *parent)
4268 {
4269  ExprState *state;
4270 
4271  if (node == NULL)
4272  return NULL;
4273 
4274  /* Guard against stack overflow due to overly complex expressions */
4276 
4277  switch (nodeTag(node))
4278  {
4279  case T_Var:
4280  /* varattno == InvalidAttrNumber means it's a whole-row Var */
4281  if (((Var *) node)->varattno == InvalidAttrNumber)
4282  {
4284 
4285  wstate->parent = parent;
4286  wstate->wrv_tupdesc = NULL;
4287  wstate->wrv_junkFilter = NULL;
4288  state = (ExprState *) wstate;
4290  }
4291  else
4292  {
4293  state = makeNode(ExprState);
4294  state->evalfunc = ExecEvalScalarVar;
4295  }
4296  break;
4297  case T_Const:
4298  state = makeNode(ExprState);
4299  state->evalfunc = ExecEvalConst;
4300  break;
4301  case T_Param:
4302  state = makeNode(ExprState);
4303  switch (((Param *) node)->paramkind)
4304  {
4305  case PARAM_EXEC:
4306  state->evalfunc = ExecEvalParamExec;
4307  break;
4308  case PARAM_EXTERN:
4309  state->evalfunc = ExecEvalParamExtern;
4310  break;
4311  default:
4312  elog(ERROR, "unrecognized paramkind: %d",
4313  (int) ((Param *) node)->paramkind);
4314  break;
4315  }
4316  break;
4317  case T_CoerceToDomainValue:
4318  state = makeNode(ExprState);
4320  break;
4321  case T_CaseTestExpr:
4322  state = makeNode(ExprState);
4323  state->evalfunc = ExecEvalCaseTestExpr;
4324  break;
4325  case T_Aggref:
4326  {
4328 
4330  if (parent && IsA(parent, AggState))
4331  {
4332  AggState *aggstate = (AggState *) parent;
4333 
4334  aggstate->aggs = lcons(astate, aggstate->aggs);
4335  aggstate->numaggs++;
4336  }
4337  else
4338  {
4339  /* planner messed up */
4340  elog(ERROR, "Aggref found in non-Agg plan node");
4341  }
4342  state = (ExprState *) astate;
4343  }
4344  break;
4345  case T_GroupingFunc:
4346  {
4347  GroupingFunc *grp_node = (GroupingFunc *) node;
4349  Agg *agg = NULL;
4350 
4351  if (!parent || !IsA(parent, AggState) ||!IsA(parent->plan, Agg))
4352  elog(ERROR, "parent of GROUPING is not Agg node");
4353 
4354  grp_state->aggstate = (AggState *) parent;
4355 
4356  agg = (Agg *) (parent->plan);
4357 
4358  if (agg->groupingSets)
4359  grp_state->clauses = grp_node->cols;
4360  else
4361  grp_state->clauses = NIL;
4362 
4363  state = (ExprState *) grp_state;
4365  }
4366  break;
4367  case T_WindowFunc:
4368  {
4369  WindowFunc *wfunc = (WindowFunc *) node;
4371 
4373  if (parent && IsA(parent, WindowAggState))
4374  {
4375  WindowAggState *winstate = (WindowAggState *) parent;
4376  int nfuncs;
4377 
4378  winstate->funcs = lcons(wfstate, winstate->funcs);
4379  nfuncs = ++winstate->numfuncs;
4380  if (wfunc->winagg)
4381  winstate->numaggs++;
4382 
4383  wfstate->args = (List *) ExecInitExpr((Expr *) wfunc->args,
4384  parent);
4385  wfstate->aggfilter = ExecInitExpr(wfunc->aggfilter,
4386  parent);
4387 
4388  /*
4389  * Complain if the windowfunc's arguments contain any
4390  * windowfuncs; nested window functions are semantically
4391  * nonsensical. (This should have been caught earlier,
4392  * but we defend against it here anyway.)
4393  */
4394  if (nfuncs != winstate->numfuncs)
4395  ereport(ERROR,
4396  (errcode(ERRCODE_WINDOWING_ERROR),
4397  errmsg("window function calls cannot be nested")));
4398  }
4399  else
4400  {
4401  /* planner messed up */
4402  elog(ERROR, "WindowFunc found in non-WindowAgg plan node");
4403  }
4404  state = (ExprState *) wfstate;
4405  }
4406  break;
4407  case T_ArrayRef:
4408  {
4409  ArrayRef *aref = (ArrayRef *) node;
4411 
4413  astate->refupperindexpr = (List *)
4414  ExecInitExpr((Expr *) aref->refupperindexpr, parent);
4415  astate->reflowerindexpr = (List *)
4416  ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
4417  astate->refexpr = ExecInitExpr(aref->refexpr, parent);
4418  astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
4419  parent);
4420  /* do one-time catalog lookups for type info */
4421  astate->refattrlength = get_typlen(aref->refarraytype);
4423  &astate->refelemlength,
4424  &astate->refelembyval,
4425  &astate->refelemalign);
4426  state = (ExprState *) astate;
4427  }
4428  break;
4429  case T_FuncExpr:
4430  {
4431  FuncExpr *funcexpr = (FuncExpr *) node;
4433 
4435  fstate->args = (List *)
4436  ExecInitExpr((Expr *) funcexpr->args, parent);
4437  fstate->func.fn_oid = InvalidOid; /* not initialized */
4438  fstate->funcReturnsSet = funcexpr->funcretset;
4439  state = (ExprState *) fstate;
4440  }
4441  break;
4442  case T_OpExpr:
4443  {
4444  OpExpr *opexpr = (OpExpr *) node;
4446 
4448  fstate->args = (List *)
4449  ExecInitExpr((Expr *) opexpr->args, parent);
4450  fstate->func.fn_oid = InvalidOid; /* not initialized */
4451  fstate->funcReturnsSet = opexpr->opretset;
4452  state = (ExprState *) fstate;
4453  }
4454  break;
4455  case T_DistinctExpr:
4456  {
4457  DistinctExpr *distinctexpr = (DistinctExpr *) node;
4459 
4461  fstate->args = (List *)
4462  ExecInitExpr((Expr *) distinctexpr->args, parent);
4463  fstate->func.fn_oid = InvalidOid; /* not initialized */
4464  fstate->funcReturnsSet = false; /* not supported */
4465  state = (ExprState *) fstate;
4466  }
4467  break;
4468  case T_NullIfExpr:
4469  {
4470  NullIfExpr *nullifexpr = (NullIfExpr *) node;
4472 
4474  fstate->args = (List *)
4475  ExecInitExpr((Expr *) nullifexpr->args, parent);
4476  fstate->func.fn_oid = InvalidOid; /* not initialized */
4477  fstate->funcReturnsSet = false; /* not supported */
4478  state = (ExprState *) fstate;
4479  }
4480  break;
4481  case T_ScalarArrayOpExpr:
4482  {
4483  ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
4485 
4487  sstate->fxprstate.args = (List *)
4488  ExecInitExpr((Expr *) opexpr->args, parent);
4489  sstate->fxprstate.func.fn_oid = InvalidOid; /* not initialized */
4490  sstate->fxprstate.funcReturnsSet = false; /* not supported */
4491  sstate->element_type = InvalidOid; /* ditto */
4492  state = (ExprState *) sstate;
4493  }
4494  break;
4495  case T_BoolExpr:
4496  {
4497  BoolExpr *boolexpr = (BoolExpr *) node;
4499 
4500  switch (boolexpr->boolop)
4501  {
4502  case AND_EXPR:
4504  break;
4505  case OR_EXPR:
4507  break;
4508  case NOT_EXPR:
4510  break;
4511  default:
4512  elog(ERROR, "unrecognized boolop: %d",
4513  (int) boolexpr->boolop);
4514  break;
4515  }
4516  bstate->args = (List *)
4517  ExecInitExpr((Expr *) boolexpr->args, parent);
4518  state = (ExprState *) bstate;
4519  }
4520  break;
4521  case T_SubPlan:
4522  {
4523  SubPlan *subplan = (SubPlan *) node;
4524  SubPlanState *sstate;
4525 
4526  if (!parent)
4527  elog(ERROR, "SubPlan found with no parent plan");
4528 
4529  sstate = ExecInitSubPlan(subplan, parent);
4530 
4531  /* Add SubPlanState nodes to parent->subPlan */
4532  parent->subPlan = lappend(parent->subPlan, sstate);
4533 
4534  state = (ExprState *) sstate;
4535  }
4536  break;
4537  case T_AlternativeSubPlan:
4538  {
4539  AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
4540  AlternativeSubPlanState *asstate;
4541 
4542  if (!parent)
4543  elog(ERROR, "AlternativeSubPlan found with no parent plan");
4544 
4545  asstate = ExecInitAlternativeSubPlan(asplan, parent);
4546 
4547  state = (ExprState *) asstate;
4548  }
4549  break;
4550  case T_FieldSelect:
4551  {
4552  FieldSelect *fselect = (FieldSelect *) node;
4554 
4556  fstate->arg = ExecInitExpr(fselect->arg, parent);
4557  fstate->argdesc = NULL;
4558  state = (ExprState *) fstate;
4559  }
4560  break;
4561  case T_FieldStore:
4562  {
4563  FieldStore *fstore = (FieldStore *) node;
4565 
4567  fstate->arg = ExecInitExpr(fstore->arg, parent);
4568  fstate->newvals = (List *) ExecInitExpr((Expr *) fstore->newvals, parent);
4569  fstate->argdesc = NULL;
4570  state = (ExprState *) fstate;
4571  }
4572  break;
4573  case T_RelabelType:
4574  {
4575  RelabelType *relabel = (RelabelType *) node;
4577 
4579  gstate->arg = ExecInitExpr(relabel->arg, parent);
4580  state = (ExprState *) gstate;
4581  }
4582  break;
4583  case T_CoerceViaIO:
4584  {
4585  CoerceViaIO *iocoerce = (CoerceViaIO *) node;
4587  Oid iofunc;
4588  bool typisvarlena;
4589 
4591  iostate->arg = ExecInitExpr(iocoerce->arg, parent);
4592  /* lookup the result type's input function */
4593  getTypeInputInfo(iocoerce->resulttype, &iofunc,
4594  &iostate->intypioparam);
4595  fmgr_info(iofunc, &iostate->infunc);
4596  /* lookup the input type's output function */
4597  getTypeOutputInfo(exprType((Node *) iocoerce->arg),
4598  &iofunc, &typisvarlena);
4599  fmgr_info(iofunc, &iostate->outfunc);
4600  state = (ExprState *) iostate;
4601  }
4602  break;
4603  case T_ArrayCoerceExpr:
4604  {
4605  ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
4607 
4609  astate->arg = ExecInitExpr(acoerce->arg, parent);
4610  astate->resultelemtype = get_element_type(acoerce->resulttype);
4611  if (astate->resultelemtype == InvalidOid)
4612  ereport(ERROR,
4613  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4614  errmsg("target type is not an array")));
4615  /* Arrays over domains aren't supported yet */
4616  Assert(getBaseType(astate->resultelemtype) ==
4617  astate->resultelemtype);
4618  astate->elemfunc.fn_oid = InvalidOid; /* not initialized */
4619  astate->amstate = (ArrayMapState *) palloc0(sizeof(ArrayMapState));
4620  state = (ExprState *) astate;
4621  }
4622  break;
4623  case T_ConvertRowtypeExpr:
4624  {
4627 
4629  cstate->arg = ExecInitExpr(convert->arg, parent);
4630  state = (ExprState *) cstate;
4631  }
4632  break;
4633  case T_CaseExpr:
4634  {
4635  CaseExpr *caseexpr = (CaseExpr *) node;
4637  List *outlist = NIL;
4638  ListCell *l;
4639 
4641  cstate->arg = ExecInitExpr(caseexpr->arg, parent);
4642  foreach(l, caseexpr->args)
4643  {
4646 
4647  wstate->xprstate.evalfunc = NULL; /* not used */
4648  wstate->xprstate.expr = (Expr *) when;
4649  wstate->expr = ExecInitExpr(when->expr, parent);
4650  wstate->result = ExecInitExpr(when->result, parent);
4651  outlist = lappend(outlist, wstate);
4652  }
4653  cstate->args = outlist;
4654  cstate->defresult = ExecInitExpr(caseexpr->defresult, parent);
4655  if (caseexpr->arg)
4656  cstate->argtyplen = get_typlen(exprType((Node *) caseexpr->arg));
4657  state = (ExprState *) cstate;
4658  }
4659  break;
4660  case T_ArrayExpr:
4661  {
4662  ArrayExpr *arrayexpr = (ArrayExpr *) node;
4664  List *outlist = NIL;
4665  ListCell *l;
4666 
4668  foreach(l, arrayexpr->elements)
4669  {
4670  Expr *e = (Expr *) lfirst(l);
4671  ExprState *estate;
4672 
4673  estate = ExecInitExpr(e, parent);
4674  outlist = lappend(outlist, estate);
4675  }
4676  astate->elements = outlist;
4677  /* do one-time catalog lookup for type info */
4679  &astate->elemlength,
4680  &astate->elembyval,
4681  &astate->elemalign);
4682  state = (ExprState *) astate;
4683  }
4684  break;
4685  case T_RowExpr:
4686  {
4687  RowExpr *rowexpr = (RowExpr *) node;
4688  RowExprState *rstate = makeNode(RowExprState);
4689  Form_pg_attribute *attrs;
4690  List *outlist = NIL;
4691  ListCell *l;
4692  int i;
4693 
4695  /* Build tupdesc to describe result tuples */
4696  if (rowexpr->row_typeid == RECORDOID)
4697  {
4698  /* generic record, use types of given expressions */
4699  rstate->tupdesc = ExecTypeFromExprList(rowexpr->args);
4700  }
4701  else
4702  {
4703  /* it's been cast to a named type, use that */
4704  rstate->tupdesc = lookup_rowtype_tupdesc_copy(rowexpr->row_typeid, -1);
4705  }
4706  /* In either case, adopt RowExpr's column aliases */
4707  ExecTypeSetColNames(rstate->tupdesc, rowexpr->colnames);
4708  /* Bless the tupdesc in case it's now of type RECORD */
4709  BlessTupleDesc(rstate->tupdesc);
4710  /* Set up evaluation, skipping any deleted columns */
4711  Assert(list_length(rowexpr->args) <= rstate->tupdesc->natts);
4712  attrs = rstate->tupdesc->attrs;
4713  i = 0;
4714  foreach(l, rowexpr->args)
4715  {
4716  Expr *e = (Expr *) lfirst(l);
4717  ExprState *estate;
4718 
4719  if (!attrs[i]->attisdropped)
4720  {
4721  /*
4722  * Guard against ALTER COLUMN TYPE on rowtype since
4723  * the RowExpr was created. XXX should we check
4724  * typmod too? Not sure we can be sure it'll be the
4725  * same.
4726  */
4727  if (exprType((Node *) e) != attrs[i]->atttypid)
4728  ereport(ERROR,
4729  (errcode(ERRCODE_DATATYPE_MISMATCH),
4730  errmsg("ROW() column has type %s instead of type %s",
4731  format_type_be(exprType((Node *) e)),
4732  format_type_be(attrs[i]->atttypid))));
4733  }
4734  else
4735  {
4736  /*
4737  * Ignore original expression and insert a NULL. We
4738  * don't really care what type of NULL it is, so
4739  * always make an int4 NULL.
4740  */
4741  e = (Expr *) makeNullConst(INT4OID, -1, InvalidOid);
4742  }
4743  estate = ExecInitExpr(e, parent);
4744  outlist = lappend(outlist, estate);
4745  i++;
4746  }
4747  rstate->args = outlist;
4748  state = (ExprState *) rstate;
4749  }
4750  break;
4751  case T_RowCompareExpr:
4752  {
4753  RowCompareExpr *rcexpr = (RowCompareExpr *) node;
4755  int nopers = list_length(rcexpr->opnos);
4756  List *outlist;
4757  ListCell *l;
4758  ListCell *l2;
4759  ListCell *l3;
4760  int i;
4761 
4763  Assert(list_length(rcexpr->largs) == nopers);
4764  outlist = NIL;
4765  foreach(l, rcexpr->largs)
4766  {
4767  Expr *e = (Expr *) lfirst(l);
4768  ExprState *estate;
4769 
4770  estate = ExecInitExpr(e, parent);
4771  outlist = lappend(outlist, estate);
4772  }
4773  rstate->largs = outlist;
4774  Assert(list_length(rcexpr->rargs) == nopers);
4775  outlist = NIL;
4776  foreach(l, rcexpr->rargs)
4777  {
4778  Expr *e = (Expr *) lfirst(l);
4779  ExprState *estate;
4780 
4781  estate = ExecInitExpr(e, parent);
4782  outlist = lappend(outlist, estate);
4783  }
4784  rstate->rargs = outlist;
4785  Assert(list_length(rcexpr->opfamilies) == nopers);
4786  rstate->funcs = (FmgrInfo *) palloc(nopers * sizeof(FmgrInfo));
4787  rstate->collations = (Oid *) palloc(nopers * sizeof(Oid));
4788  i = 0;
4789  forthree(l, rcexpr->opnos, l2, rcexpr->opfamilies, l3, rcexpr->inputcollids)
4790  {
4791  Oid opno = lfirst_oid(l);
4792  Oid opfamily = lfirst_oid(l2);
4793  Oid inputcollid = lfirst_oid(l3);
4794  int strategy;
4795  Oid lefttype;
4796  Oid righttype;
4797  Oid proc;
4798 
4799  get_op_opfamily_properties(opno, opfamily, false,
4800  &strategy,
4801  &lefttype,
4802  &righttype);
4803  proc = get_opfamily_proc(opfamily,
4804  lefttype,
4805  righttype,
4806  BTORDER_PROC);
4807 
4808  /*
4809  * If we enforced permissions checks on index support
4810  * functions, we'd need to make a check here. But the
4811  * index support machinery doesn't do that, and neither
4812  * does this code.
4813  */
4814  fmgr_info(proc, &(rstate->funcs[i]));
4815  rstate->collations[i] = inputcollid;
4816  i++;
4817  }
4818  state = (ExprState *) rstate;
4819  }
4820  break;
4821  case T_CoalesceExpr:
4822  {
4823  CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
4825  List *outlist = NIL;
4826  ListCell *l;
4827 
4829  foreach(l, coalesceexpr->args)
4830  {
4831  Expr *e = (Expr *) lfirst(l);
4832  ExprState *estate;
4833 
4834  estate = ExecInitExpr(e, parent);
4835  outlist = lappend(outlist, estate);
4836  }
4837  cstate->args = outlist;
4838  state = (ExprState *) cstate;
4839  }
4840  break;
4841  case T_MinMaxExpr:
4842  {
4843  MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
4845  List *outlist = NIL;
4846  ListCell *l;
4847  TypeCacheEntry *typentry;
4848 
4850  foreach(l, minmaxexpr->args)
4851  {
4852  Expr *e = (Expr *) lfirst(l);
4853  ExprState *estate;
4854 
4855  estate = ExecInitExpr(e, parent);
4856  outlist = lappend(outlist, estate);
4857  }
4858  mstate->args = outlist;
4859  /* Look up the btree comparison function for the datatype */
4860  typentry = lookup_type_cache(minmaxexpr->minmaxtype,
4862  if (!OidIsValid(typentry->cmp_proc))
4863  ereport(ERROR,
4864  (errcode(ERRCODE_UNDEFINED_FUNCTION),
4865  errmsg("could not identify a comparison function for type %s",
4866  format_type_be(minmaxexpr->minmaxtype))));
4867 
4868  /*
4869  * If we enforced permissions checks on index support
4870  * functions, we'd need to make a check here. But the index
4871  * support machinery doesn't do that, and neither does this
4872  * code.
4873  */
4874  fmgr_info(typentry->cmp_proc, &(mstate->cfunc));
4875  state = (ExprState *) mstate;
4876  }
4877  break;
4878  case T_SQLValueFunction:
4879  state = makeNode(ExprState);
4881  break;
4882  case T_XmlExpr:
4883  {
4884  XmlExpr *xexpr = (XmlExpr *) node;
4885  XmlExprState *xstate = makeNode(XmlExprState);
4886  List *outlist;
4887  ListCell *arg;
4888 
4890  outlist = NIL;
4891  foreach(arg, xexpr->named_args)
4892  {
4893  Expr *e = (Expr *) lfirst(arg);
4894  ExprState *estate;
4895 
4896  estate = ExecInitExpr(e, parent);
4897  outlist = lappend(outlist, estate);
4898  }
4899  xstate->named_args = outlist;
4900 
4901  outlist = NIL;
4902  foreach(arg, xexpr->args)
4903  {
4904  Expr *e = (Expr *) lfirst(arg);
4905  ExprState *estate;
4906 
4907  estate = ExecInitExpr(e, parent);
4908  outlist = lappend(outlist, estate);
4909  }
4910  xstate->args = outlist;
4911 
4912  state = (ExprState *) xstate;
4913  }
4914  break;
4915  case T_NullTest:
4916  {
4917  NullTest *ntest = (NullTest *) node;
4919 
4921  nstate->arg = ExecInitExpr(ntest->arg, parent);
4922  nstate->argdesc = NULL;
4923  state = (ExprState *) nstate;
4924  }
4925  break;
4926  case T_BooleanTest:
4927  {
4928  BooleanTest *btest = (BooleanTest *) node;
4930 
4932  gstate->arg = ExecInitExpr(btest->arg, parent);
4933  state = (ExprState *) gstate;
4934  }
4935  break;
4936  case T_CoerceToDomain:
4937  {
4938  CoerceToDomain *ctest = (CoerceToDomain *) node;
4940 
4942  cstate->arg = ExecInitExpr(ctest->arg, parent);
4943  /* We spend an extra palloc to reduce header inclusions */
4944  cstate->constraint_ref = (DomainConstraintRef *)
4945  palloc(sizeof(DomainConstraintRef));
4947  cstate->constraint_ref,
4949  state = (ExprState *) cstate;
4950  }
4951  break;
4952  case T_CurrentOfExpr:
4953  state = makeNode(ExprState);
4955  break;
4956  case T_TargetEntry:
4957  {
4958  TargetEntry *tle = (TargetEntry *) node;
4960 
4961  gstate->xprstate.evalfunc = NULL; /* not used */
4962  gstate->arg = ExecInitExpr(tle->expr, parent);
4963  state = (ExprState *) gstate;
4964  }
4965  break;
4966  case T_List:
4967  {
4968  List *outlist = NIL;
4969  ListCell *l;
4970 
4971  foreach(l, (List *) node)
4972  {
4973  outlist = lappend(outlist,
4974  ExecInitExpr((Expr *) lfirst(l),
4975  parent));
4976  }
4977  /* Don't fall through to the "common" code below */
4978  return (ExprState *) outlist;
4979  }
4980  default:
4981  elog(ERROR, "unrecognized node type: %d",
4982  (int) nodeTag(node));
4983  state = NULL; /* keep compiler quiet */
4984  break;
4985  }
4986 
4987  /* Common code for all state-node types */
4988  state->expr = node;
4989 
4990  return state;
4991 }
4992 
4993 /*
4994  * ExecPrepareExpr --- initialize for expression execution outside a normal
4995  * Plan tree context.
4996  *
4997  * This differs from ExecInitExpr in that we don't assume the caller is
4998  * already running in the EState's per-query context. Also, we run the
4999  * passed expression tree through expression_planner() to prepare it for
5000  * execution. (In ordinary Plan trees the regular planning process will have
5001  * made the appropriate transformations on expressions, but for standalone
5002  * expressions this won't have happened.)
5003  */
5004 ExprState *
5005 ExecPrepareExpr(Expr *node, EState *estate)
5006 {
5007  ExprState *result;
5008  MemoryContext oldcontext;
5009 
5010  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
5011 
5012  node = expression_planner(node);
5013 
5014  result = ExecInitExpr(node, NULL);
5015 
5016  MemoryContextSwitchTo(oldcontext);
5017 
5018  return result;
5019 }
5020 
5021 
5022 /* ----------------------------------------------------------------
5023  * ExecQual / ExecTargetList / ExecProject
5024  * ----------------------------------------------------------------
5025  */
5026 
5027 /* ----------------------------------------------------------------
5028  * ExecQual
5029  *
5030  * Evaluates a conjunctive boolean expression (qual list) and
5031  * returns true iff none of the subexpressions are false.
5032  * (We also return true if the list is empty.)
5033  *
5034  * If some of the subexpressions yield NULL but none yield FALSE,
5035  * then the result of the conjunction is NULL (ie, unknown)
5036  * according to three-valued boolean logic. In this case,
5037  * we return the value specified by the "resultForNull" parameter.
5038  *
5039  * Callers evaluating WHERE clauses should pass resultForNull=FALSE,
5040  * since SQL specifies that tuples with null WHERE results do not
5041  * get selected. On the other hand, callers evaluating constraint
5042  * conditions should pass resultForNull=TRUE, since SQL also specifies
5043  * that NULL constraint conditions are not failures.
5044  *
5045  * NOTE: it would not be correct to use this routine to evaluate an
5046  * AND subclause of a boolean expression; for that purpose, a NULL
5047  * result must be returned as NULL so that it can be properly treated
5048  * in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
5049  * This routine is only used in contexts where a complete expression
5050  * is being evaluated and we know that NULL can be treated the same
5051  * as one boolean result or the other.
5052  *
5053  * ----------------------------------------------------------------
5054  */
5055 bool
5056 ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
5057 {
5058  bool result;
5059  MemoryContext oldContext;
5060  ListCell *l;
5061 
5062  /*
5063  * debugging stuff
5064  */
5065  EV_printf("ExecQual: qual is ");
5066  EV_nodeDisplay(qual);
5067  EV_printf("\n");
5068 
5069  /*
5070  * Run in short-lived per-tuple context while computing expressions.
5071  */
5072  oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
5073 
5074  /*
5075  * Evaluate the qual conditions one at a time. If we find a FALSE result,
5076  * we can stop evaluating and return FALSE --- the AND result must be
5077  * FALSE. Also, if we find a NULL result when resultForNull is FALSE, we
5078  * can stop and return FALSE --- the AND result must be FALSE or NULL in
5079  * that case, and the caller doesn't care which.
5080  *
5081  * If we get to the end of the list, we can return TRUE. This will happen
5082  * when the AND result is indeed TRUE, or when the AND result is NULL (one
5083  * or more NULL subresult, with all the rest TRUE) and the caller has
5084  * specified resultForNull = TRUE.
5085  */
5086  result = true;
5087 
5088  foreach(l, qual)
5089  {
5090  ExprState *clause = (ExprState *) lfirst(l);
5091  Datum expr_value;
5092  bool isNull;
5093 
5094  expr_value = ExecEvalExpr(clause, econtext, &isNull);
5095 
5096  if (isNull)
5097  {
5098  if (resultForNull == false)
5099  {
5100  result = false; /* treat NULL as FALSE */
5101  break;
5102  }
5103  }
5104  else
5105  {
5106  if (!DatumGetBool(expr_value))
5107  {
5108  result = false; /* definitely FALSE */
5109  break;
5110  }
5111  }
5112  }
5113 
5114  MemoryContextSwitchTo(oldContext);
5115 
5116  return result;
5117 }
5118 
5119 /*
5120  * Number of items in a tlist (including any resjunk items!)
5121  */
5122 int
5124 {
5125  /* This used to be more complex, but fjoins are dead */
5126  return list_length(targetlist);
5127 }
5128 
5129 /*
5130  * Number of items in a tlist, not including any resjunk items
5131  */
5132 int
5134 {
5135  int len = 0;
5136  ListCell *tl;
5137 
5138  foreach(tl, targetlist)
5139  {
5140  TargetEntry *curTle = castNode(TargetEntry, lfirst(tl));
5141 
5142  if (!curTle->resjunk)
5143  len++;
5144  }
5145  return len;
5146 }
5147 
5148 /*
5149  * ExecTargetList
5150  * Evaluates a targetlist with respect to the given
5151  * expression context.
5152  *
5153  * tupdesc must describe the rowtype of the expected result.
5154  *
5155  * Results are stored into the passed values and isnull arrays.
5156  *
5157  * Since fields of the result tuple might be multiply referenced in higher
5158  * plan nodes, we have to force any read/write expanded values to read-only
5159  * status. It's a bit annoying to have to do that for every projected
5160  * expression; in the future, consider teaching the planner to detect
5161  * actually-multiply-referenced Vars and insert an expression node that
5162  * would do that only where really required.
5163  */
5164 static void
5165 ExecTargetList(List *targetlist,
5166  TupleDesc tupdesc,
5167  ExprContext *econtext,
5168  Datum *values,
5169  bool *isnull)
5170 {
5171  Form_pg_attribute *att = tupdesc->attrs;
5172  MemoryContext oldContext;
5173  ListCell *tl;
5174 
5175  /*
5176  * Run in short-lived per-tuple context while computing expressions.
5177  */
5178  oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
5179 
5180  /*
5181  * evaluate all the expressions in the target list
5182  */
5183  foreach(tl, targetlist)
5184  {
5185  GenericExprState *gstate = (GenericExprState *) lfirst(tl);
5186  TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
5187  AttrNumber resind = tle->resno - 1;
5188 
5189  values[resind] = ExecEvalExpr(gstate->arg,
5190  econtext,
5191  &isnull[resind]);
5192 
5193  values[resind] = MakeExpandedObjectReadOnly(values[resind],
5194  isnull[resind],
5195  att[resind]->attlen);
5196  }
5197 
5198  MemoryContextSwitchTo(oldContext);
5199 }
5200 
5201 /*
5202  * ExecProject
5203  *
5204  * projects a tuple based on projection info and stores
5205  * it in the previously specified tuple table slot.
5206  *
5207  * Note: the result is always a virtual tuple; therefore it
5208  * may reference the contents of the exprContext's scan tuples
5209  * and/or temporary results constructed in the exprContext.
5210  * If the caller wishes the result to be valid longer than that
5211  * data will be valid, he must call ExecMaterializeSlot on the
5212  * result slot.
5213  */
5216 {
5217  TupleTableSlot *slot;
5218  ExprContext *econtext;
5219  int numSimpleVars;
5220 
5221  /*
5222  * sanity checks
5223  */
5224  Assert(projInfo != NULL);
5225 
5226  /*
5227  * get the projection info we want
5228  */
5229  slot = projInfo->pi_slot;
5230  econtext = projInfo->pi_exprContext;
5231 
5232  /*
5233  * Clear any former contents of the result slot. This makes it safe for
5234  * us to use the slot's Datum/isnull arrays as workspace.
5235  */
5236  ExecClearTuple(slot);
5237 
5238  /*
5239  * Force extraction of all input values that we'll need. The
5240  * Var-extraction loops below depend on this, and we are also prefetching
5241  * all attributes that will be referenced in the generic expressions.
5242  */
5243  if (projInfo->pi_lastInnerVar > 0)
5245  projInfo->pi_lastInnerVar);
5246  if (projInfo->pi_lastOuterVar > 0)
5248  projInfo->pi_lastOuterVar);
5249  if (projInfo->pi_lastScanVar > 0)
5251  projInfo->pi_lastScanVar);
5252 
5253  /*
5254  * Assign simple Vars to result by direct extraction of fields from source
5255  * slots ... a mite ugly, but fast ...
5256  */
5257  numSimpleVars = projInfo->pi_numSimpleVars;
5258  if (numSimpleVars > 0)
5259  {
5260  Datum *values = slot->tts_values;
5261  bool *isnull = slot->tts_isnull;
5262  int *varSlotOffsets = projInfo->pi_varSlotOffsets;
5263  int *varNumbers = projInfo->pi_varNumbers;
5264  int i;
5265 
5266  if (projInfo->pi_directMap)
5267  {
5268  /* especially simple case where vars go to output in order */
5269  for (i = 0; i < numSimpleVars; i++)
5270  {
5271  char *slotptr = ((char *) econtext) + varSlotOffsets[i];
5272  TupleTableSlot *varSlot = *((TupleTableSlot **) slotptr);
5273  int varNumber = varNumbers[i] - 1;
5274 
5275  values[i] = varSlot->tts_values[varNumber];
5276  isnull[i] = varSlot->tts_isnull[varNumber];
5277  }
5278  }
5279  else
5280  {
5281  /* we have to pay attention to varOutputCols[] */
5282  int *varOutputCols = projInfo->pi_varOutputCols;
5283 
5284  for (i = 0; i < numSimpleVars; i++)
5285  {
5286  char *slotptr = ((char *) econtext) + varSlotOffsets[i];
5287  TupleTableSlot *varSlot = *((TupleTableSlot **) slotptr);
5288  int varNumber = varNumbers[i] - 1;
5289  int varOutputCol = varOutputCols[i] - 1;
5290 
5291  values[varOutputCol] = varSlot->tts_values[varNumber];
5292  isnull[varOutputCol] = varSlot->tts_isnull[varNumber];
5293  }
5294  }
5295  }
5296 
5297  /*
5298  * If there are any generic expressions, evaluate them.
5299  */
5300  if (projInfo->pi_targetlist)
5301  {
5302  ExecTargetList(projInfo->pi_targetlist,
5303  slot->tts_tupleDescriptor,
5304  econtext,
5305  slot->tts_values,
5306  slot->tts_isnull);
5307  }
5308 
5309  /*
5310  * Mark the result slot as containing a valid virtual tuple.
5311  */
5312  return ExecStoreVirtualTuple(slot);
5313 }
Datum constvalue
Definition: primnodes.h:196
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
Definition: tuplestore.c:735
int indx[MAXDIM]
Definition: c.h:422
ExprState xprstate
Definition: execnodes.h:978
signed short int16
Definition: c.h:255
Oid minmaxtype
Definition: primnodes.h:1061
bool multidims
Definition: primnodes.h:954
#define NIL
Definition: pg_list.h:69
static Datum ExecEvalDistinct(FuncExprState *fcache, ExprContext *econtext, bool *isNull)
Definition: execQual.c:2278
Datum value
Definition: params.h:56
ExprState xprstate
Definition: execnodes.h:1001
Datum array_get_slice(Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:2015
ExprState xprstate
Definition: execnodes.h:635
Expr * refassgnexpr
Definition: primnodes.h:409
Definition: fmgr.h:53
static struct @76 value
List * args
Definition: primnodes.h:1065
List * args
Definition: primnodes.h:984
struct TupleConversionMap * map
Definition: execnodes.h:883
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:141
TupleTableSlot * ExecProject(ProjectionInfo *projInfo)
Definition: execQual.c:5215
ExprState * ExecPrepareExpr(Expr *node, EState *estate)
Definition: execQual.c:5005
#define IsA(nodeptr, _type_)
Definition: nodes.h:569
struct AggState * aggstate
Definition: execnodes.h:651
static void ExecEvalFuncArgs(FunctionCallInfo fcinfo, List *argList, ExprContext *econtext)
Definition: execQual.c:1460
#define BTORDER_PROC
Definition: nbtree.h:229
static Datum ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext, bool *isNull)
Definition: execQual.c:4204
ExprState xprstate
Definition: execnodes.h:906
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate)
Definition: execTuples.c:852
Datum * ecxt_aggvalues
Definition: execnodes.h:146
Oid tdtypeid
Definition: tupdesc.h:77
static Datum ExecEvalWholeRowSlow(WholeRowVarExprState *wrvstate, ExprContext *econtext, bool *isNull)
Definition: execQual.c:970
Expr * arg
Definition: primnodes.h:766
#define HeapTupleHeaderSetTypeId(tup, typeid)
Definition: htup_details.h:450
ExprState xprstate
Definition: execnodes.h:677
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:174
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2600
ExprState xprstate
Definition: execnodes.h:613
ExprState * aggfilter
Definition: execnodes.h:663
#define ARR_OVERHEAD_NONULLS(ndims)
Definition: array.h:291
Datum current_schema(PG_FUNCTION_ARGS)
Definition: name.c:280
ExprState * arg
Definition: execnodes.h:894
MemoryContext fn_mcxt
Definition: fmgr.h:62
int ExecTargetListLength(List *targetlist)
Definition: execQual.c:5123
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:144
char * name
Definition: primnodes.h:1141
bool shutdown_reg
Definition: execnodes.h:745
void UpdateDomainConstraintRef(DomainConstraintRef *ref)
Definition: typcache.c:1001
#define ARR_SIZE(a)
Definition: array.h:270
List * args
Definition: primnodes.h:359
List * args
Definition: primnodes.h:456
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1245
static Datum ExecEvalScalarVarFast(ExprState *exprstate, ExprContext *econtext, bool *isNull)
Definition: execQual.c:647
List * args
Definition: execnodes.h:980
ExprState xprstate
Definition: execnodes.h:623
List * colnames
Definition: primnodes.h:43
ExprState * expr
Definition: execnodes.h:907
#define DatumGetInt32(X)
Definition: postgres.h:478
Datum array_map(FunctionCallInfo fcinfo, Oid retType, ArrayMapState *amstate)
Definition: arrayfuncs.c:3120
ExprState xprstate
Definition: execnodes.h:839
#define MAXDIM
Definition: c.h:419
int numaggs
Definition: execnodes.h:1951
Oid GetUserId(void)
Definition: miscinit.c:283
DomainConstraintType constrainttype
Definition: execnodes.h:1024
Oid resulttype
Definition: primnodes.h:742
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:850
#define castNode(_type_, nodeptr)
Definition: nodes.h:587
static Datum ExecEvalWholeRowVar(WholeRowVarExprState *wrvstate, ExprContext *econtext, bool *isNull)
Definition: execQual.c:692
static void ExecPrepareTuplestoreResult(FuncExprState *fcache, ExprContext *econtext, Tuplestorestate *resultStore, TupleDesc resultDesc)
Definition: execQual.c:1490
ExprState xprstate
Definition: execnodes.h:967
ExprState * refexpr
Definition: execnodes.h:680
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2452
List * args
Definition: execnodes.h:778
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:1989
#define PointerGetDatum(X)
Definition: postgres.h:562
NodeTag type
Definition: execnodes.h:197
static Datum ExecEvalGroupingFuncExpr(GroupingFuncExprState *gstate, ExprContext *econtext, bool *isNull)
Definition: execQual.c:2833
void InitDomainConstraintRef(Oid type_id, DomainConstraintRef *ref, MemoryContext refctx)
Definition: typcache.c:967
#define forthree(cell1, list1, cell2, list2, cell3, list3)
Definition: pg_list.h:183
List * args
Definition: execnodes.h:699
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:136
void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, int nitems)
Definition: arrayfuncs.c:4624
Oid resulttype
Definition: primnodes.h:810
#define DatumGetTextPP(X)
Definition: fmgr.h:248
FmgrInfo * funcs
Definition: execnodes.h:947
List * opfamilies
Definition: primnodes.h:1031
static Datum ExecEvalCoerceToDomainValue(ExprState *exprstate, ExprContext *econtext, bool *isNull)
Definition: execQual.c:3895
Expr * expression_planner(Expr *expr)
Definition: planner.c:5382
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:75
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
struct DomainConstraintRef * constraint_ref
Definition: execnodes.h:1005
Form_pg_attribute * attrs
Definition: tupdesc.h:74
#define TimeTzADTPGetDatum(X)
Definition: date.h:58
List * subPlan
Definition: execnodes.h:1069
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
ExprState * arg
Definition: execnodes.h:840
List * args
Definition: execnodes.h:895
Expr * arg
Definition: primnodes.h:789
ExprState * check_expr
Definition: execnodes.h:1026
ExprState xprstate
Definition: execnodes.h:661
xmltype * xmlconcat(List *args)
Definition: xml.c:507
bool setArgsValid
Definition: execnodes.h:737
#define INT4OID
Definition: pg_type.h:316
#define gettext_noop(x)
Definition: c.h:139