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