]> granicus.if.org Git - postgresql/blob - src/backend/executor/execQual.c
Fix oversight in my recent patch to allow ExecMakeFunctionResult to handle
[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.238 2008/12/18 19:38:22 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_data;
1338         FunctionCallInfo fcinfo;
1339         PgStat_FunctionCallUsage fcusage;
1340         ReturnSetInfo rsinfo;           /* for functions returning sets */
1341         ExprDoneCond argDone;
1342         bool            hasSetArg;
1343         int                     i;
1344
1345 restart:
1346
1347         /* Guard against stack overflow due to overly complex expressions */
1348         check_stack_depth();
1349
1350         /*
1351          * If a previous call of the function returned a set result in the form
1352          * of a tuplestore, continue reading rows from the tuplestore until it's
1353          * empty.
1354          */
1355         if (fcache->funcResultStore)
1356         {
1357                 Assert(isDone);                         /* it was provided before ... */
1358                 if (tuplestore_gettupleslot(fcache->funcResultStore, true,
1359                                                                         fcache->funcResultSlot))
1360                 {
1361                         *isDone = ExprMultipleResult;
1362                         if (fcache->funcReturnsTuple)
1363                         {
1364                                 /* We must return the whole tuple as a Datum. */
1365                                 *isNull = false;
1366                                 return ExecFetchSlotTupleDatum(fcache->funcResultSlot);
1367                         }
1368                         else
1369                         {
1370                                 /* Extract the first column and return it as a scalar. */
1371                                 return slot_getattr(fcache->funcResultSlot, 1, isNull);
1372                         }
1373                 }
1374                 /* Exhausted the tuplestore, so clean up */
1375                 tuplestore_end(fcache->funcResultStore);
1376                 fcache->funcResultStore = NULL;
1377                 /* We are done unless there was a set-valued argument */
1378                 if (!fcache->setHasSetArg)
1379                 {
1380                         *isDone = ExprEndResult;
1381                         *isNull = true;
1382                         return (Datum) 0;
1383                 }
1384                 /* If there was, continue evaluating the argument values */
1385                 Assert(!fcache->setArgsValid);
1386         }
1387
1388         /*
1389          * For non-set-returning functions, we just use a local-variable
1390          * FunctionCallInfoData.  For set-returning functions we keep the callinfo
1391          * record in fcache->setArgs so that it can survive across multiple
1392          * value-per-call invocations.  (The reason we don't just do the latter
1393          * all the time is that plpgsql expects to be able to use simple expression
1394          * trees re-entrantly.  Which might not be a good idea, but the penalty
1395          * for not doing so is high.)
1396          */
1397         if (fcache->func.fn_retset)
1398                 fcinfo = &fcache->setArgs;
1399         else
1400                 fcinfo = &fcinfo_data;
1401
1402         /*
1403          * arguments is a list of expressions to evaluate before passing to the
1404          * function manager.  We skip the evaluation if it was already done in the
1405          * previous call (ie, we are continuing the evaluation of a set-valued
1406          * function).  Otherwise, collect the current argument values into fcinfo.
1407          */
1408         arguments = fcache->args;
1409         if (!fcache->setArgsValid)
1410         {
1411                 /* Need to prep callinfo structure */
1412                 InitFunctionCallInfoData(*fcinfo, &(fcache->func), 0, NULL, NULL);
1413                 argDone = ExecEvalFuncArgs(fcinfo, arguments, econtext);
1414                 if (argDone == ExprEndResult)
1415                 {
1416                         /* input is an empty set, so return an empty set. */
1417                         *isNull = true;
1418                         if (isDone)
1419                                 *isDone = ExprEndResult;
1420                         else
1421                                 ereport(ERROR,
1422                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1423                                                  errmsg("set-valued function called in context that cannot accept a set")));
1424                         return (Datum) 0;
1425                 }
1426                 hasSetArg = (argDone != ExprSingleResult);
1427         }
1428         else
1429         {
1430                 /* Re-use callinfo from previous evaluation */
1431                 hasSetArg = fcache->setHasSetArg;
1432                 /* Reset flag (we may set it again below) */
1433                 fcache->setArgsValid = false;
1434         }
1435
1436         /*
1437          * Now call the function, passing the evaluated parameter values.
1438          */
1439         if (fcache->func.fn_retset || hasSetArg)
1440         {
1441                 /*
1442                  * We need to return a set result.      Complain if caller not ready to
1443                  * accept one.
1444                  */
1445                 if (isDone == NULL)
1446                         ereport(ERROR,
1447                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1448                                          errmsg("set-valued function called in context that cannot accept a set")));
1449
1450                 /*
1451                  * Prepare a resultinfo node for communication.  If the function
1452                  * doesn't itself return set, we don't pass the resultinfo to the
1453                  * function, but we need to fill it in anyway for internal use.
1454                  */
1455                 if (fcache->func.fn_retset)
1456                         fcinfo->resultinfo = (Node *) &rsinfo;
1457                 rsinfo.type = T_ReturnSetInfo;
1458                 rsinfo.econtext = econtext;
1459                 rsinfo.expectedDesc = fcache->funcResultDesc;
1460                 rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
1461                 /* note we do not set SFRM_Materialize_Random or _Preferred */
1462                 rsinfo.returnMode = SFRM_ValuePerCall;
1463                 /* isDone is filled below */
1464                 rsinfo.setResult = NULL;
1465                 rsinfo.setDesc = NULL;
1466
1467                 /*
1468                  * This loop handles the situation where we have both a set argument
1469                  * and a set-valued function.  Once we have exhausted the function's
1470                  * value(s) for a particular argument value, we have to get the next
1471                  * argument value and start the function over again. We might have to
1472                  * do it more than once, if the function produces an empty result set
1473                  * for a particular input value.
1474                  */
1475                 for (;;)
1476                 {
1477                         /*
1478                          * If function is strict, and there are any NULL arguments, skip
1479                          * calling the function (at least for this set of args).
1480                          */
1481                         bool            callit = true;
1482
1483                         if (fcache->func.fn_strict)
1484                         {
1485                                 for (i = 0; i < fcinfo->nargs; i++)
1486                                 {
1487                                         if (fcinfo->argnull[i])
1488                                         {
1489                                                 callit = false;
1490                                                 break;
1491                                         }
1492                                 }
1493                         }
1494
1495                         if (callit)
1496                         {
1497                                 pgstat_init_function_usage(fcinfo, &fcusage);
1498
1499                                 fcinfo->isnull = false;
1500                                 rsinfo.isDone = ExprSingleResult;
1501                                 result = FunctionCallInvoke(fcinfo);
1502                                 *isNull = fcinfo->isnull;
1503                                 *isDone = rsinfo.isDone;
1504
1505                                 pgstat_end_function_usage(&fcusage,
1506                                                                                   rsinfo.isDone != ExprMultipleResult);
1507                         }
1508                         else
1509                         {
1510                                 result = (Datum) 0;
1511                                 *isNull = true;
1512                                 *isDone = ExprEndResult;
1513                         }
1514
1515                         /* Which protocol does function want to use? */
1516                         if (rsinfo.returnMode == SFRM_ValuePerCall)
1517                         {
1518                                 if (*isDone != ExprEndResult)
1519                                 {
1520                                         /*
1521                                          * Got a result from current argument. If function itself
1522                                          * returns set, save the current argument values to re-use
1523                                          * on the next call.
1524                                          */
1525                                         if (fcache->func.fn_retset &&
1526                                                 *isDone == ExprMultipleResult)
1527                                         {
1528                                                 Assert(fcinfo == &fcache->setArgs);
1529                                                 fcache->setHasSetArg = hasSetArg;
1530                                                 fcache->setArgsValid = true;
1531                                                 /* Register cleanup callback if we didn't already */
1532                                                 if (!fcache->shutdown_reg)
1533                                                 {
1534                                                         RegisterExprContextCallback(econtext,
1535                                                                                                                 ShutdownFuncExpr,
1536                                                                                                                 PointerGetDatum(fcache));
1537                                                         fcache->shutdown_reg = true;
1538                                                 }
1539                                         }
1540
1541                                         /*
1542                                          * Make sure we say we are returning a set, even if the
1543                                          * function itself doesn't return sets.
1544                                          */
1545                                         if (hasSetArg)
1546                                                 *isDone = ExprMultipleResult;
1547                                         break;
1548                                 }
1549                         }
1550                         else if (rsinfo.returnMode == SFRM_Materialize)
1551                         {
1552                                 /* check we're on the same page as the function author */
1553                                 if (rsinfo.isDone != ExprSingleResult)
1554                                         ereport(ERROR,
1555                                                         (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1556                                                          errmsg("table-function protocol for materialize mode was not followed")));
1557                                 if (rsinfo.setResult != NULL)
1558                                 {
1559                                         /* prepare to return values from the tuplestore */
1560                                         ExecPrepareTuplestoreResult(fcache, econtext,
1561                                                                                                 rsinfo.setResult,
1562                                                                                                 rsinfo.setDesc);
1563                                         /* remember whether we had set arguments */
1564                                         fcache->setHasSetArg = hasSetArg;
1565                                         /* loop back to top to start returning from tuplestore */
1566                                         goto restart;
1567                                 }
1568                                 /* if setResult was left null, treat it as empty set */
1569                                 *isDone = ExprEndResult;
1570                                 *isNull = true;
1571                                 result = (Datum) 0;
1572                         }
1573                         else
1574                                 ereport(ERROR,
1575                                                 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1576                                                  errmsg("unrecognized table-function returnMode: %d",
1577                                                                 (int) rsinfo.returnMode)));
1578
1579                         /* Else, done with this argument */
1580                         if (!hasSetArg)
1581                                 break;                  /* input not a set, so done */
1582
1583                         /* Re-eval args to get the next element of the input set */
1584                         argDone = ExecEvalFuncArgs(fcinfo, arguments, econtext);
1585
1586                         if (argDone != ExprMultipleResult)
1587                         {
1588                                 /* End of argument set, so we're done. */
1589                                 *isNull = true;
1590                                 *isDone = ExprEndResult;
1591                                 result = (Datum) 0;
1592                                 break;
1593                         }
1594
1595                         /*
1596                          * If we reach here, loop around to run the function on the new
1597                          * argument.
1598                          */
1599                 }
1600         }
1601         else
1602         {
1603                 /*
1604                  * Non-set case: much easier.
1605                  *
1606                  * We change the ExprState function pointer to use the simpler
1607                  * ExecMakeFunctionResultNoSets on subsequent calls.  This amounts to
1608                  * assuming that no argument can return a set if it didn't do so the
1609                  * first time.
1610                  */
1611                 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResultNoSets;
1612
1613                 if (isDone)
1614                         *isDone = ExprSingleResult;
1615
1616                 /*
1617                  * If function is strict, and there are any NULL arguments, skip
1618                  * calling the function and return NULL.
1619                  */
1620                 if (fcache->func.fn_strict)
1621                 {
1622                         for (i = 0; i < fcinfo->nargs; i++)
1623                         {
1624                                 if (fcinfo->argnull[i])
1625                                 {
1626                                         *isNull = true;
1627                                         return (Datum) 0;
1628                                 }
1629                         }
1630                 }
1631
1632                 pgstat_init_function_usage(fcinfo, &fcusage);
1633
1634                 fcinfo->isnull = false;
1635                 result = FunctionCallInvoke(fcinfo);
1636                 *isNull = fcinfo->isnull;
1637
1638                 pgstat_end_function_usage(&fcusage, true);
1639         }
1640
1641         return result;
1642 }
1643
1644 /*
1645  *              ExecMakeFunctionResultNoSets
1646  *
1647  * Simplified version of ExecMakeFunctionResult that can only handle
1648  * non-set cases.  Hand-tuned for speed.
1649  */
1650 static Datum
1651 ExecMakeFunctionResultNoSets(FuncExprState *fcache,
1652                                                          ExprContext *econtext,
1653                                                          bool *isNull,
1654                                                          ExprDoneCond *isDone)
1655 {
1656         ListCell   *arg;
1657         Datum           result;
1658         FunctionCallInfoData fcinfo;
1659         PgStat_FunctionCallUsage fcusage;
1660         int                     i;
1661
1662         /* Guard against stack overflow due to overly complex expressions */
1663         check_stack_depth();
1664
1665         if (isDone)
1666                 *isDone = ExprSingleResult;
1667
1668         /* inlined, simplified version of ExecEvalFuncArgs */
1669         i = 0;
1670         foreach(arg, fcache->args)
1671         {
1672                 ExprState  *argstate = (ExprState *) lfirst(arg);
1673
1674                 fcinfo.arg[i] = ExecEvalExpr(argstate,
1675                                                                          econtext,
1676                                                                          &fcinfo.argnull[i],
1677                                                                          NULL);
1678                 i++;
1679         }
1680
1681         InitFunctionCallInfoData(fcinfo, &(fcache->func), i, NULL, NULL);
1682
1683         /*
1684          * If function is strict, and there are any NULL arguments, skip calling
1685          * the function and return NULL.
1686          */
1687         if (fcache->func.fn_strict)
1688         {
1689                 while (--i >= 0)
1690                 {
1691                         if (fcinfo.argnull[i])
1692                         {
1693                                 *isNull = true;
1694                                 return (Datum) 0;
1695                         }
1696                 }
1697         }
1698
1699         pgstat_init_function_usage(&fcinfo, &fcusage);
1700
1701         /* fcinfo.isnull = false; */    /* handled by InitFunctionCallInfoData */
1702         result = FunctionCallInvoke(&fcinfo);
1703         *isNull = fcinfo.isnull;
1704
1705         pgstat_end_function_usage(&fcusage, true);
1706
1707         return result;
1708 }
1709
1710
1711 /*
1712  *              ExecMakeTableFunctionResult
1713  *
1714  * Evaluate a table function, producing a materialized result in a Tuplestore
1715  * object.
1716  */
1717 Tuplestorestate *
1718 ExecMakeTableFunctionResult(ExprState *funcexpr,
1719                                                         ExprContext *econtext,
1720                                                         TupleDesc expectedDesc,
1721                                                         bool randomAccess)
1722 {
1723         Tuplestorestate *tupstore = NULL;
1724         TupleDesc       tupdesc = NULL;
1725         Oid                     funcrettype;
1726         bool            returnsTuple;
1727         bool            returnsSet = false;
1728         FunctionCallInfoData fcinfo;
1729         PgStat_FunctionCallUsage fcusage;
1730         ReturnSetInfo rsinfo;
1731         HeapTupleData tmptup;
1732         MemoryContext callerContext;
1733         MemoryContext oldcontext;
1734         bool            direct_function_call;
1735         bool            first_time = true;
1736
1737         callerContext = CurrentMemoryContext;
1738
1739         funcrettype = exprType((Node *) funcexpr->expr);
1740
1741         returnsTuple = type_is_rowtype(funcrettype);
1742
1743         /*
1744          * Prepare a resultinfo node for communication.  We always do this even if
1745          * not expecting a set result, so that we can pass expectedDesc.  In the
1746          * generic-expression case, the expression doesn't actually get to see the
1747          * resultinfo, but set it up anyway because we use some of the fields as
1748          * our own state variables.
1749          */
1750         InitFunctionCallInfoData(fcinfo, NULL, 0, NULL, (Node *) &rsinfo);
1751         rsinfo.type = T_ReturnSetInfo;
1752         rsinfo.econtext = econtext;
1753         rsinfo.expectedDesc = expectedDesc;
1754         rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize | SFRM_Materialize_Preferred);
1755         if (randomAccess)
1756                 rsinfo.allowedModes |= (int) SFRM_Materialize_Random;
1757         rsinfo.returnMode = SFRM_ValuePerCall;
1758         /* isDone is filled below */
1759         rsinfo.setResult = NULL;
1760         rsinfo.setDesc = NULL;
1761
1762         /*
1763          * Normally the passed expression tree will be a FuncExprState, since the
1764          * grammar only allows a function call at the top level of a table
1765          * function reference.  However, if the function doesn't return set then
1766          * the planner might have replaced the function call via constant-folding
1767          * or inlining.  So if we see any other kind of expression node, execute
1768          * it via the general ExecEvalExpr() code; the only difference is that we
1769          * don't get a chance to pass a special ReturnSetInfo to any functions
1770          * buried in the expression.
1771          */
1772         if (funcexpr && IsA(funcexpr, FuncExprState) &&
1773                 IsA(funcexpr->expr, FuncExpr))
1774         {
1775                 FuncExprState *fcache = (FuncExprState *) funcexpr;
1776                 ExprDoneCond argDone;
1777
1778                 /*
1779                  * This path is similar to ExecMakeFunctionResult.
1780                  */
1781                 direct_function_call = true;
1782
1783                 /*
1784                  * Initialize function cache if first time through
1785                  */
1786                 if (fcache->func.fn_oid == InvalidOid)
1787                 {
1788                         FuncExpr   *func = (FuncExpr *) fcache->xprstate.expr;
1789
1790                         init_fcache(func->funcid, fcache,
1791                                                 econtext->ecxt_per_query_memory, false);
1792                 }
1793                 returnsSet = fcache->func.fn_retset;
1794
1795                 /*
1796                  * Evaluate the function's argument list.
1797                  *
1798                  * Note: ideally, we'd do this in the per-tuple context, but then the
1799                  * argument values would disappear when we reset the context in the
1800                  * inner loop.  So do it in caller context.  Perhaps we should make a
1801                  * separate context just to hold the evaluated arguments?
1802                  */
1803                 fcinfo.flinfo = &(fcache->func);
1804                 argDone = ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
1805                 /* We don't allow sets in the arguments of the table function */
1806                 if (argDone != ExprSingleResult)
1807                         ereport(ERROR,
1808                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1809                                          errmsg("set-valued function called in context that cannot accept a set")));
1810
1811                 /*
1812                  * If function is strict, and there are any NULL arguments, skip
1813                  * calling the function and act like it returned NULL (or an empty
1814                  * set, in the returns-set case).
1815                  */
1816                 if (fcache->func.fn_strict)
1817                 {
1818                         int                     i;
1819
1820                         for (i = 0; i < fcinfo.nargs; i++)
1821                         {
1822                                 if (fcinfo.argnull[i])
1823                                         goto no_function_result;
1824                         }
1825                 }
1826         }
1827         else
1828         {
1829                 /* Treat funcexpr as a generic expression */
1830                 direct_function_call = false;
1831         }
1832
1833         /*
1834          * Switch to short-lived context for calling the function or expression.
1835          */
1836         MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1837
1838         /*
1839          * Loop to handle the ValuePerCall protocol (which is also the same
1840          * behavior needed in the generic ExecEvalExpr path).
1841          */
1842         for (;;)
1843         {
1844                 Datum           result;
1845
1846                 CHECK_FOR_INTERRUPTS();
1847
1848                 /*
1849                  * reset per-tuple memory context before each call of the function or
1850                  * expression. This cleans up any local memory the function may leak
1851                  * when called.
1852                  */
1853                 ResetExprContext(econtext);
1854
1855                 /* Call the function or expression one time */
1856                 if (direct_function_call)
1857                 {
1858                         pgstat_init_function_usage(&fcinfo, &fcusage);
1859
1860                         fcinfo.isnull = false;
1861                         rsinfo.isDone = ExprSingleResult;
1862                         result = FunctionCallInvoke(&fcinfo);
1863
1864                         pgstat_end_function_usage(&fcusage,
1865                                                                           rsinfo.isDone != ExprMultipleResult);
1866                 }
1867                 else
1868                 {
1869                         result = ExecEvalExpr(funcexpr, econtext,
1870                                                                   &fcinfo.isnull, &rsinfo.isDone);
1871                 }
1872
1873                 /* Which protocol does function want to use? */
1874                 if (rsinfo.returnMode == SFRM_ValuePerCall)
1875                 {
1876                         /*
1877                          * Check for end of result set.
1878                          */
1879                         if (rsinfo.isDone == ExprEndResult)
1880                                 break;
1881
1882                         /*
1883                          * Can't do anything very useful with NULL rowtype values. For a
1884                          * function returning set, we consider this a protocol violation
1885                          * (but another alternative would be to just ignore the result and
1886                          * "continue" to get another row).      For a function not returning
1887                          * set, we fall out of the loop; we'll cons up an all-nulls result
1888                          * row below.
1889                          */
1890                         if (returnsTuple && fcinfo.isnull)
1891                         {
1892                                 if (!returnsSet)
1893                                         break;
1894                                 ereport(ERROR,
1895                                                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1896                                                  errmsg("function returning set of rows cannot return null value")));
1897                         }
1898
1899                         /*
1900                          * If first time through, build tupdesc and tuplestore for result
1901                          */
1902                         if (first_time)
1903                         {
1904                                 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1905                                 if (returnsTuple)
1906                                 {
1907                                         /*
1908                                          * Use the type info embedded in the rowtype Datum to look
1909                                          * up the needed tupdesc.  Make a copy for the query.
1910                                          */
1911                                         HeapTupleHeader td;
1912
1913                                         td = DatumGetHeapTupleHeader(result);
1914                                         tupdesc = lookup_rowtype_tupdesc_copy(HeapTupleHeaderGetTypeId(td),
1915                                                                                            HeapTupleHeaderGetTypMod(td));
1916                                 }
1917                                 else
1918                                 {
1919                                         /*
1920                                          * Scalar type, so make a single-column descriptor
1921                                          */
1922                                         tupdesc = CreateTemplateTupleDesc(1, false);
1923                                         TupleDescInitEntry(tupdesc,
1924                                                                            (AttrNumber) 1,
1925                                                                            "column",
1926                                                                            funcrettype,
1927                                                                            -1,
1928                                                                            0);
1929                                 }
1930                                 tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
1931                                 MemoryContextSwitchTo(oldcontext);
1932                                 rsinfo.setResult = tupstore;
1933                                 rsinfo.setDesc = tupdesc;
1934                         }
1935
1936                         /*
1937                          * Store current resultset item.
1938                          */
1939                         if (returnsTuple)
1940                         {
1941                                 HeapTupleHeader td;
1942
1943                                 td = DatumGetHeapTupleHeader(result);
1944
1945                                 /*
1946                                  * tuplestore_puttuple needs a HeapTuple not a bare
1947                                  * HeapTupleHeader, but it doesn't need all the fields.
1948                                  */
1949                                 tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
1950                                 tmptup.t_data = td;
1951
1952                                 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1953                                 tuplestore_puttuple(tupstore, &tmptup);
1954                         }
1955                         else
1956                         {
1957                                 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1958                                 tuplestore_putvalues(tupstore, tupdesc, &result, &fcinfo.isnull);
1959                         }
1960                         MemoryContextSwitchTo(oldcontext);
1961
1962                         /*
1963                          * Are we done?
1964                          */
1965                         if (rsinfo.isDone != ExprMultipleResult)
1966                                 break;
1967                 }
1968                 else if (rsinfo.returnMode == SFRM_Materialize)
1969                 {
1970                         /* check we're on the same page as the function author */
1971                         if (!first_time || rsinfo.isDone != ExprSingleResult)
1972                                 ereport(ERROR,
1973                                                 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1974                                                  errmsg("table-function protocol for materialize mode was not followed")));
1975                         /* Done evaluating the set result */
1976                         break;
1977                 }
1978                 else
1979                         ereport(ERROR,
1980                                         (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1981                                          errmsg("unrecognized table-function returnMode: %d",
1982                                                         (int) rsinfo.returnMode)));
1983
1984                 first_time = false;
1985         }
1986
1987 no_function_result:
1988
1989         /*
1990          * If we got nothing from the function (ie, an empty-set or NULL result),
1991          * we have to create the tuplestore to return, and if it's a
1992          * non-set-returning function then insert a single all-nulls row.
1993          */
1994         if (rsinfo.setResult == NULL)
1995         {
1996                 MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1997                 tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
1998                 rsinfo.setResult = tupstore;
1999                 if (!returnsSet)
2000                 {
2001                         int                     natts = expectedDesc->natts;
2002                         Datum      *nulldatums;
2003                         bool       *nullflags;
2004
2005                         MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
2006                         nulldatums = (Datum *) palloc0(natts * sizeof(Datum));
2007                         nullflags = (bool *) palloc(natts * sizeof(bool));
2008                         memset(nullflags, true, natts * sizeof(bool));
2009                         MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2010                         tuplestore_putvalues(tupstore, expectedDesc, nulldatums, nullflags);
2011                 }
2012         }
2013
2014         /*
2015          * If function provided a tupdesc, cross-check it.      We only really
2016          * need to do this for functions returning RECORD, but might as well
2017          * do it always.
2018          */
2019         if (rsinfo.setDesc)
2020         {
2021                 tupledesc_match(expectedDesc, rsinfo.setDesc);
2022
2023                 /*
2024                  * If it is a dynamically-allocated TupleDesc, free it: it is
2025                  * typically allocated in a per-query context, so we must avoid
2026                  * leaking it across multiple usages.
2027                  */
2028                 if (rsinfo.setDesc->tdrefcount == -1)
2029                         FreeTupleDesc(rsinfo.setDesc);
2030         }
2031
2032         MemoryContextSwitchTo(callerContext);
2033
2034         /* All done, pass back the tuplestore */
2035         return rsinfo.setResult;
2036 }
2037
2038
2039 /* ----------------------------------------------------------------
2040  *              ExecEvalFunc
2041  *              ExecEvalOper
2042  *
2043  *              Evaluate the functional result of a list of arguments by calling the
2044  *              function manager.
2045  * ----------------------------------------------------------------
2046  */
2047
2048 /* ----------------------------------------------------------------
2049  *              ExecEvalFunc
2050  * ----------------------------------------------------------------
2051  */
2052 static Datum
2053 ExecEvalFunc(FuncExprState *fcache,
2054                          ExprContext *econtext,
2055                          bool *isNull,
2056                          ExprDoneCond *isDone)
2057 {
2058         /* This is called only the first time through */
2059         FuncExpr   *func = (FuncExpr *) fcache->xprstate.expr;
2060
2061         /* Initialize function lookup info */
2062         init_fcache(func->funcid, fcache, econtext->ecxt_per_query_memory, true);
2063
2064         /* Go directly to ExecMakeFunctionResult on subsequent uses */
2065         fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
2066
2067         return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
2068 }
2069
2070 /* ----------------------------------------------------------------
2071  *              ExecEvalOper
2072  * ----------------------------------------------------------------
2073  */
2074 static Datum
2075 ExecEvalOper(FuncExprState *fcache,
2076                          ExprContext *econtext,
2077                          bool *isNull,
2078                          ExprDoneCond *isDone)
2079 {
2080         /* This is called only the first time through */
2081         OpExpr     *op = (OpExpr *) fcache->xprstate.expr;
2082
2083         /* Initialize function lookup info */
2084         init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory, true);
2085
2086         /* Go directly to ExecMakeFunctionResult on subsequent uses */
2087         fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
2088
2089         return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
2090 }
2091
2092 /* ----------------------------------------------------------------
2093  *              ExecEvalDistinct
2094  *
2095  * IS DISTINCT FROM must evaluate arguments to determine whether
2096  * they are NULL; if either is NULL then the result is already
2097  * known. If neither is NULL, then proceed to evaluate the
2098  * function. Note that this is *always* derived from the equals
2099  * operator, but since we need special processing of the arguments
2100  * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
2101  * ----------------------------------------------------------------
2102  */
2103 static Datum
2104 ExecEvalDistinct(FuncExprState *fcache,
2105                                  ExprContext *econtext,
2106                                  bool *isNull,
2107                                  ExprDoneCond *isDone)
2108 {
2109         Datum           result;
2110         FunctionCallInfoData fcinfo;
2111         ExprDoneCond argDone;
2112         List       *argList;
2113
2114         /* Set default values for result flags: non-null, not a set result */
2115         *isNull = false;
2116         if (isDone)
2117                 *isDone = ExprSingleResult;
2118
2119         /*
2120          * Initialize function cache if first time through
2121          */
2122         if (fcache->func.fn_oid == InvalidOid)
2123         {
2124                 DistinctExpr *op = (DistinctExpr *) fcache->xprstate.expr;
2125
2126                 init_fcache(op->opfuncid, fcache,
2127                                         econtext->ecxt_per_query_memory, true);
2128                 Assert(!fcache->func.fn_retset);
2129         }
2130
2131         /*
2132          * extract info from fcache
2133          */
2134         argList = fcache->args;
2135
2136         /* Need to prep callinfo structure */
2137         InitFunctionCallInfoData(fcinfo, &(fcache->func), 0, NULL, NULL);
2138         argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
2139         if (argDone != ExprSingleResult)
2140                 ereport(ERROR,
2141                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
2142                                  errmsg("IS DISTINCT FROM does not support set arguments")));
2143         Assert(fcinfo.nargs == 2);
2144
2145         if (fcinfo.argnull[0] && fcinfo.argnull[1])
2146         {
2147                 /* Both NULL? Then is not distinct... */
2148                 result = BoolGetDatum(FALSE);
2149         }
2150         else if (fcinfo.argnull[0] || fcinfo.argnull[1])
2151         {
2152                 /* Only one is NULL? Then is distinct... */
2153                 result = BoolGetDatum(TRUE);
2154         }
2155         else
2156         {
2157                 fcinfo.isnull = false;
2158                 result = FunctionCallInvoke(&fcinfo);
2159                 *isNull = fcinfo.isnull;
2160                 /* Must invert result of "=" */
2161                 result = BoolGetDatum(!DatumGetBool(result));
2162         }
2163
2164         return result;
2165 }
2166
2167 /*
2168  * ExecEvalScalarArrayOp
2169  *
2170  * Evaluate "scalar op ANY/ALL (array)".  The operator always yields boolean,
2171  * and we combine the results across all array elements using OR and AND
2172  * (for ANY and ALL respectively).      Of course we short-circuit as soon as
2173  * the result is known.
2174  */
2175 static Datum
2176 ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
2177                                           ExprContext *econtext,
2178                                           bool *isNull, ExprDoneCond *isDone)
2179 {
2180         ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) sstate->fxprstate.xprstate.expr;
2181         bool            useOr = opexpr->useOr;
2182         ArrayType  *arr;
2183         int                     nitems;
2184         Datum           result;
2185         bool            resultnull;
2186         FunctionCallInfoData fcinfo;
2187         ExprDoneCond argDone;
2188         int                     i;
2189         int16           typlen;
2190         bool            typbyval;
2191         char            typalign;
2192         char       *s;
2193         bits8      *bitmap;
2194         int                     bitmask;
2195
2196         /* Set default values for result flags: non-null, not a set result */
2197         *isNull = false;
2198         if (isDone)
2199                 *isDone = ExprSingleResult;
2200
2201         /*
2202          * Initialize function cache if first time through
2203          */
2204         if (sstate->fxprstate.func.fn_oid == InvalidOid)
2205         {
2206                 init_fcache(opexpr->opfuncid, &sstate->fxprstate,
2207                                         econtext->ecxt_per_query_memory, true);
2208                 Assert(!sstate->fxprstate.func.fn_retset);
2209         }
2210
2211         /* Need to prep callinfo structure */
2212         InitFunctionCallInfoData(fcinfo, &(sstate->fxprstate.func), 0, NULL, NULL);
2213         argDone = ExecEvalFuncArgs(&fcinfo, sstate->fxprstate.args, econtext);
2214         if (argDone != ExprSingleResult)
2215                 ereport(ERROR,
2216                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
2217                            errmsg("op ANY/ALL (array) does not support set arguments")));
2218         Assert(fcinfo.nargs == 2);
2219
2220         /*
2221          * If the array is NULL then we return NULL --- it's not very meaningful
2222          * to do anything else, even if the operator isn't strict.
2223          */
2224         if (fcinfo.argnull[1])
2225         {
2226                 *isNull = true;
2227                 return (Datum) 0;
2228         }
2229         /* Else okay to fetch and detoast the array */
2230         arr = DatumGetArrayTypeP(fcinfo.arg[1]);
2231
2232         /*
2233          * If the array is empty, we return either FALSE or TRUE per the useOr
2234          * flag.  This is correct even if the scalar is NULL; since we would
2235          * evaluate the operator zero times, it matters not whether it would want
2236          * to return NULL.
2237          */
2238         nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
2239         if (nitems <= 0)
2240                 return BoolGetDatum(!useOr);
2241
2242         /*
2243          * If the scalar is NULL, and the function is strict, return NULL; no
2244          * point in iterating the loop.
2245          */
2246         if (fcinfo.argnull[0] && sstate->fxprstate.func.fn_strict)
2247         {
2248                 *isNull = true;
2249                 return (Datum) 0;
2250         }
2251
2252         /*
2253          * We arrange to look up info about the element type only once per series
2254          * of calls, assuming the element type doesn't change underneath us.
2255          */
2256         if (sstate->element_type != ARR_ELEMTYPE(arr))
2257         {
2258                 get_typlenbyvalalign(ARR_ELEMTYPE(arr),
2259                                                          &sstate->typlen,
2260                                                          &sstate->typbyval,
2261                                                          &sstate->typalign);
2262                 sstate->element_type = ARR_ELEMTYPE(arr);
2263         }
2264         typlen = sstate->typlen;
2265         typbyval = sstate->typbyval;
2266         typalign = sstate->typalign;
2267
2268         result = BoolGetDatum(!useOr);
2269         resultnull = false;
2270
2271         /* Loop over the array elements */
2272         s = (char *) ARR_DATA_PTR(arr);
2273         bitmap = ARR_NULLBITMAP(arr);
2274         bitmask = 1;
2275
2276         for (i = 0; i < nitems; i++)
2277         {
2278                 Datum           elt;
2279                 Datum           thisresult;
2280
2281                 /* Get array element, checking for NULL */
2282                 if (bitmap && (*bitmap & bitmask) == 0)
2283                 {
2284                         fcinfo.arg[1] = (Datum) 0;
2285                         fcinfo.argnull[1] = true;
2286                 }
2287                 else
2288                 {
2289                         elt = fetch_att(s, typbyval, typlen);
2290                         s = att_addlength_pointer(s, typlen, s);
2291                         s = (char *) att_align_nominal(s, typalign);
2292                         fcinfo.arg[1] = elt;
2293                         fcinfo.argnull[1] = false;
2294                 }
2295
2296                 /* Call comparison function */
2297                 if (fcinfo.argnull[1] && sstate->fxprstate.func.fn_strict)
2298                 {
2299                         fcinfo.isnull = true;
2300                         thisresult = (Datum) 0;
2301                 }
2302                 else
2303                 {
2304                         fcinfo.isnull = false;
2305                         thisresult = FunctionCallInvoke(&fcinfo);
2306                 }
2307
2308                 /* Combine results per OR or AND semantics */
2309                 if (fcinfo.isnull)
2310                         resultnull = true;
2311                 else if (useOr)
2312                 {
2313                         if (DatumGetBool(thisresult))
2314                         {
2315                                 result = BoolGetDatum(true);
2316                                 resultnull = false;
2317                                 break;                  /* needn't look at any more elements */
2318                         }
2319                 }
2320                 else
2321                 {
2322                         if (!DatumGetBool(thisresult))
2323                         {
2324                                 result = BoolGetDatum(false);
2325                                 resultnull = false;
2326                                 break;                  /* needn't look at any more elements */
2327                         }
2328                 }
2329
2330                 /* advance bitmap pointer if any */
2331                 if (bitmap)
2332                 {
2333                         bitmask <<= 1;
2334                         if (bitmask == 0x100)
2335                         {
2336                                 bitmap++;
2337                                 bitmask = 1;
2338                         }
2339                 }
2340         }
2341
2342         *isNull = resultnull;
2343         return result;
2344 }
2345
2346 /* ----------------------------------------------------------------
2347  *              ExecEvalNot
2348  *              ExecEvalOr
2349  *              ExecEvalAnd
2350  *
2351  *              Evaluate boolean expressions, with appropriate short-circuiting.
2352  *
2353  *              The query planner reformulates clause expressions in the
2354  *              qualification to conjunctive normal form.  If we ever get
2355  *              an AND to evaluate, we can be sure that it's not a top-level
2356  *              clause in the qualification, but appears lower (as a function
2357  *              argument, for example), or in the target list.  Not that you
2358  *              need to know this, mind you...
2359  * ----------------------------------------------------------------
2360  */
2361 static Datum
2362 ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
2363                         bool *isNull, ExprDoneCond *isDone)
2364 {
2365         ExprState  *clause = linitial(notclause->args);
2366         Datum           expr_value;
2367
2368         if (isDone)
2369                 *isDone = ExprSingleResult;
2370
2371         expr_value = ExecEvalExpr(clause, econtext, isNull, NULL);
2372
2373         /*
2374          * if the expression evaluates to null, then we just cascade the null back
2375          * to whoever called us.
2376          */
2377         if (*isNull)
2378                 return expr_value;
2379
2380         /*
2381          * evaluation of 'not' is simple.. expr is false, then return 'true' and
2382          * vice versa.
2383          */
2384         return BoolGetDatum(!DatumGetBool(expr_value));
2385 }
2386
2387 /* ----------------------------------------------------------------
2388  *              ExecEvalOr
2389  * ----------------------------------------------------------------
2390  */
2391 static Datum
2392 ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
2393                    bool *isNull, ExprDoneCond *isDone)
2394 {
2395         List       *clauses = orExpr->args;
2396         ListCell   *clause;
2397         bool            AnyNull;
2398
2399         if (isDone)
2400                 *isDone = ExprSingleResult;
2401
2402         AnyNull = false;
2403
2404         /*
2405          * If any of the clauses is TRUE, the OR result is TRUE regardless of the
2406          * states of the rest of the clauses, so we can stop evaluating and return
2407          * TRUE immediately.  If none are TRUE and one or more is NULL, we return
2408          * NULL; otherwise we return FALSE.  This makes sense when you interpret
2409          * NULL as "don't know": if we have a TRUE then the OR is TRUE even if we
2410          * aren't sure about some of the other inputs. If all the known inputs are
2411          * FALSE, but we have one or more "don't knows", then we have to report
2412          * that we "don't know" what the OR's result should be --- perhaps one of
2413          * the "don't knows" would have been TRUE if we'd known its value.  Only
2414          * when all the inputs are known to be FALSE can we state confidently that
2415          * the OR's result is FALSE.
2416          */
2417         foreach(clause, clauses)
2418         {
2419                 ExprState  *clausestate = (ExprState *) lfirst(clause);
2420                 Datum           clause_value;
2421
2422                 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
2423
2424                 /*
2425                  * if we have a non-null true result, then return it.
2426                  */
2427                 if (*isNull)
2428                         AnyNull = true;         /* remember we got a null */
2429                 else if (DatumGetBool(clause_value))
2430                         return clause_value;
2431         }
2432
2433         /* AnyNull is true if at least one clause evaluated to NULL */
2434         *isNull = AnyNull;
2435         return BoolGetDatum(false);
2436 }
2437
2438 /* ----------------------------------------------------------------
2439  *              ExecEvalAnd
2440  * ----------------------------------------------------------------
2441  */
2442 static Datum
2443 ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
2444                         bool *isNull, ExprDoneCond *isDone)
2445 {
2446         List       *clauses = andExpr->args;
2447         ListCell   *clause;
2448         bool            AnyNull;
2449
2450         if (isDone)
2451                 *isDone = ExprSingleResult;
2452
2453         AnyNull = false;
2454
2455         /*
2456          * If any of the clauses is FALSE, the AND result is FALSE regardless of
2457          * the states of the rest of the clauses, so we can stop evaluating and
2458          * return FALSE immediately.  If none are FALSE and one or more is NULL,
2459          * we return NULL; otherwise we return TRUE.  This makes sense when you
2460          * interpret NULL as "don't know", using the same sort of reasoning as for
2461          * OR, above.
2462          */
2463
2464         foreach(clause, clauses)
2465         {
2466                 ExprState  *clausestate = (ExprState *) lfirst(clause);
2467                 Datum           clause_value;
2468
2469                 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
2470
2471                 /*
2472                  * if we have a non-null false result, then return it.
2473                  */
2474                 if (*isNull)
2475                         AnyNull = true;         /* remember we got a null */
2476                 else if (!DatumGetBool(clause_value))
2477                         return clause_value;
2478         }
2479
2480         /* AnyNull is true if at least one clause evaluated to NULL */
2481         *isNull = AnyNull;
2482         return BoolGetDatum(!AnyNull);
2483 }
2484
2485 /* ----------------------------------------------------------------
2486  *              ExecEvalConvertRowtype
2487  *
2488  *              Evaluate a rowtype coercion operation.  This may require
2489  *              rearranging field positions.
2490  * ----------------------------------------------------------------
2491  */
2492 static Datum
2493 ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
2494                                            ExprContext *econtext,
2495                                            bool *isNull, ExprDoneCond *isDone)
2496 {
2497         ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) cstate->xprstate.expr;
2498         HeapTuple       result;
2499         Datum           tupDatum;
2500         HeapTupleHeader tuple;
2501         HeapTupleData tmptup;
2502         AttrNumber *attrMap;
2503         Datum      *invalues;
2504         bool       *inisnull;
2505         Datum      *outvalues;
2506         bool       *outisnull;
2507         int                     i;
2508         int                     outnatts;
2509
2510         tupDatum = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
2511
2512         /* this test covers the isDone exception too: */
2513         if (*isNull)
2514                 return tupDatum;
2515
2516         tuple = DatumGetHeapTupleHeader(tupDatum);
2517
2518         /* Lookup tupdescs if first time through or after rescan */
2519         if (cstate->indesc == NULL)
2520                 get_cached_rowtype(exprType((Node *) convert->arg), -1,
2521                                                    &cstate->indesc, econtext);
2522         if (cstate->outdesc == NULL)
2523                 get_cached_rowtype(convert->resulttype, -1,
2524                                                    &cstate->outdesc, econtext);
2525
2526         Assert(HeapTupleHeaderGetTypeId(tuple) == cstate->indesc->tdtypeid);
2527         Assert(HeapTupleHeaderGetTypMod(tuple) == cstate->indesc->tdtypmod);
2528
2529         /* if first time through, initialize */
2530         if (cstate->attrMap == NULL)
2531         {
2532                 MemoryContext old_cxt;
2533                 int                     n;
2534
2535                 /* allocate state in long-lived memory context */
2536                 old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2537
2538                 /* prepare map from old to new attribute numbers */
2539                 n = cstate->outdesc->natts;
2540                 cstate->attrMap = (AttrNumber *) palloc0(n * sizeof(AttrNumber));
2541                 for (i = 0; i < n; i++)
2542                 {
2543                         Form_pg_attribute att = cstate->outdesc->attrs[i];
2544                         char       *attname;
2545                         Oid                     atttypid;
2546                         int32           atttypmod;
2547                         int                     j;
2548
2549                         if (att->attisdropped)
2550                                 continue;               /* attrMap[i] is already 0 */
2551                         attname = NameStr(att->attname);
2552                         atttypid = att->atttypid;
2553                         atttypmod = att->atttypmod;
2554                         for (j = 0; j < cstate->indesc->natts; j++)
2555                         {
2556                                 att = cstate->indesc->attrs[j];
2557                                 if (att->attisdropped)
2558                                         continue;
2559                                 if (strcmp(attname, NameStr(att->attname)) == 0)
2560                                 {
2561                                         /* Found it, check type */
2562                                         if (atttypid != att->atttypid || atttypmod != att->atttypmod)
2563                                                 elog(ERROR, "attribute \"%s\" of type %s does not match corresponding attribute of type %s",
2564                                                          attname,
2565                                                          format_type_be(cstate->indesc->tdtypeid),
2566                                                          format_type_be(cstate->outdesc->tdtypeid));
2567                                         cstate->attrMap[i] = (AttrNumber) (j + 1);
2568                                         break;
2569                                 }
2570                         }
2571                         if (cstate->attrMap[i] == 0)
2572                                 elog(ERROR, "attribute \"%s\" of type %s does not exist",
2573                                          attname,
2574                                          format_type_be(cstate->indesc->tdtypeid));
2575                 }
2576                 /* preallocate workspace for Datum arrays */
2577                 n = cstate->indesc->natts + 1;  /* +1 for NULL */
2578                 cstate->invalues = (Datum *) palloc(n * sizeof(Datum));
2579                 cstate->inisnull = (bool *) palloc(n * sizeof(bool));
2580                 n = cstate->outdesc->natts;
2581                 cstate->outvalues = (Datum *) palloc(n * sizeof(Datum));
2582                 cstate->outisnull = (bool *) palloc(n * sizeof(bool));
2583
2584                 MemoryContextSwitchTo(old_cxt);
2585         }
2586
2587         attrMap = cstate->attrMap;
2588         invalues = cstate->invalues;
2589         inisnull = cstate->inisnull;
2590         outvalues = cstate->outvalues;
2591         outisnull = cstate->outisnull;
2592         outnatts = cstate->outdesc->natts;
2593
2594         /*
2595          * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader.
2596          */
2597         tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2598         tmptup.t_data = tuple;
2599
2600         /*
2601          * Extract all the values of the old tuple, offsetting the arrays so that
2602          * invalues[0] is NULL and invalues[1] is the first source attribute; this
2603          * exactly matches the numbering convention in attrMap.
2604          */
2605         heap_deform_tuple(&tmptup, cstate->indesc, invalues + 1, inisnull + 1);
2606         invalues[0] = (Datum) 0;
2607         inisnull[0] = true;
2608
2609         /*
2610          * Transpose into proper fields of the new tuple.
2611          */
2612         for (i = 0; i < outnatts; i++)
2613         {
2614                 int                     j = attrMap[i];
2615
2616                 outvalues[i] = invalues[j];
2617                 outisnull[i] = inisnull[j];
2618         }
2619
2620         /*
2621          * Now form the new tuple.
2622          */
2623         result = heap_form_tuple(cstate->outdesc, outvalues, outisnull);
2624
2625         return HeapTupleGetDatum(result);
2626 }
2627
2628 /* ----------------------------------------------------------------
2629  *              ExecEvalCase
2630  *
2631  *              Evaluate a CASE clause. Will have boolean expressions
2632  *              inside the WHEN clauses, and will have expressions
2633  *              for results.
2634  *              - thomas 1998-11-09
2635  * ----------------------------------------------------------------
2636  */
2637 static Datum
2638 ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
2639                          bool *isNull, ExprDoneCond *isDone)
2640 {
2641         List       *clauses = caseExpr->args;
2642         ListCell   *clause;
2643         Datum           save_datum;
2644         bool            save_isNull;
2645
2646         if (isDone)
2647                 *isDone = ExprSingleResult;
2648
2649         /*
2650          * If there's a test expression, we have to evaluate it and save the value
2651          * where the CaseTestExpr placeholders can find it. We must save and
2652          * restore prior setting of econtext's caseValue fields, in case this node
2653          * is itself within a larger CASE.
2654          */
2655         save_datum = econtext->caseValue_datum;
2656         save_isNull = econtext->caseValue_isNull;
2657
2658         if (caseExpr->arg)
2659         {
2660                 econtext->caseValue_datum = ExecEvalExpr(caseExpr->arg,
2661                                                                                                  econtext,
2662                                                                                                  &econtext->caseValue_isNull,
2663                                                                                                  NULL);
2664         }
2665
2666         /*
2667          * we evaluate each of the WHEN clauses in turn, as soon as one is true we
2668          * return the corresponding result. If none are true then we return the
2669          * value of the default clause, or NULL if there is none.
2670          */
2671         foreach(clause, clauses)
2672         {
2673                 CaseWhenState *wclause = lfirst(clause);
2674                 Datum           clause_value;
2675
2676                 clause_value = ExecEvalExpr(wclause->expr,
2677                                                                         econtext,
2678                                                                         isNull,
2679                                                                         NULL);
2680
2681                 /*
2682                  * if we have a true test, then we return the result, since the case
2683                  * statement is satisfied.      A NULL result from the test is not
2684                  * considered true.
2685                  */
2686                 if (DatumGetBool(clause_value) && !*isNull)
2687                 {
2688                         econtext->caseValue_datum = save_datum;
2689                         econtext->caseValue_isNull = save_isNull;
2690                         return ExecEvalExpr(wclause->result,
2691                                                                 econtext,
2692                                                                 isNull,
2693                                                                 isDone);
2694                 }
2695         }
2696
2697         econtext->caseValue_datum = save_datum;
2698         econtext->caseValue_isNull = save_isNull;
2699
2700         if (caseExpr->defresult)
2701         {
2702                 return ExecEvalExpr(caseExpr->defresult,
2703                                                         econtext,
2704                                                         isNull,
2705                                                         isDone);
2706         }
2707
2708         *isNull = true;
2709         return (Datum) 0;
2710 }
2711
2712 /*
2713  * ExecEvalCaseTestExpr
2714  *
2715  * Return the value stored by CASE.
2716  */
2717 static Datum
2718 ExecEvalCaseTestExpr(ExprState *exprstate,
2719                                          ExprContext *econtext,
2720                                          bool *isNull, ExprDoneCond *isDone)
2721 {
2722         if (isDone)
2723                 *isDone = ExprSingleResult;
2724         *isNull = econtext->caseValue_isNull;
2725         return econtext->caseValue_datum;
2726 }
2727
2728 /* ----------------------------------------------------------------
2729  *              ExecEvalArray - ARRAY[] expressions
2730  * ----------------------------------------------------------------
2731  */
2732 static Datum
2733 ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
2734                           bool *isNull, ExprDoneCond *isDone)
2735 {
2736         ArrayExpr  *arrayExpr = (ArrayExpr *) astate->xprstate.expr;
2737         ArrayType  *result;
2738         ListCell   *element;
2739         Oid                     element_type = arrayExpr->element_typeid;
2740         int                     ndims = 0;
2741         int                     dims[MAXDIM];
2742         int                     lbs[MAXDIM];
2743
2744         /* Set default values for result flags: non-null, not a set result */
2745         *isNull = false;
2746         if (isDone)
2747                 *isDone = ExprSingleResult;
2748
2749         if (!arrayExpr->multidims)
2750         {
2751                 /* Elements are presumably of scalar type */
2752                 int                     nelems;
2753                 Datum      *dvalues;
2754                 bool       *dnulls;
2755                 int                     i = 0;
2756
2757                 ndims = 1;
2758                 nelems = list_length(astate->elements);
2759
2760                 /* Shouldn't happen here, but if length is 0, return empty array */
2761                 if (nelems == 0)
2762                         return PointerGetDatum(construct_empty_array(element_type));
2763
2764                 dvalues = (Datum *) palloc(nelems * sizeof(Datum));
2765                 dnulls = (bool *) palloc(nelems * sizeof(bool));
2766
2767                 /* loop through and build array of datums */
2768                 foreach(element, astate->elements)
2769                 {
2770                         ExprState  *e = (ExprState *) lfirst(element);
2771
2772                         dvalues[i] = ExecEvalExpr(e, econtext, &dnulls[i], NULL);
2773                         i++;
2774                 }
2775
2776                 /* setup for 1-D array of the given length */
2777                 dims[0] = nelems;
2778                 lbs[0] = 1;
2779
2780                 result = construct_md_array(dvalues, dnulls, ndims, dims, lbs,
2781                                                                         element_type,
2782                                                                         astate->elemlength,
2783                                                                         astate->elembyval,
2784                                                                         astate->elemalign);
2785         }
2786         else
2787         {
2788                 /* Must be nested array expressions */
2789                 int                     nbytes = 0;
2790                 int                     nitems = 0;
2791                 int                     outer_nelems = 0;
2792                 int                     elem_ndims = 0;
2793                 int                *elem_dims = NULL;
2794                 int                *elem_lbs = NULL;
2795                 bool            firstone = true;
2796                 bool            havenulls = false;
2797                 bool            haveempty = false;
2798                 char      **subdata;
2799                 bits8     **subbitmaps;
2800                 int                *subbytes;
2801                 int                *subnitems;
2802                 int                     i;
2803                 int32           dataoffset;
2804                 char       *dat;
2805                 int                     iitem;
2806
2807                 i = list_length(astate->elements);
2808                 subdata = (char **) palloc(i * sizeof(char *));
2809                 subbitmaps = (bits8 **) palloc(i * sizeof(bits8 *));
2810                 subbytes = (int *) palloc(i * sizeof(int));
2811                 subnitems = (int *) palloc(i * sizeof(int));
2812
2813                 /* loop through and get data area from each element */
2814                 foreach(element, astate->elements)
2815                 {
2816                         ExprState  *e = (ExprState *) lfirst(element);
2817                         bool            eisnull;
2818                         Datum           arraydatum;
2819                         ArrayType  *array;
2820                         int                     this_ndims;
2821
2822                         arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
2823                         /* temporarily ignore null subarrays */
2824                         if (eisnull)
2825                         {
2826                                 haveempty = true;
2827                                 continue;
2828                         }
2829
2830                         array = DatumGetArrayTypeP(arraydatum);
2831
2832                         /* run-time double-check on element type */
2833                         if (element_type != ARR_ELEMTYPE(array))
2834                                 ereport(ERROR,
2835                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
2836                                                  errmsg("cannot merge incompatible arrays"),
2837                                                  errdetail("Array with element type %s cannot be "
2838                                                  "included in ARRAY construct with element type %s.",
2839                                                                    format_type_be(ARR_ELEMTYPE(array)),
2840                                                                    format_type_be(element_type))));
2841
2842                         this_ndims = ARR_NDIM(array);
2843                         /* temporarily ignore zero-dimensional subarrays */
2844                         if (this_ndims <= 0)
2845                         {
2846                                 haveempty = true;
2847                                 continue;
2848                         }
2849
2850                         if (firstone)
2851                         {
2852                                 /* Get sub-array details from first member */
2853                                 elem_ndims = this_ndims;
2854                                 ndims = elem_ndims + 1;
2855                                 if (ndims <= 0 || ndims > MAXDIM)
2856                                         ereport(ERROR,
2857                                                         (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2858                                                   errmsg("number of array dimensions (%d) exceeds " \
2859                                                                  "the maximum allowed (%d)", ndims, MAXDIM)));
2860
2861                                 elem_dims = (int *) palloc(elem_ndims * sizeof(int));
2862                                 memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
2863                                 elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
2864                                 memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
2865
2866                                 firstone = false;
2867                         }
2868                         else
2869                         {
2870                                 /* Check other sub-arrays are compatible */
2871                                 if (elem_ndims != this_ndims ||
2872                                         memcmp(elem_dims, ARR_DIMS(array),
2873                                                    elem_ndims * sizeof(int)) != 0 ||
2874                                         memcmp(elem_lbs, ARR_LBOUND(array),
2875                                                    elem_ndims * sizeof(int)) != 0)
2876                                         ereport(ERROR,
2877                                                         (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2878                                                          errmsg("multidimensional arrays must have array "
2879                                                                         "expressions with matching dimensions")));
2880                         }
2881
2882                         subdata[outer_nelems] = ARR_DATA_PTR(array);
2883                         subbitmaps[outer_nelems] = ARR_NULLBITMAP(array);
2884                         subbytes[outer_nelems] = ARR_SIZE(array) - ARR_DATA_OFFSET(array);
2885                         nbytes += subbytes[outer_nelems];
2886                         subnitems[outer_nelems] = ArrayGetNItems(this_ndims,
2887                                                                                                          ARR_DIMS(array));
2888                         nitems += subnitems[outer_nelems];
2889                         havenulls |= ARR_HASNULL(array);
2890                         outer_nelems++;
2891                 }
2892
2893                 /*
2894                  * If all items were null or empty arrays, return an empty array;
2895                  * otherwise, if some were and some weren't, raise error.  (Note: we
2896                  * must special-case this somehow to avoid trying to generate a 1-D
2897                  * array formed from empty arrays.      It's not ideal...)
2898                  */
2899                 if (haveempty)
2900                 {
2901                         if (ndims == 0)         /* didn't find any nonempty array */
2902                                 return PointerGetDatum(construct_empty_array(element_type));
2903                         ereport(ERROR,
2904                                         (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2905                                          errmsg("multidimensional arrays must have array "
2906                                                         "expressions with matching dimensions")));
2907                 }
2908
2909                 /* setup for multi-D array */
2910                 dims[0] = outer_nelems;
2911                 lbs[0] = 1;
2912                 for (i = 1; i < ndims; i++)
2913                 {
2914                         dims[i] = elem_dims[i - 1];
2915                         lbs[i] = elem_lbs[i - 1];
2916                 }
2917
2918                 if (havenulls)
2919                 {
2920                         dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nitems);
2921                         nbytes += dataoffset;
2922                 }
2923                 else
2924                 {
2925                         dataoffset = 0;         /* marker for no null bitmap */
2926                         nbytes += ARR_OVERHEAD_NONULLS(ndims);
2927                 }
2928
2929                 result = (ArrayType *) palloc(nbytes);
2930                 SET_VARSIZE(result, nbytes);
2931                 result->ndim = ndims;
2932                 result->dataoffset = dataoffset;
2933                 result->elemtype = element_type;
2934                 memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
2935                 memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
2936
2937                 dat = ARR_DATA_PTR(result);
2938                 iitem = 0;
2939                 for (i = 0; i < outer_nelems; i++)
2940                 {
2941                         memcpy(dat, subdata[i], subbytes[i]);
2942                         dat += subbytes[i];
2943                         if (havenulls)
2944                                 array_bitmap_copy(ARR_NULLBITMAP(result), iitem,
2945                                                                   subbitmaps[i], 0,
2946                                                                   subnitems[i]);
2947                         iitem += subnitems[i];
2948                 }
2949         }
2950
2951         return PointerGetDatum(result);
2952 }
2953
2954 /* ----------------------------------------------------------------
2955  *              ExecEvalRow - ROW() expressions
2956  * ----------------------------------------------------------------
2957  */
2958 static Datum
2959 ExecEvalRow(RowExprState *rstate,
2960                         ExprContext *econtext,
2961                         bool *isNull, ExprDoneCond *isDone)
2962 {
2963         HeapTuple       tuple;
2964         Datum      *values;
2965         bool       *isnull;
2966         int                     natts;
2967         ListCell   *arg;
2968         int                     i;
2969
2970         /* Set default values for result flags: non-null, not a set result */
2971         *isNull = false;
2972         if (isDone)
2973                 *isDone = ExprSingleResult;
2974
2975         /* Allocate workspace */
2976         natts = rstate->tupdesc->natts;
2977         values = (Datum *) palloc0(natts * sizeof(Datum));
2978         isnull = (bool *) palloc(natts * sizeof(bool));
2979
2980         /* preset to nulls in case rowtype has some later-added columns */
2981         memset(isnull, true, natts * sizeof(bool));
2982
2983         /* Evaluate field values */
2984         i = 0;
2985         foreach(arg, rstate->args)
2986         {
2987                 ExprState  *e = (ExprState *) lfirst(arg);
2988
2989                 values[i] = ExecEvalExpr(e, econtext, &isnull[i], NULL);
2990                 i++;
2991         }
2992
2993         tuple = heap_form_tuple(rstate->tupdesc, values, isnull);
2994
2995         pfree(values);
2996         pfree(isnull);
2997
2998         return HeapTupleGetDatum(tuple);
2999 }
3000
3001 /* ----------------------------------------------------------------
3002  *              ExecEvalRowCompare - ROW() comparison-op ROW()
3003  * ----------------------------------------------------------------
3004  */
3005 static Datum
3006 ExecEvalRowCompare(RowCompareExprState *rstate,
3007                                    ExprContext *econtext,
3008                                    bool *isNull, ExprDoneCond *isDone)
3009 {
3010         bool            result;
3011         RowCompareType rctype = ((RowCompareExpr *) rstate->xprstate.expr)->rctype;
3012         int32           cmpresult = 0;
3013         ListCell   *l;
3014         ListCell   *r;
3015         int                     i;
3016
3017         if (isDone)
3018                 *isDone = ExprSingleResult;
3019         *isNull = true;                         /* until we get a result */
3020
3021         i = 0;
3022         forboth(l, rstate->largs, r, rstate->rargs)
3023         {
3024                 ExprState  *le = (ExprState *) lfirst(l);
3025                 ExprState  *re = (ExprState *) lfirst(r);
3026                 FunctionCallInfoData locfcinfo;
3027
3028                 InitFunctionCallInfoData(locfcinfo, &(rstate->funcs[i]), 2,
3029                                                                  NULL, NULL);
3030                 locfcinfo.arg[0] = ExecEvalExpr(le, econtext,
3031                                                                                 &locfcinfo.argnull[0], NULL);
3032                 locfcinfo.arg[1] = ExecEvalExpr(re, econtext,
3033                                                                                 &locfcinfo.argnull[1], NULL);
3034                 if (rstate->funcs[i].fn_strict &&
3035                         (locfcinfo.argnull[0] || locfcinfo.argnull[1]))
3036                         return (Datum) 0;       /* force NULL result */
3037                 locfcinfo.isnull = false;
3038                 cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
3039                 if (locfcinfo.isnull)
3040                         return (Datum) 0;       /* force NULL result */
3041                 if (cmpresult != 0)
3042                         break;                          /* no need to compare remaining columns */
3043                 i++;
3044         }
3045
3046         switch (rctype)
3047         {
3048                         /* EQ and NE cases aren't allowed here */
3049                 case ROWCOMPARE_LT:
3050                         result = (cmpresult < 0);
3051                         break;
3052                 case ROWCOMPARE_LE:
3053                         result = (cmpresult <= 0);
3054                         break;
3055                 case ROWCOMPARE_GE:
3056                         result = (cmpresult >= 0);
3057                         break;
3058                 case ROWCOMPARE_GT:
3059                         result = (cmpresult > 0);
3060                         break;
3061                 default:
3062                         elog(ERROR, "unrecognized RowCompareType: %d", (int) rctype);
3063                         result = 0;                     /* keep compiler quiet */
3064                         break;
3065         }
3066
3067         *isNull = false;
3068         return BoolGetDatum(result);
3069 }
3070
3071 /* ----------------------------------------------------------------
3072  *              ExecEvalCoalesce
3073  * ----------------------------------------------------------------
3074  */
3075 static Datum
3076 ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
3077                                  bool *isNull, ExprDoneCond *isDone)
3078 {
3079         ListCell   *arg;
3080
3081         if (isDone)
3082                 *isDone = ExprSingleResult;
3083
3084         /* Simply loop through until something NOT NULL is found */
3085         foreach(arg, coalesceExpr->args)
3086         {
3087                 ExprState  *e = (ExprState *) lfirst(arg);
3088                 Datum           value;
3089
3090                 value = ExecEvalExpr(e, econtext, isNull, NULL);
3091                 if (!*isNull)
3092                         return value;
3093         }
3094
3095         /* Else return NULL */
3096         *isNull = true;
3097         return (Datum) 0;
3098 }
3099
3100 /* ----------------------------------------------------------------
3101  *              ExecEvalMinMax
3102  * ----------------------------------------------------------------
3103  */
3104 static Datum
3105 ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
3106                            bool *isNull, ExprDoneCond *isDone)
3107 {
3108         Datum           result = (Datum) 0;
3109         MinMaxOp        op = ((MinMaxExpr *) minmaxExpr->xprstate.expr)->op;
3110         FunctionCallInfoData locfcinfo;
3111         ListCell   *arg;
3112
3113         if (isDone)
3114                 *isDone = ExprSingleResult;
3115         *isNull = true;                         /* until we get a result */
3116
3117         InitFunctionCallInfoData(locfcinfo, &minmaxExpr->cfunc, 2, NULL, NULL);
3118         locfcinfo.argnull[0] = false;
3119         locfcinfo.argnull[1] = false;
3120
3121         foreach(arg, minmaxExpr->args)
3122         {
3123                 ExprState  *e = (ExprState *) lfirst(arg);
3124                 Datum           value;
3125                 bool            valueIsNull;
3126                 int32           cmpresult;
3127
3128                 value = ExecEvalExpr(e, econtext, &valueIsNull, NULL);
3129                 if (valueIsNull)
3130                         continue;                       /* ignore NULL inputs */
3131
3132                 if (*isNull)
3133                 {
3134                         /* first nonnull input, adopt value */
3135                         result = value;
3136                         *isNull = false;
3137                 }
3138                 else
3139                 {
3140                         /* apply comparison function */
3141                         locfcinfo.arg[0] = result;
3142                         locfcinfo.arg[1] = value;
3143                         locfcinfo.isnull = false;
3144                         cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
3145                         if (locfcinfo.isnull)           /* probably should not happen */
3146                                 continue;
3147                         if (cmpresult > 0 && op == IS_LEAST)
3148                                 result = value;
3149                         else if (cmpresult < 0 && op == IS_GREATEST)
3150                                 result = value;
3151                 }
3152         }
3153
3154         return result;
3155 }
3156
3157 /* ----------------------------------------------------------------
3158  *              ExecEvalXml
3159  * ----------------------------------------------------------------
3160  */
3161 static Datum
3162 ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
3163                         bool *isNull, ExprDoneCond *isDone)
3164 {
3165         XmlExpr    *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
3166         Datum           value;
3167         bool            isnull;
3168         ListCell   *arg;
3169         ListCell   *narg;
3170
3171         if (isDone)
3172                 *isDone = ExprSingleResult;
3173         *isNull = true;                         /* until we get a result */
3174
3175         switch (xexpr->op)
3176         {
3177                 case IS_XMLCONCAT:
3178                         {
3179                                 List       *values = NIL;
3180
3181                                 foreach(arg, xmlExpr->args)
3182                                 {
3183                                         ExprState  *e = (ExprState *) lfirst(arg);
3184
3185                                         value = ExecEvalExpr(e, econtext, &isnull, NULL);
3186                                         if (!isnull)
3187                                                 values = lappend(values, DatumGetPointer(value));
3188                                 }
3189
3190                                 if (list_length(values) > 0)
3191                                 {
3192                                         *isNull = false;
3193                                         return PointerGetDatum(xmlconcat(values));
3194                                 }
3195                                 else
3196                                         return (Datum) 0;
3197                         }
3198                         break;
3199
3200                 case IS_XMLFOREST:
3201                 {
3202                         StringInfoData buf;
3203
3204                         initStringInfo(&buf);
3205                         forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
3206                         {
3207                                 ExprState  *e = (ExprState *) lfirst(arg);
3208                                 char       *argname = strVal(lfirst(narg));
3209
3210                                 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3211                                 if (!isnull)
3212                                 {
3213                                         appendStringInfo(&buf, "<%s>%s</%s>",
3214                                                                          argname,
3215                                                                          map_sql_value_to_xml_value(value, exprType((Node *) e->expr)),
3216                                                                          argname);
3217                                         *isNull = false;
3218                                 }
3219                         }
3220
3221                         if (*isNull)
3222                         {
3223                                 pfree(buf.data);
3224                                 return (Datum) 0;
3225                         }
3226                         else
3227                         {
3228                                 text       *result;
3229
3230                                 result = cstring_to_text_with_len(buf.data, buf.len);
3231                                 pfree(buf.data);
3232
3233                                 return PointerGetDatum(result);
3234                         }
3235                 }
3236                         break;
3237
3238                 case IS_XMLELEMENT:
3239                         *isNull = false;
3240                         return PointerGetDatum(xmlelement(xmlExpr, econtext));
3241                         break;
3242
3243                 case IS_XMLPARSE:
3244                         {
3245                                 ExprState  *e;
3246                                 text       *data;
3247                                 bool            preserve_whitespace;
3248
3249                                 /* arguments are known to be text, bool */
3250                                 Assert(list_length(xmlExpr->args) == 2);
3251
3252                                 e = (ExprState *) linitial(xmlExpr->args);
3253                                 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3254                                 if (isnull)
3255                                         return (Datum) 0;
3256                                 data = DatumGetTextP(value);
3257
3258                                 e = (ExprState *) lsecond(xmlExpr->args);
3259                                 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3260                                 if (isnull)             /* probably can't happen */
3261                                         return (Datum) 0;
3262                                 preserve_whitespace = DatumGetBool(value);
3263
3264                                 *isNull = false;
3265
3266                                 return PointerGetDatum(xmlparse(data,
3267                                                                                                 xexpr->xmloption,
3268                                                                                                 preserve_whitespace));
3269                         }
3270                         break;
3271
3272                 case IS_XMLPI:
3273                         {
3274                                 ExprState  *e;
3275                                 text       *arg;
3276
3277                                 /* optional argument is known to be text */
3278                                 Assert(list_length(xmlExpr->args) <= 1);
3279
3280                                 if (xmlExpr->args)
3281                                 {
3282                                         e = (ExprState *) linitial(xmlExpr->args);
3283                                         value = ExecEvalExpr(e, econtext, &isnull, NULL);
3284                                         if (isnull)
3285                                                 arg = NULL;
3286                                         else
3287                                                 arg = DatumGetTextP(value);
3288                                 }
3289                                 else
3290                                 {
3291                                         arg = NULL;
3292                                         isnull = false;
3293                                 }
3294
3295                                 return PointerGetDatum(xmlpi(xexpr->name, arg, isnull, isNull));
3296                         }
3297                         break;
3298
3299                 case IS_XMLROOT:
3300                         {
3301                                 ExprState  *e;
3302                                 xmltype    *data;
3303                                 text       *version;
3304                                 int                     standalone;
3305
3306                                 /* arguments are known to be xml, text, int */
3307                                 Assert(list_length(xmlExpr->args) == 3);
3308
3309                                 e = (ExprState *) linitial(xmlExpr->args);
3310                                 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3311                                 if (isnull)
3312                                         return (Datum) 0;
3313                                 data = DatumGetXmlP(value);
3314
3315                                 e = (ExprState *) lsecond(xmlExpr->args);
3316                                 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3317                                 if (isnull)
3318                                         version = NULL;
3319                                 else
3320                                         version = DatumGetTextP(value);
3321
3322                                 e = (ExprState *) lthird(xmlExpr->args);
3323                                 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3324                                 standalone = DatumGetInt32(value);
3325
3326                                 *isNull = false;
3327
3328                                 return PointerGetDatum(xmlroot(data,
3329                                                                                            version,
3330                                                                                            standalone));
3331                         }
3332                         break;
3333
3334                 case IS_XMLSERIALIZE:
3335                         {
3336                                 ExprState  *e;
3337
3338                                 /* argument type is known to be xml */
3339                                 Assert(list_length(xmlExpr->args) == 1);
3340
3341                                 e = (ExprState *) linitial(xmlExpr->args);
3342                                 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3343                                 if (isnull)
3344                                         return (Datum) 0;
3345
3346                                 *isNull = false;
3347
3348                                 return PointerGetDatum(xmltotext_with_xmloption(DatumGetXmlP(value), xexpr->xmloption));
3349                         }
3350                         break;
3351
3352                 case IS_DOCUMENT:
3353                         {
3354                                 ExprState  *e;
3355
3356                                 /* optional argument is known to be xml */
3357                                 Assert(list_length(xmlExpr->args) == 1);
3358
3359                                 e = (ExprState *) linitial(xmlExpr->args);
3360                                 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3361                                 if (isnull)
3362                                         return (Datum) 0;
3363                                 else
3364                                 {
3365                                         *isNull = false;
3366                                         return BoolGetDatum(xml_is_document(DatumGetXmlP(value)));
3367                                 }
3368                         }
3369                         break;
3370         }
3371
3372         elog(ERROR, "unrecognized XML operation");
3373         return (Datum) 0;
3374 }
3375
3376 /* ----------------------------------------------------------------
3377  *              ExecEvalNullIf
3378  *
3379  * Note that this is *always* derived from the equals operator,
3380  * but since we need special processing of the arguments
3381  * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
3382  * ----------------------------------------------------------------
3383  */
3384 static Datum
3385 ExecEvalNullIf(FuncExprState *nullIfExpr,
3386                            ExprContext *econtext,
3387                            bool *isNull, ExprDoneCond *isDone)
3388 {
3389         Datum           result;
3390         FunctionCallInfoData fcinfo;
3391         ExprDoneCond argDone;
3392         List       *argList;
3393
3394         if (isDone)
3395                 *isDone = ExprSingleResult;
3396
3397         /*
3398          * Initialize function cache if first time through
3399          */
3400         if (nullIfExpr->func.fn_oid == InvalidOid)
3401         {
3402                 NullIfExpr *op = (NullIfExpr *) nullIfExpr->xprstate.expr;
3403
3404                 init_fcache(op->opfuncid, nullIfExpr,
3405                                         econtext->ecxt_per_query_memory, true);
3406                 Assert(!nullIfExpr->func.fn_retset);
3407         }
3408
3409         /*
3410          * extract info from nullIfExpr
3411          */
3412         argList = nullIfExpr->args;
3413
3414         /* Need to prep callinfo structure */
3415         InitFunctionCallInfoData(fcinfo, &(nullIfExpr->func), 0, NULL, NULL);
3416         argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
3417         if (argDone != ExprSingleResult)
3418                 ereport(ERROR,
3419                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
3420                                  errmsg("NULLIF does not support set arguments")));
3421         Assert(fcinfo.nargs == 2);
3422
3423         /* if either argument is NULL they can't be equal */
3424         if (!fcinfo.argnull[0] && !fcinfo.argnull[1])
3425         {
3426                 fcinfo.isnull = false;
3427                 result = FunctionCallInvoke(&fcinfo);
3428                 /* if the arguments are equal return null */
3429                 if (!fcinfo.isnull && DatumGetBool(result))
3430                 {
3431                         *isNull = true;
3432                         return (Datum) 0;
3433                 }
3434         }
3435
3436         /* else return first argument */
3437         *isNull = fcinfo.argnull[0];
3438         return fcinfo.arg[0];
3439 }
3440
3441 /* ----------------------------------------------------------------
3442  *              ExecEvalNullTest
3443  *
3444  *              Evaluate a NullTest node.
3445  * ----------------------------------------------------------------
3446  */
3447 static Datum
3448 ExecEvalNullTest(NullTestState *nstate,
3449                                  ExprContext *econtext,
3450                                  bool *isNull,
3451                                  ExprDoneCond *isDone)
3452 {
3453         NullTest   *ntest = (NullTest *) nstate->xprstate.expr;
3454         Datum           result;
3455
3456         result = ExecEvalExpr(nstate->arg, econtext, isNull, isDone);
3457
3458         if (isDone && *isDone == ExprEndResult)
3459                 return result;                  /* nothing to check */
3460
3461         if (nstate->argisrow && !(*isNull))
3462         {
3463                 HeapTupleHeader tuple;
3464                 Oid                     tupType;
3465                 int32           tupTypmod;
3466                 TupleDesc       tupDesc;
3467                 HeapTupleData tmptup;
3468                 int                     att;
3469
3470                 tuple = DatumGetHeapTupleHeader(result);
3471
3472                 tupType = HeapTupleHeaderGetTypeId(tuple);
3473                 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3474
3475                 /* Lookup tupdesc if first time through or if type changes */
3476                 tupDesc = get_cached_rowtype(tupType, tupTypmod,
3477                                                                          &nstate->argdesc, econtext);
3478
3479                 /*
3480                  * heap_attisnull needs a HeapTuple not a bare HeapTupleHeader.
3481                  */
3482                 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3483                 tmptup.t_data = tuple;
3484
3485                 for (att = 1; att <= tupDesc->natts; att++)
3486                 {
3487                         /* ignore dropped columns */
3488                         if (tupDesc->attrs[att - 1]->attisdropped)
3489                                 continue;
3490                         if (heap_attisnull(&tmptup, att))
3491                         {
3492                                 /* null field disproves IS NOT NULL */
3493                                 if (ntest->nulltesttype == IS_NOT_NULL)
3494                                         return BoolGetDatum(false);
3495                         }
3496                         else
3497                         {
3498                                 /* non-null field disproves IS NULL */
3499                                 if (ntest->nulltesttype == IS_NULL)
3500                                         return BoolGetDatum(false);
3501                         }
3502                 }
3503
3504                 return BoolGetDatum(true);
3505         }
3506         else
3507         {
3508                 /* Simple scalar-argument case, or a null rowtype datum */
3509                 switch (ntest->nulltesttype)
3510                 {
3511                         case IS_NULL:
3512                                 if (*isNull)
3513                                 {
3514                                         *isNull = false;
3515                                         return BoolGetDatum(true);
3516                                 }
3517                                 else
3518                                         return BoolGetDatum(false);
3519                         case IS_NOT_NULL:
3520                                 if (*isNull)
3521                                 {
3522                                         *isNull = false;
3523                                         return BoolGetDatum(false);
3524                                 }
3525                                 else
3526                                         return BoolGetDatum(true);
3527                         default:
3528                                 elog(ERROR, "unrecognized nulltesttype: %d",
3529                                          (int) ntest->nulltesttype);
3530                                 return (Datum) 0;               /* keep compiler quiet */
3531                 }
3532         }
3533 }
3534
3535 /* ----------------------------------------------------------------
3536  *              ExecEvalBooleanTest
3537  *
3538  *              Evaluate a BooleanTest node.
3539  * ----------------------------------------------------------------
3540  */
3541 static Datum
3542 ExecEvalBooleanTest(GenericExprState *bstate,
3543                                         ExprContext *econtext,
3544                                         bool *isNull,
3545                                         ExprDoneCond *isDone)
3546 {
3547         BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;
3548         Datum           result;
3549
3550         result = ExecEvalExpr(bstate->arg, econtext, isNull, isDone);
3551
3552         if (isDone && *isDone == ExprEndResult)
3553                 return result;                  /* nothing to check */
3554
3555         switch (btest->booltesttype)
3556         {
3557                 case IS_TRUE:
3558                         if (*isNull)
3559                         {
3560                                 *isNull = false;
3561                                 return BoolGetDatum(false);
3562                         }
3563                         else if (DatumGetBool(result))
3564                                 return BoolGetDatum(true);
3565                         else
3566                                 return BoolGetDatum(false);
3567                 case IS_NOT_TRUE:
3568                         if (*isNull)
3569                         {
3570                                 *isNull = false;
3571                                 return BoolGetDatum(true);
3572                         }
3573                         else if (DatumGetBool(result))
3574                                 return BoolGetDatum(false);
3575                         else
3576                                 return BoolGetDatum(true);
3577                 case IS_FALSE:
3578                         if (*isNull)
3579                         {
3580                                 *isNull = false;
3581                                 return BoolGetDatum(false);
3582                         }
3583                         else if (DatumGetBool(result))
3584                                 return BoolGetDatum(false);
3585                         else
3586                                 return BoolGetDatum(true);
3587                 case IS_NOT_FALSE:
3588                         if (*isNull)
3589                         {
3590                                 *isNull = false;
3591                                 return BoolGetDatum(true);
3592                         }
3593                         else if (DatumGetBool(result))
3594                                 return BoolGetDatum(true);
3595                         else
3596                                 return BoolGetDatum(false);
3597                 case IS_UNKNOWN:
3598                         if (*isNull)
3599                         {
3600                                 *isNull = false;
3601                                 return BoolGetDatum(true);
3602                         }
3603                         else
3604                                 return BoolGetDatum(false);
3605                 case IS_NOT_UNKNOWN:
3606                         if (*isNull)
3607                         {
3608                                 *isNull = false;
3609                                 return BoolGetDatum(false);
3610                         }
3611                         else
3612                                 return BoolGetDatum(true);
3613                 default:
3614                         elog(ERROR, "unrecognized booltesttype: %d",
3615                                  (int) btest->booltesttype);
3616                         return (Datum) 0;       /* keep compiler quiet */
3617         }
3618 }
3619
3620 /*
3621  * ExecEvalCoerceToDomain
3622  *
3623  * Test the provided data against the domain constraint(s).  If the data
3624  * passes the constraint specifications, pass it through (return the
3625  * datum) otherwise throw an error.
3626  */
3627 static Datum
3628 ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
3629                                            bool *isNull, ExprDoneCond *isDone)
3630 {
3631         CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
3632         Datum           result;
3633         ListCell   *l;
3634
3635         result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
3636
3637         if (isDone && *isDone == ExprEndResult)
3638                 return result;                  /* nothing to check */
3639
3640         foreach(l, cstate->constraints)
3641         {
3642                 DomainConstraintState *con = (DomainConstraintState *) lfirst(l);
3643
3644                 switch (con->constrainttype)
3645                 {
3646                         case DOM_CONSTRAINT_NOTNULL:
3647                                 if (*isNull)
3648                                         ereport(ERROR,
3649                                                         (errcode(ERRCODE_NOT_NULL_VIOLATION),
3650                                                          errmsg("domain %s does not allow null values",
3651                                                                         format_type_be(ctest->resulttype))));
3652                                 break;
3653                         case DOM_CONSTRAINT_CHECK:
3654                                 {
3655                                         Datum           conResult;
3656                                         bool            conIsNull;
3657                                         Datum           save_datum;
3658                                         bool            save_isNull;
3659
3660                                         /*
3661                                          * Set up value to be returned by CoerceToDomainValue
3662                                          * nodes. We must save and restore prior setting of
3663                                          * econtext's domainValue fields, in case this node is
3664                                          * itself within a check expression for another domain.
3665                                          */
3666                                         save_datum = econtext->domainValue_datum;
3667                                         save_isNull = econtext->domainValue_isNull;
3668
3669                                         econtext->domainValue_datum = result;
3670                                         econtext->domainValue_isNull = *isNull;
3671
3672                                         conResult = ExecEvalExpr(con->check_expr,
3673                                                                                          econtext, &conIsNull, NULL);
3674
3675                                         if (!conIsNull &&
3676                                                 !DatumGetBool(conResult))
3677                                                 ereport(ERROR,
3678                                                                 (errcode(ERRCODE_CHECK_VIOLATION),
3679                                                                  errmsg("value for domain %s violates check constraint \"%s\"",
3680                                                                                 format_type_be(ctest->resulttype),
3681                                                                                 con->name)));
3682                                         econtext->domainValue_datum = save_datum;
3683                                         econtext->domainValue_isNull = save_isNull;
3684
3685                                         break;
3686                                 }
3687                         default:
3688                                 elog(ERROR, "unrecognized constraint type: %d",
3689                                          (int) con->constrainttype);
3690                                 break;
3691                 }
3692         }
3693
3694         /* If all has gone well (constraints did not fail) return the datum */
3695         return result;
3696 }
3697
3698 /*
3699  * ExecEvalCoerceToDomainValue
3700  *
3701  * Return the value stored by CoerceToDomain.
3702  */
3703 static Datum
3704 ExecEvalCoerceToDomainValue(ExprState *exprstate,
3705                                                         ExprContext *econtext,
3706                                                         bool *isNull, ExprDoneCond *isDone)
3707 {
3708         if (isDone)
3709                 *isDone = ExprSingleResult;
3710         *isNull = econtext->domainValue_isNull;
3711         return econtext->domainValue_datum;
3712 }
3713
3714 /* ----------------------------------------------------------------
3715  *              ExecEvalFieldSelect
3716  *
3717  *              Evaluate a FieldSelect node.
3718  * ----------------------------------------------------------------
3719  */
3720 static Datum
3721 ExecEvalFieldSelect(FieldSelectState *fstate,
3722                                         ExprContext *econtext,
3723                                         bool *isNull,
3724                                         ExprDoneCond *isDone)
3725 {
3726         FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
3727         AttrNumber      fieldnum = fselect->fieldnum;
3728         Datum           result;
3729         Datum           tupDatum;
3730         HeapTupleHeader tuple;
3731         Oid                     tupType;
3732         int32           tupTypmod;
3733         TupleDesc       tupDesc;
3734         Form_pg_attribute attr;
3735         HeapTupleData tmptup;
3736
3737         tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
3738
3739         /* this test covers the isDone exception too: */
3740         if (*isNull)
3741                 return tupDatum;
3742
3743         tuple = DatumGetHeapTupleHeader(tupDatum);
3744
3745         tupType = HeapTupleHeaderGetTypeId(tuple);
3746         tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3747
3748         /* Lookup tupdesc if first time through or if type changes */
3749         tupDesc = get_cached_rowtype(tupType, tupTypmod,
3750                                                                  &fstate->argdesc, econtext);
3751
3752         /* Check for dropped column, and force a NULL result if so */
3753         if (fieldnum <= 0 ||
3754                 fieldnum > tupDesc->natts)              /* should never happen */
3755                 elog(ERROR, "attribute number %d exceeds number of columns %d",
3756                          fieldnum, tupDesc->natts);
3757         attr = tupDesc->attrs[fieldnum - 1];
3758         if (attr->attisdropped)
3759         {
3760                 *isNull = true;
3761                 return (Datum) 0;
3762         }
3763
3764         /* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
3765         /* As in ExecEvalVar, we should but can't check typmod */
3766         if (fselect->resulttype != attr->atttypid)
3767                 ereport(ERROR,
3768                                 (errmsg("attribute %d has wrong type", fieldnum),
3769                                  errdetail("Table has type %s, but query expects %s.",
3770                                                    format_type_be(attr->atttypid),
3771                                                    format_type_be(fselect->resulttype))));
3772
3773         /*
3774          * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set all
3775          * the fields in the struct just in case user tries to inspect system
3776          * columns.
3777          */
3778         tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3779         ItemPointerSetInvalid(&(tmptup.t_self));
3780         tmptup.t_tableOid = InvalidOid;
3781         tmptup.t_data = tuple;
3782
3783         result = heap_getattr(&tmptup,
3784                                                   fieldnum,
3785                                                   tupDesc,
3786                                                   isNull);
3787         return result;
3788 }
3789
3790 /* ----------------------------------------------------------------
3791  *              ExecEvalFieldStore
3792  *
3793  *              Evaluate a FieldStore node.
3794  * ----------------------------------------------------------------
3795  */
3796 static Datum
3797 ExecEvalFieldStore(FieldStoreState *fstate,
3798                                    ExprContext *econtext,
3799                                    bool *isNull,
3800                                    ExprDoneCond *isDone)
3801 {
3802         FieldStore *fstore = (FieldStore *) fstate->xprstate.expr;
3803         HeapTuple       tuple;
3804         Datum           tupDatum;
3805         TupleDesc       tupDesc;
3806         Datum      *values;
3807         bool       *isnull;
3808         Datum           save_datum;
3809         bool            save_isNull;
3810         ListCell   *l1,
3811                            *l2;
3812
3813         tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
3814
3815         if (isDone && *isDone == ExprEndResult)
3816                 return tupDatum;
3817
3818         /* Lookup tupdesc if first time through or after rescan */
3819         tupDesc = get_cached_rowtype(fstore->resulttype, -1,
3820                                                                  &fstate->argdesc, econtext);
3821
3822         /* Allocate workspace */
3823         values = (Datum *) palloc(tupDesc->natts * sizeof(Datum));
3824         isnull = (bool *) palloc(tupDesc->natts * sizeof(bool));
3825
3826         if (!*isNull)
3827         {
3828                 /*
3829                  * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader. We
3830                  * set all the fields in the struct just in case.
3831                  */
3832                 HeapTupleHeader tuphdr;
3833                 HeapTupleData tmptup;
3834
3835                 tuphdr = DatumGetHeapTupleHeader(tupDatum);
3836                 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuphdr);
3837                 ItemPointerSetInvalid(&(tmptup.t_self));
3838                 tmptup.t_tableOid = InvalidOid;
3839                 tmptup.t_data = tuphdr;
3840
3841                 heap_deform_tuple(&tmptup, tupDesc, values, isnull);
3842         }
3843         else
3844         {
3845                 /* Convert null input tuple into an all-nulls row */
3846                 memset(isnull, true, tupDesc->natts * sizeof(bool));
3847         }
3848
3849         /* Result is never null */
3850         *isNull = false;
3851
3852         save_datum = econtext->caseValue_datum;
3853         save_isNull = econtext->caseValue_isNull;
3854
3855         forboth(l1, fstate->newvals, l2, fstore->fieldnums)
3856         {
3857                 ExprState  *newval = (ExprState *) lfirst(l1);
3858                 AttrNumber      fieldnum = lfirst_int(l2);
3859
3860                 Assert(fieldnum > 0 && fieldnum <= tupDesc->natts);
3861
3862                 /*
3863                  * Use the CaseTestExpr mechanism to pass down the old value of the
3864                  * field being replaced; this is useful in case we have a nested field
3865                  * update situation.  It's safe to reuse the CASE mechanism because
3866                  * there cannot be a CASE between here and where the value would be
3867                  * needed.
3868                  */
3869                 econtext->caseValue_datum = values[fieldnum - 1];
3870                 econtext->caseValue_isNull = isnull[fieldnum - 1];
3871
3872                 values[fieldnum - 1] = ExecEvalExpr(newval,
3873                                                                                         econtext,
3874                                                                                         &isnull[fieldnum - 1],
3875                                                                                         NULL);
3876         }
3877
3878         econtext->caseValue_datum = save_datum;
3879         econtext->caseValue_isNull = save_isNull;
3880
3881         tuple = heap_form_tuple(tupDesc, values, isnull);
3882
3883         pfree(values);
3884         pfree(isnull);
3885
3886         return HeapTupleGetDatum(tuple);
3887 }
3888
3889 /* ----------------------------------------------------------------
3890  *              ExecEvalRelabelType
3891  *
3892  *              Evaluate a RelabelType node.
3893  * ----------------------------------------------------------------
3894  */
3895 static Datum
3896 ExecEvalRelabelType(GenericExprState *exprstate,
3897                                         ExprContext *econtext,
3898                                         bool *isNull, ExprDoneCond *isDone)
3899 {
3900         return ExecEvalExpr(exprstate->arg, econtext, isNull, isDone);
3901 }
3902
3903 /* ----------------------------------------------------------------
3904  *              ExecEvalCoerceViaIO
3905  *
3906  *              Evaluate a CoerceViaIO node.
3907  * ----------------------------------------------------------------
3908  */
3909 static Datum
3910 ExecEvalCoerceViaIO(CoerceViaIOState *iostate,
3911                                         ExprContext *econtext,
3912                                         bool *isNull, ExprDoneCond *isDone)
3913 {
3914         Datum           result;
3915         Datum           inputval;
3916         char       *string;
3917
3918         inputval = ExecEvalExpr(iostate->arg, econtext, isNull, isDone);
3919
3920         if (isDone && *isDone == ExprEndResult)
3921                 return inputval;                /* nothing to do */
3922
3923         if (*isNull)
3924                 string = NULL;                  /* output functions are not called on nulls */
3925         else
3926                 string = OutputFunctionCall(&iostate->outfunc, inputval);
3927
3928         result = InputFunctionCall(&iostate->infunc,
3929                                                            string,
3930                                                            iostate->intypioparam,
3931                                                            -1);
3932
3933         /* The input function cannot change the null/not-null status */
3934         return result;
3935 }
3936
3937 /* ----------------------------------------------------------------
3938  *              ExecEvalArrayCoerceExpr
3939  *
3940  *              Evaluate an ArrayCoerceExpr node.
3941  * ----------------------------------------------------------------
3942  */
3943 static Datum
3944 ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
3945                                                 ExprContext *econtext,
3946                                                 bool *isNull, ExprDoneCond *isDone)
3947 {
3948         ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) astate->xprstate.expr;
3949         Datum           result;
3950         ArrayType  *array;
3951         FunctionCallInfoData locfcinfo;
3952
3953         result = ExecEvalExpr(astate->arg, econtext, isNull, isDone);
3954
3955         if (isDone && *isDone == ExprEndResult)
3956                 return result;                  /* nothing to do */
3957         if (*isNull)
3958                 return result;                  /* nothing to do */
3959
3960         /*
3961          * If it's binary-compatible, modify the element type in the array header,
3962          * but otherwise leave the array as we received it.
3963          */
3964         if (!OidIsValid(acoerce->elemfuncid))
3965         {
3966                 /* Detoast input array if necessary, and copy in any case */
3967                 array = DatumGetArrayTypePCopy(result);
3968                 ARR_ELEMTYPE(array) = astate->resultelemtype;
3969                 PG_RETURN_ARRAYTYPE_P(array);
3970         }
3971
3972         /* Detoast input array if necessary, but don't make a useless copy */
3973         array = DatumGetArrayTypeP(result);
3974
3975         /* Initialize function cache if first time through */
3976         if (astate->elemfunc.fn_oid == InvalidOid)
3977         {
3978                 AclResult       aclresult;
3979
3980                 /* Check permission to call function */
3981                 aclresult = pg_proc_aclcheck(acoerce->elemfuncid, GetUserId(),
3982                                                                          ACL_EXECUTE);
3983                 if (aclresult != ACLCHECK_OK)
3984                         aclcheck_error(aclresult, ACL_KIND_PROC,
3985                                                    get_func_name(acoerce->elemfuncid));
3986
3987                 /* Set up the primary fmgr lookup information */
3988                 fmgr_info_cxt(acoerce->elemfuncid, &(astate->elemfunc),
3989                                           econtext->ecxt_per_query_memory);
3990
3991                 /* Initialize additional info */
3992                 astate->elemfunc.fn_expr = (Node *) acoerce;
3993         }
3994
3995         /*
3996          * Use array_map to apply the function to each array element.
3997          *
3998          * We pass on the desttypmod and isExplicit flags whether or not the
3999          * function wants them.
4000          */
4001         InitFunctionCallInfoData(locfcinfo, &(astate->elemfunc), 3,
4002                                                          NULL, NULL);
4003         locfcinfo.arg[0] = PointerGetDatum(array);
4004         locfcinfo.arg[1] = Int32GetDatum(acoerce->resulttypmod);
4005         locfcinfo.arg[2] = BoolGetDatum(acoerce->isExplicit);
4006         locfcinfo.argnull[0] = false;
4007         locfcinfo.argnull[1] = false;
4008         locfcinfo.argnull[2] = false;
4009
4010         return array_map(&locfcinfo, ARR_ELEMTYPE(array), astate->resultelemtype,
4011                                          astate->amstate);
4012 }
4013
4014 /* ----------------------------------------------------------------
4015  *              ExecEvalCurrentOfExpr
4016  *
4017  * The planner must convert CURRENT OF into a TidScan qualification.
4018  * So, we have to be able to do ExecInitExpr on a CurrentOfExpr,
4019  * but we shouldn't ever actually execute it.
4020  * ----------------------------------------------------------------
4021  */
4022 static Datum
4023 ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
4024                                           bool *isNull, ExprDoneCond *isDone)
4025 {
4026         elog(ERROR, "CURRENT OF cannot be executed");
4027         return 0;                                       /* keep compiler quiet */
4028 }
4029
4030
4031 /*
4032  * ExecEvalExprSwitchContext
4033  *
4034  * Same as ExecEvalExpr, but get into the right allocation context explicitly.
4035  */
4036 Datum
4037 ExecEvalExprSwitchContext(ExprState *expression,
4038                                                   ExprContext *econtext,
4039                                                   bool *isNull,
4040                                                   ExprDoneCond *isDone)
4041 {
4042         Datum           retDatum;
4043         MemoryContext oldContext;
4044
4045         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
4046         retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
4047         MemoryContextSwitchTo(oldContext);
4048         return retDatum;
4049 }
4050
4051
4052 /*
4053  * ExecInitExpr: prepare an expression tree for execution
4054  *
4055  * This function builds and returns an ExprState tree paralleling the given
4056  * Expr node tree.      The ExprState tree can then be handed to ExecEvalExpr
4057  * for execution.  Because the Expr tree itself is read-only as far as
4058  * ExecInitExpr and ExecEvalExpr are concerned, several different executions
4059  * of the same plan tree can occur concurrently.
4060  *
4061  * This must be called in a memory context that will last as long as repeated
4062  * executions of the expression are needed.  Typically the context will be
4063  * the same as the per-query context of the associated ExprContext.
4064  *
4065  * Any Aggref and SubPlan nodes found in the tree are added to the lists
4066  * of such nodes held by the parent PlanState.  Otherwise, we do very little
4067  * initialization here other than building the state-node tree.  Any nontrivial
4068  * work associated with initializing runtime info for a node should happen
4069  * during the first actual evaluation of that node.  (This policy lets us
4070  * avoid work if the node is never actually evaluated.)
4071  *
4072  * Note: there is no ExecEndExpr function; we assume that any resource
4073  * cleanup needed will be handled by just releasing the memory context
4074  * in which the state tree is built.  Functions that require additional
4075  * cleanup work can register a shutdown callback in the ExprContext.
4076  *
4077  *      'node' is the root of the expression tree to examine
4078  *      'parent' is the PlanState node that owns the expression.
4079  *
4080  * 'parent' may be NULL if we are preparing an expression that is not
4081  * associated with a plan tree.  (If so, it can't have aggs or subplans.)
4082  * This case should usually come through ExecPrepareExpr, not directly here.
4083  */
4084 ExprState *
4085 ExecInitExpr(Expr *node, PlanState *parent)
4086 {
4087         ExprState  *state;
4088
4089         if (node == NULL)
4090                 return NULL;
4091
4092         /* Guard against stack overflow due to overly complex expressions */
4093         check_stack_depth();
4094
4095         switch (nodeTag(node))
4096         {
4097                 case T_Var:
4098                         state = (ExprState *) makeNode(ExprState);
4099                         state->evalfunc = ExecEvalVar;
4100                         break;
4101                 case T_Const:
4102                         state = (ExprState *) makeNode(ExprState);
4103                         state->evalfunc = ExecEvalConst;
4104                         break;
4105                 case T_Param:
4106                         state = (ExprState *) makeNode(ExprState);
4107                         state->evalfunc = ExecEvalParam;
4108                         break;
4109                 case T_CoerceToDomainValue:
4110                         state = (ExprState *) makeNode(ExprState);
4111                         state->evalfunc = ExecEvalCoerceToDomainValue;
4112                         break;
4113                 case T_CaseTestExpr:
4114                         state = (ExprState *) makeNode(ExprState);
4115                         state->evalfunc = ExecEvalCaseTestExpr;
4116                         break;
4117                 case T_Aggref:
4118                         {
4119                                 Aggref     *aggref = (Aggref *) node;
4120                                 AggrefExprState *astate = makeNode(AggrefExprState);
4121
4122                                 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAggref;
4123                                 if (parent && IsA(parent, AggState))
4124                                 {
4125                                         AggState   *aggstate = (AggState *) parent;
4126                                         int                     naggs;
4127
4128                                         aggstate->aggs = lcons(astate, aggstate->aggs);
4129                                         naggs = ++aggstate->numaggs;
4130
4131                                         astate->args = (List *) ExecInitExpr((Expr *) aggref->args,
4132                                                                                                                  parent);
4133
4134                                         /*
4135                                          * Complain if the aggregate's arguments contain any
4136                                          * aggregates; nested agg functions are semantically
4137                                          * nonsensical.  (This should have been caught earlier,
4138                                          * but we defend against it here anyway.)
4139                                          */
4140                                         if (naggs != aggstate->numaggs)
4141                                                 ereport(ERROR,
4142                                                                 (errcode(ERRCODE_GROUPING_ERROR),
4143                                                 errmsg("aggregate function calls cannot be nested")));
4144                                 }
4145                                 else
4146                                 {
4147                                         /* planner messed up */
4148                                         elog(ERROR, "aggref found in non-Agg plan node");
4149                                 }
4150                                 state = (ExprState *) astate;
4151                         }
4152                         break;
4153                 case T_ArrayRef:
4154                         {
4155                                 ArrayRef   *aref = (ArrayRef *) node;
4156                                 ArrayRefExprState *astate = makeNode(ArrayRefExprState);
4157
4158                                 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayRef;
4159                                 astate->refupperindexpr = (List *)
4160                                         ExecInitExpr((Expr *) aref->refupperindexpr, parent);
4161                                 astate->reflowerindexpr = (List *)
4162                                         ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
4163                                 astate->refexpr = ExecInitExpr(aref->refexpr, parent);
4164                                 astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
4165                                                                                                         parent);
4166                                 /* do one-time catalog lookups for type info */
4167                                 astate->refattrlength = get_typlen(aref->refarraytype);
4168                                 get_typlenbyvalalign(aref->refelemtype,
4169                                                                          &astate->refelemlength,
4170                                                                          &astate->refelembyval,
4171                                                                          &astate->refelemalign);
4172                                 state = (ExprState *) astate;
4173                         }
4174                         break;
4175                 case T_FuncExpr:
4176                         {
4177                                 FuncExpr   *funcexpr = (FuncExpr *) node;
4178                                 FuncExprState *fstate = makeNode(FuncExprState);
4179
4180                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFunc;
4181                                 fstate->args = (List *)
4182                                         ExecInitExpr((Expr *) funcexpr->args, parent);
4183                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
4184                                 state = (ExprState *) fstate;
4185                         }
4186                         break;
4187                 case T_OpExpr:
4188                         {
4189                                 OpExpr     *opexpr = (OpExpr *) node;
4190                                 FuncExprState *fstate = makeNode(FuncExprState);
4191
4192                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOper;
4193                                 fstate->args = (List *)
4194                                         ExecInitExpr((Expr *) opexpr->args, parent);
4195                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
4196                                 state = (ExprState *) fstate;
4197                         }
4198                         break;
4199                 case T_DistinctExpr:
4200                         {
4201                                 DistinctExpr *distinctexpr = (DistinctExpr *) node;
4202                                 FuncExprState *fstate = makeNode(FuncExprState);
4203
4204                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalDistinct;
4205                                 fstate->args = (List *)
4206                                         ExecInitExpr((Expr *) distinctexpr->args, parent);
4207                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
4208                                 state = (ExprState *) fstate;
4209                         }
4210                         break;
4211                 case T_ScalarArrayOpExpr:
4212                         {
4213                                 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
4214                                 ScalarArrayOpExprState *sstate = makeNode(ScalarArrayOpExprState);
4215
4216                                 sstate->fxprstate.xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalScalarArrayOp;
4217                                 sstate->fxprstate.args = (List *)
4218                                         ExecInitExpr((Expr *) opexpr->args, parent);
4219                                 sstate->fxprstate.func.fn_oid = InvalidOid;             /* not initialized */
4220                                 sstate->element_type = InvalidOid;              /* ditto */
4221                                 state = (ExprState *) sstate;
4222                         }
4223                         break;
4224                 case T_BoolExpr:
4225                         {
4226                                 BoolExpr   *boolexpr = (BoolExpr *) node;
4227                                 BoolExprState *bstate = makeNode(BoolExprState);
4228
4229                                 switch (boolexpr->boolop)
4230                                 {
4231                                         case AND_EXPR:
4232                                                 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAnd;
4233                                                 break;
4234                                         case OR_EXPR:
4235                                                 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOr;
4236                                                 break;
4237                                         case NOT_EXPR:
4238                                                 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNot;
4239                                                 break;
4240                                         default:
4241                                                 elog(ERROR, "unrecognized boolop: %d",
4242                                                          (int) boolexpr->boolop);
4243                                                 break;
4244                                 }
4245                                 bstate->args = (List *)
4246                                         ExecInitExpr((Expr *) boolexpr->args, parent);
4247                                 state = (ExprState *) bstate;
4248                         }
4249                         break;
4250                 case T_SubPlan:
4251                         {
4252                                 SubPlan    *subplan = (SubPlan *) node;
4253                                 SubPlanState *sstate;
4254
4255                                 if (!parent)
4256                                         elog(ERROR, "SubPlan found with no parent plan");
4257
4258                                 sstate = ExecInitSubPlan(subplan, parent);
4259
4260                                 /* Add SubPlanState nodes to parent->subPlan */
4261                                 parent->subPlan = lcons(sstate, parent->subPlan);
4262
4263                                 state = (ExprState *) sstate;
4264                         }
4265                         break;
4266                 case T_AlternativeSubPlan:
4267                         {
4268                                 AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
4269                                 AlternativeSubPlanState *asstate;
4270
4271                                 if (!parent)
4272                                         elog(ERROR, "AlternativeSubPlan found with no parent plan");
4273
4274                                 asstate = ExecInitAlternativeSubPlan(asplan, parent);
4275
4276                                 state = (ExprState *) asstate;
4277                         }
4278                         break;
4279                 case T_FieldSelect:
4280                         {
4281                                 FieldSelect *fselect = (FieldSelect *) node;
4282                                 FieldSelectState *fstate = makeNode(FieldSelectState);
4283
4284                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldSelect;
4285                                 fstate->arg = ExecInitExpr(fselect->arg, parent);
4286                                 fstate->argdesc = NULL;
4287                                 state = (ExprState *) fstate;
4288                         }
4289                         break;
4290                 case T_FieldStore:
4291                         {
4292                                 FieldStore *fstore = (FieldStore *) node;
4293                                 FieldStoreState *fstate = makeNode(FieldStoreState);
4294
4295                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldStore;
4296                                 fstate->arg = ExecInitExpr(fstore->arg, parent);
4297                                 fstate->newvals = (List *) ExecInitExpr((Expr *) fstore->newvals, parent);
4298                                 fstate->argdesc = NULL;
4299                                 state = (ExprState *) fstate;
4300                         }
4301                         break;
4302                 case T_RelabelType:
4303                         {
4304                                 RelabelType *relabel = (RelabelType *) node;
4305                                 GenericExprState *gstate = makeNode(GenericExprState);
4306
4307                                 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRelabelType;
4308                                 gstate->arg = ExecInitExpr(relabel->arg, parent);
4309                                 state = (ExprState *) gstate;
4310                         }
4311                         break;
4312                 case T_CoerceViaIO:
4313                         {
4314                                 CoerceViaIO *iocoerce = (CoerceViaIO *) node;
4315                                 CoerceViaIOState *iostate = makeNode(CoerceViaIOState);
4316                                 Oid                     iofunc;
4317                                 bool            typisvarlena;
4318
4319                                 iostate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceViaIO;
4320                                 iostate->arg = ExecInitExpr(iocoerce->arg, parent);
4321                                 /* lookup the result type's input function */
4322                                 getTypeInputInfo(iocoerce->resulttype, &iofunc,
4323                                                                  &iostate->intypioparam);
4324                                 fmgr_info(iofunc, &iostate->infunc);
4325                                 /* lookup the input type's output function */
4326                                 getTypeOutputInfo(exprType((Node *) iocoerce->arg),
4327                                                                   &iofunc, &typisvarlena);
4328                                 fmgr_info(iofunc, &iostate->outfunc);
4329                                 state = (ExprState *) iostate;
4330                         }
4331                         break;
4332                 case T_ArrayCoerceExpr:
4333                         {
4334                                 ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
4335                                 ArrayCoerceExprState *astate = makeNode(ArrayCoerceExprState);
4336
4337                                 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayCoerceExpr;
4338                                 astate->arg = ExecInitExpr(acoerce->arg, parent);
4339                                 astate->resultelemtype = get_element_type(acoerce->resulttype);
4340                                 if (astate->resultelemtype == InvalidOid)
4341                                         ereport(ERROR,
4342                                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4343                                                          errmsg("target type is not an array")));
4344                                 /* Arrays over domains aren't supported yet */
4345                                 Assert(getBaseType(astate->resultelemtype) ==
4346                                            astate->resultelemtype);
4347                                 astate->elemfunc.fn_oid = InvalidOid;   /* not initialized */
4348                                 astate->amstate = (ArrayMapState *) palloc0(sizeof(ArrayMapState));
4349                                 state = (ExprState *) astate;
4350                         }
4351                         break;
4352                 case T_ConvertRowtypeExpr:
4353                         {
4354                                 ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) node;
4355                                 ConvertRowtypeExprState *cstate = makeNode(ConvertRowtypeExprState);
4356
4357                                 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalConvertRowtype;
4358                                 cstate->arg = ExecInitExpr(convert->arg, parent);
4359                                 state = (ExprState *) cstate;
4360                         }
4361                         break;
4362                 case T_CaseExpr:
4363                         {
4364                                 CaseExpr   *caseexpr = (CaseExpr *) node;
4365                                 CaseExprState *cstate = makeNode(CaseExprState);
4366                                 List       *outlist = NIL;
4367                                 ListCell   *l;
4368
4369                                 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCase;
4370                                 cstate->arg = ExecInitExpr(caseexpr->arg, parent);
4371                                 foreach(l, caseexpr->args)
4372                                 {
4373                                         CaseWhen   *when = (CaseWhen *) lfirst(l);
4374                                         CaseWhenState *wstate = makeNode(CaseWhenState);
4375
4376                                         Assert(IsA(when, CaseWhen));
4377                                         wstate->xprstate.evalfunc = NULL;       /* not used */
4378                                         wstate->xprstate.expr = (Expr *) when;
4379                                         wstate->expr = ExecInitExpr(when->expr, parent);
4380                                         wstate->result = ExecInitExpr(when->result, parent);
4381                                         outlist = lappend(outlist, wstate);
4382                                 }
4383                                 cstate->args = outlist;
4384                                 cstate->defresult = ExecInitExpr(caseexpr->defresult, parent);
4385                                 state = (ExprState *) cstate;
4386                         }
4387                         break;
4388                 case T_ArrayExpr:
4389                         {
4390                                 ArrayExpr  *arrayexpr = (ArrayExpr *) node;
4391                                 ArrayExprState *astate = makeNode(ArrayExprState);
4392                                 List       *outlist = NIL;
4393                                 ListCell   *l;
4394
4395                                 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArray;
4396                                 foreach(l, arrayexpr->elements)
4397                                 {
4398                                         Expr       *e = (Expr *) lfirst(l);
4399                                         ExprState  *estate;
4400
4401                                         estate = ExecInitExpr(e, parent);
4402                                         outlist = lappend(outlist, estate);
4403                                 }
4404                                 astate->elements = outlist;
4405                                 /* do one-time catalog lookup for type info */
4406                                 get_typlenbyvalalign(arrayexpr->element_typeid,
4407                                                                          &astate->elemlength,
4408                                                                          &astate->elembyval,
4409                                                                          &astate->elemalign);
4410                                 state = (ExprState *) astate;
4411                         }
4412                         break;
4413                 case T_RowExpr:
4414                         {
4415                                 RowExpr    *rowexpr = (RowExpr *) node;
4416                                 RowExprState *rstate = makeNode(RowExprState);
4417                                 Form_pg_attribute *attrs;
4418                                 List       *outlist = NIL;
4419                                 ListCell   *l;
4420                                 int                     i;
4421
4422                                 rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRow;
4423                                 /* Build tupdesc to describe result tuples */
4424                                 if (rowexpr->row_typeid == RECORDOID)
4425                                 {
4426                                         /* generic record, use runtime type assignment */
4427                                         rstate->tupdesc = ExecTypeFromExprList(rowexpr->args);
4428                                         BlessTupleDesc(rstate->tupdesc);
4429                                         /* we won't need to redo this at runtime */
4430                                 }
4431                                 else
4432                                 {
4433                                         /* it's been cast to a named type, use that */
4434                                         rstate->tupdesc = lookup_rowtype_tupdesc_copy(rowexpr->row_typeid, -1);
4435                                 }
4436                                 /* Set up evaluation, skipping any deleted columns */
4437                                 Assert(list_length(rowexpr->args) <= rstate->tupdesc->natts);
4438                                 attrs = rstate->tupdesc->attrs;
4439                                 i = 0;
4440                                 foreach(l, rowexpr->args)
4441                                 {
4442                                         Expr       *e = (Expr *) lfirst(l);
4443                                         ExprState  *estate;
4444
4445                                         if (!attrs[i]->attisdropped)
4446                                         {
4447                                                 /*
4448                                                  * Guard against ALTER COLUMN TYPE on rowtype since
4449                                                  * the RowExpr was created.  XXX should we check
4450                                                  * typmod too?  Not sure we can be sure it'll be the
4451                                                  * same.
4452                                                  */
4453                                                 if (exprType((Node *) e) != attrs[i]->atttypid)
4454                                                         ereport(ERROR,
4455                                                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
4456                                                                          errmsg("ROW() column has type %s instead of type %s",
4457                                                                                 format_type_be(exprType((Node *) e)),
4458                                                                            format_type_be(attrs[i]->atttypid))));
4459                                         }
4460                                         else
4461                                         {
4462                                                 /*
4463                                                  * Ignore original expression and insert a NULL. We
4464                                                  * don't really care what type of NULL it is, so
4465                                                  * always make an int4 NULL.
4466                                                  */
4467                                                 e = (Expr *) makeNullConst(INT4OID, -1);
4468                                         }
4469                                         estate = ExecInitExpr(e, parent);
4470                                         outlist = lappend(outlist, estate);
4471                                         i++;
4472                                 }
4473                                 rstate->args = outlist;
4474                                 state = (ExprState *) rstate;
4475                         }
4476                         break;
4477                 case T_RowCompareExpr:
4478                         {
4479                                 RowCompareExpr *rcexpr = (RowCompareExpr *) node;
4480                                 RowCompareExprState *rstate = makeNode(RowCompareExprState);
4481                                 int                     nopers = list_length(rcexpr->opnos);
4482                                 List       *outlist;
4483                                 ListCell   *l;
4484                                 ListCell   *l2;
4485                                 int                     i;
4486
4487                                 rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRowCompare;
4488                                 Assert(list_length(rcexpr->largs) == nopers);
4489                                 outlist = NIL;
4490                                 foreach(l, rcexpr->largs)
4491                                 {
4492                                         Expr       *e = (Expr *) lfirst(l);
4493                                         ExprState  *estate;
4494
4495                                         estate = ExecInitExpr(e, parent);
4496                                         outlist = lappend(outlist, estate);
4497                                 }
4498                                 rstate->largs = outlist;
4499                                 Assert(list_length(rcexpr->rargs) == nopers);
4500                                 outlist = NIL;
4501                                 foreach(l, rcexpr->rargs)
4502                                 {
4503                                         Expr       *e = (Expr *) lfirst(l);
4504                                         ExprState  *estate;
4505
4506                                         estate = ExecInitExpr(e, parent);
4507                                         outlist = lappend(outlist, estate);
4508                                 }
4509                                 rstate->rargs = outlist;
4510                                 Assert(list_length(rcexpr->opfamilies) == nopers);
4511                                 rstate->funcs = (FmgrInfo *) palloc(nopers * sizeof(FmgrInfo));
4512                                 i = 0;
4513                                 forboth(l, rcexpr->opnos, l2, rcexpr->opfamilies)
4514                                 {
4515                                         Oid                     opno = lfirst_oid(l);
4516                                         Oid                     opfamily = lfirst_oid(l2);
4517                                         int                     strategy;
4518                                         Oid                     lefttype;
4519                                         Oid                     righttype;
4520                                         Oid                     proc;
4521
4522                                         get_op_opfamily_properties(opno, opfamily,
4523                                                                                            &strategy,
4524                                                                                            &lefttype,
4525                                                                                            &righttype);
4526                                         proc = get_opfamily_proc(opfamily,
4527                                                                                          lefttype,
4528                                                                                          righttype,
4529                                                                                          BTORDER_PROC);
4530
4531                                         /*
4532                                          * If we enforced permissions checks on index support
4533                                          * functions, we'd need to make a check here.  But the
4534                                          * index support machinery doesn't do that, and neither
4535                                          * does this code.
4536                                          */
4537                                         fmgr_info(proc, &(rstate->funcs[i]));
4538                                         i++;
4539                                 }
4540                                 state = (ExprState *) rstate;
4541                         }
4542                         break;
4543                 case T_CoalesceExpr:
4544                         {
4545                                 CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
4546                                 CoalesceExprState *cstate = makeNode(CoalesceExprState);
4547                                 List       *outlist = NIL;
4548                                 ListCell   *l;
4549
4550                                 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoalesce;
4551                                 foreach(l, coalesceexpr->args)
4552                                 {
4553                                         Expr       *e = (Expr *) lfirst(l);
4554                                         ExprState  *estate;
4555
4556                                         estate = ExecInitExpr(e, parent);
4557                                         outlist = lappend(outlist, estate);
4558                                 }
4559                                 cstate->args = outlist;
4560                                 state = (ExprState *) cstate;
4561                         }
4562                         break;
4563                 case T_MinMaxExpr:
4564                         {
4565                                 MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
4566                                 MinMaxExprState *mstate = makeNode(MinMaxExprState);
4567                                 List       *outlist = NIL;
4568                                 ListCell   *l;
4569                                 TypeCacheEntry *typentry;
4570
4571                                 mstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalMinMax;
4572                                 foreach(l, minmaxexpr->args)
4573                                 {
4574                                         Expr       *e = (Expr *) lfirst(l);
4575                                         ExprState  *estate;
4576
4577                                         estate = ExecInitExpr(e, parent);
4578                                         outlist = lappend(outlist, estate);
4579                                 }
4580                                 mstate->args = outlist;
4581                                 /* Look up the btree comparison function for the datatype */
4582                                 typentry = lookup_type_cache(minmaxexpr->minmaxtype,
4583                                                                                          TYPECACHE_CMP_PROC);
4584                                 if (!OidIsValid(typentry->cmp_proc))
4585                                         ereport(ERROR,
4586                                                         (errcode(ERRCODE_UNDEFINED_FUNCTION),
4587                                                          errmsg("could not identify a comparison function for type %s",
4588                                                                         format_type_be(minmaxexpr->minmaxtype))));
4589
4590                                 /*
4591                                  * If we enforced permissions checks on index support
4592                                  * functions, we'd need to make a check here.  But the index
4593                                  * support machinery doesn't do that, and neither does this
4594                                  * code.
4595                                  */
4596                                 fmgr_info(typentry->cmp_proc, &(mstate->cfunc));
4597                                 state = (ExprState *) mstate;
4598                         }
4599                         break;
4600                 case T_XmlExpr:
4601                         {
4602                                 XmlExpr    *xexpr = (XmlExpr *) node;
4603                                 XmlExprState *xstate = makeNode(XmlExprState);
4604                                 List       *outlist;
4605                                 ListCell   *arg;
4606                                 int                     i;
4607
4608                                 xstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalXml;
4609                                 xstate->named_outfuncs = (FmgrInfo *)
4610                                         palloc0(list_length(xexpr->named_args) * sizeof(FmgrInfo));
4611                                 outlist = NIL;
4612                                 i = 0;
4613                                 foreach(arg, xexpr->named_args)
4614                                 {
4615                                         Expr       *e = (Expr *) lfirst(arg);
4616                                         ExprState  *estate;
4617                                         Oid                     typOutFunc;
4618                                         bool            typIsVarlena;
4619
4620                                         estate = ExecInitExpr(e, parent);
4621                                         outlist = lappend(outlist, estate);
4622
4623                                         getTypeOutputInfo(exprType((Node *) e),
4624                                                                           &typOutFunc, &typIsVarlena);
4625                                         fmgr_info(typOutFunc, &xstate->named_outfuncs[i]);
4626                                         i++;
4627                                 }
4628                                 xstate->named_args = outlist;
4629
4630                                 outlist = NIL;
4631                                 foreach(arg, xexpr->args)
4632                                 {
4633                                         Expr       *e = (Expr *) lfirst(arg);
4634                                         ExprState  *estate;
4635
4636                                         estate = ExecInitExpr(e, parent);
4637                                         outlist = lappend(outlist, estate);
4638                                 }
4639                                 xstate->args = outlist;
4640
4641                                 state = (ExprState *) xstate;
4642                         }
4643                         break;
4644                 case T_NullIfExpr:
4645                         {
4646                                 NullIfExpr *nullifexpr = (NullIfExpr *) node;
4647                                 FuncExprState *fstate = makeNode(FuncExprState);
4648
4649                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullIf;
4650                                 fstate->args = (List *)
4651                                         ExecInitExpr((Expr *) nullifexpr->args, parent);
4652                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
4653                                 state = (ExprState *) fstate;
4654                         }
4655                         break;
4656                 case T_NullTest:
4657                         {
4658                                 NullTest   *ntest = (NullTest *) node;
4659                                 NullTestState *nstate = makeNode(NullTestState);
4660
4661                                 nstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullTest;
4662                                 nstate->arg = ExecInitExpr(ntest->arg, parent);
4663                                 nstate->argisrow = type_is_rowtype(exprType((Node *) ntest->arg));
4664                                 nstate->argdesc = NULL;
4665                                 state = (ExprState *) nstate;
4666                         }
4667                         break;
4668                 case T_BooleanTest:
4669                         {
4670                                 BooleanTest *btest = (BooleanTest *) node;
4671                                 GenericExprState *gstate = makeNode(GenericExprState);
4672
4673                                 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalBooleanTest;
4674                                 gstate->arg = ExecInitExpr(btest->arg, parent);
4675                                 state = (ExprState *) gstate;
4676                         }
4677                         break;
4678                 case T_CoerceToDomain:
4679                         {
4680                                 CoerceToDomain *ctest = (CoerceToDomain *) node;
4681                                 CoerceToDomainState *cstate = makeNode(CoerceToDomainState);
4682
4683                                 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceToDomain;
4684                                 cstate->arg = ExecInitExpr(ctest->arg, parent);
4685                                 cstate->constraints = GetDomainConstraints(ctest->resulttype);
4686                                 state = (ExprState *) cstate;
4687                         }
4688                         break;
4689                 case T_CurrentOfExpr:
4690                         state = (ExprState *) makeNode(ExprState);
4691                         state->evalfunc = ExecEvalCurrentOfExpr;
4692                         break;
4693                 case T_TargetEntry:
4694                         {
4695                                 TargetEntry *tle = (TargetEntry *) node;
4696                                 GenericExprState *gstate = makeNode(GenericExprState);
4697
4698                                 gstate->xprstate.evalfunc = NULL;               /* not used */
4699                                 gstate->arg = ExecInitExpr(tle->expr, parent);
4700                                 state = (ExprState *) gstate;
4701                         }
4702                         break;
4703                 case T_List:
4704                         {
4705                                 List       *outlist = NIL;
4706                                 ListCell   *l;
4707
4708                                 foreach(l, (List *) node)
4709                                 {
4710                                         outlist = lappend(outlist,
4711                                                                           ExecInitExpr((Expr *) lfirst(l),
4712                                                                                                    parent));
4713                                 }
4714                                 /* Don't fall through to the "common" code below */
4715                                 return (ExprState *) outlist;
4716                         }
4717                 default:
4718                         elog(ERROR, "unrecognized node type: %d",
4719                                  (int) nodeTag(node));
4720                         state = NULL;           /* keep compiler quiet */
4721                         break;
4722         }
4723
4724         /* Common code for all state-node types */
4725         state->expr = node;
4726
4727         return state;
4728 }
4729
4730 /*
4731  * ExecPrepareExpr --- initialize for expression execution outside a normal
4732  * Plan tree context.
4733  *
4734  * This differs from ExecInitExpr in that we don't assume the caller is
4735  * already running in the EState's per-query context.  Also, we apply
4736  * fix_opfuncids() to the passed expression tree to be sure it is ready
4737  * to run.      (In ordinary Plan trees the planner will have fixed opfuncids,
4738  * but callers outside the executor will not have done this.)
4739  */
4740 ExprState *
4741 ExecPrepareExpr(Expr *node, EState *estate)
4742 {
4743         ExprState  *result;
4744         MemoryContext oldcontext;
4745
4746         fix_opfuncids((Node *) node);
4747
4748         oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
4749
4750         result = ExecInitExpr(node, NULL);
4751
4752         MemoryContextSwitchTo(oldcontext);
4753
4754         return result;
4755 }
4756
4757
4758 /* ----------------------------------------------------------------
4759  *                                       ExecQual / ExecTargetList / ExecProject
4760  * ----------------------------------------------------------------
4761  */
4762
4763 /* ----------------------------------------------------------------
4764  *              ExecQual
4765  *
4766  *              Evaluates a conjunctive boolean expression (qual list) and
4767  *              returns true iff none of the subexpressions are false.
4768  *              (We also return true if the list is empty.)
4769  *
4770  *      If some of the subexpressions yield NULL but none yield FALSE,
4771  *      then the result of the conjunction is NULL (ie, unknown)
4772  *      according to three-valued boolean logic.  In this case,
4773  *      we return the value specified by the "resultForNull" parameter.
4774  *
4775  *      Callers evaluating WHERE clauses should pass resultForNull=FALSE,
4776  *      since SQL specifies that tuples with null WHERE results do not
4777  *      get selected.  On the other hand, callers evaluating constraint
4778  *      conditions should pass resultForNull=TRUE, since SQL also specifies
4779  *      that NULL constraint conditions are not failures.
4780  *
4781  *      NOTE: it would not be correct to use this routine to evaluate an
4782  *      AND subclause of a boolean expression; for that purpose, a NULL
4783  *      result must be returned as NULL so that it can be properly treated
4784  *      in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
4785  *      This routine is only used in contexts where a complete expression
4786  *      is being evaluated and we know that NULL can be treated the same
4787  *      as one boolean result or the other.
4788  *
4789  * ----------------------------------------------------------------
4790  */
4791 bool
4792 ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
4793 {
4794         bool            result;
4795         MemoryContext oldContext;
4796         ListCell   *l;
4797
4798         /*
4799          * debugging stuff
4800          */
4801         EV_printf("ExecQual: qual is ");
4802         EV_nodeDisplay(qual);
4803         EV_printf("\n");
4804
4805         IncrProcessed();
4806
4807         /*
4808          * Run in short-lived per-tuple context while computing expressions.
4809          */
4810         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
4811
4812         /*
4813          * Evaluate the qual conditions one at a time.  If we find a FALSE result,
4814          * we can stop evaluating and return FALSE --- the AND result must be
4815          * FALSE.  Also, if we find a NULL result when resultForNull is FALSE, we
4816          * can stop and return FALSE --- the AND result must be FALSE or NULL in
4817          * that case, and the caller doesn't care which.
4818          *
4819          * If we get to the end of the list, we can return TRUE.  This will happen
4820          * when the AND result is indeed TRUE, or when the AND result is NULL (one
4821          * or more NULL subresult, with all the rest TRUE) and the caller has
4822          * specified resultForNull = TRUE.
4823          */
4824         result = true;
4825
4826         foreach(l, qual)
4827         {
4828                 ExprState  *clause = (ExprState *) lfirst(l);
4829                 Datum           expr_value;
4830                 bool            isNull;
4831
4832                 expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
4833
4834                 if (isNull)
4835                 {
4836                         if (resultForNull == false)
4837                         {
4838                                 result = false; /* treat NULL as FALSE */
4839                                 break;
4840                         }
4841                 }
4842                 else
4843                 {
4844                         if (!DatumGetBool(expr_value))
4845                         {
4846                                 result = false; /* definitely FALSE */
4847                                 break;
4848                         }
4849                 }
4850         }
4851
4852         MemoryContextSwitchTo(oldContext);
4853
4854         return result;
4855 }
4856
4857 /*
4858  * Number of items in a tlist (including any resjunk items!)
4859  */
4860 int
4861 ExecTargetListLength(List *targetlist)
4862 {
4863         /* This used to be more complex, but fjoins are dead */
4864         return list_length(targetlist);
4865 }
4866
4867 /*
4868  * Number of items in a tlist, not including any resjunk items
4869  */
4870 int
4871 ExecCleanTargetListLength(List *targetlist)
4872 {
4873         int                     len = 0;
4874         ListCell   *tl;
4875
4876         foreach(tl, targetlist)
4877         {
4878                 TargetEntry *curTle = (TargetEntry *) lfirst(tl);
4879
4880                 Assert(IsA(curTle, TargetEntry));
4881                 if (!curTle->resjunk)
4882                         len++;
4883         }
4884         return len;
4885 }
4886
4887 /*
4888  * ExecTargetList
4889  *              Evaluates a targetlist with respect to the given
4890  *              expression context.  Returns TRUE if we were able to create
4891  *              a result, FALSE if we have exhausted a set-valued expression.
4892  *
4893  * Results are stored into the passed values and isnull arrays.
4894  * The caller must provide an itemIsDone array that persists across calls.
4895  *
4896  * As with ExecEvalExpr, the caller should pass isDone = NULL if not
4897  * prepared to deal with sets of result tuples.  Otherwise, a return
4898  * of *isDone = ExprMultipleResult signifies a set element, and a return
4899  * of *isDone = ExprEndResult signifies end of the set of tuple.
4900  */
4901 static bool
4902 ExecTargetList(List *targetlist,
4903                            ExprContext *econtext,
4904                            Datum *values,
4905                            bool *isnull,
4906                            ExprDoneCond *itemIsDone,
4907                            ExprDoneCond *isDone)
4908 {
4909         MemoryContext oldContext;
4910         ListCell   *tl;
4911         bool            haveDoneSets;
4912
4913         /*
4914          * Run in short-lived per-tuple context while computing expressions.
4915          */
4916         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
4917
4918         /*
4919          * evaluate all the expressions in the target list
4920          */
4921         if (isDone)
4922                 *isDone = ExprSingleResult;             /* until proven otherwise */
4923
4924         haveDoneSets = false;           /* any exhausted set exprs in tlist? */
4925
4926         foreach(tl, targetlist)
4927         {
4928                 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
4929                 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
4930                 AttrNumber      resind = tle->resno - 1;
4931
4932                 values[resind] = ExecEvalExpr(gstate->arg,
4933                                                                           econtext,
4934                                                                           &isnull[resind],
4935                                                                           &itemIsDone[resind]);
4936
4937                 if (itemIsDone[resind] != ExprSingleResult)
4938                 {
4939                         /* We have a set-valued expression in the tlist */
4940                         if (isDone == NULL)
4941                                 ereport(ERROR,
4942                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4943                                                  errmsg("set-valued function called in context that cannot accept a set")));
4944                         if (itemIsDone[resind] == ExprMultipleResult)
4945                         {
4946                                 /* we have undone sets in the tlist, set flag */
4947                                 *isDone = ExprMultipleResult;
4948                         }
4949                         else
4950                         {
4951                                 /* we have done sets in the tlist, set flag for that */
4952                                 haveDoneSets = true;
4953                         }
4954                 }
4955         }
4956
4957         if (haveDoneSets)
4958         {
4959                 /*
4960                  * note: can't get here unless we verified isDone != NULL
4961                  */
4962                 if (*isDone == ExprSingleResult)
4963                 {
4964                         /*
4965                          * all sets are done, so report that tlist expansion is complete.
4966                          */
4967                         *isDone = ExprEndResult;
4968                         MemoryContextSwitchTo(oldContext);
4969                         return false;
4970                 }
4971                 else
4972                 {
4973                         /*
4974                          * We have some done and some undone sets.      Restart the done ones
4975                          * so that we can deliver a tuple (if possible).
4976                          */
4977                         foreach(tl, targetlist)
4978                         {
4979                                 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
4980                                 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
4981                                 AttrNumber      resind = tle->resno - 1;
4982
4983                                 if (itemIsDone[resind] == ExprEndResult)
4984                                 {
4985                                         values[resind] = ExecEvalExpr(gstate->arg,
4986                                                                                                   econtext,
4987                                                                                                   &isnull[resind],
4988                                                                                                   &itemIsDone[resind]);
4989
4990                                         if (itemIsDone[resind] == ExprEndResult)
4991                                         {
4992                                                 /*
4993                                                  * Oh dear, this item is returning an empty set. Guess
4994                                                  * we can't make a tuple after all.
4995                                                  */
4996                                                 *isDone = ExprEndResult;
4997                                                 break;
4998                                         }
4999                                 }
5000                         }
5001
5002                         /*
5003                          * If we cannot make a tuple because some sets are empty, we still
5004                          * have to cycle the nonempty sets to completion, else resources
5005                          * will not be released from subplans etc.
5006                          *
5007                          * XXX is that still necessary?
5008                          */
5009                         if (*isDone == ExprEndResult)
5010                         {
5011                                 foreach(tl, targetlist)
5012                                 {
5013                                         GenericExprState *gstate = (GenericExprState *) lfirst(tl);
5014                                         TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
5015                                         AttrNumber      resind = tle->resno - 1;
5016
5017                                         while (itemIsDone[resind] == ExprMultipleResult)
5018                                         {
5019                                                 values[resind] = ExecEvalExpr(gstate->arg,
5020                                                                                                           econtext,
5021                                                                                                           &isnull[resind],
5022                                                                                                           &itemIsDone[resind]);
5023                                         }
5024                                 }
5025
5026                                 MemoryContextSwitchTo(oldContext);
5027                                 return false;
5028                         }
5029                 }
5030         }
5031
5032         /* Report success */
5033         MemoryContextSwitchTo(oldContext);
5034
5035         return true;
5036 }
5037
5038 /*
5039  * ExecVariableList
5040  *              Evaluates a simple-Variable-list projection.
5041  *
5042  * Results are stored into the passed values and isnull arrays.
5043  */
5044 static void
5045 ExecVariableList(ProjectionInfo *projInfo,
5046                                  Datum *values,
5047                                  bool *isnull)
5048 {
5049         ExprContext *econtext = projInfo->pi_exprContext;
5050         int                *varSlotOffsets = projInfo->pi_varSlotOffsets;
5051         int                *varNumbers = projInfo->pi_varNumbers;
5052         int                     i;
5053
5054         /*
5055          * Force extraction of all input values that we need.
5056          */
5057         if (projInfo->pi_lastInnerVar > 0)
5058                 slot_getsomeattrs(econtext->ecxt_innertuple,
5059                                                   projInfo->pi_lastInnerVar);
5060         if (projInfo->pi_lastOuterVar > 0)
5061                 slot_getsomeattrs(econtext->ecxt_outertuple,
5062                                                   projInfo->pi_lastOuterVar);
5063         if (projInfo->pi_lastScanVar > 0)
5064                 slot_getsomeattrs(econtext->ecxt_scantuple,
5065                                                   projInfo->pi_lastScanVar);
5066
5067         /*
5068          * Assign to result by direct extraction of fields from source slots ... a
5069          * mite ugly, but fast ...
5070          */
5071         for (i = list_length(projInfo->pi_targetlist) - 1; i >= 0; i--)
5072         {
5073                 char       *slotptr = ((char *) econtext) + varSlotOffsets[i];
5074                 TupleTableSlot *varSlot = *((TupleTableSlot **) slotptr);
5075                 int                     varNumber = varNumbers[i] - 1;
5076
5077                 values[i] = varSlot->tts_values[varNumber];
5078                 isnull[i] = varSlot->tts_isnull[varNumber];
5079         }
5080 }
5081
5082 /*
5083  * ExecProject
5084  *
5085  *              projects a tuple based on projection info and stores
5086  *              it in the previously specified tuple table slot.
5087  *
5088  *              Note: the result is always a virtual tuple; therefore it
5089  *              may reference the contents of the exprContext's scan tuples
5090  *              and/or temporary results constructed in the exprContext.
5091  *              If the caller wishes the result to be valid longer than that
5092  *              data will be valid, he must call ExecMaterializeSlot on the
5093  *              result slot.
5094  */
5095 TupleTableSlot *
5096 ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
5097 {
5098         TupleTableSlot *slot;
5099
5100         /*
5101          * sanity checks
5102          */
5103         Assert(projInfo != NULL);
5104
5105         /*
5106          * get the projection info we want
5107          */
5108         slot = projInfo->pi_slot;
5109
5110         /*
5111          * Clear any former contents of the result slot.  This makes it safe for
5112          * us to use the slot's Datum/isnull arrays as workspace. (Also, we can
5113          * return the slot as-is if we decide no rows can be projected.)
5114          */
5115         ExecClearTuple(slot);
5116
5117         /*
5118          * form a new result tuple (if possible); if successful, mark the result
5119          * slot as containing a valid virtual tuple
5120          */
5121         if (projInfo->pi_isVarList)
5122         {
5123                 /* simple Var list: this always succeeds with one result row */
5124                 if (isDone)
5125                         *isDone = ExprSingleResult;
5126                 ExecVariableList(projInfo,
5127                                                  slot->tts_values,
5128                                                  slot->tts_isnull);
5129                 ExecStoreVirtualTuple(slot);
5130         }
5131         else
5132         {
5133                 if (ExecTargetList(projInfo->pi_targetlist,
5134                                                    projInfo->pi_exprContext,
5135                                                    slot->tts_values,
5136                                                    slot->tts_isnull,
5137                                                    projInfo->pi_itemIsDone,
5138                                                    isDone))
5139                         ExecStoreVirtualTuple(slot);
5140         }
5141
5142         return slot;
5143 }