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