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