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