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