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