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