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