]> granicus.if.org Git - postgresql/blob - src/backend/executor/execQual.c
8ada5e6faf254573b91eafdf8728df6380336182
[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.163 2004/06/05 19:48:08 tgl Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 /*
16  *       INTERFACE ROUTINES
17  *              ExecEvalExpr    - (now a macro) evaluate an expression, return a datum
18  *              ExecEvalExprSwitchContext - same, but switch into eval memory context
19  *              ExecQual                - return true/false if qualification is satisfied
20  *              ExecProject             - form a new tuple by projecting the given tuple
21  *
22  *       NOTES
23  *              The more heavily used ExecEvalExpr routines, such as ExecEvalVar(),
24  *              are hotspots. Making these faster will speed up the entire system.
25  *
26  *              ExecProject() is used to make tuple projections.  Rather then
27  *              trying to speed it up, the execution plan should be pre-processed
28  *              to facilitate attribute sharing between nodes wherever possible,
29  *              instead of doing needless copying.      -cim 5/31/91
30  *
31  *              During expression evaluation, we check_stack_depth only in
32  *              ExecMakeFunctionResult 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         values = (Datum *) palloc(nargs * sizeof(Datum));
2133         nulls = (char *) palloc(nargs * sizeof(char));
2134
2135         /* Evaluate field values */
2136         i = 0;
2137         foreach(arg, rstate->args)
2138         {
2139                 ExprState  *e = (ExprState *) lfirst(arg);
2140                 bool            eisnull;
2141
2142                 values[i] = ExecEvalExpr(e, econtext, &eisnull, NULL);
2143                 nulls[i] = eisnull ? 'n' : ' ';
2144                 i++;
2145         }
2146
2147         tuple = heap_formtuple(rstate->tupdesc, values, nulls);
2148
2149         pfree(values);
2150         pfree(nulls);
2151
2152         return HeapTupleGetDatum(tuple);
2153 }
2154
2155 /* ----------------------------------------------------------------
2156  *              ExecEvalCoalesce
2157  * ----------------------------------------------------------------
2158  */
2159 static Datum
2160 ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
2161                                  bool *isNull, ExprDoneCond *isDone)
2162 {
2163         ListCell   *arg;
2164
2165         if (isDone)
2166                 *isDone = ExprSingleResult;
2167
2168         /* Simply loop through until something NOT NULL is found */
2169         foreach(arg, coalesceExpr->args)
2170         {
2171                 ExprState  *e = (ExprState *) lfirst(arg);
2172                 Datum           value;
2173
2174                 value = ExecEvalExpr(e, econtext, isNull, NULL);
2175                 if (!*isNull)
2176                         return value;
2177         }
2178
2179         /* Else return NULL */
2180         *isNull = true;
2181         return (Datum) 0;
2182 }
2183
2184 /* ----------------------------------------------------------------
2185  *              ExecEvalNullIf
2186  *
2187  * Note that this is *always* derived from the equals operator,
2188  * but since we need special processing of the arguments
2189  * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
2190  * ----------------------------------------------------------------
2191  */
2192 static Datum
2193 ExecEvalNullIf(FuncExprState *nullIfExpr,
2194                            ExprContext *econtext,
2195                            bool *isNull, ExprDoneCond *isDone)
2196 {
2197         Datum           result;
2198         FunctionCallInfoData fcinfo;
2199         ExprDoneCond argDone;
2200         List       *argList;
2201
2202         if (isDone)
2203                 *isDone = ExprSingleResult;
2204
2205         /*
2206          * Initialize function cache if first time through
2207          */
2208         if (nullIfExpr->func.fn_oid == InvalidOid)
2209         {
2210                 NullIfExpr *op = (NullIfExpr *) nullIfExpr->xprstate.expr;
2211
2212                 init_fcache(op->opfuncid, nullIfExpr, econtext->ecxt_per_query_memory);
2213                 Assert(!nullIfExpr->func.fn_retset);
2214         }
2215
2216         /*
2217          * extract info from nullIfExpr
2218          */
2219         argList = nullIfExpr->args;
2220
2221         /* Need to prep callinfo structure */
2222         MemSet(&fcinfo, 0, sizeof(fcinfo));
2223         fcinfo.flinfo = &(nullIfExpr->func);
2224         argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
2225         if (argDone != ExprSingleResult)
2226                 ereport(ERROR,
2227                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
2228                                  errmsg("NULLIF does not support set arguments")));
2229         Assert(fcinfo.nargs == 2);
2230
2231         /* if either argument is NULL they can't be equal */
2232         if (!fcinfo.argnull[0] && !fcinfo.argnull[1])
2233         {
2234                 fcinfo.isnull = false;
2235                 result = FunctionCallInvoke(&fcinfo);
2236                 /* if the arguments are equal return null */
2237                 if (!fcinfo.isnull && DatumGetBool(result))
2238                 {
2239                         *isNull = true;
2240                         return (Datum) 0;
2241                 }
2242         }
2243
2244         /* else return first argument */
2245         *isNull = fcinfo.argnull[0];
2246         return fcinfo.arg[0];
2247 }
2248
2249 /* ----------------------------------------------------------------
2250  *              ExecEvalNullTest
2251  *
2252  *              Evaluate a NullTest node.
2253  * ----------------------------------------------------------------
2254  */
2255 static Datum
2256 ExecEvalNullTest(GenericExprState *nstate,
2257                                  ExprContext *econtext,
2258                                  bool *isNull,
2259                                  ExprDoneCond *isDone)
2260 {
2261         NullTest   *ntest = (NullTest *) nstate->xprstate.expr;
2262         Datum           result;
2263
2264         result = ExecEvalExpr(nstate->arg, econtext, isNull, isDone);
2265
2266         if (isDone && *isDone == ExprEndResult)
2267                 return result;                  /* nothing to check */
2268
2269         switch (ntest->nulltesttype)
2270         {
2271                 case IS_NULL:
2272                         if (*isNull)
2273                         {
2274                                 *isNull = false;
2275                                 return BoolGetDatum(true);
2276                         }
2277                         else
2278                                 return BoolGetDatum(false);
2279                 case IS_NOT_NULL:
2280                         if (*isNull)
2281                         {
2282                                 *isNull = false;
2283                                 return BoolGetDatum(false);
2284                         }
2285                         else
2286                                 return BoolGetDatum(true);
2287                 default:
2288                         elog(ERROR, "unrecognized nulltesttype: %d",
2289                                  (int) ntest->nulltesttype);
2290                         return (Datum) 0;       /* keep compiler quiet */
2291         }
2292 }
2293
2294 /* ----------------------------------------------------------------
2295  *              ExecEvalBooleanTest
2296  *
2297  *              Evaluate a BooleanTest node.
2298  * ----------------------------------------------------------------
2299  */
2300 static Datum
2301 ExecEvalBooleanTest(GenericExprState *bstate,
2302                                         ExprContext *econtext,
2303                                         bool *isNull,
2304                                         ExprDoneCond *isDone)
2305 {
2306         BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;
2307         Datum           result;
2308
2309         result = ExecEvalExpr(bstate->arg, econtext, isNull, isDone);
2310
2311         if (isDone && *isDone == ExprEndResult)
2312                 return result;                  /* nothing to check */
2313
2314         switch (btest->booltesttype)
2315         {
2316                 case IS_TRUE:
2317                         if (*isNull)
2318                         {
2319                                 *isNull = false;
2320                                 return BoolGetDatum(false);
2321                         }
2322                         else if (DatumGetBool(result))
2323                                 return BoolGetDatum(true);
2324                         else
2325                                 return BoolGetDatum(false);
2326                 case IS_NOT_TRUE:
2327                         if (*isNull)
2328                         {
2329                                 *isNull = false;
2330                                 return BoolGetDatum(true);
2331                         }
2332                         else if (DatumGetBool(result))
2333                                 return BoolGetDatum(false);
2334                         else
2335                                 return BoolGetDatum(true);
2336                 case IS_FALSE:
2337                         if (*isNull)
2338                         {
2339                                 *isNull = false;
2340                                 return BoolGetDatum(false);
2341                         }
2342                         else if (DatumGetBool(result))
2343                                 return BoolGetDatum(false);
2344                         else
2345                                 return BoolGetDatum(true);
2346                 case IS_NOT_FALSE:
2347                         if (*isNull)
2348                         {
2349                                 *isNull = false;
2350                                 return BoolGetDatum(true);
2351                         }
2352                         else if (DatumGetBool(result))
2353                                 return BoolGetDatum(true);
2354                         else
2355                                 return BoolGetDatum(false);
2356                 case IS_UNKNOWN:
2357                         if (*isNull)
2358                         {
2359                                 *isNull = false;
2360                                 return BoolGetDatum(true);
2361                         }
2362                         else
2363                                 return BoolGetDatum(false);
2364                 case IS_NOT_UNKNOWN:
2365                         if (*isNull)
2366                         {
2367                                 *isNull = false;
2368                                 return BoolGetDatum(false);
2369                         }
2370                         else
2371                                 return BoolGetDatum(true);
2372                 default:
2373                         elog(ERROR, "unrecognized booltesttype: %d",
2374                                  (int) btest->booltesttype);
2375                         return (Datum) 0;       /* keep compiler quiet */
2376         }
2377 }
2378
2379 /*
2380  * ExecEvalCoerceToDomain
2381  *
2382  * Test the provided data against the domain constraint(s).  If the data
2383  * passes the constraint specifications, pass it through (return the
2384  * datum) otherwise throw an error.
2385  */
2386 static Datum
2387 ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
2388                                            bool *isNull, ExprDoneCond *isDone)
2389 {
2390         CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
2391         Datum           result;
2392         ListCell   *l;
2393
2394         result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
2395
2396         if (isDone && *isDone == ExprEndResult)
2397                 return result;                  /* nothing to check */
2398
2399         foreach(l, cstate->constraints)
2400         {
2401                 DomainConstraintState *con = (DomainConstraintState *) lfirst(l);
2402
2403                 switch (con->constrainttype)
2404                 {
2405                         case DOM_CONSTRAINT_NOTNULL:
2406                                 if (*isNull)
2407                                         ereport(ERROR,
2408                                                         (errcode(ERRCODE_NOT_NULL_VIOLATION),
2409                                                    errmsg("domain %s does not allow null values",
2410                                                                   format_type_be(ctest->resulttype))));
2411                                 break;
2412                         case DOM_CONSTRAINT_CHECK:
2413                                 {
2414                                         Datum           conResult;
2415                                         bool            conIsNull;
2416                                         Datum           save_datum;
2417                                         bool            save_isNull;
2418
2419                                         /*
2420                                          * Set up value to be returned by CoerceToDomainValue
2421                                          * nodes. We must save and restore prior setting of
2422                                          * econtext's domainValue fields, in case this node is
2423                                          * itself within a check expression for another
2424                                          * domain.
2425                                          */
2426                                         save_datum = econtext->domainValue_datum;
2427                                         save_isNull = econtext->domainValue_isNull;
2428
2429                                         econtext->domainValue_datum = result;
2430                                         econtext->domainValue_isNull = *isNull;
2431
2432                                         conResult = ExecEvalExpr(con->check_expr,
2433                                                                                          econtext, &conIsNull, NULL);
2434
2435                                         if (!conIsNull &&
2436                                                 !DatumGetBool(conResult))
2437                                                 ereport(ERROR,
2438                                                                 (errcode(ERRCODE_CHECK_VIOLATION),
2439                                                                  errmsg("value for domain %s violates check constraint \"%s\"",
2440                                                                                 format_type_be(ctest->resulttype),
2441                                                                                 con->name)));
2442                                         econtext->domainValue_datum = save_datum;
2443                                         econtext->domainValue_isNull = save_isNull;
2444
2445                                         break;
2446                                 }
2447                         default:
2448                                 elog(ERROR, "unrecognized constraint type: %d",
2449                                          (int) con->constrainttype);
2450                                 break;
2451                 }
2452         }
2453
2454         /* If all has gone well (constraints did not fail) return the datum */
2455         return result;
2456 }
2457
2458 /*
2459  * ExecEvalCoerceToDomainValue
2460  *
2461  * Return the value stored by CoerceToDomain.
2462  */
2463 static Datum
2464 ExecEvalCoerceToDomainValue(ExprState *exprstate,
2465                                                         ExprContext *econtext,
2466                                                         bool *isNull, ExprDoneCond *isDone)
2467 {
2468         if (isDone)
2469                 *isDone = ExprSingleResult;
2470         *isNull = econtext->domainValue_isNull;
2471         return econtext->domainValue_datum;
2472 }
2473
2474 /* ----------------------------------------------------------------
2475  *              ExecEvalFieldSelect
2476  *
2477  *              Evaluate a FieldSelect node.
2478  * ----------------------------------------------------------------
2479  */
2480 static Datum
2481 ExecEvalFieldSelect(FieldSelectState *fstate,
2482                                         ExprContext *econtext,
2483                                         bool *isNull,
2484                                         ExprDoneCond *isDone)
2485 {
2486         FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
2487         Datum           result;
2488         Datum           tupDatum;
2489         HeapTupleHeader tuple;
2490         Oid                     tupType;
2491         int32           tupTypmod;
2492         TupleDesc       tupDesc;
2493         HeapTupleData tmptup;
2494
2495         tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
2496
2497         /* this test covers the isDone exception too: */
2498         if (*isNull)
2499                 return tupDatum;
2500
2501         tuple = DatumGetHeapTupleHeader(tupDatum);
2502
2503         tupType = HeapTupleHeaderGetTypeId(tuple);
2504         tupTypmod = HeapTupleHeaderGetTypMod(tuple);
2505
2506         /* Lookup tupdesc if first time through or if type changes */
2507         tupDesc = fstate->argdesc;
2508         if (tupDesc == NULL ||
2509                 tupType != tupDesc->tdtypeid ||
2510                 tupTypmod != tupDesc->tdtypmod)
2511         {
2512                 MemoryContext oldcontext;
2513
2514                 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
2515                 /* Copy the tupdesc into query storage for safety */
2516                 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2517                 tupDesc = CreateTupleDescCopy(tupDesc);
2518                 if (fstate->argdesc)
2519                         FreeTupleDesc(fstate->argdesc);
2520                 fstate->argdesc = tupDesc;
2521                 MemoryContextSwitchTo(oldcontext);
2522         }
2523
2524         /*
2525          * heap_getattr needs a HeapTuple not a bare HeapTupleHeader.  We set
2526          * all the fields in the struct just in case user tries to inspect
2527          * system columns.
2528          */
2529         tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2530         ItemPointerSetInvalid(&(tmptup.t_self));
2531         tmptup.t_tableOid = InvalidOid;
2532         tmptup.t_data = tuple;
2533
2534         result = heap_getattr(&tmptup,
2535                                                   fselect->fieldnum,
2536                                                   tupDesc,
2537                                                   isNull);
2538         return result;
2539 }
2540
2541 /* ----------------------------------------------------------------
2542  *              ExecEvalRelabelType
2543  *
2544  *              Evaluate a RelabelType node.
2545  * ----------------------------------------------------------------
2546  */
2547 static Datum
2548 ExecEvalRelabelType(GenericExprState *exprstate,
2549                                         ExprContext *econtext,
2550                                         bool *isNull, ExprDoneCond *isDone)
2551 {
2552         return ExecEvalExpr(exprstate->arg, econtext, isNull, isDone);
2553 }
2554
2555
2556 /*
2557  * ExecEvalExprSwitchContext
2558  *
2559  * Same as ExecEvalExpr, but get into the right allocation context explicitly.
2560  */
2561 Datum
2562 ExecEvalExprSwitchContext(ExprState *expression,
2563                                                   ExprContext *econtext,
2564                                                   bool *isNull,
2565                                                   ExprDoneCond *isDone)
2566 {
2567         Datum           retDatum;
2568         MemoryContext oldContext;
2569
2570         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
2571         retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
2572         MemoryContextSwitchTo(oldContext);
2573         return retDatum;
2574 }
2575
2576
2577 /*
2578  * ExecInitExpr: prepare an expression tree for execution
2579  *
2580  * This function builds and returns an ExprState tree paralleling the given
2581  * Expr node tree.      The ExprState tree can then be handed to ExecEvalExpr
2582  * for execution.  Because the Expr tree itself is read-only as far as
2583  * ExecInitExpr and ExecEvalExpr are concerned, several different executions
2584  * of the same plan tree can occur concurrently.
2585  *
2586  * This must be called in a memory context that will last as long as repeated
2587  * executions of the expression are needed.  Typically the context will be
2588  * the same as the per-query context of the associated ExprContext.
2589  *
2590  * Any Aggref and SubPlan nodes found in the tree are added to the lists
2591  * of such nodes held by the parent PlanState.  Otherwise, we do very little
2592  * initialization here other than building the state-node tree.  Any nontrivial
2593  * work associated with initializing runtime info for a node should happen
2594  * during the first actual evaluation of that node.  (This policy lets us
2595  * avoid work if the node is never actually evaluated.)
2596  *
2597  * Note: there is no ExecEndExpr function; we assume that any resource
2598  * cleanup needed will be handled by just releasing the memory context
2599  * in which the state tree is built.  Functions that require additional
2600  * cleanup work can register a shutdown callback in the ExprContext.
2601  *
2602  *      'node' is the root of the expression tree to examine
2603  *      'parent' is the PlanState node that owns the expression.
2604  *
2605  * 'parent' may be NULL if we are preparing an expression that is not
2606  * associated with a plan tree.  (If so, it can't have aggs or subplans.)
2607  * This case should usually come through ExecPrepareExpr, not directly here.
2608  */
2609 ExprState *
2610 ExecInitExpr(Expr *node, PlanState *parent)
2611 {
2612         ExprState  *state;
2613
2614         if (node == NULL)
2615                 return NULL;
2616
2617         /* Guard against stack overflow due to overly complex expressions */
2618         check_stack_depth();
2619
2620         switch (nodeTag(node))
2621         {
2622                 case T_Var:
2623                         state = (ExprState *) makeNode(ExprState);
2624                         state->evalfunc = ExecEvalVar;
2625                         break;
2626                 case T_Const:
2627                         state = (ExprState *) makeNode(ExprState);
2628                         state->evalfunc = ExecEvalConst;
2629                         break;
2630                 case T_Param:
2631                         state = (ExprState *) makeNode(ExprState);
2632                         state->evalfunc = ExecEvalParam;
2633                         break;
2634                 case T_CoerceToDomainValue:
2635                         state = (ExprState *) makeNode(ExprState);
2636                         state->evalfunc = ExecEvalCoerceToDomainValue;
2637                         break;
2638                 case T_CaseTestExpr:
2639                         state = (ExprState *) makeNode(ExprState);
2640                         state->evalfunc = ExecEvalCaseTestExpr;
2641                         break;
2642                 case T_Aggref:
2643                         {
2644                                 Aggref     *aggref = (Aggref *) node;
2645                                 AggrefExprState *astate = makeNode(AggrefExprState);
2646
2647                                 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAggref;
2648                                 if (parent && IsA(parent, AggState))
2649                                 {
2650                                         AggState   *aggstate = (AggState *) parent;
2651                                         int                     naggs;
2652
2653                                         aggstate->aggs = lcons(astate, aggstate->aggs);
2654                                         naggs = ++aggstate->numaggs;
2655
2656                                         astate->target = ExecInitExpr(aggref->target, parent);
2657
2658                                         /*
2659                                          * Complain if the aggregate's argument contains any
2660                                          * aggregates; nested agg functions are semantically
2661                                          * nonsensical.  (This should have been caught
2662                                          * earlier, but we defend against it here anyway.)
2663                                          */
2664                                         if (naggs != aggstate->numaggs)
2665                                                 ereport(ERROR,
2666                                                                 (errcode(ERRCODE_GROUPING_ERROR),
2667                                                                  errmsg("aggregate function calls may not be nested")));
2668                                 }
2669                                 else
2670                                 {
2671                                         /* planner messed up */
2672                                         elog(ERROR, "aggref found in non-Agg plan node");
2673                                 }
2674                                 state = (ExprState *) astate;
2675                         }
2676                         break;
2677                 case T_ArrayRef:
2678                         {
2679                                 ArrayRef   *aref = (ArrayRef *) node;
2680                                 ArrayRefExprState *astate = makeNode(ArrayRefExprState);
2681
2682                                 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayRef;
2683                                 astate->refupperindexpr = (List *)
2684                                         ExecInitExpr((Expr *) aref->refupperindexpr, parent);
2685                                 astate->reflowerindexpr = (List *)
2686                                         ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
2687                                 astate->refexpr = ExecInitExpr(aref->refexpr, parent);
2688                                 astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
2689                                                                                                         parent);
2690                                 /* do one-time catalog lookups for type info */
2691                                 astate->refattrlength = get_typlen(aref->refarraytype);
2692                                 get_typlenbyvalalign(aref->refelemtype,
2693                                                                          &astate->refelemlength,
2694                                                                          &astate->refelembyval,
2695                                                                          &astate->refelemalign);
2696                                 state = (ExprState *) astate;
2697                         }
2698                         break;
2699                 case T_FuncExpr:
2700                         {
2701                                 FuncExpr   *funcexpr = (FuncExpr *) node;
2702                                 FuncExprState *fstate = makeNode(FuncExprState);
2703
2704                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFunc;
2705                                 fstate->args = (List *)
2706                                         ExecInitExpr((Expr *) funcexpr->args, parent);
2707                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
2708                                 state = (ExprState *) fstate;
2709                         }
2710                         break;
2711                 case T_OpExpr:
2712                         {
2713                                 OpExpr     *opexpr = (OpExpr *) node;
2714                                 FuncExprState *fstate = makeNode(FuncExprState);
2715
2716                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOper;
2717                                 fstate->args = (List *)
2718                                         ExecInitExpr((Expr *) opexpr->args, parent);
2719                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
2720                                 state = (ExprState *) fstate;
2721                         }
2722                         break;
2723                 case T_DistinctExpr:
2724                         {
2725                                 DistinctExpr *distinctexpr = (DistinctExpr *) node;
2726                                 FuncExprState *fstate = makeNode(FuncExprState);
2727
2728                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalDistinct;
2729                                 fstate->args = (List *)
2730                                         ExecInitExpr((Expr *) distinctexpr->args, parent);
2731                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
2732                                 state = (ExprState *) fstate;
2733                         }
2734                         break;
2735                 case T_ScalarArrayOpExpr:
2736                         {
2737                                 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
2738                                 ScalarArrayOpExprState *sstate = makeNode(ScalarArrayOpExprState);
2739
2740                                 sstate->fxprstate.xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalScalarArrayOp;
2741                                 sstate->fxprstate.args = (List *)
2742                                         ExecInitExpr((Expr *) opexpr->args, parent);
2743                                 sstate->fxprstate.func.fn_oid = InvalidOid;             /* not initialized */
2744                                 sstate->element_type = InvalidOid;              /* ditto */
2745                                 state = (ExprState *) sstate;
2746                         }
2747                         break;
2748                 case T_BoolExpr:
2749                         {
2750                                 BoolExpr   *boolexpr = (BoolExpr *) node;
2751                                 BoolExprState *bstate = makeNode(BoolExprState);
2752
2753                                 switch (boolexpr->boolop)
2754                                 {
2755                                         case AND_EXPR:
2756                                                 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAnd;
2757                                                 break;
2758                                         case OR_EXPR:
2759                                                 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOr;
2760                                                 break;
2761                                         case NOT_EXPR:
2762                                                 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNot;
2763                                                 break;
2764                                         default:
2765                                                 elog(ERROR, "unrecognized boolop: %d",
2766                                                          (int) boolexpr->boolop);
2767                                                 break;
2768                                 }
2769                                 bstate->args = (List *)
2770                                         ExecInitExpr((Expr *) boolexpr->args, parent);
2771                                 state = (ExprState *) bstate;
2772                         }
2773                         break;
2774                 case T_SubPlan:
2775                         {
2776                                 /* Keep this in sync with ExecInitExprInitPlan, below */
2777                                 SubPlan    *subplan = (SubPlan *) node;
2778                                 SubPlanState *sstate = makeNode(SubPlanState);
2779
2780                                 sstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecSubPlan;
2781
2782                                 if (!parent)
2783                                         elog(ERROR, "SubPlan found with no parent plan");
2784
2785                                 /*
2786                                  * Here we just add the SubPlanState nodes to
2787                                  * parent->subPlan.  The subplans will be initialized
2788                                  * later.
2789                                  */
2790                                 parent->subPlan = lcons(sstate, parent->subPlan);
2791                                 sstate->sub_estate = NULL;
2792                                 sstate->planstate = NULL;
2793
2794                                 sstate->exprs = (List *)
2795                                         ExecInitExpr((Expr *) subplan->exprs, parent);
2796                                 sstate->args = (List *)
2797                                         ExecInitExpr((Expr *) subplan->args, parent);
2798
2799                                 state = (ExprState *) sstate;
2800                         }
2801                         break;
2802                 case T_FieldSelect:
2803                         {
2804                                 FieldSelect *fselect = (FieldSelect *) node;
2805                                 FieldSelectState *fstate = makeNode(FieldSelectState);
2806
2807                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldSelect;
2808                                 fstate->arg = ExecInitExpr(fselect->arg, parent);
2809                                 fstate->argdesc = NULL;
2810                                 state = (ExprState *) fstate;
2811                         }
2812                         break;
2813                 case T_RelabelType:
2814                         {
2815                                 RelabelType *relabel = (RelabelType *) node;
2816                                 GenericExprState *gstate = makeNode(GenericExprState);
2817
2818                                 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRelabelType;
2819                                 gstate->arg = ExecInitExpr(relabel->arg, parent);
2820                                 state = (ExprState *) gstate;
2821                         }
2822                         break;
2823                 case T_CaseExpr:
2824                         {
2825                                 CaseExpr   *caseexpr = (CaseExpr *) node;
2826                                 CaseExprState *cstate = makeNode(CaseExprState);
2827                                 List       *outlist = NIL;
2828                                 ListCell   *l;
2829
2830                                 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCase;
2831                                 cstate->arg = ExecInitExpr(caseexpr->arg, parent);
2832                                 foreach(l, caseexpr->args)
2833                                 {
2834                                         CaseWhen   *when = (CaseWhen *) lfirst(l);
2835                                         CaseWhenState *wstate = makeNode(CaseWhenState);
2836
2837                                         Assert(IsA(when, CaseWhen));
2838                                         wstate->xprstate.evalfunc = NULL;       /* not used */
2839                                         wstate->xprstate.expr = (Expr *) when;
2840                                         wstate->expr = ExecInitExpr(when->expr, parent);
2841                                         wstate->result = ExecInitExpr(when->result, parent);
2842                                         outlist = lappend(outlist, wstate);
2843                                 }
2844                                 cstate->args = outlist;
2845                                 cstate->defresult = ExecInitExpr(caseexpr->defresult, parent);
2846                                 state = (ExprState *) cstate;
2847                         }
2848                         break;
2849                 case T_ArrayExpr:
2850                         {
2851                                 ArrayExpr  *arrayexpr = (ArrayExpr *) node;
2852                                 ArrayExprState *astate = makeNode(ArrayExprState);
2853                                 List       *outlist = NIL;
2854                                 ListCell   *l;
2855
2856                                 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArray;
2857                                 foreach(l, arrayexpr->elements)
2858                                 {
2859                                         Expr       *e = (Expr *) lfirst(l);
2860                                         ExprState  *estate;
2861
2862                                         estate = ExecInitExpr(e, parent);
2863                                         outlist = lappend(outlist, estate);
2864                                 }
2865                                 astate->elements = outlist;
2866                                 /* do one-time catalog lookup for type info */
2867                                 get_typlenbyvalalign(arrayexpr->element_typeid,
2868                                                                          &astate->elemlength,
2869                                                                          &astate->elembyval,
2870                                                                          &astate->elemalign);
2871                                 state = (ExprState *) astate;
2872                         }
2873                         break;
2874                 case T_RowExpr:
2875                         {
2876                                 RowExpr    *rowexpr = (RowExpr *) node;
2877                                 RowExprState *rstate = makeNode(RowExprState);
2878                                 List       *outlist = NIL;
2879                                 ListCell   *l;
2880
2881                                 rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRow;
2882                                 foreach(l, rowexpr->args)
2883                                 {
2884                                         Expr       *e = (Expr *) lfirst(l);
2885                                         ExprState  *estate;
2886
2887                                         estate = ExecInitExpr(e, parent);
2888                                         outlist = lappend(outlist, estate);
2889                                 }
2890                                 rstate->args = outlist;
2891                                 /* Build tupdesc to describe result tuples */
2892                                 if (rowexpr->row_typeid == RECORDOID)
2893                                 {
2894                                         /* generic record, use runtime type assignment */
2895                                         rstate->tupdesc = ExecTypeFromExprList(rowexpr->args);
2896                                         rstate->tupdesc = BlessTupleDesc(rstate->tupdesc);
2897                                 }
2898                                 else
2899                                 {
2900                                         /* it's been cast to a named type, use that */
2901                                         rstate->tupdesc = lookup_rowtype_tupdesc(rowexpr->row_typeid, -1);
2902                                 }
2903                                 state = (ExprState *) rstate;
2904                         }
2905                         break;
2906                 case T_CoalesceExpr:
2907                         {
2908                                 CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
2909                                 CoalesceExprState *cstate = makeNode(CoalesceExprState);
2910                                 List       *outlist = NIL;
2911                                 ListCell   *l;
2912
2913                                 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoalesce;
2914                                 foreach(l, coalesceexpr->args)
2915                                 {
2916                                         Expr       *e = (Expr *) lfirst(l);
2917                                         ExprState  *estate;
2918
2919                                         estate = ExecInitExpr(e, parent);
2920                                         outlist = lappend(outlist, estate);
2921                                 }
2922                                 cstate->args = outlist;
2923                                 state = (ExprState *) cstate;
2924                         }
2925                         break;
2926                 case T_NullIfExpr:
2927                         {
2928                                 NullIfExpr *nullifexpr = (NullIfExpr *) node;
2929                                 FuncExprState *fstate = makeNode(FuncExprState);
2930
2931                                 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullIf;
2932                                 fstate->args = (List *)
2933                                         ExecInitExpr((Expr *) nullifexpr->args, parent);
2934                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
2935                                 state = (ExprState *) fstate;
2936                         }
2937                         break;
2938                 case T_NullTest:
2939                         {
2940                                 NullTest   *ntest = (NullTest *) node;
2941                                 GenericExprState *gstate = makeNode(GenericExprState);
2942
2943                                 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullTest;
2944                                 gstate->arg = ExecInitExpr(ntest->arg, parent);
2945                                 state = (ExprState *) gstate;
2946                         }
2947                         break;
2948                 case T_BooleanTest:
2949                         {
2950                                 BooleanTest *btest = (BooleanTest *) node;
2951                                 GenericExprState *gstate = makeNode(GenericExprState);
2952
2953                                 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalBooleanTest;
2954                                 gstate->arg = ExecInitExpr(btest->arg, parent);
2955                                 state = (ExprState *) gstate;
2956                         }
2957                         break;
2958                 case T_CoerceToDomain:
2959                         {
2960                                 CoerceToDomain *ctest = (CoerceToDomain *) node;
2961                                 CoerceToDomainState *cstate = makeNode(CoerceToDomainState);
2962
2963                                 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceToDomain;
2964                                 cstate->arg = ExecInitExpr(ctest->arg, parent);
2965                                 cstate->constraints = GetDomainConstraints(ctest->resulttype);
2966                                 state = (ExprState *) cstate;
2967                         }
2968                         break;
2969                 case T_TargetEntry:
2970                         {
2971                                 TargetEntry *tle = (TargetEntry *) node;
2972                                 GenericExprState *gstate = makeNode(GenericExprState);
2973
2974                                 gstate->xprstate.evalfunc = NULL;       /* not used */
2975                                 gstate->arg = ExecInitExpr(tle->expr, parent);
2976                                 state = (ExprState *) gstate;
2977                         }
2978                         break;
2979                 case T_List:
2980                         {
2981                                 List       *outlist = NIL;
2982                                 ListCell   *l;
2983
2984                                 foreach(l, (List *) node)
2985                                 {
2986                                         outlist = lappend(outlist,
2987                                                                           ExecInitExpr((Expr *) lfirst(l),
2988                                                                                                    parent));
2989                                 }
2990                                 /* Don't fall through to the "common" code below */
2991                                 return (ExprState *) outlist;
2992                         }
2993                 default:
2994                         elog(ERROR, "unrecognized node type: %d",
2995                                  (int) nodeTag(node));
2996                         state = NULL;           /* keep compiler quiet */
2997                         break;
2998         }
2999
3000         /* Common code for all state-node types */
3001         state->expr = node;
3002
3003         return state;
3004 }
3005
3006 /*
3007  * ExecInitExprInitPlan --- initialize a subplan expr that's being handled
3008  * as an InitPlan.      This is identical to ExecInitExpr's handling of a regular
3009  * subplan expr, except we do NOT want to add the node to the parent's
3010  * subplan list.
3011  */
3012 SubPlanState *
3013 ExecInitExprInitPlan(SubPlan *node, PlanState *parent)
3014 {
3015         SubPlanState *sstate = makeNode(SubPlanState);
3016
3017         if (!parent)
3018                 elog(ERROR, "SubPlan found with no parent plan");
3019
3020         /* The subplan's state will be initialized later */
3021         sstate->sub_estate = NULL;
3022         sstate->planstate = NULL;
3023
3024         sstate->exprs = (List *) ExecInitExpr((Expr *) node->exprs, parent);
3025         sstate->args = (List *) ExecInitExpr((Expr *) node->args, parent);
3026
3027         sstate->xprstate.expr = (Expr *) node;
3028
3029         return sstate;
3030 }
3031
3032 /*
3033  * ExecPrepareExpr --- initialize for expression execution outside a normal
3034  * Plan tree context.
3035  *
3036  * This differs from ExecInitExpr in that we don't assume the caller is
3037  * already running in the EState's per-query context.  Also, we apply
3038  * fix_opfuncids() to the passed expression tree to be sure it is ready
3039  * to run.      (In ordinary Plan trees the planner will have fixed opfuncids,
3040  * but callers outside the executor will not have done this.)
3041  */
3042 ExprState *
3043 ExecPrepareExpr(Expr *node, EState *estate)
3044 {
3045         ExprState  *result;
3046         MemoryContext oldcontext;
3047
3048         fix_opfuncids((Node *) node);
3049
3050         oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
3051
3052         result = ExecInitExpr(node, NULL);
3053
3054         MemoryContextSwitchTo(oldcontext);
3055
3056         return result;
3057 }
3058
3059
3060 /* ----------------------------------------------------------------
3061  *                                       ExecQual / ExecTargetList / ExecProject
3062  * ----------------------------------------------------------------
3063  */
3064
3065 /* ----------------------------------------------------------------
3066  *              ExecQual
3067  *
3068  *              Evaluates a conjunctive boolean expression (qual list) and
3069  *              returns true iff none of the subexpressions are false.
3070  *              (We also return true if the list is empty.)
3071  *
3072  *      If some of the subexpressions yield NULL but none yield FALSE,
3073  *      then the result of the conjunction is NULL (ie, unknown)
3074  *      according to three-valued boolean logic.  In this case,
3075  *      we return the value specified by the "resultForNull" parameter.
3076  *
3077  *      Callers evaluating WHERE clauses should pass resultForNull=FALSE,
3078  *      since SQL specifies that tuples with null WHERE results do not
3079  *      get selected.  On the other hand, callers evaluating constraint
3080  *      conditions should pass resultForNull=TRUE, since SQL also specifies
3081  *      that NULL constraint conditions are not failures.
3082  *
3083  *      NOTE: it would not be correct to use this routine to evaluate an
3084  *      AND subclause of a boolean expression; for that purpose, a NULL
3085  *      result must be returned as NULL so that it can be properly treated
3086  *      in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
3087  *      This routine is only used in contexts where a complete expression
3088  *      is being evaluated and we know that NULL can be treated the same
3089  *      as one boolean result or the other.
3090  *
3091  * ----------------------------------------------------------------
3092  */
3093 bool
3094 ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
3095 {
3096         bool            result;
3097         MemoryContext oldContext;
3098         ListCell   *l;
3099
3100         /*
3101          * debugging stuff
3102          */
3103         EV_printf("ExecQual: qual is ");
3104         EV_nodeDisplay(qual);
3105         EV_printf("\n");
3106
3107         IncrProcessed();
3108
3109         /*
3110          * Run in short-lived per-tuple context while computing expressions.
3111          */
3112         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
3113
3114         /*
3115          * Evaluate the qual conditions one at a time.  If we find a FALSE
3116          * result, we can stop evaluating and return FALSE --- the AND result
3117          * must be FALSE.  Also, if we find a NULL result when resultForNull
3118          * is FALSE, we can stop and return FALSE --- the AND result must be
3119          * FALSE or NULL in that case, and the caller doesn't care which.
3120          *
3121          * If we get to the end of the list, we can return TRUE.  This will
3122          * happen when the AND result is indeed TRUE, or when the AND result
3123          * is NULL (one or more NULL subresult, with all the rest TRUE) and
3124          * the caller has specified resultForNull = TRUE.
3125          */
3126         result = true;
3127
3128         foreach(l, qual)
3129         {
3130                 ExprState  *clause = (ExprState *) lfirst(l);
3131                 Datum           expr_value;
3132                 bool            isNull;
3133
3134                 expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
3135
3136                 if (isNull)
3137                 {
3138                         if (resultForNull == false)
3139                         {
3140                                 result = false; /* treat NULL as FALSE */
3141                                 break;
3142                         }
3143                 }
3144                 else
3145                 {
3146                         if (!DatumGetBool(expr_value))
3147                         {
3148                                 result = false; /* definitely FALSE */
3149                                 break;
3150                         }
3151                 }
3152         }
3153
3154         MemoryContextSwitchTo(oldContext);
3155
3156         return result;
3157 }
3158
3159 /*
3160  * Number of items in a tlist (including any resjunk items!)
3161  */
3162 int
3163 ExecTargetListLength(List *targetlist)
3164 {
3165         /* This used to be more complex, but fjoins are dead */
3166         return list_length(targetlist);
3167 }
3168
3169 /*
3170  * Number of items in a tlist, not including any resjunk items
3171  */
3172 int
3173 ExecCleanTargetListLength(List *targetlist)
3174 {
3175         int                     len = 0;
3176         ListCell   *tl;
3177
3178         foreach(tl, targetlist)
3179         {
3180                 TargetEntry *curTle = (TargetEntry *) lfirst(tl);
3181
3182                 Assert(IsA(curTle, TargetEntry));
3183                 if (!curTle->resdom->resjunk)
3184                         len++;
3185         }
3186         return len;
3187 }
3188
3189 /* ----------------------------------------------------------------
3190  *              ExecTargetList
3191  *
3192  *              Evaluates a targetlist with respect to the given
3193  *              expression context and returns a tuple.
3194  *
3195  * The caller must pass workspace for the values and nulls arrays
3196  * as well as the itemIsDone array.  This convention saves palloc'ing
3197  * workspace on each call, and some callers may find it useful to examine
3198  * the values array directly.
3199  *
3200  * As with ExecEvalExpr, the caller should pass isDone = NULL if not
3201  * prepared to deal with sets of result tuples.  Otherwise, a return
3202  * of *isDone = ExprMultipleResult signifies a set element, and a return
3203  * of *isDone = ExprEndResult signifies end of the set of tuple.
3204  * ----------------------------------------------------------------
3205  */
3206 static HeapTuple
3207 ExecTargetList(List *targetlist,
3208                            TupleDesc targettype,
3209                            ExprContext *econtext,
3210                            Datum *values,
3211                            char *nulls,
3212                            ExprDoneCond *itemIsDone,
3213                            ExprDoneCond *isDone)
3214 {
3215         MemoryContext oldContext;
3216         ListCell   *tl;
3217         bool            isNull;
3218         bool            haveDoneSets;
3219
3220         /*
3221          * debugging stuff
3222          */
3223         EV_printf("ExecTargetList: tl is ");
3224         EV_nodeDisplay(targetlist);
3225         EV_printf("\n");
3226
3227         /*
3228          * Run in short-lived per-tuple context while computing expressions.
3229          */
3230         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
3231
3232         /*
3233          * There used to be some klugy and demonstrably broken code here that
3234          * special-cased the situation where targetlist == NIL.  Now we just
3235          * fall through and return an empty-but-valid tuple.
3236          */
3237
3238         /*
3239          * evaluate all the expressions in the target list
3240          */
3241         if (isDone)
3242                 *isDone = ExprSingleResult;             /* until proven otherwise */
3243
3244         haveDoneSets = false;           /* any exhausted set exprs in tlist? */
3245
3246         foreach(tl, targetlist)
3247         {
3248                 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
3249                 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
3250                 AttrNumber      resind = tle->resdom->resno - 1;
3251
3252                 values[resind] = ExecEvalExpr(gstate->arg,
3253                                                                           econtext,
3254                                                                           &isNull,
3255                                                                           &itemIsDone[resind]);
3256                 nulls[resind] = isNull ? 'n' : ' ';
3257
3258                 if (itemIsDone[resind] != ExprSingleResult)
3259                 {
3260                         /* We have a set-valued expression in the tlist */
3261                         if (isDone == NULL)
3262                                 ereport(ERROR,
3263                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3264                                                  errmsg("set-valued function called in context that cannot accept a set")));
3265                         if (itemIsDone[resind] == ExprMultipleResult)
3266                         {
3267                                 /* we have undone sets in the tlist, set flag */
3268                                 *isDone = ExprMultipleResult;
3269                         }
3270                         else
3271                         {
3272                                 /* we have done sets in the tlist, set flag for that */
3273                                 haveDoneSets = true;
3274                         }
3275                 }
3276         }
3277
3278         if (haveDoneSets)
3279         {
3280                 /*
3281                  * note: can't get here unless we verified isDone != NULL
3282                  */
3283                 if (*isDone == ExprSingleResult)
3284                 {
3285                         /*
3286                          * all sets are done, so report that tlist expansion is
3287                          * complete.
3288                          */
3289                         *isDone = ExprEndResult;
3290                         MemoryContextSwitchTo(oldContext);
3291                         return NULL;
3292                 }
3293                 else
3294                 {
3295                         /*
3296                          * We have some done and some undone sets.      Restart the done
3297                          * ones so that we can deliver a tuple (if possible).
3298                          */
3299                         foreach(tl, targetlist)
3300                         {
3301                                 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
3302                                 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
3303                                 AttrNumber      resind = tle->resdom->resno - 1;
3304
3305                                 if (itemIsDone[resind] == ExprEndResult)
3306                                 {
3307                                         values[resind] = ExecEvalExpr(gstate->arg,
3308                                                                                                   econtext,
3309                                                                                                   &isNull,
3310                                                                                                   &itemIsDone[resind]);
3311                                         nulls[resind] = isNull ? 'n' : ' ';
3312
3313                                         if (itemIsDone[resind] == ExprEndResult)
3314                                         {
3315                                                 /*
3316                                                  * Oh dear, this item is returning an empty set.
3317                                                  * Guess we can't make a tuple after all.
3318                                                  */
3319                                                 *isDone = ExprEndResult;
3320                                                 break;
3321                                         }
3322                                 }
3323                         }
3324
3325                         /*
3326                          * If we cannot make a tuple because some sets are empty, we
3327                          * still have to cycle the nonempty sets to completion, else
3328                          * resources will not be released from subplans etc.
3329                          *
3330                          * XXX is that still necessary?
3331                          */
3332                         if (*isDone == ExprEndResult)
3333                         {
3334                                 foreach(tl, targetlist)
3335                                 {
3336                                         GenericExprState *gstate = (GenericExprState *) lfirst(tl);
3337                                         TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
3338                                         AttrNumber      resind = tle->resdom->resno - 1;
3339
3340                                         while (itemIsDone[resind] == ExprMultipleResult)
3341                                         {
3342                                                 (void) ExecEvalExpr(gstate->arg,
3343                                                                                         econtext,
3344                                                                                         &isNull,
3345                                                                                         &itemIsDone[resind]);
3346                                         }
3347                                 }
3348
3349                                 MemoryContextSwitchTo(oldContext);
3350                                 return NULL;
3351                         }
3352                 }
3353         }
3354
3355         /*
3356          * form the new result tuple (in the caller's memory context!)
3357          */
3358         MemoryContextSwitchTo(oldContext);
3359
3360         return heap_formtuple(targettype, values, nulls);
3361 }
3362
3363 /* ----------------------------------------------------------------
3364  *              ExecProject
3365  *
3366  *              projects a tuple based on projection info and stores
3367  *              it in the specified tuple table slot.
3368  *
3369  *              Note: someday soon the executor can be extended to eliminate
3370  *                        redundant projections by storing pointers to datums
3371  *                        in the tuple table and then passing these around when
3372  *                        possible.  this should make things much quicker.
3373  *                        -cim 6/3/91
3374  * ----------------------------------------------------------------
3375  */
3376 TupleTableSlot *
3377 ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
3378 {
3379         TupleTableSlot *slot;
3380         TupleDesc       tupType;
3381         HeapTuple       newTuple;
3382
3383         /*
3384          * sanity checks
3385          */
3386         if (projInfo == NULL)
3387                 return NULL;
3388
3389         /*
3390          * get the projection info we want
3391          */
3392         slot = projInfo->pi_slot;
3393         tupType = slot->ttc_tupleDescriptor;
3394
3395         /*
3396          * form a new result tuple (if possible --- result can be NULL)
3397          */
3398         newTuple = ExecTargetList(projInfo->pi_targetlist,
3399                                                           tupType,
3400                                                           projInfo->pi_exprContext,
3401                                                           projInfo->pi_tupValues,
3402                                                           projInfo->pi_tupNulls,
3403                                                           projInfo->pi_itemIsDone,
3404                                                           isDone);
3405
3406         /*
3407          * store the tuple in the projection slot and return the slot.
3408          */
3409         return ExecStoreTuple(newTuple,                 /* tuple to store */
3410                                                   slot,                         /* slot to store in */
3411                                                   InvalidBuffer,        /* tuple has no buffer */
3412                                                   true);
3413 }