]> granicus.if.org Git - postgresql/blob - src/backend/executor/execQual.c
Use the new List API function names throughout the backend, and disable the
[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-2003, 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.161 2004/05/30 23:40:26 neilc 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 rather than at every single node.  This
33  *              is a compromise that trades off precision of the stack limit setting
34  *              to gain speed.
35  */
36
37 #include "postgres.h"
38
39 #include "access/heapam.h"
40 #include "catalog/pg_type.h"
41 #include "commands/typecmds.h"
42 #include "executor/execdebug.h"
43 #include "executor/functions.h"
44 #include "executor/nodeSubplan.h"
45 #include "funcapi.h"
46 #include "miscadmin.h"
47 #include "optimizer/planmain.h"
48 #include "parser/parse_expr.h"
49 #include "utils/acl.h"
50 #include "utils/array.h"
51 #include "utils/builtins.h"
52 #include "utils/lsyscache.h"
53 #include "utils/typcache.h"
54
55
56 /* static function decls */
57 static Datum ExecEvalArrayRef(ArrayRefExprState *astate,
58                                  ExprContext *econtext,
59                                  bool *isNull, ExprDoneCond *isDone);
60 static Datum ExecEvalAggref(AggrefExprState *aggref,
61                                                         ExprContext *econtext,
62                                                         bool *isNull, ExprDoneCond *isDone);
63 static Datum ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
64                                                  bool *isNull, ExprDoneCond *isDone);
65 static Datum ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
66                                                  bool *isNull, ExprDoneCond *isDone);
67 static Datum ExecEvalParam(ExprState *exprstate, ExprContext *econtext,
68                                                    bool *isNull, ExprDoneCond *isDone);
69 static ExprDoneCond ExecEvalFuncArgs(FunctionCallInfo fcinfo,
70                                  List *argList, ExprContext *econtext);
71 static Datum ExecMakeFunctionResultNoSets(FuncExprState *fcache,
72                                                                                   ExprContext *econtext,
73                                                                                   bool *isNull, ExprDoneCond *isDone);
74 static Datum ExecEvalFunc(FuncExprState *fcache, ExprContext *econtext,
75                          bool *isNull, ExprDoneCond *isDone);
76 static Datum ExecEvalOper(FuncExprState *fcache, ExprContext *econtext,
77                          bool *isNull, ExprDoneCond *isDone);
78 static Datum ExecEvalDistinct(FuncExprState *fcache, ExprContext *econtext,
79                                                           bool *isNull, ExprDoneCond *isDone);
80 static Datum ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
81                                                                    ExprContext *econtext,
82                                                                    bool *isNull, ExprDoneCond *isDone);
83 static Datum ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
84                                                  bool *isNull, ExprDoneCond *isDone);
85 static Datum ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
86                                                 bool *isNull, ExprDoneCond *isDone);
87 static Datum ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
88                                                  bool *isNull, ExprDoneCond *isDone);
89 static Datum ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
90                          bool *isNull, ExprDoneCond *isDone);
91 static Datum ExecEvalCaseTestExpr(ExprState *exprstate,
92                                                                   ExprContext *econtext,
93                                                                   bool *isNull, ExprDoneCond *isDone);
94 static Datum ExecEvalArray(ArrayExprState *astate,
95                                                    ExprContext *econtext,
96                                                    bool *isNull, ExprDoneCond *isDone);
97 static Datum ExecEvalRow(RowExprState *rstate,
98                                                  ExprContext *econtext,
99                                                  bool *isNull, ExprDoneCond *isDone);
100 static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr,
101                                                           ExprContext *econtext,
102                                                           bool *isNull, ExprDoneCond *isDone);
103 static Datum ExecEvalNullIf(FuncExprState *nullIfExpr,
104                                                         ExprContext *econtext,
105                                                         bool *isNull, ExprDoneCond *isDone);
106 static Datum ExecEvalNullTest(GenericExprState *nstate,
107                                  ExprContext *econtext,
108                                  bool *isNull, ExprDoneCond *isDone);
109 static Datum ExecEvalBooleanTest(GenericExprState *bstate,
110                                         ExprContext *econtext,
111                                         bool *isNull, ExprDoneCond *isDone);
112 static Datum ExecEvalCoerceToDomain(CoerceToDomainState *cstate,
113                                            ExprContext *econtext,
114                                            bool *isNull, ExprDoneCond *isDone);
115 static Datum ExecEvalCoerceToDomainValue(ExprState *exprstate,
116                                                                                  ExprContext *econtext,
117                                                                                  bool *isNull, ExprDoneCond *isDone);
118 static Datum ExecEvalFieldSelect(FieldSelectState *fstate,
119                                         ExprContext *econtext,
120                                         bool *isNull, ExprDoneCond *isDone);
121 static Datum ExecEvalRelabelType(GenericExprState *exprstate,
122                                         ExprContext *econtext,
123                                         bool *isNull, ExprDoneCond *isDone);
124
125
126 /* ----------------------------------------------------------------
127  *              ExecEvalExpr routines
128  *
129  *              Recursively evaluate a targetlist or qualification expression.
130  *
131  * Each of the following routines having the signature
132  *              Datum ExecEvalFoo(ExprState *expression,
133  *                                                ExprContext *econtext,
134  *                                                bool *isNull,
135  *                                                ExprDoneCond *isDone);
136  * is responsible for evaluating one type or subtype of ExprState node.
137  * They are normally called via the ExecEvalExpr macro, which makes use of
138  * the function pointer set up when the ExprState node was built by
139  * ExecInitExpr.  (In some cases, we change this pointer later to avoid
140  * re-executing one-time overhead.)
141  *
142  * Note: for notational simplicity we declare these functions as taking the
143  * specific type of ExprState that they work on.  This requires casting when
144  * assigning the function pointer in ExecInitExpr.  Be careful that the
145  * function signature is declared correctly, because the cast suppresses
146  * automatic checking!
147  *
148  *
149  * All these functions share this calling convention:
150  *
151  * Inputs:
152  *              expression: the expression state tree to evaluate
153  *              econtext: evaluation context information
154  *
155  * Outputs:
156  *              return value: Datum value of result
157  *              *isNull: set to TRUE if result is NULL (actual return value is
158  *                               meaningless if so); set to FALSE if non-null result
159  *              *isDone: set to indicator of set-result status
160  *
161  * A caller that can only accept a singleton (non-set) result should pass
162  * NULL for isDone; if the expression computes a set result then an error
163  * will be reported via ereport.  If the caller does pass an isDone pointer
164  * then *isDone is set to one of these three states:
165  *              ExprSingleResult                singleton result (not a set)
166  *              ExprMultipleResult              return value is one element of a set
167  *              ExprEndResult                   there are no more elements in the set
168  * When ExprMultipleResult is returned, the caller should invoke
169  * ExecEvalExpr() repeatedly until ExprEndResult is returned.  ExprEndResult
170  * is returned after the last real set element.  For convenience isNull will
171  * always be set TRUE when ExprEndResult is returned, but this should not be
172  * taken as indicating a NULL element of the set.  Note that these return
173  * conventions allow us to distinguish among a singleton NULL, a NULL element
174  * of a set, and an empty set.
175  *
176  * The caller should already have switched into the temporary memory
177  * context econtext->ecxt_per_tuple_memory.  The convenience entry point
178  * ExecEvalExprSwitchContext() is provided for callers who don't prefer to
179  * do the switch in an outer loop.      We do not do the switch in these routines
180  * because it'd be a waste of cycles during nested expression evaluation.
181  * ----------------------------------------------------------------
182  */
183
184
185 /*----------
186  *        ExecEvalArrayRef
187  *
188  *         This function takes an ArrayRef and returns the extracted Datum
189  *         if it's a simple reference, or the modified array value if it's
190  *         an array assignment (i.e., array element or slice insertion).
191  *
192  * NOTE: if we get a NULL result from a subexpression, we return NULL when
193  * it's an array reference, or the unmodified source array when it's an
194  * array assignment.  This may seem peculiar, but if we return NULL (as was
195  * done in versions up through 7.0) then an assignment like
196  *                      UPDATE table SET arrayfield[4] = NULL
197  * will result in setting the whole array to NULL, which is certainly not
198  * very desirable.      By returning the source array we make the assignment
199  * into a no-op, instead.  (Eventually we need to redesign arrays so that
200  * individual elements can be NULL, but for now, let's try to protect users
201  * from shooting themselves in the foot.)
202  *
203  * NOTE: we deliberately refrain from applying DatumGetArrayTypeP() here,
204  * even though that might seem natural, because this code needs to support
205  * both varlena arrays and fixed-length array types.  DatumGetArrayTypeP()
206  * only works for the varlena kind.  The routines we call in arrayfuncs.c
207  * have to know the difference (that's what they need refattrlength for).
208  *----------
209  */
210 static Datum
211 ExecEvalArrayRef(ArrayRefExprState *astate,
212                                  ExprContext *econtext,
213                                  bool *isNull,
214                                  ExprDoneCond *isDone)
215 {
216         ArrayRef   *arrayRef = (ArrayRef *) astate->xprstate.expr;
217         ArrayType  *array_source;
218         ArrayType  *resultArray;
219         bool            isAssignment = (arrayRef->refassgnexpr != NULL);
220         ListCell   *l;
221         int                     i = 0,
222                                 j = 0;
223         IntArray        upper,
224                                 lower;
225         int                *lIndex;
226
227         /* Set default values for result flags: non-null, not a set result */
228         *isNull = false;
229         if (isDone)
230                 *isDone = ExprSingleResult;
231
232         if (arrayRef->refexpr != NULL)
233         {
234                 array_source = (ArrayType *)
235                         DatumGetPointer(ExecEvalExpr(astate->refexpr,
236                                                                                  econtext,
237                                                                                  isNull,
238                                                                                  isDone));
239
240                 /*
241                  * If refexpr yields NULL, result is always NULL, for now anyway.
242                  * (This means you cannot assign to an element or slice of an
243                  * array that's NULL; it'll just stay NULL.)
244                  */
245                 if (*isNull)
246                         return (Datum) NULL;
247         }
248         else
249         {
250                 /*
251                  * Empty refexpr indicates we are doing an INSERT into an array
252                  * column. For now, we just take the refassgnexpr (which the
253                  * parser will have ensured is an array value) and return it
254                  * as-is, ignoring any subscripts that may have been supplied in
255                  * the INSERT column list. This is a kluge, but it's not real
256                  * clear what the semantics ought to be...
257                  */
258                 array_source = NULL;
259         }
260
261         foreach(l, astate->refupperindexpr)
262         {
263                 ExprState  *eltstate = (ExprState *) lfirst(l);
264
265                 if (i >= MAXDIM)
266                         ereport(ERROR,
267                                         (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
268                                          errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
269                                                         i, MAXDIM)));
270
271                 upper.indx[i++] = DatumGetInt32(ExecEvalExpr(eltstate,
272                                                                                                          econtext,
273                                                                                                          isNull,
274                                                                                                          NULL));
275                 /* If any index expr yields NULL, result is NULL or source array */
276                 if (*isNull)
277                 {
278                         if (!isAssignment || array_source == NULL)
279                                 return (Datum) NULL;
280                         *isNull = false;
281                         return PointerGetDatum(array_source);
282                 }
283         }
284
285         if (astate->reflowerindexpr != NIL)
286         {
287                 foreach(l, astate->reflowerindexpr)
288                 {
289                         ExprState  *eltstate = (ExprState *) lfirst(l);
290
291                         if (j >= MAXDIM)
292                                 ereport(ERROR,
293                                                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
294                                                  errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
295                                                                 i, MAXDIM)));
296
297                         lower.indx[j++] = DatumGetInt32(ExecEvalExpr(eltstate,
298                                                                                                                  econtext,
299                                                                                                                  isNull,
300                                                                                                                  NULL));
301
302                         /*
303                          * If any index expr yields NULL, result is NULL or source
304                          * array
305                          */
306                         if (*isNull)
307                         {
308                                 if (!isAssignment || array_source == NULL)
309                                         return (Datum) NULL;
310                                 *isNull = false;
311                                 return PointerGetDatum(array_source);
312                         }
313                 }
314                 /* this can't happen unless parser messed up */
315                 if (i != j)
316                         elog(ERROR, "upper and lower index lists are not same length");
317                 lIndex = lower.indx;
318         }
319         else
320                 lIndex = NULL;
321
322         if (isAssignment)
323         {
324                 Datum           sourceData = ExecEvalExpr(astate->refassgnexpr,
325                                                                                           econtext,
326                                                                                           isNull,
327                                                                                           NULL);
328
329                 /*
330                  * For now, can't cope with inserting NULL into an array, so make
331                  * it a no-op per discussion above...
332                  */
333                 if (*isNull)
334                 {
335                         if (array_source == NULL)
336                                 return (Datum) NULL;
337                         *isNull = false;
338                         return PointerGetDatum(array_source);
339                 }
340
341                 if (array_source == NULL)
342                         return sourceData;      /* XXX do something else? */
343
344                 if (lIndex == NULL)
345                         resultArray = array_set(array_source, i,
346                                                                         upper.indx,
347                                                                         sourceData,
348                                                                         astate->refattrlength,
349                                                                         astate->refelemlength,
350                                                                         astate->refelembyval,
351                                                                         astate->refelemalign,
352                                                                         isNull);
353                 else
354                         resultArray = array_set_slice(array_source, i,
355                                                                                   upper.indx, lower.indx,
356                                                            (ArrayType *) DatumGetPointer(sourceData),
357                                                                                   astate->refattrlength,
358                                                                                   astate->refelemlength,
359                                                                                   astate->refelembyval,
360                                                                                   astate->refelemalign,
361                                                                                   isNull);
362                 return PointerGetDatum(resultArray);
363         }
364
365         if (lIndex == NULL)
366                 return array_ref(array_source, i, upper.indx,
367                                                  astate->refattrlength,
368                                                  astate->refelemlength,
369                                                  astate->refelembyval,
370                                                  astate->refelemalign,
371                                                  isNull);
372         else
373         {
374                 resultArray = array_get_slice(array_source, i,
375                                                                           upper.indx, lower.indx,
376                                                                           astate->refattrlength,
377                                                                           astate->refelemlength,
378                                                                           astate->refelembyval,
379                                                                           astate->refelemalign,
380                                                                           isNull);
381                 return PointerGetDatum(resultArray);
382         }
383 }
384
385
386 /* ----------------------------------------------------------------
387  *              ExecEvalAggref
388  *
389  *              Returns a Datum whose value is the value of the precomputed
390  *              aggregate found in the given expression context.
391  * ----------------------------------------------------------------
392  */
393 static Datum
394 ExecEvalAggref(AggrefExprState *aggref, ExprContext *econtext,
395                            bool *isNull, ExprDoneCond *isDone)
396 {
397         if (isDone)
398                 *isDone = ExprSingleResult;
399
400         if (econtext->ecxt_aggvalues == NULL)           /* safety check */
401                 elog(ERROR, "no aggregates in this expression context");
402
403         *isNull = econtext->ecxt_aggnulls[aggref->aggno];
404         return econtext->ecxt_aggvalues[aggref->aggno];
405 }
406
407 /* ----------------------------------------------------------------
408  *              ExecEvalVar
409  *
410  *              Returns a Datum whose value is the value of a range
411  *              variable with respect to given expression context.
412  * ---------------------------------------------------------------- */
413 static Datum
414 ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
415                         bool *isNull, ExprDoneCond *isDone)
416 {
417         Var                *variable = (Var *) exprstate->expr;
418         Datum           result;
419         TupleTableSlot *slot;
420         AttrNumber      attnum;
421         HeapTuple       heapTuple;
422         TupleDesc       tuple_type;
423
424         if (isDone)
425                 *isDone = ExprSingleResult;
426
427         /*
428          * Get the slot and attribute number we want
429          *
430          * The asserts check that references to system attributes only appear
431          * at the level of a relation scan; at higher levels, system attributes
432          * must be treated as ordinary variables (since we no longer have access
433          * to the original tuple).
434          */
435         attnum = variable->varattno;
436
437         switch (variable->varno)
438         {
439                 case INNER:                             /* get the tuple from the inner node */
440                         slot = econtext->ecxt_innertuple;
441                         Assert(attnum > 0);
442                         break;
443
444                 case OUTER:                             /* get the tuple from the outer node */
445                         slot = econtext->ecxt_outertuple;
446                         Assert(attnum > 0);
447                         break;
448
449                 default:                                /* get the tuple from the relation being
450                                                                  * scanned */
451                         slot = econtext->ecxt_scantuple;
452                         break;
453         }
454
455         /*
456          * extract tuple information from the slot
457          */
458         heapTuple = slot->val;
459         tuple_type = slot->ttc_tupleDescriptor;
460
461         /*
462          * Some checks that are only applied for user attribute numbers
463          * (bogus system attnums will be caught inside heap_getattr).
464          */
465         if (attnum > 0)
466         {
467                 /*
468                  * This assert checks that the attnum is valid.
469                  */
470                 Assert(attnum <= tuple_type->natts &&
471                            tuple_type->attrs[attnum - 1] != NULL);
472
473                 /*
474                  * If the attribute's column has been dropped, we force a NULL result.
475                  * This case should not happen in normal use, but it could happen if
476                  * we are executing a plan cached before the column was dropped.
477                  */
478                 if (tuple_type->attrs[attnum - 1]->attisdropped)
479                 {
480                         *isNull = true;
481                         return (Datum) 0;
482                 }
483
484                 /*
485                  * This assert checks that the datatype the plan expects to get (as
486                  * told by our "variable" argument) is in fact the datatype of the
487                  * attribute being fetched (as seen in the current context, identified
488                  * by our "econtext" argument).  Otherwise crashes are likely.
489                  *
490                  * Note that we can't check dropped columns, since their atttypid
491                  * has been zeroed.
492                  */
493                 Assert(variable->vartype == tuple_type->attrs[attnum - 1]->atttypid);
494         }
495
496         result = heap_getattr(heapTuple,        /* tuple containing attribute */
497                                                   attnum,               /* attribute number of desired
498                                                                                  * attribute */
499                                                   tuple_type,   /* tuple descriptor of tuple */
500                                                   isNull);              /* return: is attribute null? */
501
502         return result;
503 }
504
505 /* ----------------------------------------------------------------
506  *              ExecEvalConst
507  *
508  *              Returns the value of a constant.
509  *
510  *              Note that for pass-by-ref datatypes, we return a pointer to the
511  *              actual constant node.  This is one of the reasons why functions
512  *              must treat their input arguments as read-only.
513  * ----------------------------------------------------------------
514  */
515 static Datum
516 ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
517                           bool *isNull, ExprDoneCond *isDone)
518 {
519         Const      *con = (Const *) exprstate->expr;
520
521         if (isDone)
522                 *isDone = ExprSingleResult;
523
524         *isNull = con->constisnull;
525         return con->constvalue;
526 }
527
528 /* ----------------------------------------------------------------
529  *              ExecEvalParam
530  *
531  *              Returns the value of a parameter.  A param node contains
532  *              something like ($.name) and the expression context contains
533  *              the current parameter bindings (name = "sam") (age = 34)...
534  *              so our job is to find and return the appropriate datum ("sam").
535  *
536  *              Q: if we have a parameter ($.foo) without a binding, i.e.
537  *                 there is no (foo = xxx) in the parameter list info,
538  *                 is this a fatal error or should this be a "not available"
539  *                 (in which case we could return NULL)?        -cim 10/13/89
540  * ----------------------------------------------------------------
541  */
542 static Datum
543 ExecEvalParam(ExprState *exprstate, ExprContext *econtext,
544                           bool *isNull, ExprDoneCond *isDone)
545 {
546         Param      *expression = (Param *) exprstate->expr;
547         int                     thisParamKind = expression->paramkind;
548         AttrNumber      thisParamId = expression->paramid;
549
550         if (isDone)
551                 *isDone = ExprSingleResult;
552
553         if (thisParamKind == PARAM_EXEC)
554         {
555                 /*
556                  * PARAM_EXEC params (internal executor parameters) are stored in
557                  * the ecxt_param_exec_vals array, and can be accessed by array
558                  * index.
559                  */
560                 ParamExecData *prm;
561
562                 prm = &(econtext->ecxt_param_exec_vals[thisParamId]);
563                 if (prm->execPlan != NULL)
564                 {
565                         /* Parameter not evaluated yet, so go do it */
566                         ExecSetParamPlan(prm->execPlan, econtext);
567                         /* ExecSetParamPlan should have processed this param... */
568                         Assert(prm->execPlan == NULL);
569                 }
570                 *isNull = prm->isnull;
571                 return prm->value;
572         }
573         else
574         {
575                 /*
576                  * All other parameter types must be sought in
577                  * ecxt_param_list_info. NOTE: The last entry in the param array
578                  * is always an entry with kind == PARAM_INVALID.
579                  */
580                 ParamListInfo paramList = econtext->ecxt_param_list_info;
581                 char       *thisParamName = expression->paramname;
582                 bool            matchFound = false;
583
584                 if (paramList != NULL)
585                 {
586                         while (paramList->kind != PARAM_INVALID && !matchFound)
587                         {
588                                 if (thisParamKind == paramList->kind)
589                                 {
590                                         switch (thisParamKind)
591                                         {
592                                                 case PARAM_NAMED:
593                                                         if (strcmp(paramList->name, thisParamName) == 0)
594                                                                 matchFound = true;
595                                                         break;
596                                                 case PARAM_NUM:
597                                                         if (paramList->id == thisParamId)
598                                                                 matchFound = true;
599                                                         break;
600                                                 default:
601                                                         elog(ERROR, "unrecognized paramkind: %d",
602                                                                  thisParamKind);
603                                         }
604                                 }
605                                 if (!matchFound)
606                                         paramList++;
607                         }                                       /* while */
608                 }                                               /* if */
609
610                 if (!matchFound)
611                 {
612                         if (thisParamKind == PARAM_NAMED)
613                                 ereport(ERROR,
614                                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
615                                                  errmsg("no value found for parameter \"%s\"",
616                                                                 thisParamName)));
617                         else
618                                 ereport(ERROR,
619                                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
620                                                  errmsg("no value found for parameter %d",
621                                                                 thisParamId)));
622                 }
623
624                 *isNull = paramList->isnull;
625                 return paramList->value;
626         }
627 }
628
629
630 /* ----------------------------------------------------------------
631  *              ExecEvalOper / ExecEvalFunc support routines
632  * ----------------------------------------------------------------
633  */
634
635 /*
636  *              GetAttributeByName
637  *              GetAttributeByNum
638  *
639  *              These functions return the value of the requested attribute
640  *              out of the given tuple Datum.
641  *              C functions which take a tuple as an argument are expected
642  *              to use these.  Ex: overpaid(EMP) might call GetAttributeByNum().
643  *              Note: these are actually rather slow because they do a typcache
644  *              lookup on each call.
645  */
646 Datum
647 GetAttributeByNum(HeapTupleHeader tuple,
648                                   AttrNumber attrno,
649                                   bool *isNull)
650 {
651         Datum           result;
652         Oid                     tupType;
653         int32           tupTypmod;
654         TupleDesc       tupDesc;
655         HeapTupleData tmptup;
656
657         if (!AttributeNumberIsValid(attrno))
658                 elog(ERROR, "invalid attribute number %d", attrno);
659
660         if (isNull == NULL)
661                 elog(ERROR, "a NULL isNull pointer was passed");
662
663         if (tuple == NULL)
664         {
665                 /* Kinda bogus but compatible with old behavior... */
666                 *isNull = true;
667                 return (Datum) 0;
668         }
669
670         tupType = HeapTupleHeaderGetTypeId(tuple);
671         tupTypmod = HeapTupleHeaderGetTypMod(tuple);
672         tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
673
674         /*
675          * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set
676          * all the fields in the struct just in case user tries to inspect
677          * system columns.
678          */
679         tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
680         ItemPointerSetInvalid(&(tmptup.t_self));
681         tmptup.t_tableOid = InvalidOid;
682         tmptup.t_data = tuple;
683
684         result = heap_getattr(&tmptup,
685                                                   attrno,
686                                                   tupDesc,
687                                                   isNull);
688         return result;
689 }
690
691 Datum
692 GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
693 {
694         AttrNumber      attrno;
695         Datum           result;
696         Oid                     tupType;
697         int32           tupTypmod;
698         TupleDesc       tupDesc;
699         HeapTupleData tmptup;
700         int                     i;
701
702         if (attname == NULL)
703                 elog(ERROR, "invalid attribute name");
704
705         if (isNull == NULL)
706                 elog(ERROR, "a NULL isNull pointer was passed");
707
708         if (tuple == NULL)
709         {
710                 /* Kinda bogus but compatible with old behavior... */
711                 *isNull = true;
712                 return (Datum) 0;
713         }
714
715         tupType = HeapTupleHeaderGetTypeId(tuple);
716         tupTypmod = HeapTupleHeaderGetTypMod(tuple);
717         tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
718
719         attrno = InvalidAttrNumber;
720         for (i = 0; i < tupDesc->natts; i++)
721         {
722                 if (namestrcmp(&(tupDesc->attrs[i]->attname), attname) == 0)
723                 {
724                         attrno = tupDesc->attrs[i]->attnum;
725                         break;
726                 }
727         }
728
729         if (attrno == InvalidAttrNumber)
730                 elog(ERROR, "attribute \"%s\" does not exist", attname);
731
732         /*
733          * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set
734          * all the fields in the struct just in case user tries to inspect
735          * system columns.
736          */
737         tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
738         ItemPointerSetInvalid(&(tmptup.t_self));
739         tmptup.t_tableOid = InvalidOid;
740         tmptup.t_data = tuple;
741
742         result = heap_getattr(&tmptup,
743                                                   attrno,
744                                                   tupDesc,
745                                                   isNull);
746         return result;
747 }
748
749 /*
750  * init_fcache - initialize a FuncExprState node during first use
751  */
752 void
753 init_fcache(Oid foid, FuncExprState *fcache, MemoryContext fcacheCxt)
754 {
755         AclResult       aclresult;
756
757         /* Check permission to call function */
758         aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
759         if (aclresult != ACLCHECK_OK)
760                 aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(foid));
761
762         /* Safety check (should never fail, as parser should check sooner) */
763         if (list_length(fcache->args) > FUNC_MAX_ARGS)
764                 elog(ERROR, "too many arguments");
765
766         /* Set up the primary fmgr lookup information */
767         fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
768
769         /* Initialize additional info */
770         fcache->setArgsValid = false;
771         fcache->shutdown_reg = false;
772         fcache->func.fn_expr = (Node *) fcache->xprstate.expr;
773 }
774
775 /*
776  * callback function in case a FuncExpr returning a set needs to be shut down
777  * before it has been run to completion
778  */
779 static void
780 ShutdownFuncExpr(Datum arg)
781 {
782         FuncExprState *fcache = (FuncExprState *) DatumGetPointer(arg);
783
784         /* Clear any active set-argument state */
785         fcache->setArgsValid = false;
786
787         /* execUtils will deregister the callback... */
788         fcache->shutdown_reg = false;
789 }
790
791 /*
792  * Evaluate arguments for a function.
793  */
794 static ExprDoneCond
795 ExecEvalFuncArgs(FunctionCallInfo fcinfo,
796                                  List *argList,
797                                  ExprContext *econtext)
798 {
799         ExprDoneCond argIsDone;
800         int                     i;
801         ListCell   *arg;
802
803         argIsDone = ExprSingleResult;           /* default assumption */
804
805         i = 0;
806         foreach(arg, argList)
807         {
808                 ExprState  *argstate = (ExprState *) lfirst(arg);
809                 ExprDoneCond thisArgIsDone;
810
811                 fcinfo->arg[i] = ExecEvalExpr(argstate,
812                                                                           econtext,
813                                                                           &fcinfo->argnull[i],
814                                                                           &thisArgIsDone);
815
816                 if (thisArgIsDone != ExprSingleResult)
817                 {
818                         /*
819                          * We allow only one argument to have a set value; we'd need
820                          * much more complexity to keep track of multiple set
821                          * arguments (cf. ExecTargetList) and it doesn't seem worth
822                          * it.
823                          */
824                         if (argIsDone != ExprSingleResult)
825                                 ereport(ERROR,
826                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
827                                                  errmsg("functions and operators can take at most one set argument")));
828                         argIsDone = thisArgIsDone;
829                 }
830                 i++;
831         }
832
833         fcinfo->nargs = i;
834
835         return argIsDone;
836 }
837
838 /*
839  *              ExecMakeFunctionResult
840  *
841  * Evaluate the arguments to a function and then the function itself.
842  */
843 Datum
844 ExecMakeFunctionResult(FuncExprState *fcache,
845                                            ExprContext *econtext,
846                                            bool *isNull,
847                                            ExprDoneCond *isDone)
848 {
849         List       *arguments = fcache->args;
850         Datum           result;
851         FunctionCallInfoData fcinfo;
852         ReturnSetInfo rsinfo;           /* for functions returning sets */
853         ExprDoneCond argDone;
854         bool            hasSetArg;
855         int                     i;
856
857         /* Guard against stack overflow due to overly complex expressions */
858         check_stack_depth();
859
860         /*
861          * arguments is a list of expressions to evaluate before passing to
862          * the function manager.  We skip the evaluation if it was already
863          * done in the previous call (ie, we are continuing the evaluation of
864          * a set-valued function).      Otherwise, collect the current argument
865          * values into fcinfo.
866          */
867         if (!fcache->setArgsValid)
868         {
869                 /* Need to prep callinfo structure */
870                 MemSet(&fcinfo, 0, sizeof(fcinfo));
871                 fcinfo.flinfo = &(fcache->func);
872                 argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);
873                 if (argDone == ExprEndResult)
874                 {
875                         /* input is an empty set, so return an empty set. */
876                         *isNull = true;
877                         if (isDone)
878                                 *isDone = ExprEndResult;
879                         else
880                                 ereport(ERROR,
881                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
882                                                  errmsg("set-valued function called in context that cannot accept a set")));
883                         return (Datum) 0;
884                 }
885                 hasSetArg = (argDone != ExprSingleResult);
886         }
887         else
888         {
889                 /* Copy callinfo from previous evaluation */
890                 memcpy(&fcinfo, &fcache->setArgs, sizeof(fcinfo));
891                 hasSetArg = fcache->setHasSetArg;
892                 /* Reset flag (we may set it again below) */
893                 fcache->setArgsValid = false;
894         }
895
896         /*
897          * If function returns set, prepare a resultinfo node for
898          * communication
899          */
900         if (fcache->func.fn_retset)
901         {
902                 fcinfo.resultinfo = (Node *) &rsinfo;
903                 rsinfo.type = T_ReturnSetInfo;
904                 rsinfo.econtext = econtext;
905                 rsinfo.expectedDesc = NULL;
906                 rsinfo.allowedModes = (int) SFRM_ValuePerCall;
907                 rsinfo.returnMode = SFRM_ValuePerCall;
908                 /* isDone is filled below */
909                 rsinfo.setResult = NULL;
910                 rsinfo.setDesc = NULL;
911         }
912
913         /*
914          * now return the value gotten by calling the function manager,
915          * passing the function the evaluated parameter values.
916          */
917         if (fcache->func.fn_retset || hasSetArg)
918         {
919                 /*
920                  * We need to return a set result.      Complain if caller not ready
921                  * to accept one.
922                  */
923                 if (isDone == NULL)
924                         ereport(ERROR,
925                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
926                                          errmsg("set-valued function called in context that cannot accept a set")));
927
928                 /*
929                  * This loop handles the situation where we have both a set
930                  * argument and a set-valued function.  Once we have exhausted the
931                  * function's value(s) for a particular argument value, we have to
932                  * get the next argument value and start the function over again.
933                  * We might have to do it more than once, if the function produces
934                  * an empty result set for a particular input value.
935                  */
936                 for (;;)
937                 {
938                         /*
939                          * If function is strict, and there are any NULL arguments,
940                          * skip calling the function (at least for this set of args).
941                          */
942                         bool            callit = true;
943
944                         if (fcache->func.fn_strict)
945                         {
946                                 for (i = 0; i < fcinfo.nargs; i++)
947                                 {
948                                         if (fcinfo.argnull[i])
949                                         {
950                                                 callit = false;
951                                                 break;
952                                         }
953                                 }
954                         }
955
956                         if (callit)
957                         {
958                                 fcinfo.isnull = false;
959                                 rsinfo.isDone = ExprSingleResult;
960                                 result = FunctionCallInvoke(&fcinfo);
961                                 *isNull = fcinfo.isnull;
962                                 *isDone = rsinfo.isDone;
963                         }
964                         else
965                         {
966                                 result = (Datum) 0;
967                                 *isNull = true;
968                                 *isDone = ExprEndResult;
969                         }
970
971                         if (*isDone != ExprEndResult)
972                         {
973                                 /*
974                                  * Got a result from current argument.  If function itself
975                                  * returns set, save the current argument values to re-use
976                                  * on the next call.
977                                  */
978                                 if (fcache->func.fn_retset)
979                                 {
980                                         memcpy(&fcache->setArgs, &fcinfo, sizeof(fcinfo));
981                                         fcache->setHasSetArg = hasSetArg;
982                                         fcache->setArgsValid = true;
983                                         /* Register cleanup callback if we didn't already */
984                                         if (!fcache->shutdown_reg)
985                                         {
986                                                 RegisterExprContextCallback(econtext,
987                                                                                                         ShutdownFuncExpr,
988                                                                                                         PointerGetDatum(fcache));
989                                                 fcache->shutdown_reg = true;
990                                         }
991                                 }
992
993                                 /*
994                                  * Make sure we say we are returning a set, even if the
995                                  * function itself doesn't return sets.
996                                  */
997                                 *isDone = ExprMultipleResult;
998                                 break;
999                         }
1000
1001                         /* Else, done with this argument */
1002                         if (!hasSetArg)
1003                                 break;                  /* input not a set, so done */
1004
1005                         /* Re-eval args to get the next element of the input set */
1006                         argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);
1007
1008                         if (argDone != ExprMultipleResult)
1009                         {
1010                                 /* End of argument set, so we're done. */
1011                                 *isNull = true;
1012                                 *isDone = ExprEndResult;
1013                                 result = (Datum) 0;
1014                                 break;
1015                         }
1016
1017                         /*
1018                          * If we reach here, loop around to run the function on the
1019                          * new argument.
1020                          */
1021                 }
1022         }
1023         else
1024         {
1025                 /*
1026                  * Non-set case: much easier.
1027                  *
1028                  * We change the ExprState function pointer to use the simpler
1029                  * ExecMakeFunctionResultNoSets on subsequent calls.  This amounts
1030                  * to assuming that no argument can return a set if it didn't do so
1031                  * the first time.
1032                  */
1033                 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResultNoSets;
1034
1035                 if (isDone)
1036                         *isDone = ExprSingleResult;
1037
1038                 /*
1039                  * If function is strict, and there are any NULL arguments, skip
1040                  * calling the function and return NULL.
1041                  */
1042                 if (fcache->func.fn_strict)
1043                 {
1044                         for (i = 0; i < fcinfo.nargs; i++)
1045                         {
1046                                 if (fcinfo.argnull[i])
1047                                 {
1048                                         *isNull = true;
1049                                         return (Datum) 0;
1050                                 }
1051                         }
1052                 }
1053                 fcinfo.isnull = false;
1054                 result = FunctionCallInvoke(&fcinfo);
1055                 *isNull = fcinfo.isnull;
1056         }
1057
1058         return result;
1059 }
1060
1061 /*
1062  *              ExecMakeFunctionResultNoSets
1063  *
1064  * Simplified version of ExecMakeFunctionResult that can only handle
1065  * non-set cases.  Hand-tuned for speed.
1066  */
1067 static Datum
1068 ExecMakeFunctionResultNoSets(FuncExprState *fcache,
1069                                                          ExprContext *econtext,
1070                                                          bool *isNull,
1071                                                          ExprDoneCond *isDone)
1072 {
1073         ListCell   *arg;
1074         Datum           result;
1075         FunctionCallInfoData fcinfo;
1076         int                     i;
1077
1078         /* Guard against stack overflow due to overly complex expressions */
1079         check_stack_depth();
1080
1081         if (isDone)
1082                 *isDone = ExprSingleResult;
1083
1084         MemSet(&fcinfo, 0, sizeof(fcinfo));
1085         fcinfo.flinfo = &(fcache->func);
1086
1087         /* inlined, simplified version of ExecEvalFuncArgs */
1088         i = 0;
1089         foreach(arg, fcache->args)
1090         {
1091                 ExprState  *argstate = (ExprState *) lfirst(arg);
1092                 ExprDoneCond thisArgIsDone;
1093
1094                 fcinfo.arg[i] = ExecEvalExpr(argstate,
1095                                                                          econtext,
1096                                                                          &fcinfo.argnull[i],
1097                                                                          &thisArgIsDone);
1098
1099                 if (thisArgIsDone != ExprSingleResult)
1100                         ereport(ERROR,
1101                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1102                                          errmsg("set-valued function called in context that cannot accept a set")));
1103                 i++;
1104         }
1105         fcinfo.nargs = i;
1106
1107         /*
1108          * If function is strict, and there are any NULL arguments, skip
1109          * calling the function and return NULL.
1110          */
1111         if (fcache->func.fn_strict)
1112         {
1113                 while (--i >= 0)
1114                 {
1115                         if (fcinfo.argnull[i])
1116                         {
1117                                 *isNull = true;
1118                                 return (Datum) 0;
1119                         }
1120                 }
1121         }
1122         /* fcinfo.isnull = false; */            /* handled by MemSet */
1123         result = FunctionCallInvoke(&fcinfo);
1124         *isNull = fcinfo.isnull;
1125
1126         return result;
1127 }
1128
1129
1130 /*
1131  *              ExecMakeTableFunctionResult
1132  *
1133  * Evaluate a table function, producing a materialized result in a Tuplestore
1134  * object.      (If function returns an empty set, we just return NULL instead.)
1135  */
1136 Tuplestorestate *
1137 ExecMakeTableFunctionResult(ExprState *funcexpr,
1138                                                         ExprContext *econtext,
1139                                                         TupleDesc expectedDesc,
1140                                                         TupleDesc *returnDesc)
1141 {
1142         Tuplestorestate *tupstore = NULL;
1143         TupleDesc       tupdesc = NULL;
1144         Oid                     funcrettype;
1145         bool            returnsTuple;
1146         FunctionCallInfoData fcinfo;
1147         ReturnSetInfo rsinfo;
1148         HeapTupleData tmptup;
1149         MemoryContext callerContext;
1150         MemoryContext oldcontext;
1151         bool            direct_function_call;
1152         bool            first_time = true;
1153
1154         /*
1155          * Normally the passed expression tree will be a FuncExprState, since
1156          * the grammar only allows a function call at the top level of a table
1157          * function reference.  However, if the function doesn't return set
1158          * then the planner might have replaced the function call via
1159          * constant-folding or inlining.  So if we see any other kind of
1160          * expression node, execute it via the general ExecEvalExpr() code;
1161          * the only difference is that we don't get a chance to pass a special
1162          * ReturnSetInfo to any functions buried in the expression.
1163          */
1164         if (funcexpr && IsA(funcexpr, FuncExprState) &&
1165                 IsA(funcexpr->expr, FuncExpr))
1166         {
1167                 FuncExprState *fcache = (FuncExprState *) funcexpr;
1168                 ExprDoneCond argDone;
1169
1170                 /*
1171                  * This path is similar to ExecMakeFunctionResult.
1172                  */
1173                 direct_function_call = true;
1174
1175                 /*
1176                  * Initialize function cache if first time through
1177                  */
1178                 if (fcache->func.fn_oid == InvalidOid)
1179                 {
1180                         FuncExpr   *func = (FuncExpr *) fcache->xprstate.expr;
1181
1182                         init_fcache(func->funcid, fcache, econtext->ecxt_per_query_memory);
1183                 }
1184
1185                 /*
1186                  * Evaluate the function's argument list.
1187                  *
1188                  * Note: ideally, we'd do this in the per-tuple context, but then the
1189                  * argument values would disappear when we reset the context in
1190                  * the inner loop.      So do it in caller context.  Perhaps we should
1191                  * make a separate context just to hold the evaluated arguments?
1192                  */
1193                 MemSet(&fcinfo, 0, sizeof(fcinfo));
1194                 fcinfo.flinfo = &(fcache->func);
1195                 argDone = ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
1196                 /* We don't allow sets in the arguments of the table function */
1197                 if (argDone != ExprSingleResult)
1198                         ereport(ERROR,
1199                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1200                                          errmsg("set-valued function called in context that cannot accept a set")));
1201
1202                 /*
1203                  * If function is strict, and there are any NULL arguments, skip
1204                  * calling the function and return NULL (actually an empty set).
1205                  */
1206                 if (fcache->func.fn_strict)
1207                 {
1208                         int                     i;
1209
1210                         for (i = 0; i < fcinfo.nargs; i++)
1211                         {
1212                                 if (fcinfo.argnull[i])
1213                                 {
1214                                         *returnDesc = NULL;
1215                                         return NULL;
1216                                 }
1217                         }
1218                 }
1219         }
1220         else
1221         {
1222                 /* Treat funcexpr as a generic expression */
1223                 direct_function_call = false;
1224         }
1225
1226         funcrettype = exprType((Node *) funcexpr->expr);
1227
1228         returnsTuple = (funcrettype == RECORDOID ||
1229                                         get_typtype(funcrettype) == 'c');
1230
1231         /*
1232          * Prepare a resultinfo node for communication.  We always do this
1233          * even if not expecting a set result, so that we can pass
1234          * expectedDesc.  In the generic-expression case, the expression
1235          * doesn't actually get to see the resultinfo, but set it up anyway
1236          * because we use some of the fields as our own state variables.
1237          */
1238         fcinfo.resultinfo = (Node *) &rsinfo;
1239         rsinfo.type = T_ReturnSetInfo;
1240         rsinfo.econtext = econtext;
1241         rsinfo.expectedDesc = expectedDesc;
1242         rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
1243         rsinfo.returnMode = SFRM_ValuePerCall;
1244         /* isDone is filled below */
1245         rsinfo.setResult = NULL;
1246         rsinfo.setDesc = NULL;
1247
1248         /*
1249          * Switch to short-lived context for calling the function or
1250          * expression.
1251          */
1252         callerContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1253
1254         /*
1255          * Loop to handle the ValuePerCall protocol (which is also the same
1256          * behavior needed in the generic ExecEvalExpr path).
1257          */
1258         for (;;)
1259         {
1260                 Datum           result;
1261                 HeapTuple       tuple;
1262
1263                 /*
1264                  * reset per-tuple memory context before each call of the function
1265                  * or expression. This cleans up any local memory the function may
1266                  * leak when called.
1267                  */
1268                 ResetExprContext(econtext);
1269
1270                 /* Call the function or expression one time */
1271                 if (direct_function_call)
1272                 {
1273                         fcinfo.isnull = false;
1274                         rsinfo.isDone = ExprSingleResult;
1275                         result = FunctionCallInvoke(&fcinfo);
1276                 }
1277                 else
1278                 {
1279                         result = ExecEvalExpr(funcexpr, econtext,
1280                                                                   &fcinfo.isnull, &rsinfo.isDone);
1281                 }
1282
1283                 /* Which protocol does function want to use? */
1284                 if (rsinfo.returnMode == SFRM_ValuePerCall)
1285                 {
1286                         /*
1287                          * Check for end of result set.
1288                          *
1289                          * Note: if function returns an empty set, we don't build a
1290                          * tupdesc or tuplestore (since we can't get a tupdesc in the
1291                          * function-returning-tuple case)
1292                          */
1293                         if (rsinfo.isDone == ExprEndResult)
1294                                 break;
1295
1296                         /*
1297                          * Can't do anything useful with NULL rowtype values.  Currently
1298                          * we raise an error, but another alternative is to just ignore
1299                          * the result and "continue" to get another row.
1300                          */
1301                         if (returnsTuple && fcinfo.isnull)
1302                                 ereport(ERROR,
1303                                                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1304                                                  errmsg("function returning row cannot return null value")));
1305
1306                         /*
1307                          * If first time through, build tupdesc and tuplestore for
1308                          * result
1309                          */
1310                         if (first_time)
1311                         {
1312                                 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1313                                 if (returnsTuple)
1314                                 {
1315                                         /*
1316                                          * Use the type info embedded in the rowtype Datum to
1317                                          * look up the needed tupdesc.  Make a copy for the query.
1318                                          */
1319                                         HeapTupleHeader td;
1320
1321                                         td = DatumGetHeapTupleHeader(result);
1322                                         tupdesc = lookup_rowtype_tupdesc(HeapTupleHeaderGetTypeId(td),
1323                                                                                                          HeapTupleHeaderGetTypMod(td));
1324                                         tupdesc = CreateTupleDescCopy(tupdesc);
1325                                 }
1326                                 else
1327                                 {
1328                                         /*
1329                                          * Scalar type, so make a single-column descriptor
1330                                          */
1331                                         tupdesc = CreateTemplateTupleDesc(1, false);
1332                                         TupleDescInitEntry(tupdesc,
1333                                                                            (AttrNumber) 1,
1334                                                                            "column",
1335                                                                            funcrettype,
1336                                                                            -1,
1337                                                                            0);
1338                                 }
1339                                 tupstore = tuplestore_begin_heap(true, false, work_mem);
1340                                 MemoryContextSwitchTo(oldcontext);
1341                                 rsinfo.setResult = tupstore;
1342                                 rsinfo.setDesc = tupdesc;
1343                         }
1344
1345                         /*
1346                          * Store current resultset item.
1347                          */
1348                         if (returnsTuple)
1349                         {
1350                                 HeapTupleHeader td;
1351
1352                                 td = DatumGetHeapTupleHeader(result);
1353
1354                                 /*
1355                                  * tuplestore_puttuple needs a HeapTuple not a bare
1356                                  * HeapTupleHeader, but it doesn't need all the fields.
1357                                  */
1358                                 tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
1359                                 tmptup.t_data = td;
1360                                 tuple = &tmptup;
1361                         }
1362                         else
1363                         {
1364                                 char            nullflag;
1365
1366                                 nullflag = fcinfo.isnull ? 'n' : ' ';
1367                                 tuple = heap_formtuple(tupdesc, &result, &nullflag);
1368                         }
1369
1370                         oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1371                         tuplestore_puttuple(tupstore, tuple);
1372                         MemoryContextSwitchTo(oldcontext);
1373
1374                         /*
1375                          * Are we done?
1376                          */
1377                         if (rsinfo.isDone != ExprMultipleResult)
1378                                 break;
1379                 }
1380                 else if (rsinfo.returnMode == SFRM_Materialize)
1381                 {
1382                         /* check we're on the same page as the function author */
1383                         if (!first_time || rsinfo.isDone != ExprSingleResult)
1384                                 ereport(ERROR,
1385                                                 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1386                                                  errmsg("table-function protocol for materialize mode was not followed")));
1387                         /* Done evaluating the set result */
1388                         break;
1389                 }
1390                 else
1391                         ereport(ERROR,
1392                                         (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1393                                          errmsg("unrecognized table-function returnMode: %d",
1394                                                         (int) rsinfo.returnMode)));
1395
1396                 first_time = false;
1397         }
1398
1399         MemoryContextSwitchTo(callerContext);
1400
1401         /* The returned pointers are those in rsinfo */
1402         *returnDesc = rsinfo.setDesc;
1403         return rsinfo.setResult;
1404 }
1405
1406
1407 /* ----------------------------------------------------------------
1408  *              ExecEvalFunc
1409  *              ExecEvalOper
1410  *
1411  *              Evaluate the functional result of a list of arguments by calling the
1412  *              function manager.
1413  * ----------------------------------------------------------------
1414  */
1415
1416 /* ----------------------------------------------------------------
1417  *              ExecEvalFunc
1418  * ----------------------------------------------------------------
1419  */
1420 static Datum
1421 ExecEvalFunc(FuncExprState *fcache,
1422                          ExprContext *econtext,
1423                          bool *isNull,
1424                          ExprDoneCond *isDone)
1425 {
1426         /* This is called only the first time through */
1427         FuncExpr   *func = (FuncExpr *) fcache->xprstate.expr;
1428
1429         /* Initialize function lookup info */
1430         init_fcache(func->funcid, fcache, econtext->ecxt_per_query_memory);
1431
1432         /* Go directly to ExecMakeFunctionResult on subsequent uses */
1433         fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
1434
1435         return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
1436 }
1437
1438 /* ----------------------------------------------------------------
1439  *              ExecEvalOper
1440  * ----------------------------------------------------------------
1441  */
1442 static Datum
1443 ExecEvalOper(FuncExprState *fcache,
1444                          ExprContext *econtext,
1445                          bool *isNull,
1446                          ExprDoneCond *isDone)
1447 {
1448         /* This is called only the first time through */
1449         OpExpr     *op = (OpExpr *) fcache->xprstate.expr;
1450
1451         /* Initialize function lookup info */
1452         init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory);
1453
1454         /* Go directly to ExecMakeFunctionResult on subsequent uses */
1455         fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
1456
1457         return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
1458 }
1459
1460 /* ----------------------------------------------------------------
1461  *              ExecEvalDistinct
1462  *
1463  * IS DISTINCT FROM must evaluate arguments to determine whether
1464  * they are NULL; if either is NULL then the result is already
1465  * known. If neither is NULL, then proceed to evaluate the
1466  * function. Note that this is *always* derived from the equals
1467  * operator, but since we need special processing of the arguments
1468  * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
1469  * ----------------------------------------------------------------
1470  */
1471 static Datum
1472 ExecEvalDistinct(FuncExprState *fcache,
1473                                  ExprContext *econtext,
1474                                  bool *isNull,
1475                                  ExprDoneCond *isDone)
1476 {
1477         Datum           result;
1478         FunctionCallInfoData fcinfo;
1479         ExprDoneCond argDone;
1480         List       *argList;
1481
1482         /* Set default values for result flags: non-null, not a set result */
1483         *isNull = false;
1484         if (isDone)
1485                 *isDone = ExprSingleResult;
1486
1487         /*
1488          * Initialize function cache if first time through
1489          */
1490         if (fcache->func.fn_oid == InvalidOid)
1491         {
1492                 DistinctExpr *op = (DistinctExpr *) fcache->xprstate.expr;
1493
1494                 init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory);
1495                 Assert(!fcache->func.fn_retset);
1496         }
1497
1498         /*
1499          * extract info from fcache
1500          */
1501         argList = fcache->args;
1502
1503         /* Need to prep callinfo structure */
1504         MemSet(&fcinfo, 0, sizeof(fcinfo));
1505         fcinfo.flinfo = &(fcache->func);
1506         argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
1507         if (argDone != ExprSingleResult)
1508                 ereport(ERROR,
1509                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
1510                          errmsg("IS DISTINCT FROM does not support set arguments")));
1511         Assert(fcinfo.nargs == 2);
1512
1513         if (fcinfo.argnull[0] && fcinfo.argnull[1])
1514         {
1515                 /* Both NULL? Then is not distinct... */
1516                 result = BoolGetDatum(FALSE);
1517         }
1518         else if (fcinfo.argnull[0] || fcinfo.argnull[1])
1519         {
1520                 /* Only one is NULL? Then is distinct... */
1521                 result = BoolGetDatum(TRUE);
1522         }
1523         else
1524         {
1525                 fcinfo.isnull = false;
1526                 result = FunctionCallInvoke(&fcinfo);
1527                 *isNull = fcinfo.isnull;
1528                 /* Must invert result of "=" */
1529                 result = BoolGetDatum(!DatumGetBool(result));
1530         }
1531
1532         return result;
1533 }
1534
1535 /*
1536  * ExecEvalScalarArrayOp
1537  *
1538  * Evaluate "scalar op ANY/ALL (array)".  The operator always yields boolean,
1539  * and we combine the results across all array elements using OR and AND
1540  * (for ANY and ALL respectively).      Of course we short-circuit as soon as
1541  * the result is known.
1542  */
1543 static Datum
1544 ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
1545                                           ExprContext *econtext,
1546                                           bool *isNull, ExprDoneCond *isDone)
1547 {
1548         ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) sstate->fxprstate.xprstate.expr;
1549         bool            useOr = opexpr->useOr;
1550         ArrayType  *arr;
1551         int                     nitems;
1552         Datum           result;
1553         bool            resultnull;
1554         FunctionCallInfoData fcinfo;
1555         ExprDoneCond argDone;
1556         int                     i;
1557         int16           typlen;
1558         bool            typbyval;
1559         char            typalign;
1560         char       *s;
1561
1562         /* Set default values for result flags: non-null, not a set result */
1563         *isNull = false;
1564         if (isDone)
1565                 *isDone = ExprSingleResult;
1566
1567         /*
1568          * Initialize function cache if first time through
1569          */
1570         if (sstate->fxprstate.func.fn_oid == InvalidOid)
1571         {
1572                 init_fcache(opexpr->opfuncid, &sstate->fxprstate,
1573                                         econtext->ecxt_per_query_memory);
1574                 Assert(!sstate->fxprstate.func.fn_retset);
1575         }
1576
1577         /* Need to prep callinfo structure */
1578         MemSet(&fcinfo, 0, sizeof(fcinfo));
1579         fcinfo.flinfo = &(sstate->fxprstate.func);
1580         argDone = ExecEvalFuncArgs(&fcinfo, sstate->fxprstate.args, econtext);
1581         if (argDone != ExprSingleResult)
1582                 ereport(ERROR,
1583                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
1584                    errmsg("op ANY/ALL (array) does not support set arguments")));
1585         Assert(fcinfo.nargs == 2);
1586
1587         /*
1588          * If the array is NULL then we return NULL --- it's not very
1589          * meaningful to do anything else, even if the operator isn't strict.
1590          */
1591         if (fcinfo.argnull[1])
1592         {
1593                 *isNull = true;
1594                 return (Datum) 0;
1595         }
1596         /* Else okay to fetch and detoast the array */
1597         arr = DatumGetArrayTypeP(fcinfo.arg[1]);
1598
1599         /*
1600          * If the array is empty, we return either FALSE or TRUE per the useOr
1601          * flag.  This is correct even if the scalar is NULL; since we would
1602          * evaluate the operator zero times, it matters not whether it would
1603          * want to return NULL.
1604          */
1605         nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
1606         if (nitems <= 0)
1607                 return BoolGetDatum(!useOr);
1608
1609         /*
1610          * If the scalar is NULL, and the function is strict, return NULL.
1611          * This is just to avoid having to test for strictness inside the
1612          * loop.  (XXX but if arrays could have null elements, we'd need a
1613          * test anyway.)
1614          */
1615         if (fcinfo.argnull[0] && sstate->fxprstate.func.fn_strict)
1616         {
1617                 *isNull = true;
1618                 return (Datum) 0;
1619         }
1620
1621         /*
1622          * We arrange to look up info about the element type only once per
1623          * series of calls, assuming the element type doesn't change
1624          * underneath us.
1625          */
1626         if (sstate->element_type != ARR_ELEMTYPE(arr))
1627         {
1628                 get_typlenbyvalalign(ARR_ELEMTYPE(arr),
1629                                                          &sstate->typlen,
1630                                                          &sstate->typbyval,
1631                                                          &sstate->typalign);
1632                 sstate->element_type = ARR_ELEMTYPE(arr);
1633         }
1634         typlen = sstate->typlen;
1635         typbyval = sstate->typbyval;
1636         typalign = sstate->typalign;
1637
1638         result = BoolGetDatum(!useOr);
1639         resultnull = false;
1640
1641         /* Loop over the array elements */
1642         s = (char *) ARR_DATA_PTR(arr);
1643         for (i = 0; i < nitems; i++)
1644         {
1645                 Datum           elt;
1646                 Datum           thisresult;
1647
1648                 /* Get array element */
1649                 elt = fetch_att(s, typbyval, typlen);
1650
1651                 s = att_addlength(s, typlen, PointerGetDatum(s));
1652                 s = (char *) att_align(s, typalign);
1653
1654                 /* Call comparison function */
1655                 fcinfo.arg[1] = elt;
1656                 fcinfo.argnull[1] = false;
1657                 fcinfo.isnull = false;
1658                 thisresult = FunctionCallInvoke(&fcinfo);
1659
1660                 /* Combine results per OR or AND semantics */
1661                 if (fcinfo.isnull)
1662                         resultnull = true;
1663                 else if (useOr)
1664                 {
1665                         if (DatumGetBool(thisresult))
1666                         {
1667                                 result = BoolGetDatum(true);
1668                                 resultnull = false;
1669                                 break;                  /* needn't look at any more elements */
1670                         }
1671                 }
1672                 else
1673                 {
1674                         if (!DatumGetBool(thisresult))
1675                         {
1676                                 result = BoolGetDatum(false);
1677                                 resultnull = false;
1678                                 break;                  /* needn't look at any more elements */
1679                         }
1680                 }
1681         }
1682
1683         *isNull = resultnull;
1684         return result;
1685 }
1686
1687 /* ----------------------------------------------------------------
1688  *              ExecEvalNot
1689  *              ExecEvalOr
1690  *              ExecEvalAnd
1691  *
1692  *              Evaluate boolean expressions, with appropriate short-circuiting.
1693  *
1694  *              The query planner reformulates clause expressions in the
1695  *              qualification to conjunctive normal form.  If we ever get
1696  *              an AND to evaluate, we can be sure that it's not a top-level
1697  *              clause in the qualification, but appears lower (as a function
1698  *              argument, for example), or in the target list.  Not that you
1699  *              need to know this, mind you...
1700  * ----------------------------------------------------------------
1701  */
1702 static Datum
1703 ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
1704                         bool *isNull, ExprDoneCond *isDone)
1705 {
1706         ExprState  *clause = linitial(notclause->args);
1707         Datum           expr_value;
1708
1709         if (isDone)
1710                 *isDone = ExprSingleResult;
1711
1712         expr_value = ExecEvalExpr(clause, econtext, isNull, NULL);
1713
1714         /*
1715          * if the expression evaluates to null, then we just cascade the null
1716          * back to whoever called us.
1717          */
1718         if (*isNull)
1719                 return expr_value;
1720
1721         /*
1722          * evaluation of 'not' is simple.. expr is false, then return 'true'
1723          * and vice versa.
1724          */
1725         return BoolGetDatum(!DatumGetBool(expr_value));
1726 }
1727
1728 /* ----------------------------------------------------------------
1729  *              ExecEvalOr
1730  * ----------------------------------------------------------------
1731  */
1732 static Datum
1733 ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
1734                    bool *isNull, ExprDoneCond *isDone)
1735 {
1736         List       *clauses = orExpr->args;
1737         ListCell   *clause;
1738         bool            AnyNull;
1739
1740         if (isDone)
1741                 *isDone = ExprSingleResult;
1742
1743         AnyNull = false;
1744
1745         /*
1746          * If any of the clauses is TRUE, the OR result is TRUE regardless of
1747          * the states of the rest of the clauses, so we can stop evaluating
1748          * and return TRUE immediately.  If none are TRUE and one or more is
1749          * NULL, we return NULL; otherwise we return FALSE.  This makes sense
1750          * when you interpret NULL as "don't know": if we have a TRUE then the
1751          * OR is TRUE even if we aren't sure about some of the other inputs.
1752          * If all the known inputs are FALSE, but we have one or more "don't
1753          * knows", then we have to report that we "don't know" what the OR's
1754          * result should be --- perhaps one of the "don't knows" would have
1755          * been TRUE if we'd known its value.  Only when all the inputs are
1756          * known to be FALSE can we state confidently that the OR's result is
1757          * FALSE.
1758          */
1759         foreach(clause, clauses)
1760         {
1761                 ExprState  *clausestate = (ExprState *) lfirst(clause);
1762                 Datum           clause_value;
1763
1764                 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
1765
1766                 /*
1767                  * if we have a non-null true result, then return it.
1768                  */
1769                 if (*isNull)
1770                         AnyNull = true;         /* remember we got a null */
1771                 else if (DatumGetBool(clause_value))
1772                         return clause_value;
1773         }
1774
1775         /* AnyNull is true if at least one clause evaluated to NULL */
1776         *isNull = AnyNull;
1777         return BoolGetDatum(false);
1778 }
1779
1780 /* ----------------------------------------------------------------
1781  *              ExecEvalAnd
1782  * ----------------------------------------------------------------
1783  */
1784 static Datum
1785 ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
1786                         bool *isNull, ExprDoneCond *isDone)
1787 {
1788         List       *clauses = andExpr->args;
1789         ListCell   *clause;
1790         bool            AnyNull;
1791
1792         if (isDone)
1793                 *isDone = ExprSingleResult;
1794
1795         AnyNull = false;
1796
1797         /*
1798          * If any of the clauses is FALSE, the AND result is FALSE regardless
1799          * of the states of the rest of the clauses, so we can stop evaluating
1800          * and return FALSE immediately.  If none are FALSE and one or more is
1801          * NULL, we return NULL; otherwise we return TRUE.      This makes sense
1802          * when you interpret NULL as "don't know", using the same sort of
1803          * reasoning as for OR, above.
1804          */
1805
1806         foreach(clause, clauses)
1807         {
1808                 ExprState  *clausestate = (ExprState *) lfirst(clause);
1809                 Datum           clause_value;
1810
1811                 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
1812
1813                 /*
1814                  * if we have a non-null false result, then return it.
1815                  */
1816                 if (*isNull)
1817                         AnyNull = true;         /* remember we got a null */
1818                 else if (!DatumGetBool(clause_value))
1819                         return clause_value;
1820         }
1821
1822         /* AnyNull is true if at least one clause evaluated to NULL */
1823         *isNull = AnyNull;
1824         return BoolGetDatum(!AnyNull);
1825 }
1826
1827
1828 /* ----------------------------------------------------------------
1829  *              ExecEvalCase
1830  *
1831  *              Evaluate a CASE clause. Will have boolean expressions
1832  *              inside the WHEN clauses, and will have expressions
1833  *              for results.
1834  *              - thomas 1998-11-09
1835  * ----------------------------------------------------------------
1836  */
1837 static Datum
1838 ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
1839                          bool *isNull, ExprDoneCond *isDone)
1840 {
1841         List       *clauses = caseExpr->args;
1842         ListCell   *clause;
1843         Datum           save_datum;
1844         bool            save_isNull;
1845
1846         if (isDone)
1847                 *isDone = ExprSingleResult;
1848
1849         /*
1850          * If there's a test expression, we have to evaluate it and save
1851          * the value where the CaseTestExpr placeholders can find it.
1852          * We must save and restore prior setting of econtext's caseValue fields,
1853          * in case this node is itself within a larger CASE.
1854          */
1855         save_datum = econtext->caseValue_datum;
1856         save_isNull = econtext->caseValue_isNull;
1857
1858         if (caseExpr->arg)
1859         {
1860                 econtext->caseValue_datum = ExecEvalExpr(caseExpr->arg,
1861                                                                                                  econtext,
1862                                                                                                  &econtext->caseValue_isNull,
1863                                                                                                  NULL);
1864         }
1865
1866         /*
1867          * we evaluate each of the WHEN clauses in turn, as soon as one is
1868          * true we return the corresponding result. If none are true then we
1869          * return the value of the default clause, or NULL if there is none.
1870          */
1871         foreach(clause, clauses)
1872         {
1873                 CaseWhenState *wclause = lfirst(clause);
1874                 Datum           clause_value;
1875
1876                 clause_value = ExecEvalExpr(wclause->expr,
1877                                                                         econtext,
1878                                                                         isNull,
1879                                                                         NULL);
1880
1881                 /*
1882                  * if we have a true test, then we return the result, since the
1883                  * case statement is satisfied.  A NULL result from the test is
1884                  * not considered true.
1885                  */
1886                 if (DatumGetBool(clause_value) && !*isNull)
1887                 {
1888                         econtext->caseValue_datum = save_datum;
1889                         econtext->caseValue_isNull = save_isNull;
1890                         return ExecEvalExpr(wclause->result,
1891                                                                 econtext,
1892                                                                 isNull,
1893                                                                 isDone);
1894                 }
1895         }
1896
1897         econtext->caseValue_datum = save_datum;
1898         econtext->caseValue_isNull = save_isNull;
1899
1900         if (caseExpr->defresult)
1901         {
1902                 return ExecEvalExpr(caseExpr->defresult,
1903                                                         econtext,
1904                                                         isNull,
1905                                                         isDone);
1906         }
1907
1908         *isNull = true;
1909         return (Datum) 0;
1910 }
1911
1912 /*
1913  * ExecEvalCaseTestExpr
1914  *
1915  * Return the value stored by CASE.
1916  */
1917 static Datum
1918 ExecEvalCaseTestExpr(ExprState *exprstate,
1919                                          ExprContext *econtext,
1920                                          bool *isNull, ExprDoneCond *isDone)
1921 {
1922         if (isDone)
1923                 *isDone = ExprSingleResult;
1924         *isNull = econtext->caseValue_isNull;
1925         return econtext->caseValue_datum;
1926 }
1927
1928 /* ----------------------------------------------------------------
1929  *              ExecEvalArray - ARRAY[] expressions
1930  *
1931  * NOTE: currently, if any input value is NULL then we return a NULL array,
1932  * so the ARRAY[] construct can be considered strict.  Eventually this will
1933  * change; when it does, be sure to fix contain_nonstrict_functions().
1934  * ----------------------------------------------------------------
1935  */
1936 static Datum
1937 ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
1938                           bool *isNull, ExprDoneCond *isDone)
1939 {
1940         ArrayExpr  *arrayExpr = (ArrayExpr *) astate->xprstate.expr;
1941         ArrayType  *result;
1942         ListCell   *element;
1943         Oid                     element_type = arrayExpr->element_typeid;
1944         int                     ndims = 0;
1945         int                     dims[MAXDIM];
1946         int                     lbs[MAXDIM];
1947
1948         /* Set default values for result flags: non-null, not a set result */
1949         *isNull = false;
1950         if (isDone)
1951                 *isDone = ExprSingleResult;
1952
1953         if (!arrayExpr->multidims)
1954         {
1955                 /* Elements are presumably of scalar type */
1956                 int                     nelems;
1957                 Datum      *dvalues;
1958                 int                     i = 0;
1959
1960                 ndims = 1;
1961                 nelems = list_length(astate->elements);
1962
1963                 /* Shouldn't happen here, but if length is 0, return NULL */
1964                 if (nelems == 0)
1965                 {
1966                         *isNull = true;
1967                         return (Datum) 0;
1968                 }
1969
1970                 dvalues = (Datum *) palloc(nelems * sizeof(Datum));
1971
1972                 /* loop through and build array of datums */
1973                 foreach(element, astate->elements)
1974                 {
1975                         ExprState  *e = (ExprState *) lfirst(element);
1976                         bool            eisnull;
1977
1978                         dvalues[i++] = ExecEvalExpr(e, econtext, &eisnull, NULL);
1979                         if (eisnull)
1980                         {
1981                                 *isNull = true;
1982                                 return (Datum) 0;
1983                         }
1984                 }
1985
1986                 /* setup for 1-D array of the given length */
1987                 dims[0] = nelems;
1988                 lbs[0] = 1;
1989
1990                 result = construct_md_array(dvalues, ndims, dims, lbs,
1991                                                                         element_type,
1992                                                                         astate->elemlength,
1993                                                                         astate->elembyval,
1994                                                                         astate->elemalign);
1995         }
1996         else
1997         {
1998                 /* Must be nested array expressions */
1999                 char       *dat = NULL;
2000                 Size            ndatabytes = 0;
2001                 int                     nbytes;
2002                 int                     outer_nelems = list_length(astate->elements);
2003                 int                     elem_ndims = 0;
2004                 int                *elem_dims = NULL;
2005                 int                *elem_lbs = NULL;
2006                 bool            firstone = true;
2007                 int                     i;
2008
2009                 /* loop through and get data area from each element */
2010                 foreach(element, astate->elements)
2011                 {
2012                         ExprState  *e = (ExprState *) lfirst(element);
2013                         bool            eisnull;
2014                         Datum           arraydatum;
2015                         ArrayType  *array;
2016                         int                     elem_ndatabytes;
2017
2018                         arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
2019                         if (eisnull)
2020                         {
2021                                 *isNull = true;
2022                                 return (Datum) 0;
2023                         }
2024
2025                         array = DatumGetArrayTypeP(arraydatum);
2026
2027                         /* run-time double-check on element type */
2028                         if (element_type != ARR_ELEMTYPE(array))
2029                                 ereport(ERROR,
2030                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
2031                                                  errmsg("cannot merge incompatible arrays"),
2032                                                  errdetail("Array with element type %s cannot be "
2033                                                                    "included in ARRAY construct with element type %s.",
2034                                                                    format_type_be(ARR_ELEMTYPE(array)),
2035                                                                    format_type_be(element_type))));
2036
2037                         if (firstone)
2038                         {
2039                                 /* Get sub-array details from first member */
2040                                 elem_ndims = ARR_NDIM(array);
2041                                 ndims = elem_ndims + 1;
2042                                 if (ndims <= 0 || ndims > MAXDIM)
2043                                         ereport(ERROR,
2044                                                         (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2045                                                          errmsg("number of array dimensions (%d) exceeds " \
2046                                                                         "the maximum allowed (%d)", ndims, MAXDIM)));
2047
2048                                 elem_dims = (int *) palloc(elem_ndims * sizeof(int));
2049                                 memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
2050                                 elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
2051                                 memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
2052
2053                                 firstone = false;
2054                         }
2055                         else
2056                         {
2057                                 /* Check other sub-arrays are compatible */
2058                                 if (elem_ndims != ARR_NDIM(array) ||
2059                                         memcmp(elem_dims, ARR_DIMS(array),
2060                                                    elem_ndims * sizeof(int)) != 0 ||
2061                                         memcmp(elem_lbs, ARR_LBOUND(array),
2062                                                    elem_ndims * sizeof(int)) != 0)
2063                                         ereport(ERROR,
2064                                                         (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2065                                                 errmsg("multidimensional arrays must have array "
2066                                                            "expressions with matching dimensions")));
2067                         }
2068
2069                         elem_ndatabytes = ARR_SIZE(array) - ARR_OVERHEAD(elem_ndims);
2070                         ndatabytes += elem_ndatabytes;
2071                         if (dat == NULL)
2072                                 dat = (char *) palloc(ndatabytes);
2073                         else
2074                                 dat = (char *) repalloc(dat, ndatabytes);
2075
2076                         memcpy(dat + (ndatabytes - elem_ndatabytes),
2077                                    ARR_DATA_PTR(array),
2078                                    elem_ndatabytes);
2079                 }
2080
2081                 /* setup for multi-D array */
2082                 dims[0] = outer_nelems;
2083                 lbs[0] = 1;
2084                 for (i = 1; i < ndims; i++)
2085                 {
2086                         dims[i] = elem_dims[i - 1];
2087                         lbs[i] = elem_lbs[i - 1];
2088                 }
2089
2090                 nbytes = ndatabytes + ARR_OVERHEAD(ndims);
2091                 result = (ArrayType *) palloc(nbytes);
2092
2093                 result->size = nbytes;
2094                 result->ndim = ndims;
2095                 result->flags = 0;
2096                 result->elemtype = element_type;
2097                 memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
2098                 memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
2099                 if (ndatabytes > 0)
2100                         memcpy(ARR_DATA_PTR(result), dat, ndatabytes);
2101
2102                 if (dat != NULL)
2103                         pfree(dat);
2104         }
2105
2106         return PointerGetDatum(result);
2107 }
2108
2109 /* ----------------------------------------------------------------
2110  *              ExecEvalRow - ROW() expressions
2111  * ----------------------------------------------------------------
2112  */
2113 static Datum
2114 ExecEvalRow(RowExprState *rstate,
2115                         ExprContext *econtext,
2116                         bool *isNull, ExprDoneCond *isDone)
2117 {
2118         HeapTuple       tuple;
2119         Datum      *values;
2120         char       *nulls;
2121         int                     nargs;
2122         ListCell   *arg;
2123         int                     i;
2124
2125         /* Set default values for result flags: non-null, not a set result */
2126         *isNull = false;
2127         if (isDone)
2128                 *isDone = ExprSingleResult;
2129
2130         /* Allocate workspace */
2131         nargs = list_length(rstate->args);
2132         if (nargs == 0)                         /* avoid palloc(0) if no fields */
2133                 nargs = 1;
2134         values = (Datum *) palloc(nargs * sizeof(Datum));
2135         nulls = (char *) palloc(nargs * sizeof(char));
2136
2137         /* Evaluate field values */
2138         i = 0;
2139         foreach(arg, rstate->args)
2140         {
2141                 ExprState  *e = (ExprState *) lfirst(arg);
2142                 bool            eisnull;
2143
2144                 values[i] = ExecEvalExpr(e, econtext, &eisnull, NULL);
2145                 nulls[i] = eisnull ? 'n' : ' ';
2146                 i++;
2147         }
2148
2149         tuple = heap_formtuple(rstate->tupdesc, values, nulls);
2150
2151         pfree(values);
2152         pfree(nulls);
2153
2154         return HeapTupleGetDatum(tuple);
2155 }
2156
2157 /* ----------------------------------------------------------------
2158  *              ExecEvalCoalesce
2159  * ----------------------------------------------------------------
2160  */
2161 static Datum
2162 ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
2163                                  bool *isNull, ExprDoneCond *isDone)
2164 {
2165         ListCell   *arg;
2166
2167         if (isDone)
2168                 *isDone = ExprSingleResult;
2169
2170         /* Simply loop through until something NOT NULL is found */
2171         foreach(arg, coalesceExpr->args)
2172         {
2173                 ExprState  *e = (ExprState *) lfirst(arg);
2174                 Datum           value;
2175
2176                 value = ExecEvalExpr(e, econtext, isNull, NULL);
2177                 if (!*isNull)
2178                         return value;
2179         }
2180
2181         /* Else return NULL */
2182         *isNull = true;
2183         return (Datum) 0;
2184 }
2185
2186 /* ----------------------------------------------------------------
2187  *              ExecEvalNullIf
2188  *
2189  * Note that this is *always* derived from the equals operator,
2190  * but since we need special processing of the arguments
2191  * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
2192  * ----------------------------------------------------------------
2193  */
2194 static Datum
2195 ExecEvalNullIf(FuncExprState *nullIfExpr,
2196                            ExprContext *econtext,
2197                            bool *isNull, ExprDoneCond *isDone)
2198 {
2199         Datum           result;
2200         FunctionCallInfoData fcinfo;
2201         ExprDoneCond argDone;
2202         List       *argList;
2203
2204         if (isDone)
2205                 *isDone = ExprSingleResult;
2206
2207         /*
2208          * Initialize function cache if first time through
2209          */
2210         if (nullIfExpr->func.fn_oid == InvalidOid)
2211         {
2212                 NullIfExpr *op = (NullIfExpr *) nullIfExpr->xprstate.expr;
2213
2214                 init_fcache(op->opfuncid, nullIfExpr, econtext->ecxt_per_query_memory);
2215                 Assert(!nullIfExpr->func.fn_retset);
2216         }
2217
2218         /*
2219          * extract info from nullIfExpr
2220          */
2221         argList = nullIfExpr->args;
2222
2223         /* Need to prep callinfo structure */
2224         MemSet(&fcinfo, 0, sizeof(fcinfo));
2225         fcinfo.flinfo = &(nullIfExpr->func);
2226         argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
2227         if (argDone != ExprSingleResult)
2228                 ereport(ERROR,
2229                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
2230                                  errmsg("NULLIF does not support set arguments")));
2231         Assert(fcinfo.nargs == 2);
2232
2233         /* if either argument is NULL they can't be equal */
2234         if (!fcinfo.argnull[0] && !fcinfo.argnull[1])
2235         {
2236                 fcinfo.isnull = false;
2237                 result = FunctionCallInvoke(&fcinfo);
2238                 /* if the arguments are equal return null */
2239                 if (!fcinfo.isnull && DatumGetBool(result))
2240                 {
2241                         *isNull = true;
2242                         return (Datum) 0;
2243                 }
2244         }
2245
2246         /* else return first argument */
2247         *isNull = fcinfo.argnull[0];
2248         return fcinfo.arg[0];
2249 }
2250
2251 /* ----------------------------------------------------------------
2252  *              ExecEvalNullTest
2253  *
2254  *              Evaluate a NullTest node.
2255  * ----------------------------------------------------------------
2256  */
2257 static Datum
2258 ExecEvalNullTest(GenericExprState *nstate,
2259                                  ExprContext *econtext,
2260                                  bool *isNull,
2261                                  ExprDoneCond *isDone)
2262 {
2263         NullTest   *ntest = (NullTest *) nstate->xprstate.expr;
2264         Datum           result;
2265
2266         result = ExecEvalExpr(nstate->arg, econtext, isNull, isDone);
2267
2268         if (isDone && *isDone == ExprEndResult)
2269                 return result;                  /* nothing to check */
2270
2271         switch (ntest->nulltesttype)
2272         {
2273                 case IS_NULL:
2274                         if (*isNull)
2275                         {
2276                                 *isNull = false;
2277                                 return BoolGetDatum(true);
2278                         }
2279                         else
2280                                 return BoolGetDatum(false);
2281                 case IS_NOT_NULL:
2282                         if (*isNull)
2283                         {
2284                                 *isNull = false;
2285                                 return BoolGetDatum(false);
2286                         }
2287                         else
2288                                 return BoolGetDatum(true);
2289                 default:
2290                         elog(ERROR, "unrecognized nulltesttype: %d",
2291                                  (int) ntest->nulltesttype);
2292                         return (Datum) 0;       /* keep compiler quiet */
2293         }
2294 }
2295
2296 /* ----------------------------------------------------------------
2297  *              ExecEvalBooleanTest
2298  *
2299  *              Evaluate a BooleanTest node.
2300  * ----------------------------------------------------------------
2301  */
2302 static Datum
2303 ExecEvalBooleanTest(GenericExprState *bstate,
2304                                         ExprContext *econtext,
2305                                         bool *isNull,
2306                                         ExprDoneCond *isDone)
2307 {
2308         BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;
2309         Datum           result;
2310
2311         result = ExecEvalExpr(bstate->arg, econtext, isNull, isDone);
2312
2313         if (isDone && *isDone == ExprEndResult)
2314                 return result;                  /* nothing to check */
2315
2316         switch (btest->booltesttype)
2317         {
2318                 case IS_TRUE:
2319                         if (*isNull)
2320                         {
2321                                 *isNull = false;
2322                                 return BoolGetDatum(false);
2323                         }
2324                         else if (DatumGetBool(result))
2325                                 return BoolGetDatum(true);
2326                         else
2327                                 return BoolGetDatum(false);
2328                 case IS_NOT_TRUE:
2329                         if (*isNull)
2330                         {
2331                                 *isNull = false;
2332                                 return BoolGetDatum(true);
2333                         }
2334                         else if (DatumGetBool(result))
2335                                 return BoolGetDatum(false);
2336                         else
2337                                 return BoolGetDatum(true);
2338                 case IS_FALSE:
2339                         if (*isNull)
2340                         {
2341                                 *isNull = false;
2342                                 return BoolGetDatum(false);
2343                         }
2344                         else if (DatumGetBool(result))
2345                                 return BoolGetDatum(false);
2346                         else
2347                                 return BoolGetDatum(true);
2348                 case IS_NOT_FALSE:
2349                         if (*isNull)
2350                         {
2351                                 *isNull = false;
2352                                 return BoolGetDatum(true);
2353                         }
2354                         else if (DatumGetBool(result))
2355                                 return BoolGetDatum(true);
2356                         else
2357                                 return BoolGetDatum(false);
2358                 case IS_UNKNOWN:
2359                         if (*isNull)
2360                         {
2361                                 *isNull = false;
2362                                 return BoolGetDatum(true);
2363                         }
2364                         else
2365                                 return BoolGetDatum(false);
2366                 case IS_NOT_UNKNOWN:
2367                         if (*isNull)
2368                         {
2369                                 *isNull = false;
2370                                 return BoolGetDatum(false);
2371                         }
2372                         else
2373                                 return BoolGetDatum(true);
2374                 default:
2375                         elog(ERROR, "unrecognized booltesttype: %d",
2376                                  (int) btest->booltesttype);
2377                         return (Datum) 0;       /* keep compiler quiet */
2378         }
2379 }
2380
2381 /*
2382  * ExecEvalCoerceToDomain
2383  *
2384  * Test the provided data against the domain constraint(s).  If the data
2385  * passes the constraint specifications, pass it through (return the
2386  * datum) otherwise throw an error.
2387  */
2388 static Datum
2389 ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
2390                                            bool *isNull, ExprDoneCond *isDone)
2391 {
2392         CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
2393         Datum           result;
2394         ListCell   *l;
2395
2396         result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
2397
2398         if (isDone && *isDone == ExprEndResult)
2399                 return result;                  /* nothing to check */
2400
2401         foreach(l, cstate->constraints)
2402         {
2403                 DomainConstraintState *con = (DomainConstraintState *) lfirst(l);
2404
2405                 switch (con->constrainttype)
2406                 {
2407                         case DOM_CONSTRAINT_NOTNULL:
2408                                 if (*isNull)
2409                                         ereport(ERROR,
2410                                                         (errcode(ERRCODE_NOT_NULL_VIOLATION),
2411                                                    errmsg("domain %s does not allow null values",
2412                                                                   format_type_be(ctest->resulttype))));
2413                                 break;
2414                         case DOM_CONSTRAINT_CHECK:
2415                                 {
2416                                         Datum           conResult;
2417                                         bool            conIsNull;
2418                                         Datum           save_datum;
2419                                         bool            save_isNull;
2420
2421                                         /*
2422                                          * Set up value to be returned by CoerceToDomainValue
2423                                          * nodes. We must save and restore prior setting of
2424                                          * econtext's domainValue fields, in case this node is
2425                                          * itself within a check expression for another
2426                                          * domain.
2427                                          */
2428                                         save_datum = econtext->domainValue_datum;
2429                                         save_isNull = econtext->domainValue_isNull;
2430
2431                                         econtext->domainValue_datum = result;
2432                                         econtext->domainValue_isNull = *isNull;
2433
2434                                         conResult = ExecEvalExpr(con->check_expr,
2435                                                                                          econtext, &conIsNull, NULL);
2436
2437                                         if (!conIsNull &&
2438                                                 !DatumGetBool(conResult))
2439                                                 ereport(ERROR,
2440                                                                 (errcode(ERRCODE_CHECK_VIOLATION),
2441                                                                  errmsg("value for domain %s violates check constraint \"%s\"",
2442                                                                                 format_type_be(ctest->resulttype),
2443                                                                                 con->name)));
2444                                         econtext->domainValue_datum = save_datum;
2445                                         econtext->domainValue_isNull = save_isNull;
2446
2447                                         break;
2448                                 }
2449                         default:
2450                                 elog(ERROR, "unrecognized constraint type: %d",
2451                                          (int) con->constrainttype);
2452                                 break;
2453                 }
2454         }
2455
2456         /* If all has gone well (constraints did not fail) return the datum */
2457         return result;
2458 }
2459
2460 /*
2461  * ExecEvalCoerceToDomainValue
2462  *
2463  * Return the value stored by CoerceToDomain.
2464  */
2465 static Datum
2466 ExecEvalCoerceToDomainValue(ExprState *exprstate,
2467                                                         ExprContext *econtext,
2468                                                         bool *isNull, ExprDoneCond *isDone)
2469 {
2470         if (isDone)
2471                 *isDone = ExprSingleResult;
2472         *isNull = econtext->domainValue_isNull;
2473         return econtext->domainValue_datum;
2474 }
2475
2476 /* ----------------------------------------------------------------
2477  *              ExecEvalFieldSelect
2478  *
2479  *              Evaluate a FieldSelect node.
2480  * ----------------------------------------------------------------
2481  */
2482 static Datum
2483 ExecEvalFieldSelect(FieldSelectState *fstate,
2484                                         ExprContext *econtext,
2485                                         bool *isNull,
2486                                         ExprDoneCond *isDone)
2487 {
2488         FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
2489         Datum           result;
2490         Datum           tupDatum;
2491         HeapTupleHeader tuple;
2492         Oid                     tupType;
2493         int32           tupTypmod;
2494         TupleDesc       tupDesc;
2495         HeapTupleData tmptup;
2496
2497         tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
2498
2499         /* this test covers the isDone exception too: */
2500         if (*isNull)
2501                 return tupDatum;
2502
2503         tuple = DatumGetHeapTupleHeader(tupDatum);
2504
2505         tupType = HeapTupleHeaderGetTypeId(tuple);
2506         tupTypmod = HeapTupleHeaderGetTypMod(tuple);
2507
2508         /* Lookup tupdesc if first time through or if type changes */
2509         tupDesc = fstate->argdesc;
2510         if (tupDesc == NULL ||
2511                 tupType != tupDesc->tdtypeid ||
2512                 tupTypmod != tupDesc->tdtypmod)
2513         {
2514                 MemoryContext oldcontext;
2515
2516                 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
2517                 /* Copy the tupdesc into query storage for safety */
2518                 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2519                 tupDesc = CreateTupleDescCopy(tupDesc);
2520                 if (fstate->argdesc)
2521                         FreeTupleDesc(fstate->argdesc);
2522                 fstate->argdesc = tupDesc;
2523                 MemoryContextSwitchTo(oldcontext);
2524         }
2525
2526         /*
2527          * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set
2528          * all the fields in the struct just in case user tries to inspect
2529          * system columns.
2530          */
2531         tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2532         ItemPointerSetInvalid(&(tmptup.t_self));
2533         tmptup.t_tableOid = InvalidOid;
2534         tmptup.t_data = tuple;
2535
2536         result = heap_getattr(&tmptup,
2537                                                   fselect->fieldnum,
2538                                                   tupDesc,
2539                                                   isNull);
2540         return result;
2541 }
2542
2543 /* ----------------------------------------------------------------
2544  *              ExecEvalRelabelType
2545  *
2546  *              Evaluate a RelabelType node.
2547  * ----------------------------------------------------------------
2548  */
2549 static Datum
2550 ExecEvalRelabelType(GenericExprState *exprstate,
2551                                         ExprContext *econtext,
2552                                         bool *isNull, ExprDoneCond *isDone)
2553 {
2554         return ExecEvalExpr(exprstate->arg, econtext, isNull, isDone);
2555 }
2556
2557
2558 /*
2559  * ExecEvalExprSwitchContext
2560  *
2561  * Same as ExecEvalExpr, but get into the right allocation context explicitly.
2562  */
2563 Datum
2564 ExecEvalExprSwitchContext(ExprState *expression,
2565                                                   ExprContext *econtext,
2566                                                   bool *isNull,
2567                                                   ExprDoneCond *isDone)
2568 {
2569         Datum           retDatum;
2570         MemoryContext oldContext;
2571
2572         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
2573         retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
2574         MemoryContextSwitchTo(oldContext);
2575         return retDatum;
2576 }
2577
2578
2579 /*
2580  * ExecInitExpr: prepare an expression tree for execution
2581  *
2582  * This function builds and returns an ExprState tree paralleling the given
2583  * Expr node tree.      The ExprState tree can then be handed to ExecEvalExpr
2584  * for execution.  Because the Expr tree itself is read-only as far as
2585  * ExecInitExpr and ExecEvalExpr are concerned, several different executions
2586  * of the same plan tree can occur concurrently.
2587  *
2588  * This must be called in a memory context that will last as long as repeated
2589  * executions of the expression are needed.  Typically the context will be
2590  * the same as the per-query context of the associated ExprContext.
2591  *
2592  * Any Aggref and SubPlan nodes found in the tree are added to the lists
2593  * of such nodes held by the parent PlanState.  Otherwise, we do very little
2594  * initialization here other than building the state-node tree.  Any nontrivial
2595  * work associated with initializing runtime info for a node should happen
2596  * during the first actual evaluation of that node.  (This policy lets us
2597  * avoid work if the node is never actually evaluated.)
2598  *
2599  * Note: there is no ExecEndExpr function; we assume that any resource
2600  * cleanup needed will be handled by just releasing the memory context
2601  * in which the state tree is built.  Functions that require additional
2602  * cleanup work can register a shutdown callback in the ExprContext.
2603  *
2604  *      'node' is the root of the expression tree to examine
2605  *      'parent' is the PlanState node that owns the expression.
2606  *
2607  * 'parent' may be NULL if we are preparing an expression that is not
2608  * associated with a plan tree.  (If so, it can't have aggs or subplans.)
2609  * This case should usually come through ExecPrepareExpr, not directly here.
2610  */
2611 ExprState *
2612 ExecInitExpr(Expr *node, PlanState *parent)
2613 {
2614         ExprState  *state;
2615
2616         if (node == NULL)
2617                 return NULL;
2618
2619         /* Guard against stack overflow due to overly complex expressions */
2620         check_stack_depth();
2621
2622         switch (nodeTag(node))
2623         {
2624                 case T_Var:
2625                         state = (ExprState *) makeNode(ExprState);
2626                         state->evalfunc = ExecEvalVar;
2627                         break;
2628                 case T_Const:
2629                         state = (ExprState *) makeNode(ExprState);
2630                         state->evalfunc = ExecEvalConst;
2631                         break;
2632                 case T_Param:
2633                         state = (ExprState *) makeNode(ExprState);
2634                         state->evalfunc = ExecEvalParam;
2635                         break;
2636                 case T_CoerceToDomainValue:
2637                         state = (ExprState *) makeNode(ExprState);
2638                         state->evalfunc = ExecEvalCoerceToDomainValue;
2639                         break;
2640                 case T_CaseTestExpr:
2641                         state = (ExprState *) makeNode(ExprState);
2642                         state->evalfunc = ExecEvalCaseTestExpr;
2643                         break;
2644                 case T_Aggref:
2645                         {
2646                                 Aggref     *aggref = (Aggref *) node;
2647                                 AggrefExprState *astate = makeNode(AggrefExprState);
2648
2649                                 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAggref;
2650                                 if (parent && IsA(parent, AggState))
2651                                 {
2652                                         AggState   *aggstate = (AggState *) parent;
2653                                         int                     naggs;
2654
2655                                         aggstate->aggs = lcons(astate, aggstate->aggs);
2656                                         naggs = ++aggstate->numaggs;
2657
2658                                         astate->target = ExecInitExpr(aggref->target, parent);
2659
2660                                         /*
2661                                          * Complain if the aggregate's argument contains any
2662                                          * aggregates; nested agg functions are semantically
2663                                          * nonsensical.  (This should have been caught
2664                                          * earlier, but we defend against it here anyway.)
2665                                          */
2666                                         if (naggs != aggstate->numaggs)
2667                                                 ereport(ERROR,
2668                                                                 (errcode(ERRCODE_GROUPING_ERROR),
2669                                                                  errmsg("aggregate function calls may not be nested")));
2670                                 }
2671                                 else
2672                                 {
2673                                         /* planner messed up */
2674                                         elog(ERROR, "aggref found in non-Agg plan node");
2675                                 }
2676                                 state = (ExprState *) astate;
2677                         }
2678                         break;
2679                 case T_ArrayRef:
2680                         {
2681                                 ArrayRef   *aref = (ArrayRef *) node;
2682                                 ArrayRefExprState *astate = makeNode(ArrayRefExprState);
2683
2684                                 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayRef;
2685                                 astate->refupperindexpr = (List *)
2686                                         ExecInitExpr((Expr *) aref->refupperindexpr, parent);
2687                                 astate->reflowerindexpr = (List *)
2688                                         ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
2689                                 astate->refexpr = ExecInitExpr(aref->refexpr, parent);
2690                                 astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
2691                                                                                                         parent);
2692                                 /* do one-time catalog lookups for type info */
2693                                 astate->refattrlength = get_typlen(aref->refarraytype);
2694                                 get_typlenbyvalalign(aref->refelemtype,
2695                                                                          &astate->refelemlength,
2696                                                                          &astate->refelembyval,
2697                                                                          &astate->refelemalign);
2698                                 state = (ExprState *) astate;
2699                         }
2700                         break;
2701                 case T_FuncExpr:
2702                         {
2703                                 FuncExpr   *funcexpr = (FuncExpr *) node;
2704                                 FuncExprState *fstate = makeNode(FuncExprState);
2705
2706                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFunc;
2707                                 fstate->args = (List *)
2708                                         ExecInitExpr((Expr *) funcexpr->args, parent);
2709                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
2710                                 state = (ExprState *) fstate;
2711                         }
2712                         break;
2713                 case T_OpExpr:
2714                         {
2715                                 OpExpr     *opexpr = (OpExpr *) node;
2716                                 FuncExprState *fstate = makeNode(FuncExprState);
2717
2718                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOper;
2719                                 fstate->args = (List *)
2720                                         ExecInitExpr((Expr *) opexpr->args, parent);
2721                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
2722                                 state = (ExprState *) fstate;
2723                         }
2724                         break;
2725                 case T_DistinctExpr:
2726                         {
2727                                 DistinctExpr *distinctexpr = (DistinctExpr *) node;
2728                                 FuncExprState *fstate = makeNode(FuncExprState);
2729
2730                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalDistinct;
2731                                 fstate->args = (List *)
2732                                         ExecInitExpr((Expr *) distinctexpr->args, parent);
2733                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
2734                                 state = (ExprState *) fstate;
2735                         }
2736                         break;
2737                 case T_ScalarArrayOpExpr:
2738                         {
2739                                 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
2740                                 ScalarArrayOpExprState *sstate = makeNode(ScalarArrayOpExprState);
2741
2742                                 sstate->fxprstate.xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalScalarArrayOp;
2743                                 sstate->fxprstate.args = (List *)
2744                                         ExecInitExpr((Expr *) opexpr->args, parent);
2745                                 sstate->fxprstate.func.fn_oid = InvalidOid;             /* not initialized */
2746                                 sstate->element_type = InvalidOid;              /* ditto */
2747                                 state = (ExprState *) sstate;
2748                         }
2749                         break;
2750                 case T_BoolExpr:
2751                         {
2752                                 BoolExpr   *boolexpr = (BoolExpr *) node;
2753                                 BoolExprState *bstate = makeNode(BoolExprState);
2754
2755                                 switch (boolexpr->boolop)
2756                                 {
2757                                         case AND_EXPR:
2758                                                 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAnd;
2759                                                 break;
2760                                         case OR_EXPR:
2761                                                 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOr;
2762                                                 break;
2763                                         case NOT_EXPR:
2764                                                 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNot;
2765                                                 break;
2766                                         default:
2767                                                 elog(ERROR, "unrecognized boolop: %d",
2768                                                          (int) boolexpr->boolop);
2769                                                 break;
2770                                 }
2771                                 bstate->args = (List *)
2772                                         ExecInitExpr((Expr *) boolexpr->args, parent);
2773                                 state = (ExprState *) bstate;
2774                         }
2775                         break;
2776                 case T_SubPlan:
2777                         {
2778                                 /* Keep this in sync with ExecInitExprInitPlan, below */
2779                                 SubPlan    *subplan = (SubPlan *) node;
2780                                 SubPlanState *sstate = makeNode(SubPlanState);
2781
2782                                 sstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecSubPlan;
2783
2784                                 if (!parent)
2785                                         elog(ERROR, "SubPlan found with no parent plan");
2786
2787                                 /*
2788                                  * Here we just add the SubPlanState nodes to
2789                                  * parent->subPlan.  The subplans will be initialized
2790                                  * later.
2791                                  */
2792                                 parent->subPlan = lcons(sstate, parent->subPlan);
2793                                 sstate->sub_estate = NULL;
2794                                 sstate->planstate = NULL;
2795
2796                                 sstate->exprs = (List *)
2797                                         ExecInitExpr((Expr *) subplan->exprs, parent);
2798                                 sstate->args = (List *)
2799                                         ExecInitExpr((Expr *) subplan->args, parent);
2800
2801                                 state = (ExprState *) sstate;
2802                         }
2803                         break;
2804                 case T_FieldSelect:
2805                         {
2806                                 FieldSelect *fselect = (FieldSelect *) node;
2807                                 FieldSelectState *fstate = makeNode(FieldSelectState);
2808
2809                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldSelect;
2810                                 fstate->arg = ExecInitExpr(fselect->arg, parent);
2811                                 fstate->argdesc = NULL;
2812                                 state = (ExprState *) fstate;
2813                         }
2814                         break;
2815                 case T_RelabelType:
2816                         {
2817                                 RelabelType *relabel = (RelabelType *) node;
2818                                 GenericExprState *gstate = makeNode(GenericExprState);
2819
2820                                 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRelabelType;
2821                                 gstate->arg = ExecInitExpr(relabel->arg, parent);
2822                                 state = (ExprState *) gstate;
2823                         }
2824                         break;
2825                 case T_CaseExpr:
2826                         {
2827                                 CaseExpr   *caseexpr = (CaseExpr *) node;
2828                                 CaseExprState *cstate = makeNode(CaseExprState);
2829                                 FastList        outlist;
2830                                 ListCell   *l;
2831
2832                                 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCase;
2833                                 cstate->arg = ExecInitExpr(caseexpr->arg, parent);
2834                                 FastListInit(&outlist);
2835                                 foreach(l, caseexpr->args)
2836                                 {
2837                                         CaseWhen   *when = (CaseWhen *) lfirst(l);
2838                                         CaseWhenState *wstate = makeNode(CaseWhenState);
2839
2840                                         Assert(IsA(when, CaseWhen));
2841                                         wstate->xprstate.evalfunc = NULL;       /* not used */
2842                                         wstate->xprstate.expr = (Expr *) when;
2843                                         wstate->expr = ExecInitExpr(when->expr, parent);
2844                                         wstate->result = ExecInitExpr(when->result, parent);
2845                                         FastAppend(&outlist, wstate);
2846                                 }
2847                                 cstate->args = FastListValue(&outlist);
2848                                 cstate->defresult = ExecInitExpr(caseexpr->defresult, parent);
2849                                 state = (ExprState *) cstate;
2850                         }
2851                         break;
2852                 case T_ArrayExpr:
2853                         {
2854                                 ArrayExpr  *arrayexpr = (ArrayExpr *) node;
2855                                 ArrayExprState *astate = makeNode(ArrayExprState);
2856                                 FastList        outlist;
2857                                 ListCell   *l;
2858
2859                                 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArray;
2860                                 FastListInit(&outlist);
2861                                 foreach(l, arrayexpr->elements)
2862                                 {
2863                                         Expr       *e = (Expr *) lfirst(l);
2864                                         ExprState  *estate;
2865
2866                                         estate = ExecInitExpr(e, parent);
2867                                         FastAppend(&outlist, estate);
2868                                 }
2869                                 astate->elements = FastListValue(&outlist);
2870                                 /* do one-time catalog lookup for type info */
2871                                 get_typlenbyvalalign(arrayexpr->element_typeid,
2872                                                                          &astate->elemlength,
2873                                                                          &astate->elembyval,
2874                                                                          &astate->elemalign);
2875                                 state = (ExprState *) astate;
2876                         }
2877                         break;
2878                 case T_RowExpr:
2879                         {
2880                                 RowExpr    *rowexpr = (RowExpr *) node;
2881                                 RowExprState *rstate = makeNode(RowExprState);
2882                                 List       *outlist;
2883                                 ListCell   *l;
2884
2885                                 rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRow;
2886                                 outlist = NIL;
2887                                 foreach(l, rowexpr->args)
2888                                 {
2889                                         Expr       *e = (Expr *) lfirst(l);
2890                                         ExprState  *estate;
2891
2892                                         estate = ExecInitExpr(e, parent);
2893                                         outlist = lappend(outlist, estate);
2894                                 }
2895                                 rstate->args = outlist;
2896                                 /* Build tupdesc to describe result tuples */
2897                                 if (rowexpr->row_typeid == RECORDOID)
2898                                 {
2899                                         /* generic record, use runtime type assignment */
2900                                         rstate->tupdesc = ExecTypeFromExprList(rowexpr->args);
2901                                         rstate->tupdesc = BlessTupleDesc(rstate->tupdesc);
2902                                 }
2903                                 else
2904                                 {
2905                                         /* it's been cast to a named type, use that */
2906                                         rstate->tupdesc = lookup_rowtype_tupdesc(rowexpr->row_typeid, -1);
2907                                 }
2908                                 state = (ExprState *) rstate;
2909                         }
2910                         break;
2911                 case T_CoalesceExpr:
2912                         {
2913                                 CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
2914                                 CoalesceExprState *cstate = makeNode(CoalesceExprState);
2915                                 FastList        outlist;
2916                                 ListCell   *l;
2917
2918                                 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoalesce;
2919                                 FastListInit(&outlist);
2920                                 foreach(l, coalesceexpr->args)
2921                                 {
2922                                         Expr       *e = (Expr *) lfirst(l);
2923                                         ExprState  *estate;
2924
2925                                         estate = ExecInitExpr(e, parent);
2926                                         FastAppend(&outlist, estate);
2927                                 }
2928                                 cstate->args = FastListValue(&outlist);
2929                                 state = (ExprState *) cstate;
2930                         }
2931                         break;
2932                 case T_NullIfExpr:
2933                         {
2934                                 NullIfExpr *nullifexpr = (NullIfExpr *) node;
2935                                 FuncExprState *fstate = makeNode(FuncExprState);
2936
2937                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullIf;
2938                                 fstate->args = (List *)
2939                                         ExecInitExpr((Expr *) nullifexpr->args, parent);
2940                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
2941                                 state = (ExprState *) fstate;
2942                         }
2943                         break;
2944                 case T_NullTest:
2945                         {
2946                                 NullTest   *ntest = (NullTest *) node;
2947                                 GenericExprState *gstate = makeNode(GenericExprState);
2948
2949                                 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullTest;
2950                                 gstate->arg = ExecInitExpr(ntest->arg, parent);
2951                                 state = (ExprState *) gstate;
2952                         }
2953                         break;
2954                 case T_BooleanTest:
2955                         {
2956                                 BooleanTest *btest = (BooleanTest *) node;
2957                                 GenericExprState *gstate = makeNode(GenericExprState);
2958
2959                                 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalBooleanTest;
2960                                 gstate->arg = ExecInitExpr(btest->arg, parent);
2961                                 state = (ExprState *) gstate;
2962                         }
2963                         break;
2964                 case T_CoerceToDomain:
2965                         {
2966                                 CoerceToDomain *ctest = (CoerceToDomain *) node;
2967                                 CoerceToDomainState *cstate = makeNode(CoerceToDomainState);
2968
2969                                 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceToDomain;
2970                                 cstate->arg = ExecInitExpr(ctest->arg, parent);
2971                                 cstate->constraints = GetDomainConstraints(ctest->resulttype);
2972                                 state = (ExprState *) cstate;
2973                         }
2974                         break;
2975                 case T_TargetEntry:
2976                         {
2977                                 TargetEntry *tle = (TargetEntry *) node;
2978                                 GenericExprState *gstate = makeNode(GenericExprState);
2979
2980                                 gstate->xprstate.evalfunc = NULL;       /* not used */
2981                                 gstate->arg = ExecInitExpr(tle->expr, parent);
2982                                 state = (ExprState *) gstate;
2983                         }
2984                         break;
2985                 case T_List:
2986                         {
2987                                 FastList        outlist;
2988                                 ListCell   *l;
2989
2990                                 FastListInit(&outlist);
2991                                 foreach(l, (List *) node)
2992                                 {
2993                                         FastAppend(&outlist,
2994                                                            ExecInitExpr((Expr *) lfirst(l),
2995                                                                                         parent));
2996                                 }
2997                                 /* Don't fall through to the "common" code below */
2998                                 return (ExprState *) FastListValue(&outlist);
2999                         }
3000                 default:
3001                         elog(ERROR, "unrecognized node type: %d",
3002                                  (int) nodeTag(node));
3003                         state = NULL;           /* keep compiler quiet */
3004                         break;
3005         }
3006
3007         /* Common code for all state-node types */
3008         state->expr = node;
3009
3010         return state;
3011 }
3012
3013 /*
3014  * ExecInitExprInitPlan --- initialize a subplan expr that's being handled
3015  * as an InitPlan.      This is identical to ExecInitExpr's handling of a regular
3016  * subplan expr, except we do NOT want to add the node to the parent's
3017  * subplan list.
3018  */
3019 SubPlanState *
3020 ExecInitExprInitPlan(SubPlan *node, PlanState *parent)
3021 {
3022         SubPlanState *sstate = makeNode(SubPlanState);
3023
3024         if (!parent)
3025                 elog(ERROR, "SubPlan found with no parent plan");
3026
3027         /* The subplan's state will be initialized later */
3028         sstate->sub_estate = NULL;
3029         sstate->planstate = NULL;
3030
3031         sstate->exprs = (List *) ExecInitExpr((Expr *) node->exprs, parent);
3032         sstate->args = (List *) ExecInitExpr((Expr *) node->args, parent);
3033
3034         sstate->xprstate.expr = (Expr *) node;
3035
3036         return sstate;
3037 }
3038
3039 /*
3040  * ExecPrepareExpr --- initialize for expression execution outside a normal
3041  * Plan tree context.
3042  *
3043  * This differs from ExecInitExpr in that we don't assume the caller is
3044  * already running in the EState's per-query context.  Also, we apply
3045  * fix_opfuncids() to the passed expression tree to be sure it is ready
3046  * to run.      (In ordinary Plan trees the planner will have fixed opfuncids,
3047  * but callers outside the executor will not have done this.)
3048  */
3049 ExprState *
3050 ExecPrepareExpr(Expr *node, EState *estate)
3051 {
3052         ExprState  *result;
3053         MemoryContext oldcontext;
3054
3055         fix_opfuncids((Node *) node);
3056
3057         oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
3058
3059         result = ExecInitExpr(node, NULL);
3060
3061         MemoryContextSwitchTo(oldcontext);
3062
3063         return result;
3064 }
3065
3066
3067 /* ----------------------------------------------------------------
3068  *                                       ExecQual / ExecTargetList / ExecProject
3069  * ----------------------------------------------------------------
3070  */
3071
3072 /* ----------------------------------------------------------------
3073  *              ExecQual
3074  *
3075  *              Evaluates a conjunctive boolean expression (qual list) and
3076  *              returns true iff none of the subexpressions are false.
3077  *              (We also return true if the list is empty.)
3078  *
3079  *      If some of the subexpressions yield NULL but none yield FALSE,
3080  *      then the result of the conjunction is NULL (ie, unknown)
3081  *      according to three-valued boolean logic.  In this case,
3082  *      we return the value specified by the "resultForNull" parameter.
3083  *
3084  *      Callers evaluating WHERE clauses should pass resultForNull=FALSE,
3085  *      since SQL specifies that tuples with null WHERE results do not
3086  *      get selected.  On the other hand, callers evaluating constraint
3087  *      conditions should pass resultForNull=TRUE, since SQL also specifies
3088  *      that NULL constraint conditions are not failures.
3089  *
3090  *      NOTE: it would not be correct to use this routine to evaluate an
3091  *      AND subclause of a boolean expression; for that purpose, a NULL
3092  *      result must be returned as NULL so that it can be properly treated
3093  *      in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
3094  *      This routine is only used in contexts where a complete expression
3095  *      is being evaluated and we know that NULL can be treated the same
3096  *      as one boolean result or the other.
3097  *
3098  * ----------------------------------------------------------------
3099  */
3100 bool
3101 ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
3102 {
3103         bool            result;
3104         MemoryContext oldContext;
3105         ListCell   *l;
3106
3107         /*
3108          * debugging stuff
3109          */
3110         EV_printf("ExecQual: qual is ");
3111         EV_nodeDisplay(qual);
3112         EV_printf("\n");
3113
3114         IncrProcessed();
3115
3116         /*
3117          * Run in short-lived per-tuple context while computing expressions.
3118          */
3119         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
3120
3121         /*
3122          * Evaluate the qual conditions one at a time.  If we find a FALSE
3123          * result, we can stop evaluating and return FALSE --- the AND result
3124          * must be FALSE.  Also, if we find a NULL result when resultForNull
3125          * is FALSE, we can stop and return FALSE --- the AND result must be
3126          * FALSE or NULL in that case, and the caller doesn't care which.
3127          *
3128          * If we get to the end of the list, we can return TRUE.  This will
3129          * happen when the AND result is indeed TRUE, or when the AND result
3130          * is NULL (one or more NULL subresult, with all the rest TRUE) and
3131          * the caller has specified resultForNull = TRUE.
3132          */
3133         result = true;
3134
3135         foreach(l, qual)
3136         {
3137                 ExprState  *clause = (ExprState *) lfirst(l);
3138                 Datum           expr_value;
3139                 bool            isNull;
3140
3141                 expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
3142
3143                 if (isNull)
3144                 {
3145                         if (resultForNull == false)
3146                         {
3147                                 result = false; /* treat NULL as FALSE */
3148                                 break;
3149                         }
3150                 }
3151                 else
3152                 {
3153                         if (!DatumGetBool(expr_value))
3154                         {
3155                                 result = false; /* definitely FALSE */
3156                                 break;
3157                         }
3158                 }
3159         }
3160
3161         MemoryContextSwitchTo(oldContext);
3162
3163         return result;
3164 }
3165
3166 /*
3167  * Number of items in a tlist (including any resjunk items!)
3168  */
3169 int
3170 ExecTargetListLength(List *targetlist)
3171 {
3172         /* This used to be more complex, but fjoins are dead */
3173         return list_length(targetlist);
3174 }
3175
3176 /*
3177  * Number of items in a tlist, not including any resjunk items
3178  */
3179 int
3180 ExecCleanTargetListLength(List *targetlist)
3181 {
3182         int                     len = 0;
3183         ListCell   *tl;
3184
3185         foreach(tl, targetlist)
3186         {
3187                 TargetEntry *curTle = (TargetEntry *) lfirst(tl);
3188
3189                 Assert(IsA(curTle, TargetEntry));
3190                 if (!curTle->resdom->resjunk)
3191                         len++;
3192         }
3193         return len;
3194 }
3195
3196 /* ----------------------------------------------------------------
3197  *              ExecTargetList
3198  *
3199  *              Evaluates a targetlist with respect to the given
3200  *              expression context and returns a tuple.
3201  *
3202  * The caller must pass workspace for the values and nulls arrays
3203  * as well as the itemIsDone array.  This convention saves palloc'ing
3204  * workspace on each call, and some callers may find it useful to examine
3205  * the values array directly.
3206  *
3207  * As with ExecEvalExpr, the caller should pass isDone = NULL if not
3208  * prepared to deal with sets of result tuples.  Otherwise, a return
3209  * of *isDone = ExprMultipleResult signifies a set element, and a return
3210  * of *isDone = ExprEndResult signifies end of the set of tuple.
3211  * ----------------------------------------------------------------
3212  */
3213 static HeapTuple
3214 ExecTargetList(List *targetlist,
3215                            TupleDesc targettype,
3216                            ExprContext *econtext,
3217                            Datum *values,
3218                            char *nulls,
3219                            ExprDoneCond *itemIsDone,
3220                            ExprDoneCond *isDone)
3221 {
3222         MemoryContext oldContext;
3223         ListCell   *tl;
3224         bool            isNull;
3225         bool            haveDoneSets;
3226
3227         /*
3228          * debugging stuff
3229          */
3230         EV_printf("ExecTargetList: tl is ");
3231         EV_nodeDisplay(targetlist);
3232         EV_printf("\n");
3233
3234         /*
3235          * Run in short-lived per-tuple context while computing expressions.
3236          */
3237         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
3238
3239         /*
3240          * There used to be some klugy and demonstrably broken code here that
3241          * special-cased the situation where targetlist == NIL.  Now we just
3242          * fall through and return an empty-but-valid tuple.
3243          */
3244
3245         /*
3246          * evaluate all the expressions in the target list
3247          */
3248         if (isDone)
3249                 *isDone = ExprSingleResult;             /* until proven otherwise */
3250
3251         haveDoneSets = false;           /* any exhausted set exprs in tlist? */
3252
3253         foreach(tl, targetlist)
3254         {
3255                 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
3256                 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
3257                 AttrNumber      resind = tle->resdom->resno - 1;
3258
3259                 values[resind] = ExecEvalExpr(gstate->arg,
3260                                                                           econtext,
3261                                                                           &isNull,
3262                                                                           &itemIsDone[resind]);
3263                 nulls[resind] = isNull ? 'n' : ' ';
3264
3265                 if (itemIsDone[resind] != ExprSingleResult)
3266                 {
3267                         /* We have a set-valued expression in the tlist */
3268                         if (isDone == NULL)
3269                                 ereport(ERROR,
3270                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3271                                                  errmsg("set-valued function called in context that cannot accept a set")));
3272                         if (itemIsDone[resind] == ExprMultipleResult)
3273                         {
3274                                 /* we have undone sets in the tlist, set flag */
3275                                 *isDone = ExprMultipleResult;
3276                         }
3277                         else
3278                         {
3279                                 /* we have done sets in the tlist, set flag for that */
3280                                 haveDoneSets = true;
3281                         }
3282                 }
3283         }
3284
3285         if (haveDoneSets)
3286         {
3287                 /*
3288                  * note: can't get here unless we verified isDone != NULL
3289                  */
3290                 if (*isDone == ExprSingleResult)
3291                 {
3292                         /*
3293                          * all sets are done, so report that tlist expansion is
3294                          * complete.
3295                          */
3296                         *isDone = ExprEndResult;
3297                         MemoryContextSwitchTo(oldContext);
3298                         return NULL;
3299                 }
3300                 else
3301                 {
3302                         /*
3303                          * We have some done and some undone sets.      Restart the done
3304                          * ones so that we can deliver a tuple (if possible).
3305                          */
3306                         foreach(tl, targetlist)
3307                         {
3308                                 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
3309                                 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
3310                                 AttrNumber      resind = tle->resdom->resno - 1;
3311
3312                                 if (itemIsDone[resind] == ExprEndResult)
3313                                 {
3314                                         values[resind] = ExecEvalExpr(gstate->arg,
3315                                                                                                   econtext,
3316                                                                                                   &isNull,
3317                                                                                                   &itemIsDone[resind]);
3318                                         nulls[resind] = isNull ? 'n' : ' ';
3319
3320                                         if (itemIsDone[resind] == ExprEndResult)
3321                                         {
3322                                                 /*
3323                                                  * Oh dear, this item is returning an empty set.
3324                                                  * Guess we can't make a tuple after all.
3325                                                  */
3326                                                 *isDone = ExprEndResult;
3327                                                 break;
3328                                         }
3329                                 }
3330                         }
3331
3332                         /*
3333                          * If we cannot make a tuple because some sets are empty, we
3334                          * still have to cycle the nonempty sets to completion, else
3335                          * resources will not be released from subplans etc.
3336                          *
3337                          * XXX is that still necessary?
3338                          */
3339                         if (*isDone == ExprEndResult)
3340                         {
3341                                 foreach(tl, targetlist)
3342                                 {
3343                                         GenericExprState *gstate = (GenericExprState *) lfirst(tl);
3344                                         TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
3345                                         AttrNumber      resind = tle->resdom->resno - 1;
3346
3347                                         while (itemIsDone[resind] == ExprMultipleResult)
3348                                         {
3349                                                 (void) ExecEvalExpr(gstate->arg,
3350                                                                                         econtext,
3351                                                                                         &isNull,
3352                                                                                         &itemIsDone[resind]);
3353                                         }
3354                                 }
3355
3356                                 MemoryContextSwitchTo(oldContext);
3357                                 return NULL;
3358                         }
3359                 }
3360         }
3361
3362         /*
3363          * form the new result tuple (in the caller's memory context!)
3364          */
3365         MemoryContextSwitchTo(oldContext);
3366
3367         return heap_formtuple(targettype, values, nulls);
3368 }
3369
3370 /* ----------------------------------------------------------------
3371  *              ExecProject
3372  *
3373  *              projects a tuple based on projection info and stores
3374  *              it in the specified tuple table slot.
3375  *
3376  *              Note: someday soon the executor can be extended to eliminate
3377  *                        redundant projections by storing pointers to datums
3378  *                        in the tuple table and then passing these around when
3379  *                        possible.  this should make things much quicker.
3380  *                        -cim 6/3/91
3381  * ----------------------------------------------------------------
3382  */
3383 TupleTableSlot *
3384 ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
3385 {
3386         TupleTableSlot *slot;
3387         TupleDesc       tupType;
3388         HeapTuple       newTuple;
3389
3390         /*
3391          * sanity checks
3392          */
3393         if (projInfo == NULL)
3394                 return NULL;
3395
3396         /*
3397          * get the projection info we want
3398          */
3399         slot = projInfo->pi_slot;
3400         tupType = slot->ttc_tupleDescriptor;
3401
3402         /*
3403          * form a new result tuple (if possible --- result can be NULL)
3404          */
3405         newTuple = ExecTargetList(projInfo->pi_targetlist,
3406                                                           tupType,
3407                                                           projInfo->pi_exprContext,
3408                                                           projInfo->pi_tupValues,
3409                                                           projInfo->pi_tupNulls,
3410                                                           projInfo->pi_itemIsDone,
3411                                                           isDone);
3412
3413         /*
3414          * store the tuple in the projection slot and return the slot.
3415          */
3416         return ExecStoreTuple(newTuple,                 /* tuple to store */
3417                                                   slot,                         /* slot to store in */
3418                                                   InvalidBuffer,        /* tuple has no buffer */
3419                                                   true);
3420 }