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