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