]> granicus.if.org Git - postgresql/blob - src/backend/executor/execQual.c
OK, some of these syntax errors should be given other codes.
[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-2003, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.144 2003/09/15 20:03:37 petere Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 /*
16  *       INTERFACE ROUTINES
17  *              ExecEvalExpr    - evaluate an expression and 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  *              ExecEvalExpr() and ExecEvalVar() are hotspots.  making these faster
24  *              will speed up the entire system.  Unfortunately they are currently
25  *              implemented recursively.  Eliminating the recursion is bound to
26  *              improve the speed of the executor.
27  *
28  *              ExecProject() is used to make tuple projections.  Rather then
29  *              trying to speed it up, the execution plan should be pre-processed
30  *              to facilitate attribute sharing between nodes wherever possible,
31  *              instead of doing needless copying.      -cim 5/31/91
32  *
33  */
34
35 #include "postgres.h"
36
37 #include "access/heapam.h"
38 #include "catalog/pg_type.h"
39 #include "commands/typecmds.h"
40 #include "executor/execdebug.h"
41 #include "executor/functions.h"
42 #include "executor/nodeSubplan.h"
43 #include "miscadmin.h"
44 #include "optimizer/planmain.h"
45 #include "parser/parse_expr.h"
46 #include "utils/acl.h"
47 #include "utils/array.h"
48 #include "utils/builtins.h"
49 #include "utils/lsyscache.h"
50
51
52 /* static function decls */
53 static Datum ExecEvalAggref(AggrefExprState *aggref,
54                            ExprContext *econtext,
55                            bool *isNull);
56 static Datum ExecEvalArrayRef(ArrayRefExprState *astate,
57                                  ExprContext *econtext,
58                                  bool *isNull, ExprDoneCond *isDone);
59 static Datum ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull);
60 static Datum ExecEvalParam(Param *expression, ExprContext *econtext,
61                           bool *isNull);
62 static Datum ExecEvalFunc(FuncExprState *fcache, ExprContext *econtext,
63                          bool *isNull, ExprDoneCond *isDone);
64 static Datum ExecEvalOper(FuncExprState *fcache, ExprContext *econtext,
65                          bool *isNull, ExprDoneCond *isDone);
66 static Datum ExecEvalDistinct(FuncExprState *fcache, ExprContext *econtext,
67                                  bool *isNull);
68 static Datum ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
69                                           ExprContext *econtext, bool *isNull);
70 static ExprDoneCond ExecEvalFuncArgs(FunctionCallInfo fcinfo,
71                                  List *argList, ExprContext *econtext);
72 static Datum ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
73                         bool *isNull);
74 static Datum ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
75                    bool *isNull);
76 static Datum ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
77                         bool *isNull);
78 static Datum ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
79                          bool *isNull, ExprDoneCond *isDone);
80 static Datum ExecEvalArray(ArrayExprState *astate,
81                           ExprContext *econtext,
82                           bool *isNull);
83 static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr,
84                                  ExprContext *econtext,
85                                  bool *isNull);
86 static Datum ExecEvalNullIf(FuncExprState *nullIfExpr, ExprContext *econtext,
87                            bool *isNull);
88 static Datum ExecEvalNullTest(GenericExprState *nstate,
89                                  ExprContext *econtext,
90                                  bool *isNull, ExprDoneCond *isDone);
91 static Datum ExecEvalBooleanTest(GenericExprState *bstate,
92                                         ExprContext *econtext,
93                                         bool *isNull, ExprDoneCond *isDone);
94 static Datum ExecEvalCoerceToDomain(CoerceToDomainState *cstate,
95                                            ExprContext *econtext,
96                                            bool *isNull, ExprDoneCond *isDone);
97 static Datum ExecEvalCoerceToDomainValue(CoerceToDomainValue *conVal,
98                                                         ExprContext *econtext, bool *isNull);
99 static Datum ExecEvalFieldSelect(GenericExprState *fstate,
100                                         ExprContext *econtext,
101                                         bool *isNull, ExprDoneCond *isDone);
102
103
104 /*----------
105  *        ExecEvalArrayRef
106  *
107  *         This function takes an ArrayRef and returns the extracted Datum
108  *         if it's a simple reference, or the modified array value if it's
109  *         an array assignment (i.e., array element or slice insertion).
110  *
111  * NOTE: if we get a NULL result from a subexpression, we return NULL when
112  * it's an array reference, or the unmodified source array when it's an
113  * array assignment.  This may seem peculiar, but if we return NULL (as was
114  * done in versions up through 7.0) then an assignment like
115  *                      UPDATE table SET arrayfield[4] = NULL
116  * will result in setting the whole array to NULL, which is certainly not
117  * very desirable.      By returning the source array we make the assignment
118  * into a no-op, instead.  (Eventually we need to redesign arrays so that
119  * individual elements can be NULL, but for now, let's try to protect users
120  * from shooting themselves in the foot.)
121  *
122  * NOTE: we deliberately refrain from applying DatumGetArrayTypeP() here,
123  * even though that might seem natural, because this code needs to support
124  * both varlena arrays and fixed-length array types.  DatumGetArrayTypeP()
125  * only works for the varlena kind.  The routines we call in arrayfuncs.c
126  * have to know the difference (that's what they need refattrlength for).
127  *----------
128  */
129 static Datum
130 ExecEvalArrayRef(ArrayRefExprState *astate,
131                                  ExprContext *econtext,
132                                  bool *isNull,
133                                  ExprDoneCond *isDone)
134 {
135         ArrayRef   *arrayRef = (ArrayRef *) astate->xprstate.expr;
136         ArrayType  *array_source;
137         ArrayType  *resultArray;
138         bool            isAssignment = (arrayRef->refassgnexpr != NULL);
139         List       *elt;
140         int                     i = 0,
141                                 j = 0;
142         IntArray        upper,
143                                 lower;
144         int                *lIndex;
145
146         if (arrayRef->refexpr != NULL)
147         {
148                 array_source = (ArrayType *)
149                         DatumGetPointer(ExecEvalExpr(astate->refexpr,
150                                                                                  econtext,
151                                                                                  isNull,
152                                                                                  isDone));
153
154                 /*
155                  * If refexpr yields NULL, result is always NULL, for now anyway.
156                  * (This means you cannot assign to an element or slice of an
157                  * array that's NULL; it'll just stay NULL.)
158                  */
159                 if (*isNull)
160                         return (Datum) NULL;
161         }
162         else
163         {
164                 /*
165                  * Empty refexpr indicates we are doing an INSERT into an array
166                  * column. For now, we just take the refassgnexpr (which the
167                  * parser will have ensured is an array value) and return it
168                  * as-is, ignoring any subscripts that may have been supplied in
169                  * the INSERT column list. This is a kluge, but it's not real
170                  * clear what the semantics ought to be...
171                  */
172                 array_source = NULL;
173         }
174
175         foreach(elt, astate->refupperindexpr)
176         {
177                 if (i >= MAXDIM)
178                         ereport(ERROR,
179                                         (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
180                                          errmsg("number of array dimensions exceeds the maximum allowed, %d",
181                                                         MAXDIM)));
182
183                 upper.indx[i++] = DatumGetInt32(ExecEvalExpr((ExprState *) lfirst(elt),
184                                                                                                          econtext,
185                                                                                                          isNull,
186                                                                                                          NULL));
187                 /* If any index expr yields NULL, result is NULL or source array */
188                 if (*isNull)
189                 {
190                         if (!isAssignment || array_source == NULL)
191                                 return (Datum) NULL;
192                         *isNull = false;
193                         return PointerGetDatum(array_source);
194                 }
195         }
196
197         if (astate->reflowerindexpr != NIL)
198         {
199                 foreach(elt, astate->reflowerindexpr)
200                 {
201                         if (j >= MAXDIM)
202                                 ereport(ERROR,
203                                                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
204                                                  errmsg("number of array dimensions exceeds the maximum allowed, %d",
205                                                                 MAXDIM)));
206
207                         lower.indx[j++] = DatumGetInt32(ExecEvalExpr((ExprState *) lfirst(elt),
208                                                                                                                  econtext,
209                                                                                                                  isNull,
210                                                                                                                  NULL));
211
212                         /*
213                          * If any index expr yields NULL, result is NULL or source
214                          * array
215                          */
216                         if (*isNull)
217                         {
218                                 if (!isAssignment || array_source == NULL)
219                                         return (Datum) NULL;
220                                 *isNull = false;
221                                 return PointerGetDatum(array_source);
222                         }
223                 }
224                 /* this can't happen unless parser messed up */
225                 if (i != j)
226                         elog(ERROR, "upper and lower index lists are not same length");
227                 lIndex = lower.indx;
228         }
229         else
230                 lIndex = NULL;
231
232         if (isAssignment)
233         {
234                 Datum           sourceData = ExecEvalExpr(astate->refassgnexpr,
235                                                                                           econtext,
236                                                                                           isNull,
237                                                                                           NULL);
238
239                 /*
240                  * For now, can't cope with inserting NULL into an array, so make
241                  * it a no-op per discussion above...
242                  */
243                 if (*isNull)
244                 {
245                         if (array_source == NULL)
246                                 return (Datum) NULL;
247                         *isNull = false;
248                         return PointerGetDatum(array_source);
249                 }
250
251                 if (array_source == NULL)
252                         return sourceData;      /* XXX do something else? */
253
254                 if (lIndex == NULL)
255                         resultArray = array_set(array_source, i,
256                                                                         upper.indx,
257                                                                         sourceData,
258                                                                         astate->refattrlength,
259                                                                         astate->refelemlength,
260                                                                         astate->refelembyval,
261                                                                         astate->refelemalign,
262                                                                         isNull);
263                 else
264                         resultArray = array_set_slice(array_source, i,
265                                                                                   upper.indx, lower.indx,
266                                                            (ArrayType *) DatumGetPointer(sourceData),
267                                                                                   astate->refattrlength,
268                                                                                   astate->refelemlength,
269                                                                                   astate->refelembyval,
270                                                                                   astate->refelemalign,
271                                                                                   isNull);
272                 return PointerGetDatum(resultArray);
273         }
274
275         if (lIndex == NULL)
276                 return array_ref(array_source, i, upper.indx,
277                                                  astate->refattrlength,
278                                                  astate->refelemlength,
279                                                  astate->refelembyval,
280                                                  astate->refelemalign,
281                                                  isNull);
282         else
283         {
284                 resultArray = array_get_slice(array_source, i,
285                                                                           upper.indx, lower.indx,
286                                                                           astate->refattrlength,
287                                                                           astate->refelemlength,
288                                                                           astate->refelembyval,
289                                                                           astate->refelemalign,
290                                                                           isNull);
291                 return PointerGetDatum(resultArray);
292         }
293 }
294
295
296 /* ----------------------------------------------------------------
297  *              ExecEvalAggref
298  *
299  *              Returns a Datum whose value is the value of the precomputed
300  *              aggregate found in the given expression context.
301  * ----------------------------------------------------------------
302  */
303 static Datum
304 ExecEvalAggref(AggrefExprState *aggref, ExprContext *econtext, bool *isNull)
305 {
306         if (econtext->ecxt_aggvalues == NULL)           /* safety check */
307                 elog(ERROR, "no aggregates in this expression context");
308
309         *isNull = econtext->ecxt_aggnulls[aggref->aggno];
310         return econtext->ecxt_aggvalues[aggref->aggno];
311 }
312
313 /* ----------------------------------------------------------------
314  *              ExecEvalVar
315  *
316  *              Returns a Datum whose value is the value of a range
317  *              variable with respect to given expression context.
318  *
319  *
320  *              As an entry condition, we expect that the datatype the
321  *              plan expects to get (as told by our "variable" argument) is in
322  *              fact the datatype of the attribute the plan says to fetch (as
323  *              seen in the current context, identified by our "econtext"
324  *              argument).
325  *
326  *              If we fetch a Type A attribute and Caller treats it as if it
327  *              were Type B, there will be undefined results (e.g. crash).
328  *              One way these might mismatch now is that we're accessing a
329  *              catalog class and the type information in the pg_attribute
330  *              class does not match the hardcoded pg_attribute information
331  *              (in pg_attribute.h) for the class in question.
332  *
333  *              We have an Assert to make sure this entry condition is met.
334  *
335  * ---------------------------------------------------------------- */
336 static Datum
337 ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
338 {
339         Datum           result;
340         TupleTableSlot *slot;
341         AttrNumber      attnum;
342         HeapTuple       heapTuple;
343         TupleDesc       tuple_type;
344
345         /*
346          * get the slot we want
347          */
348         switch (variable->varno)
349         {
350                 case INNER:                             /* get the tuple from the inner node */
351                         slot = econtext->ecxt_innertuple;
352                         break;
353
354                 case OUTER:                             /* get the tuple from the outer node */
355                         slot = econtext->ecxt_outertuple;
356                         break;
357
358                 default:                                /* get the tuple from the relation being
359                                                                  * scanned */
360                         slot = econtext->ecxt_scantuple;
361                         break;
362         }
363
364         /*
365          * extract tuple information from the slot
366          */
367         heapTuple = slot->val;
368         tuple_type = slot->ttc_tupleDescriptor;
369
370         attnum = variable->varattno;
371
372         /* (See prolog for explanation of this Assert) */
373         Assert(attnum <= 0 ||
374                    (attnum - 1 <= tuple_type->natts - 1 &&
375                         tuple_type->attrs[attnum - 1] != NULL &&
376                   variable->vartype == tuple_type->attrs[attnum - 1]->atttypid));
377
378         /*
379          * If the attribute number is invalid, then we are supposed to return
380          * the entire tuple; we give back a whole slot so that callers know
381          * what the tuple looks like.
382          *
383          * XXX this is a horrid crock: since the pointer to the slot might live
384          * longer than the current evaluation context, we are forced to copy
385          * the tuple and slot into a long-lived context --- we use the
386          * econtext's per-query memory which should be safe enough.  This
387          * represents a serious memory leak if many such tuples are processed
388          * in one command, however.  We ought to redesign the representation
389          * of whole-tuple datums so that this is not necessary.
390          *
391          * We assume it's OK to point to the existing tupleDescriptor, rather
392          * than copy that too.
393          */
394         if (attnum == InvalidAttrNumber)
395         {
396                 MemoryContext oldContext;
397                 TupleTableSlot *tempSlot;
398                 HeapTuple       tup;
399
400                 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
401                 tempSlot = MakeTupleTableSlot();
402                 tup = heap_copytuple(heapTuple);
403                 ExecStoreTuple(tup, tempSlot, InvalidBuffer, true);
404                 ExecSetSlotDescriptor(tempSlot, tuple_type, false);
405                 MemoryContextSwitchTo(oldContext);
406                 return PointerGetDatum(tempSlot);
407         }
408
409         result = heap_getattr(heapTuple,        /* tuple containing attribute */
410                                                   attnum,               /* attribute number of desired
411                                                                                  * attribute */
412                                                   tuple_type,   /* tuple descriptor of tuple */
413                                                   isNull);              /* return: is attribute null? */
414
415         return result;
416 }
417
418 /* ----------------------------------------------------------------
419  *              ExecEvalParam
420  *
421  *              Returns the value of a parameter.  A param node contains
422  *              something like ($.name) and the expression context contains
423  *              the current parameter bindings (name = "sam") (age = 34)...
424  *              so our job is to find and return the appropriate datum ("sam").
425  *
426  *              Q: if we have a parameter ($.foo) without a binding, i.e.
427  *                 there is no (foo = xxx) in the parameter list info,
428  *                 is this a fatal error or should this be a "not available"
429  *                 (in which case we could return NULL)?        -cim 10/13/89
430  * ----------------------------------------------------------------
431  */
432 static Datum
433 ExecEvalParam(Param *expression, ExprContext *econtext, bool *isNull)
434 {
435         int                     thisParamKind = expression->paramkind;
436         AttrNumber      thisParamId = expression->paramid;
437
438         if (thisParamKind == PARAM_EXEC)
439         {
440                 /*
441                  * PARAM_EXEC params (internal executor parameters) are stored in
442                  * the ecxt_param_exec_vals array, and can be accessed by array
443                  * index.
444                  */
445                 ParamExecData *prm;
446
447                 prm = &(econtext->ecxt_param_exec_vals[thisParamId]);
448                 if (prm->execPlan != NULL)
449                 {
450                         /* Parameter not evaluated yet, so go do it */
451                         ExecSetParamPlan(prm->execPlan, econtext);
452                         /* ExecSetParamPlan should have processed this param... */
453                         Assert(prm->execPlan == NULL);
454                 }
455                 *isNull = prm->isnull;
456                 return prm->value;
457         }
458         else
459         {
460                 /*
461                  * All other parameter types must be sought in
462                  * ecxt_param_list_info. NOTE: The last entry in the param array
463                  * is always an entry with kind == PARAM_INVALID.
464                  */
465                 ParamListInfo paramList = econtext->ecxt_param_list_info;
466                 char       *thisParamName = expression->paramname;
467                 bool            matchFound = false;
468
469                 if (paramList != NULL)
470                 {
471                         while (paramList->kind != PARAM_INVALID && !matchFound)
472                         {
473                                 if (thisParamKind == paramList->kind)
474                                 {
475                                         switch (thisParamKind)
476                                         {
477                                                 case PARAM_NAMED:
478                                                         if (strcmp(paramList->name, thisParamName) == 0)
479                                                                 matchFound = true;
480                                                         break;
481                                                 case PARAM_NUM:
482                                                         if (paramList->id == thisParamId)
483                                                                 matchFound = true;
484                                                         break;
485                                                 default:
486                                                         elog(ERROR, "unrecognized paramkind: %d",
487                                                                  thisParamKind);
488                                         }
489                                 }
490                                 if (!matchFound)
491                                         paramList++;
492                         }                                       /* while */
493                 }                                               /* if */
494
495                 if (!matchFound)
496                 {
497                         if (thisParamKind == PARAM_NAMED)
498                                 ereport(ERROR,
499                                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
500                                                  errmsg("no value found for parameter \"%s\"",
501                                                                 thisParamName)));
502                         else
503                                 ereport(ERROR,
504                                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
505                                                  errmsg("no value found for parameter %d",
506                                                                 thisParamId)));
507                 }
508
509                 *isNull = paramList->isnull;
510                 return paramList->value;
511         }
512 }
513
514
515 /* ----------------------------------------------------------------
516  *              ExecEvalOper / ExecEvalFunc support routines
517  * ----------------------------------------------------------------
518  */
519
520 /*
521  *              GetAttributeByName
522  *              GetAttributeByNum
523  *
524  *              These are functions which return the value of the
525  *              named attribute out of the tuple from the arg slot.  User defined
526  *              C functions which take a tuple as an argument are expected
527  *              to use this.  Ex: overpaid(EMP) might call GetAttributeByNum().
528  */
529 Datum
530 GetAttributeByNum(TupleTableSlot *slot,
531                                   AttrNumber attrno,
532                                   bool *isNull)
533 {
534         Datum           retval;
535
536         if (!AttributeNumberIsValid(attrno))
537                 elog(ERROR, "invalid attribute number %d", attrno);
538
539         if (isNull == (bool *) NULL)
540                 elog(ERROR, "a NULL isNull pointer was passed");
541
542         if (TupIsNull(slot))
543         {
544                 *isNull = true;
545                 return (Datum) 0;
546         }
547
548         retval = heap_getattr(slot->val,
549                                                   attrno,
550                                                   slot->ttc_tupleDescriptor,
551                                                   isNull);
552         if (*isNull)
553                 return (Datum) 0;
554
555         return retval;
556 }
557
558 Datum
559 GetAttributeByName(TupleTableSlot *slot, char *attname, bool *isNull)
560 {
561         AttrNumber      attrno;
562         TupleDesc       tupdesc;
563         Datum           retval;
564         int                     natts;
565         int                     i;
566
567         if (attname == NULL)
568                 elog(ERROR, "invalid attribute name");
569
570         if (isNull == (bool *) NULL)
571                 elog(ERROR, "a NULL isNull pointer was passed");
572
573         if (TupIsNull(slot))
574         {
575                 *isNull = true;
576                 return (Datum) 0;
577         }
578
579         tupdesc = slot->ttc_tupleDescriptor;
580         natts = slot->val->t_data->t_natts;
581
582         attrno = InvalidAttrNumber;
583         for (i = 0; i < tupdesc->natts; i++)
584         {
585                 if (namestrcmp(&(tupdesc->attrs[i]->attname), attname) == 0)
586                 {
587                         attrno = tupdesc->attrs[i]->attnum;
588                         break;
589                 }
590         }
591
592         if (attrno == InvalidAttrNumber)
593                 elog(ERROR, "attribute \"%s\" does not exist", attname);
594
595         retval = heap_getattr(slot->val,
596                                                   attrno,
597                                                   tupdesc,
598                                                   isNull);
599         if (*isNull)
600                 return (Datum) 0;
601
602         return retval;
603 }
604
605 /*
606  * init_fcache - initialize a FuncExprState node during first use
607  */
608 void
609 init_fcache(Oid foid, FuncExprState *fcache, MemoryContext fcacheCxt)
610 {
611         AclResult       aclresult;
612
613         /* Check permission to call function */
614         aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
615         if (aclresult != ACLCHECK_OK)
616                 aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(foid));
617
618         /* Safety check (should never fail, as parser should check sooner) */
619         if (length(fcache->args) > FUNC_MAX_ARGS)
620                 elog(ERROR, "too many arguments");
621
622         /* Set up the primary fmgr lookup information */
623         fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
624
625         /* Initialize additional info */
626         fcache->setArgsValid = false;
627         fcache->func.fn_expr = (Node *) fcache->xprstate.expr;
628 }
629
630 /*
631  * Evaluate arguments for a function.
632  */
633 static ExprDoneCond
634 ExecEvalFuncArgs(FunctionCallInfo fcinfo,
635                                  List *argList,
636                                  ExprContext *econtext)
637 {
638         ExprDoneCond argIsDone;
639         int                     i;
640         List       *arg;
641
642         argIsDone = ExprSingleResult;           /* default assumption */
643
644         i = 0;
645         foreach(arg, argList)
646         {
647                 ExprDoneCond thisArgIsDone;
648
649                 fcinfo->arg[i] = ExecEvalExpr((ExprState *) lfirst(arg),
650                                                                           econtext,
651                                                                           &fcinfo->argnull[i],
652                                                                           &thisArgIsDone);
653
654                 if (thisArgIsDone != ExprSingleResult)
655                 {
656                         /*
657                          * We allow only one argument to have a set value; we'd need
658                          * much more complexity to keep track of multiple set
659                          * arguments (cf. ExecTargetList) and it doesn't seem worth
660                          * it.
661                          */
662                         if (argIsDone != ExprSingleResult)
663                                 ereport(ERROR,
664                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
665                                                  errmsg("functions and operators can take at most one set argument")));
666                         argIsDone = thisArgIsDone;
667                 }
668                 i++;
669         }
670
671         fcinfo->nargs = i;
672
673         return argIsDone;
674 }
675
676 /*
677  *              ExecMakeFunctionResult
678  *
679  * Evaluate the arguments to a function and then the function itself.
680  */
681 Datum
682 ExecMakeFunctionResult(FuncExprState *fcache,
683                                            ExprContext *econtext,
684                                            bool *isNull,
685                                            ExprDoneCond *isDone)
686 {
687         List       *arguments = fcache->args;
688         Datum           result;
689         FunctionCallInfoData fcinfo;
690         ReturnSetInfo rsinfo;           /* for functions returning sets */
691         ExprDoneCond argDone;
692         bool            hasSetArg;
693         int                     i;
694
695         /*
696          * arguments is a list of expressions to evaluate before passing to
697          * the function manager.  We skip the evaluation if it was already
698          * done in the previous call (ie, we are continuing the evaluation of
699          * a set-valued function).      Otherwise, collect the current argument
700          * values into fcinfo.
701          */
702         if (!fcache->setArgsValid)
703         {
704                 /* Need to prep callinfo structure */
705                 MemSet(&fcinfo, 0, sizeof(fcinfo));
706                 fcinfo.flinfo = &(fcache->func);
707                 argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);
708                 if (argDone == ExprEndResult)
709                 {
710                         /* input is an empty set, so return an empty set. */
711                         *isNull = true;
712                         if (isDone)
713                                 *isDone = ExprEndResult;
714                         else
715                                 ereport(ERROR,
716                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
717                                                  errmsg("set-valued function called in context that cannot accept a set")));
718                         return (Datum) 0;
719                 }
720                 hasSetArg = (argDone != ExprSingleResult);
721         }
722         else
723         {
724                 /* Copy callinfo from previous evaluation */
725                 memcpy(&fcinfo, &fcache->setArgs, sizeof(fcinfo));
726                 hasSetArg = fcache->setHasSetArg;
727                 /* Reset flag (we may set it again below) */
728                 fcache->setArgsValid = false;
729         }
730
731         /*
732          * If function returns set, prepare a resultinfo node for
733          * communication
734          */
735         if (fcache->func.fn_retset)
736         {
737                 fcinfo.resultinfo = (Node *) &rsinfo;
738                 rsinfo.type = T_ReturnSetInfo;
739                 rsinfo.econtext = econtext;
740                 rsinfo.expectedDesc = NULL;
741                 rsinfo.allowedModes = (int) SFRM_ValuePerCall;
742                 rsinfo.returnMode = SFRM_ValuePerCall;
743                 /* isDone is filled below */
744                 rsinfo.setResult = NULL;
745                 rsinfo.setDesc = NULL;
746         }
747
748         /*
749          * now return the value gotten by calling the function manager,
750          * passing the function the evaluated parameter values.
751          */
752         if (fcache->func.fn_retset || hasSetArg)
753         {
754                 /*
755                  * We need to return a set result.      Complain if caller not ready
756                  * to accept one.
757                  */
758                 if (isDone == NULL)
759                         ereport(ERROR,
760                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
761                                          errmsg("set-valued function called in context that cannot accept a set")));
762
763                 /*
764                  * This loop handles the situation where we have both a set
765                  * argument and a set-valued function.  Once we have exhausted the
766                  * function's value(s) for a particular argument value, we have to
767                  * get the next argument value and start the function over again.
768                  * We might have to do it more than once, if the function produces
769                  * an empty result set for a particular input value.
770                  */
771                 for (;;)
772                 {
773                         /*
774                          * If function is strict, and there are any NULL arguments,
775                          * skip calling the function (at least for this set of args).
776                          */
777                         bool            callit = true;
778
779                         if (fcache->func.fn_strict)
780                         {
781                                 for (i = 0; i < fcinfo.nargs; i++)
782                                 {
783                                         if (fcinfo.argnull[i])
784                                         {
785                                                 callit = false;
786                                                 break;
787                                         }
788                                 }
789                         }
790
791                         if (callit)
792                         {
793                                 fcinfo.isnull = false;
794                                 rsinfo.isDone = ExprSingleResult;
795                                 result = FunctionCallInvoke(&fcinfo);
796                                 *isNull = fcinfo.isnull;
797                                 *isDone = rsinfo.isDone;
798                         }
799                         else
800                         {
801                                 result = (Datum) 0;
802                                 *isNull = true;
803                                 *isDone = ExprEndResult;
804                         }
805
806                         if (*isDone != ExprEndResult)
807                         {
808                                 /*
809                                  * Got a result from current argument.  If function itself
810                                  * returns set, save the current argument values to re-use
811                                  * on the next call.
812                                  */
813                                 if (fcache->func.fn_retset)
814                                 {
815                                         memcpy(&fcache->setArgs, &fcinfo, sizeof(fcinfo));
816                                         fcache->setHasSetArg = hasSetArg;
817                                         fcache->setArgsValid = true;
818                                 }
819
820                                 /*
821                                  * Make sure we say we are returning a set, even if the
822                                  * function itself doesn't return sets.
823                                  */
824                                 *isDone = ExprMultipleResult;
825                                 break;
826                         }
827
828                         /* Else, done with this argument */
829                         if (!hasSetArg)
830                                 break;                  /* input not a set, so done */
831
832                         /* Re-eval args to get the next element of the input set */
833                         argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);
834
835                         if (argDone != ExprMultipleResult)
836                         {
837                                 /* End of argument set, so we're done. */
838                                 *isNull = true;
839                                 *isDone = ExprEndResult;
840                                 result = (Datum) 0;
841                                 break;
842                         }
843
844                         /*
845                          * If we reach here, loop around to run the function on the
846                          * new argument.
847                          */
848                 }
849         }
850         else
851         {
852                 /*
853                  * Non-set case: much easier.
854                  *
855                  * If function is strict, and there are any NULL arguments, skip
856                  * calling the function and return NULL.
857                  */
858                 if (fcache->func.fn_strict)
859                 {
860                         for (i = 0; i < fcinfo.nargs; i++)
861                         {
862                                 if (fcinfo.argnull[i])
863                                 {
864                                         *isNull = true;
865                                         return (Datum) 0;
866                                 }
867                         }
868                 }
869                 fcinfo.isnull = false;
870                 result = FunctionCallInvoke(&fcinfo);
871                 *isNull = fcinfo.isnull;
872         }
873
874         return result;
875 }
876
877
878 /*
879  *              ExecMakeTableFunctionResult
880  *
881  * Evaluate a table function, producing a materialized result in a Tuplestore
882  * object.      (If function returns an empty set, we just return NULL instead.)
883  */
884 Tuplestorestate *
885 ExecMakeTableFunctionResult(ExprState *funcexpr,
886                                                         ExprContext *econtext,
887                                                         TupleDesc expectedDesc,
888                                                         TupleDesc *returnDesc)
889 {
890         Tuplestorestate *tupstore = NULL;
891         TupleDesc       tupdesc = NULL;
892         Oid                     funcrettype;
893         FunctionCallInfoData fcinfo;
894         ReturnSetInfo rsinfo;
895         MemoryContext callerContext;
896         MemoryContext oldcontext;
897         TupleTableSlot *slot;
898         bool            direct_function_call;
899         bool            first_time = true;
900         bool            returnsTuple = false;
901
902         /*
903          * Normally the passed expression tree will be a FuncExprState, since
904          * the grammar only allows a function call at the top level of a table
905          * function reference.  However, if the function doesn't return set
906          * then the planner might have replaced the function call via
907          * constant-folding or inlining.  So if we see any other kind of
908          * expression node, execute it via the general ExecEvalExpr() code;
909          * the only difference is that we don't get a chance to pass a special
910          * ReturnSetInfo to any functions buried in the expression.
911          */
912         if (funcexpr && IsA(funcexpr, FuncExprState) &&
913                 IsA(funcexpr->expr, FuncExpr))
914         {
915                 FuncExprState *fcache = (FuncExprState *) funcexpr;
916                 ExprDoneCond argDone;
917
918                 /*
919                  * This path is similar to ExecMakeFunctionResult.
920                  */
921                 direct_function_call = true;
922
923                 /*
924                  * Initialize function cache if first time through
925                  */
926                 if (fcache->func.fn_oid == InvalidOid)
927                 {
928                         FuncExpr   *func = (FuncExpr *) fcache->xprstate.expr;
929
930                         init_fcache(func->funcid, fcache, econtext->ecxt_per_query_memory);
931                 }
932
933                 /*
934                  * Evaluate the function's argument list.
935                  *
936                  * Note: ideally, we'd do this in the per-tuple context, but then the
937                  * argument values would disappear when we reset the context in
938                  * the inner loop.      So do it in caller context.  Perhaps we should
939                  * make a separate context just to hold the evaluated arguments?
940                  */
941                 MemSet(&fcinfo, 0, sizeof(fcinfo));
942                 fcinfo.flinfo = &(fcache->func);
943                 argDone = ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
944                 /* We don't allow sets in the arguments of the table function */
945                 if (argDone != ExprSingleResult)
946                         ereport(ERROR,
947                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
948                                          errmsg("set-valued function called in context that cannot accept a set")));
949
950                 /*
951                  * If function is strict, and there are any NULL arguments, skip
952                  * calling the function and return NULL (actually an empty set).
953                  */
954                 if (fcache->func.fn_strict)
955                 {
956                         int                     i;
957
958                         for (i = 0; i < fcinfo.nargs; i++)
959                         {
960                                 if (fcinfo.argnull[i])
961                                 {
962                                         *returnDesc = NULL;
963                                         return NULL;
964                                 }
965                         }
966                 }
967         }
968         else
969         {
970                 /* Treat funcexpr as a generic expression */
971                 direct_function_call = false;
972         }
973
974         funcrettype = exprType((Node *) funcexpr->expr);
975
976         /*
977          * Prepare a resultinfo node for communication.  We always do this
978          * even if not expecting a set result, so that we can pass
979          * expectedDesc.  In the generic-expression case, the expression
980          * doesn't actually get to see the resultinfo, but set it up anyway
981          * because we use some of the fields as our own state variables.
982          */
983         fcinfo.resultinfo = (Node *) &rsinfo;
984         rsinfo.type = T_ReturnSetInfo;
985         rsinfo.econtext = econtext;
986         rsinfo.expectedDesc = expectedDesc;
987         rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
988         rsinfo.returnMode = SFRM_ValuePerCall;
989         /* isDone is filled below */
990         rsinfo.setResult = NULL;
991         rsinfo.setDesc = NULL;
992
993         /*
994          * Switch to short-lived context for calling the function or
995          * expression.
996          */
997         callerContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
998
999         /*
1000          * Loop to handle the ValuePerCall protocol (which is also the same
1001          * behavior needed in the generic ExecEvalExpr path).
1002          */
1003         for (;;)
1004         {
1005                 Datum           result;
1006                 HeapTuple       tuple;
1007
1008                 /*
1009                  * reset per-tuple memory context before each call of the function
1010                  * or expression. This cleans up any local memory the function may
1011                  * leak when called.
1012                  */
1013                 ResetExprContext(econtext);
1014
1015                 /* Call the function or expression one time */
1016                 if (direct_function_call)
1017                 {
1018                         fcinfo.isnull = false;
1019                         rsinfo.isDone = ExprSingleResult;
1020                         result = FunctionCallInvoke(&fcinfo);
1021                 }
1022                 else
1023                 {
1024                         result = ExecEvalExpr(funcexpr, econtext,
1025                                                                   &fcinfo.isnull, &rsinfo.isDone);
1026                 }
1027
1028                 /* Which protocol does function want to use? */
1029                 if (rsinfo.returnMode == SFRM_ValuePerCall)
1030                 {
1031                         /*
1032                          * Check for end of result set.
1033                          *
1034                          * Note: if function returns an empty set, we don't build a
1035                          * tupdesc or tuplestore (since we can't get a tupdesc in the
1036                          * function-returning-tuple case)
1037                          */
1038                         if (rsinfo.isDone == ExprEndResult)
1039                                 break;
1040
1041                         /*
1042                          * If first time through, build tupdesc and tuplestore for
1043                          * result
1044                          */
1045                         if (first_time)
1046                         {
1047                                 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1048                                 if (funcrettype == RECORDOID ||
1049                                         get_typtype(funcrettype) == 'c')
1050                                 {
1051                                         /*
1052                                          * Composite type, so function should have returned a
1053                                          * TupleTableSlot; use its descriptor
1054                                          */
1055                                         slot = (TupleTableSlot *) DatumGetPointer(result);
1056                                         if (fcinfo.isnull || !slot)
1057                                                 ereport(ERROR,
1058                                                                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1059                                                                  errmsg("function returning tuple cannot return NULL")));
1060                                         if (!IsA(slot, TupleTableSlot) ||
1061                                                 !slot->ttc_tupleDescriptor)
1062                                                 ereport(ERROR,
1063                                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
1064                                                                  errmsg("function returning tuple did not return a valid tuple slot")));
1065                                         tupdesc = CreateTupleDescCopy(slot->ttc_tupleDescriptor);
1066                                         returnsTuple = true;
1067                                 }
1068                                 else
1069                                 {
1070                                         /*
1071                                          * Scalar type, so make a single-column descriptor
1072                                          */
1073                                         tupdesc = CreateTemplateTupleDesc(1, false);
1074                                         TupleDescInitEntry(tupdesc,
1075                                                                            (AttrNumber) 1,
1076                                                                            "column",
1077                                                                            funcrettype,
1078                                                                            -1,
1079                                                                            0,
1080                                                                            false);
1081                                 }
1082                                 tupstore = tuplestore_begin_heap(true, false, SortMem);
1083                                 MemoryContextSwitchTo(oldcontext);
1084                                 rsinfo.setResult = tupstore;
1085                                 rsinfo.setDesc = tupdesc;
1086                         }
1087
1088                         /*
1089                          * Store current resultset item.
1090                          */
1091                         if (returnsTuple)
1092                         {
1093                                 slot = (TupleTableSlot *) DatumGetPointer(result);
1094                                 if (fcinfo.isnull ||
1095                                         !slot ||
1096                                         !IsA(slot, TupleTableSlot) ||
1097                                         TupIsNull(slot))
1098                                         ereport(ERROR,
1099                                                         (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1100                                                          errmsg("function returning tuple cannot return NULL")));
1101                                 tuple = slot->val;
1102                         }
1103                         else
1104                         {
1105                                 char            nullflag;
1106
1107                                 nullflag = fcinfo.isnull ? 'n' : ' ';
1108                                 tuple = heap_formtuple(tupdesc, &result, &nullflag);
1109                         }
1110
1111                         oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1112                         tuplestore_puttuple(tupstore, tuple);
1113                         MemoryContextSwitchTo(oldcontext);
1114
1115                         /*
1116                          * Are we done?
1117                          */
1118                         if (rsinfo.isDone != ExprMultipleResult)
1119                                 break;
1120                 }
1121                 else if (rsinfo.returnMode == SFRM_Materialize)
1122                 {
1123                         /* check we're on the same page as the function author */
1124                         if (!first_time || rsinfo.isDone != ExprSingleResult)
1125                                 ereport(ERROR,
1126                                                 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1127                                                  errmsg("table-function protocol for materialize mode was not followed")));
1128                         /* Done evaluating the set result */
1129                         break;
1130                 }
1131                 else
1132                         ereport(ERROR,
1133                                         (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1134                                          errmsg("unrecognized table-function returnMode: %d",
1135                                                         (int) rsinfo.returnMode)));
1136
1137                 first_time = false;
1138         }
1139
1140         MemoryContextSwitchTo(callerContext);
1141
1142         /* The returned pointers are those in rsinfo */
1143         *returnDesc = rsinfo.setDesc;
1144         return rsinfo.setResult;
1145 }
1146
1147
1148 /* ----------------------------------------------------------------
1149  *              ExecEvalFunc
1150  *              ExecEvalOper
1151  *
1152  *              Evaluate the functional result of a list of arguments by calling the
1153  *              function manager.
1154  * ----------------------------------------------------------------
1155  */
1156
1157 /* ----------------------------------------------------------------
1158  *              ExecEvalFunc
1159  * ----------------------------------------------------------------
1160  */
1161 static Datum
1162 ExecEvalFunc(FuncExprState *fcache,
1163                          ExprContext *econtext,
1164                          bool *isNull,
1165                          ExprDoneCond *isDone)
1166 {
1167         /*
1168          * Initialize function cache if first time through
1169          */
1170         if (fcache->func.fn_oid == InvalidOid)
1171         {
1172                 FuncExpr   *func = (FuncExpr *) fcache->xprstate.expr;
1173
1174                 init_fcache(func->funcid, fcache, econtext->ecxt_per_query_memory);
1175         }
1176
1177         return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
1178 }
1179
1180 /* ----------------------------------------------------------------
1181  *              ExecEvalOper
1182  * ----------------------------------------------------------------
1183  */
1184 static Datum
1185 ExecEvalOper(FuncExprState *fcache,
1186                          ExprContext *econtext,
1187                          bool *isNull,
1188                          ExprDoneCond *isDone)
1189 {
1190         /*
1191          * Initialize function cache if first time through
1192          */
1193         if (fcache->func.fn_oid == InvalidOid)
1194         {
1195                 OpExpr     *op = (OpExpr *) fcache->xprstate.expr;
1196
1197                 init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory);
1198         }
1199
1200         return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
1201 }
1202
1203 /* ----------------------------------------------------------------
1204  *              ExecEvalDistinct
1205  *
1206  * IS DISTINCT FROM must evaluate arguments to determine whether
1207  * they are NULL; if either is NULL then the result is already
1208  * known. If neither is NULL, then proceed to evaluate the
1209  * function. Note that this is *always* derived from the equals
1210  * operator, but since we need special processing of the arguments
1211  * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
1212  * ----------------------------------------------------------------
1213  */
1214 static Datum
1215 ExecEvalDistinct(FuncExprState *fcache,
1216                                  ExprContext *econtext,
1217                                  bool *isNull)
1218 {
1219         Datum           result;
1220         FunctionCallInfoData fcinfo;
1221         ExprDoneCond argDone;
1222         List       *argList;
1223
1224         /*
1225          * Initialize function cache if first time through
1226          */
1227         if (fcache->func.fn_oid == InvalidOid)
1228         {
1229                 DistinctExpr *op = (DistinctExpr *) fcache->xprstate.expr;
1230
1231                 init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory);
1232                 Assert(!fcache->func.fn_retset);
1233         }
1234
1235         /*
1236          * extract info from fcache
1237          */
1238         argList = fcache->args;
1239
1240         /* Need to prep callinfo structure */
1241         MemSet(&fcinfo, 0, sizeof(fcinfo));
1242         fcinfo.flinfo = &(fcache->func);
1243         argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
1244         if (argDone != ExprSingleResult)
1245                 ereport(ERROR,
1246                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
1247                          errmsg("IS DISTINCT FROM does not support set arguments")));
1248         Assert(fcinfo.nargs == 2);
1249
1250         if (fcinfo.argnull[0] && fcinfo.argnull[1])
1251         {
1252                 /* Both NULL? Then is not distinct... */
1253                 result = BoolGetDatum(FALSE);
1254         }
1255         else if (fcinfo.argnull[0] || fcinfo.argnull[1])
1256         {
1257                 /* Only one is NULL? Then is distinct... */
1258                 result = BoolGetDatum(TRUE);
1259         }
1260         else
1261         {
1262                 fcinfo.isnull = false;
1263                 result = FunctionCallInvoke(&fcinfo);
1264                 *isNull = fcinfo.isnull;
1265                 /* Must invert result of "=" */
1266                 result = BoolGetDatum(!DatumGetBool(result));
1267         }
1268
1269         return result;
1270 }
1271
1272 /*
1273  * ExecEvalScalarArrayOp
1274  *
1275  * Evaluate "scalar op ANY/ALL (array)".  The operator always yields boolean,
1276  * and we combine the results across all array elements using OR and AND
1277  * (for ANY and ALL respectively).      Of course we short-circuit as soon as
1278  * the result is known.
1279  */
1280 static Datum
1281 ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
1282                                           ExprContext *econtext, bool *isNull)
1283 {
1284         ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) sstate->fxprstate.xprstate.expr;
1285         bool            useOr = opexpr->useOr;
1286         ArrayType  *arr;
1287         int                     nitems;
1288         Datum           result;
1289         bool            resultnull;
1290         FunctionCallInfoData fcinfo;
1291         ExprDoneCond argDone;
1292         int                     i;
1293         int16           typlen;
1294         bool            typbyval;
1295         char            typalign;
1296         char       *s;
1297
1298         /*
1299          * Initialize function cache if first time through
1300          */
1301         if (sstate->fxprstate.func.fn_oid == InvalidOid)
1302         {
1303                 init_fcache(opexpr->opfuncid, &sstate->fxprstate,
1304                                         econtext->ecxt_per_query_memory);
1305                 Assert(!sstate->fxprstate.func.fn_retset);
1306         }
1307
1308         /* Need to prep callinfo structure */
1309         MemSet(&fcinfo, 0, sizeof(fcinfo));
1310         fcinfo.flinfo = &(sstate->fxprstate.func);
1311         argDone = ExecEvalFuncArgs(&fcinfo, sstate->fxprstate.args, econtext);
1312         if (argDone != ExprSingleResult)
1313                 ereport(ERROR,
1314                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
1315                    errmsg("op ANY/ALL (array) does not support set arguments")));
1316         Assert(fcinfo.nargs == 2);
1317
1318         /*
1319          * If the array is NULL then we return NULL --- it's not very
1320          * meaningful to do anything else, even if the operator isn't strict.
1321          */
1322         if (fcinfo.argnull[1])
1323         {
1324                 *isNull = true;
1325                 return (Datum) 0;
1326         }
1327         /* Else okay to fetch and detoast the array */
1328         arr = DatumGetArrayTypeP(fcinfo.arg[1]);
1329
1330         /*
1331          * If the array is empty, we return either FALSE or TRUE per the useOr
1332          * flag.  This is correct even if the scalar is NULL; since we would
1333          * evaluate the operator zero times, it matters not whether it would
1334          * want to return NULL.
1335          */
1336         nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
1337         if (nitems <= 0)
1338                 return BoolGetDatum(!useOr);
1339
1340         /*
1341          * If the scalar is NULL, and the function is strict, return NULL.
1342          * This is just to avoid having to test for strictness inside the
1343          * loop.  (XXX but if arrays could have null elements, we'd need a
1344          * test anyway.)
1345          */
1346         if (fcinfo.argnull[0] && sstate->fxprstate.func.fn_strict)
1347         {
1348                 *isNull = true;
1349                 return (Datum) 0;
1350         }
1351
1352         /*
1353          * We arrange to look up info about the element type only once per
1354          * series of calls, assuming the element type doesn't change
1355          * underneath us.
1356          */
1357         if (sstate->element_type != ARR_ELEMTYPE(arr))
1358         {
1359                 get_typlenbyvalalign(ARR_ELEMTYPE(arr),
1360                                                          &sstate->typlen,
1361                                                          &sstate->typbyval,
1362                                                          &sstate->typalign);
1363                 sstate->element_type = ARR_ELEMTYPE(arr);
1364         }
1365         typlen = sstate->typlen;
1366         typbyval = sstate->typbyval;
1367         typalign = sstate->typalign;
1368
1369         result = BoolGetDatum(!useOr);
1370         resultnull = false;
1371
1372         /* Loop over the array elements */
1373         s = (char *) ARR_DATA_PTR(arr);
1374         for (i = 0; i < nitems; i++)
1375         {
1376                 Datum           elt;
1377                 Datum           thisresult;
1378
1379                 /* Get array element */
1380                 elt = fetch_att(s, typbyval, typlen);
1381
1382                 s = att_addlength(s, typlen, PointerGetDatum(s));
1383                 s = (char *) att_align(s, typalign);
1384
1385                 /* Call comparison function */
1386                 fcinfo.arg[1] = elt;
1387                 fcinfo.argnull[1] = false;
1388                 fcinfo.isnull = false;
1389                 thisresult = FunctionCallInvoke(&fcinfo);
1390
1391                 /* Combine results per OR or AND semantics */
1392                 if (fcinfo.isnull)
1393                         resultnull = true;
1394                 else if (useOr)
1395                 {
1396                         if (DatumGetBool(thisresult))
1397                         {
1398                                 result = BoolGetDatum(true);
1399                                 resultnull = false;
1400                                 break;                  /* needn't look at any more elements */
1401                         }
1402                 }
1403                 else
1404                 {
1405                         if (!DatumGetBool(thisresult))
1406                         {
1407                                 result = BoolGetDatum(false);
1408                                 resultnull = false;
1409                                 break;                  /* needn't look at any more elements */
1410                         }
1411                 }
1412         }
1413
1414         *isNull = resultnull;
1415         return result;
1416 }
1417
1418 /* ----------------------------------------------------------------
1419  *              ExecEvalNot
1420  *              ExecEvalOr
1421  *              ExecEvalAnd
1422  *
1423  *              Evaluate boolean expressions, with appropriate short-circuiting.
1424  *
1425  *              The query planner reformulates clause expressions in the
1426  *              qualification to conjunctive normal form.  If we ever get
1427  *              an AND to evaluate, we can be sure that it's not a top-level
1428  *              clause in the qualification, but appears lower (as a function
1429  *              argument, for example), or in the target list.  Not that you
1430  *              need to know this, mind you...
1431  * ----------------------------------------------------------------
1432  */
1433 static Datum
1434 ExecEvalNot(BoolExprState *notclause, ExprContext *econtext, bool *isNull)
1435 {
1436         ExprState  *clause;
1437         Datum           expr_value;
1438
1439         clause = lfirst(notclause->args);
1440
1441         expr_value = ExecEvalExpr(clause, econtext, isNull, NULL);
1442
1443         /*
1444          * if the expression evaluates to null, then we just cascade the null
1445          * back to whoever called us.
1446          */
1447         if (*isNull)
1448                 return expr_value;
1449
1450         /*
1451          * evaluation of 'not' is simple.. expr is false, then return 'true'
1452          * and vice versa.
1453          */
1454         return BoolGetDatum(!DatumGetBool(expr_value));
1455 }
1456
1457 /* ----------------------------------------------------------------
1458  *              ExecEvalOr
1459  * ----------------------------------------------------------------
1460  */
1461 static Datum
1462 ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext, bool *isNull)
1463 {
1464         List       *clauses;
1465         List       *clause;
1466         bool            AnyNull;
1467         Datum           clause_value;
1468
1469         clauses = orExpr->args;
1470         AnyNull = false;
1471
1472         /*
1473          * If any of the clauses is TRUE, the OR result is TRUE regardless of
1474          * the states of the rest of the clauses, so we can stop evaluating
1475          * and return TRUE immediately.  If none are TRUE and one or more is
1476          * NULL, we return NULL; otherwise we return FALSE.  This makes sense
1477          * when you interpret NULL as "don't know": if we have a TRUE then the
1478          * OR is TRUE even if we aren't sure about some of the other inputs.
1479          * If all the known inputs are FALSE, but we have one or more "don't
1480          * knows", then we have to report that we "don't know" what the OR's
1481          * result should be --- perhaps one of the "don't knows" would have
1482          * been TRUE if we'd known its value.  Only when all the inputs are
1483          * known to be FALSE can we state confidently that the OR's result is
1484          * FALSE.
1485          */
1486         foreach(clause, clauses)
1487         {
1488                 clause_value = ExecEvalExpr((ExprState *) lfirst(clause),
1489                                                                         econtext, isNull, NULL);
1490
1491                 /*
1492                  * if we have a non-null true result, then return it.
1493                  */
1494                 if (*isNull)
1495                         AnyNull = true;         /* remember we got a null */
1496                 else if (DatumGetBool(clause_value))
1497                         return clause_value;
1498         }
1499
1500         /* AnyNull is true if at least one clause evaluated to NULL */
1501         *isNull = AnyNull;
1502         return BoolGetDatum(false);
1503 }
1504
1505 /* ----------------------------------------------------------------
1506  *              ExecEvalAnd
1507  * ----------------------------------------------------------------
1508  */
1509 static Datum
1510 ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext, bool *isNull)
1511 {
1512         List       *clauses;
1513         List       *clause;
1514         bool            AnyNull;
1515         Datum           clause_value;
1516
1517         clauses = andExpr->args;
1518         AnyNull = false;
1519
1520         /*
1521          * If any of the clauses is FALSE, the AND result is FALSE regardless
1522          * of the states of the rest of the clauses, so we can stop evaluating
1523          * and return FALSE immediately.  If none are FALSE and one or more is
1524          * NULL, we return NULL; otherwise we return TRUE.      This makes sense
1525          * when you interpret NULL as "don't know", using the same sort of
1526          * reasoning as for OR, above.
1527          */
1528         foreach(clause, clauses)
1529         {
1530                 clause_value = ExecEvalExpr((ExprState *) lfirst(clause),
1531                                                                         econtext, isNull, NULL);
1532
1533                 /*
1534                  * if we have a non-null false result, then return it.
1535                  */
1536                 if (*isNull)
1537                         AnyNull = true;         /* remember we got a null */
1538                 else if (!DatumGetBool(clause_value))
1539                         return clause_value;
1540         }
1541
1542         /* AnyNull is true if at least one clause evaluated to NULL */
1543         *isNull = AnyNull;
1544         return BoolGetDatum(!AnyNull);
1545 }
1546
1547
1548 /* ----------------------------------------------------------------
1549  *              ExecEvalCase
1550  *
1551  *              Evaluate a CASE clause. Will have boolean expressions
1552  *              inside the WHEN clauses, and will have expressions
1553  *              for results.
1554  *              - thomas 1998-11-09
1555  * ----------------------------------------------------------------
1556  */
1557 static Datum
1558 ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
1559                          bool *isNull, ExprDoneCond *isDone)
1560 {
1561         List       *clauses;
1562         List       *clause;
1563         Datum           clause_value;
1564
1565         clauses = caseExpr->args;
1566
1567         /*
1568          * we evaluate each of the WHEN clauses in turn, as soon as one is
1569          * true we return the corresponding result. If none are true then we
1570          * return the value of the default clause, or NULL if there is none.
1571          */
1572         foreach(clause, clauses)
1573         {
1574                 CaseWhenState *wclause = lfirst(clause);
1575
1576                 clause_value = ExecEvalExpr(wclause->expr,
1577                                                                         econtext,
1578                                                                         isNull,
1579                                                                         NULL);
1580
1581                 /*
1582                  * if we have a true test, then we return the result, since the
1583                  * case statement is satisfied.  A NULL result from the test is
1584                  * not considered true.
1585                  */
1586                 if (DatumGetBool(clause_value) && !*isNull)
1587                 {
1588                         return ExecEvalExpr(wclause->result,
1589                                                                 econtext,
1590                                                                 isNull,
1591                                                                 isDone);
1592                 }
1593         }
1594
1595         if (caseExpr->defresult)
1596         {
1597                 return ExecEvalExpr(caseExpr->defresult,
1598                                                         econtext,
1599                                                         isNull,
1600                                                         isDone);
1601         }
1602
1603         *isNull = true;
1604         return (Datum) 0;
1605 }
1606
1607 /* ----------------------------------------------------------------
1608  *              ExecEvalArray - ARRAY[] expressions
1609  *
1610  * NOTE: currently, if any input value is NULL then we return a NULL array,
1611  * so the ARRAY[] construct can be considered strict.  Eventually this will
1612  * change; when it does, be sure to fix contain_nonstrict_functions().
1613  * ----------------------------------------------------------------
1614  */
1615 static Datum
1616 ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
1617                           bool *isNull)
1618 {
1619         ArrayExpr  *arrayExpr = (ArrayExpr *) astate->xprstate.expr;
1620         ArrayType  *result;
1621         List       *element;
1622         Oid                     element_type = arrayExpr->element_typeid;
1623         int                     ndims = 0;
1624         int                     dims[MAXDIM];
1625         int                     lbs[MAXDIM];
1626
1627         if (!arrayExpr->multidims)
1628         {
1629                 /* Elements are presumably of scalar type */
1630                 int                     nelems;
1631                 Datum      *dvalues;
1632                 int                     i = 0;
1633
1634                 ndims = 1;
1635                 nelems = length(astate->elements);
1636
1637                 /* Shouldn't happen here, but if length is 0, return NULL */
1638                 if (nelems == 0)
1639                 {
1640                         *isNull = true;
1641                         return (Datum) 0;
1642                 }
1643
1644                 dvalues = (Datum *) palloc(nelems * sizeof(Datum));
1645
1646                 /* loop through and build array of datums */
1647                 foreach(element, astate->elements)
1648                 {
1649                         ExprState  *e = (ExprState *) lfirst(element);
1650                         bool            eisnull;
1651
1652                         dvalues[i++] = ExecEvalExpr(e, econtext, &eisnull, NULL);
1653                         if (eisnull)
1654                         {
1655                                 *isNull = true;
1656                                 return (Datum) 0;
1657                         }
1658                 }
1659
1660                 /* setup for 1-D array of the given length */
1661                 dims[0] = nelems;
1662                 lbs[0] = 1;
1663
1664                 result = construct_md_array(dvalues, ndims, dims, lbs,
1665                                                                         element_type,
1666                                                                         astate->elemlength,
1667                                                                         astate->elembyval,
1668                                                                         astate->elemalign);
1669         }
1670         else
1671         {
1672                 /* Must be nested array expressions */
1673                 char       *dat = NULL;
1674                 Size            ndatabytes = 0;
1675                 int                     nbytes;
1676                 int                     outer_nelems = length(astate->elements);
1677                 int                     elem_ndims = 0;
1678                 int                *elem_dims = NULL;
1679                 int                *elem_lbs = NULL;
1680                 bool            firstone = true;
1681                 int                     i;
1682
1683                 /* loop through and get data area from each element */
1684                 foreach(element, astate->elements)
1685                 {
1686                         ExprState  *e = (ExprState *) lfirst(element);
1687                         bool            eisnull;
1688                         Datum           arraydatum;
1689                         ArrayType  *array;
1690                         int                     elem_ndatabytes;
1691
1692                         arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
1693                         if (eisnull)
1694                         {
1695                                 *isNull = true;
1696                                 return (Datum) 0;
1697                         }
1698
1699                         array = DatumGetArrayTypeP(arraydatum);
1700
1701                         /* run-time double-check on element type */
1702                         if (element_type != ARR_ELEMTYPE(array))
1703                                 ereport(ERROR,
1704                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
1705                                                  errmsg("cannot merge incompatible arrays"),
1706                                                  errdetail("Array with element type %s cannot be "
1707                                                                    "included in ARRAY construct with element type %s.",
1708                                                                    format_type_be(ARR_ELEMTYPE(array)),
1709                                                                    format_type_be(element_type))));
1710
1711                         if (firstone)
1712                         {
1713                                 /* Get sub-array details from first member */
1714                                 elem_ndims = ARR_NDIM(array);
1715                                 ndims = elem_ndims + 1;
1716                                 if (ndims <= 0 || ndims > MAXDIM)
1717                                         ereport(ERROR,
1718                                                         (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1719                                                          errmsg("number of array dimensions exceeds " \
1720                                                                         "the maximum allowed, %d", MAXDIM)));
1721
1722                                 elem_dims = (int *) palloc(elem_ndims * sizeof(int));
1723                                 memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
1724                                 elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
1725                                 memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
1726
1727                                 firstone = false;
1728                         }
1729                         else
1730                         {
1731                                 /* Check other sub-arrays are compatible */
1732                                 if (elem_ndims != ARR_NDIM(array) ||
1733                                         memcmp(elem_dims, ARR_DIMS(array),
1734                                                    elem_ndims * sizeof(int)) != 0 ||
1735                                         memcmp(elem_lbs, ARR_LBOUND(array),
1736                                                    elem_ndims * sizeof(int)) != 0)
1737                                         ereport(ERROR,
1738                                                         (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1739                                                 errmsg("multidimensional arrays must have array "
1740                                                            "expressions with matching dimensions")));
1741                         }
1742
1743                         elem_ndatabytes = ARR_SIZE(array) - ARR_OVERHEAD(elem_ndims);
1744                         ndatabytes += elem_ndatabytes;
1745                         if (dat == NULL)
1746                                 dat = (char *) palloc(ndatabytes);
1747                         else
1748                                 dat = (char *) repalloc(dat, ndatabytes);
1749
1750                         memcpy(dat + (ndatabytes - elem_ndatabytes),
1751                                    ARR_DATA_PTR(array),
1752                                    elem_ndatabytes);
1753                 }
1754
1755                 /* setup for multi-D array */
1756                 dims[0] = outer_nelems;
1757                 lbs[0] = 1;
1758                 for (i = 1; i < ndims; i++)
1759                 {
1760                         dims[i] = elem_dims[i - 1];
1761                         lbs[i] = elem_lbs[i - 1];
1762                 }
1763
1764                 nbytes = ndatabytes + ARR_OVERHEAD(ndims);
1765                 result = (ArrayType *) palloc(nbytes);
1766
1767                 result->size = nbytes;
1768                 result->ndim = ndims;
1769                 result->flags = 0;
1770                 result->elemtype = element_type;
1771                 memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
1772                 memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
1773                 if (ndatabytes > 0)
1774                         memcpy(ARR_DATA_PTR(result), dat, ndatabytes);
1775
1776                 if (dat != NULL)
1777                         pfree(dat);
1778         }
1779
1780         return PointerGetDatum(result);
1781 }
1782
1783 /* ----------------------------------------------------------------
1784  *              ExecEvalCoalesce
1785  * ----------------------------------------------------------------
1786  */
1787 static Datum
1788 ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
1789                                  bool *isNull)
1790 {
1791         List       *arg;
1792
1793         /* Simply loop through until something NOT NULL is found */
1794         foreach(arg, coalesceExpr->args)
1795         {
1796                 ExprState  *e = (ExprState *) lfirst(arg);
1797                 Datum           value;
1798
1799                 value = ExecEvalExpr(e, econtext, isNull, NULL);
1800                 if (!*isNull)
1801                         return value;
1802         }
1803
1804         /* Else return NULL */
1805         *isNull = true;
1806         return (Datum) 0;
1807 }
1808
1809 /* ----------------------------------------------------------------
1810  *              ExecEvalNullIf
1811  *
1812  * Note that this is *always* derived from the equals operator,
1813  * but since we need special processing of the arguments
1814  * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
1815  * ----------------------------------------------------------------
1816  */
1817 static Datum
1818 ExecEvalNullIf(FuncExprState *fcache, ExprContext *econtext,
1819                            bool *isNull)
1820 {
1821         Datum           result;
1822         FunctionCallInfoData fcinfo;
1823         ExprDoneCond argDone;
1824         List       *argList;
1825
1826         /*
1827          * Initialize function cache if first time through
1828          */
1829         if (fcache->func.fn_oid == InvalidOid)
1830         {
1831                 NullIfExpr *op = (NullIfExpr *) fcache->xprstate.expr;
1832
1833                 init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory);
1834                 Assert(!fcache->func.fn_retset);
1835         }
1836
1837         /*
1838          * extract info from fcache
1839          */
1840         argList = fcache->args;
1841
1842         /* Need to prep callinfo structure */
1843         MemSet(&fcinfo, 0, sizeof(fcinfo));
1844         fcinfo.flinfo = &(fcache->func);
1845         argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
1846         if (argDone != ExprSingleResult)
1847                 ereport(ERROR,
1848                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
1849                                  errmsg("NULLIF does not support set arguments")));
1850         Assert(fcinfo.nargs == 2);
1851
1852         /* if either argument is NULL they can't be equal */
1853         if (!fcinfo.argnull[0] && !fcinfo.argnull[1])
1854         {
1855                 fcinfo.isnull = false;
1856                 result = FunctionCallInvoke(&fcinfo);
1857                 /* if the arguments are equal return null */
1858                 if (!fcinfo.isnull && DatumGetBool(result))
1859                 {
1860                         *isNull = true;
1861                         return (Datum) 0;
1862                 }
1863         }
1864
1865         /* else return first argument */
1866         *isNull = fcinfo.argnull[0];
1867         return fcinfo.arg[0];
1868 }
1869
1870 /* ----------------------------------------------------------------
1871  *              ExecEvalNullTest
1872  *
1873  *              Evaluate a NullTest node.
1874  * ----------------------------------------------------------------
1875  */
1876 static Datum
1877 ExecEvalNullTest(GenericExprState *nstate,
1878                                  ExprContext *econtext,
1879                                  bool *isNull,
1880                                  ExprDoneCond *isDone)
1881 {
1882         NullTest   *ntest = (NullTest *) nstate->xprstate.expr;
1883         Datum           result;
1884
1885         result = ExecEvalExpr(nstate->arg, econtext, isNull, isDone);
1886
1887         if (isDone && *isDone == ExprEndResult)
1888                 return result;                  /* nothing to check */
1889
1890         switch (ntest->nulltesttype)
1891         {
1892                 case IS_NULL:
1893                         if (*isNull)
1894                         {
1895                                 *isNull = false;
1896                                 return BoolGetDatum(true);
1897                         }
1898                         else
1899                                 return BoolGetDatum(false);
1900                 case IS_NOT_NULL:
1901                         if (*isNull)
1902                         {
1903                                 *isNull = false;
1904                                 return BoolGetDatum(false);
1905                         }
1906                         else
1907                                 return BoolGetDatum(true);
1908                 default:
1909                         elog(ERROR, "unrecognized nulltesttype: %d",
1910                                  (int) ntest->nulltesttype);
1911                         return (Datum) 0;       /* keep compiler quiet */
1912         }
1913 }
1914
1915 /* ----------------------------------------------------------------
1916  *              ExecEvalBooleanTest
1917  *
1918  *              Evaluate a BooleanTest node.
1919  * ----------------------------------------------------------------
1920  */
1921 static Datum
1922 ExecEvalBooleanTest(GenericExprState *bstate,
1923                                         ExprContext *econtext,
1924                                         bool *isNull,
1925                                         ExprDoneCond *isDone)
1926 {
1927         BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;
1928         Datum           result;
1929
1930         result = ExecEvalExpr(bstate->arg, econtext, isNull, isDone);
1931
1932         if (isDone && *isDone == ExprEndResult)
1933                 return result;                  /* nothing to check */
1934
1935         switch (btest->booltesttype)
1936         {
1937                 case IS_TRUE:
1938                         if (*isNull)
1939                         {
1940                                 *isNull = false;
1941                                 return BoolGetDatum(false);
1942                         }
1943                         else if (DatumGetBool(result))
1944                                 return BoolGetDatum(true);
1945                         else
1946                                 return BoolGetDatum(false);
1947                 case IS_NOT_TRUE:
1948                         if (*isNull)
1949                         {
1950                                 *isNull = false;
1951                                 return BoolGetDatum(true);
1952                         }
1953                         else if (DatumGetBool(result))
1954                                 return BoolGetDatum(false);
1955                         else
1956                                 return BoolGetDatum(true);
1957                 case IS_FALSE:
1958                         if (*isNull)
1959                         {
1960                                 *isNull = false;
1961                                 return BoolGetDatum(false);
1962                         }
1963                         else if (DatumGetBool(result))
1964                                 return BoolGetDatum(false);
1965                         else
1966                                 return BoolGetDatum(true);
1967                 case IS_NOT_FALSE:
1968                         if (*isNull)
1969                         {
1970                                 *isNull = false;
1971                                 return BoolGetDatum(true);
1972                         }
1973                         else if (DatumGetBool(result))
1974                                 return BoolGetDatum(true);
1975                         else
1976                                 return BoolGetDatum(false);
1977                 case IS_UNKNOWN:
1978                         if (*isNull)
1979                         {
1980                                 *isNull = false;
1981                                 return BoolGetDatum(true);
1982                         }
1983                         else
1984                                 return BoolGetDatum(false);
1985                 case IS_NOT_UNKNOWN:
1986                         if (*isNull)
1987                         {
1988                                 *isNull = false;
1989                                 return BoolGetDatum(false);
1990                         }
1991                         else
1992                                 return BoolGetDatum(true);
1993                 default:
1994                         elog(ERROR, "unrecognized booltesttype: %d",
1995                                  (int) btest->booltesttype);
1996                         return (Datum) 0;       /* keep compiler quiet */
1997         }
1998 }
1999
2000 /*
2001  * ExecEvalCoerceToDomain
2002  *
2003  * Test the provided data against the domain constraint(s).  If the data
2004  * passes the constraint specifications, pass it through (return the
2005  * datum) otherwise throw an error.
2006  */
2007 static Datum
2008 ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
2009                                            bool *isNull, ExprDoneCond *isDone)
2010 {
2011         CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
2012         Datum           result;
2013         List       *l;
2014
2015         result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
2016
2017         if (isDone && *isDone == ExprEndResult)
2018                 return result;                  /* nothing to check */
2019
2020         foreach(l, cstate->constraints)
2021         {
2022                 DomainConstraintState *con = (DomainConstraintState *) lfirst(l);
2023
2024                 switch (con->constrainttype)
2025                 {
2026                         case DOM_CONSTRAINT_NOTNULL:
2027                                 if (*isNull)
2028                                         ereport(ERROR,
2029                                                         (errcode(ERRCODE_NOT_NULL_VIOLATION),
2030                                                    errmsg("domain %s does not allow NULL values",
2031                                                                   format_type_be(ctest->resulttype))));
2032                                 break;
2033                         case DOM_CONSTRAINT_CHECK:
2034                                 {
2035                                         Datum           conResult;
2036                                         bool            conIsNull;
2037                                         Datum           save_datum;
2038                                         bool            save_isNull;
2039
2040                                         /*
2041                                          * Set up value to be returned by CoerceToDomainValue
2042                                          * nodes. We must save and restore prior setting of
2043                                          * econtext's domainValue fields, in case this node is
2044                                          * itself within a check expression for another
2045                                          * domain.
2046                                          */
2047                                         save_datum = econtext->domainValue_datum;
2048                                         save_isNull = econtext->domainValue_isNull;
2049
2050                                         econtext->domainValue_datum = result;
2051                                         econtext->domainValue_isNull = *isNull;
2052
2053                                         conResult = ExecEvalExpr(con->check_expr,
2054                                                                                          econtext, &conIsNull, NULL);
2055
2056                                         if (!conIsNull &&
2057                                                 !DatumGetBool(conResult))
2058                                                 ereport(ERROR,
2059                                                                 (errcode(ERRCODE_CHECK_VIOLATION),
2060                                                                  errmsg("value for domain %s violates CHECK constraint \"%s\"",
2061                                                                                 format_type_be(ctest->resulttype),
2062                                                                                 con->name)));
2063                                         econtext->domainValue_datum = save_datum;
2064                                         econtext->domainValue_isNull = save_isNull;
2065
2066                                         break;
2067                                 }
2068                         default:
2069                                 elog(ERROR, "unrecognized constraint type: %d",
2070                                          (int) con->constrainttype);
2071                                 break;
2072                 }
2073         }
2074
2075         /* If all has gone well (constraints did not fail) return the datum */
2076         return result;
2077 }
2078
2079 /*
2080  * ExecEvalCoerceToDomainValue
2081  *
2082  * Return the value stored by CoerceToDomain.
2083  */
2084 static Datum
2085 ExecEvalCoerceToDomainValue(CoerceToDomainValue *conVal,
2086                                                         ExprContext *econtext, bool *isNull)
2087 {
2088         *isNull = econtext->domainValue_isNull;
2089         return econtext->domainValue_datum;
2090 }
2091
2092 /* ----------------------------------------------------------------
2093  *              ExecEvalFieldSelect
2094  *
2095  *              Evaluate a FieldSelect node.
2096  * ----------------------------------------------------------------
2097  */
2098 static Datum
2099 ExecEvalFieldSelect(GenericExprState *fstate,
2100                                         ExprContext *econtext,
2101                                         bool *isNull,
2102                                         ExprDoneCond *isDone)
2103 {
2104         FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
2105         Datum           result;
2106         TupleTableSlot *resSlot;
2107
2108         result = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
2109
2110         /* this test covers the isDone exception too: */
2111         if (*isNull)
2112                 return result;
2113
2114         resSlot = (TupleTableSlot *) DatumGetPointer(result);
2115         Assert(resSlot != NULL && IsA(resSlot, TupleTableSlot));
2116         result = heap_getattr(resSlot->val,
2117                                                   fselect->fieldnum,
2118                                                   resSlot->ttc_tupleDescriptor,
2119                                                   isNull);
2120         return result;
2121 }
2122
2123 /* ----------------------------------------------------------------
2124  *              ExecEvalExpr
2125  *
2126  *              Recursively evaluate a targetlist or qualification expression.
2127  *
2128  * Inputs:
2129  *              expression: the expression state tree to evaluate
2130  *              econtext: evaluation context information
2131  *
2132  * Outputs:
2133  *              return value: Datum value of result
2134  *              *isNull: set to TRUE if result is NULL (actual return value is
2135  *                               meaningless if so); set to FALSE if non-null result
2136  *              *isDone: set to indicator of set-result status
2137  *
2138  * A caller that can only accept a singleton (non-set) result should pass
2139  * NULL for isDone; if the expression computes a set result then an error
2140  * will be reported via ereport.  If the caller does pass an isDone pointer
2141  * then *isDone is set to one of these three states:
2142  *              ExprSingleResult                singleton result (not a set)
2143  *              ExprMultipleResult              return value is one element of a set
2144  *              ExprEndResult                   there are no more elements in the set
2145  * When ExprMultipleResult is returned, the caller should invoke
2146  * ExecEvalExpr() repeatedly until ExprEndResult is returned.  ExprEndResult
2147  * is returned after the last real set element.  For convenience isNull will
2148  * always be set TRUE when ExprEndResult is returned, but this should not be
2149  * taken as indicating a NULL element of the set.  Note that these return
2150  * conventions allow us to distinguish among a singleton NULL, a NULL element
2151  * of a set, and an empty set.
2152  *
2153  * The caller should already have switched into the temporary memory
2154  * context econtext->ecxt_per_tuple_memory.  The convenience entry point
2155  * ExecEvalExprSwitchContext() is provided for callers who don't prefer to
2156  * do the switch in an outer loop.      We do not do the switch here because
2157  * it'd be a waste of cycles during recursive entries to ExecEvalExpr().
2158  *
2159  * This routine is an inner loop routine and must be as fast as possible.
2160  * ----------------------------------------------------------------
2161  */
2162 Datum
2163 ExecEvalExpr(ExprState *expression,
2164                          ExprContext *econtext,
2165                          bool *isNull,
2166                          ExprDoneCond *isDone)
2167 {
2168         Datum           retDatum;
2169         Expr       *expr;
2170
2171         /* Set default values for result flags: non-null, not a set result */
2172         *isNull = false;
2173         if (isDone)
2174                 *isDone = ExprSingleResult;
2175
2176         /* Is this still necessary?  Doubtful... */
2177         if (expression == NULL)
2178         {
2179                 *isNull = true;
2180                 return (Datum) 0;
2181         }
2182
2183         /*
2184          * here we dispatch the work to the appropriate type of function given
2185          * the type of our expression.
2186          */
2187         expr = expression->expr;
2188         switch (nodeTag(expr))
2189         {
2190                 case T_Var:
2191                         retDatum = ExecEvalVar((Var *) expr, econtext, isNull);
2192                         break;
2193                 case T_Const:
2194                         {
2195                                 Const      *con = (Const *) expr;
2196
2197                                 retDatum = con->constvalue;
2198                                 *isNull = con->constisnull;
2199                                 break;
2200                         }
2201                 case T_Param:
2202                         retDatum = ExecEvalParam((Param *) expr, econtext, isNull);
2203                         break;
2204                 case T_Aggref:
2205                         retDatum = ExecEvalAggref((AggrefExprState *) expression,
2206                                                                           econtext,
2207                                                                           isNull);
2208                         break;
2209                 case T_ArrayRef:
2210                         retDatum = ExecEvalArrayRef((ArrayRefExprState *) expression,
2211                                                                                 econtext,
2212                                                                                 isNull,
2213                                                                                 isDone);
2214                         break;
2215                 case T_FuncExpr:
2216                         retDatum = ExecEvalFunc((FuncExprState *) expression, econtext,
2217                                                                         isNull, isDone);
2218                         break;
2219                 case T_OpExpr:
2220                         retDatum = ExecEvalOper((FuncExprState *) expression, econtext,
2221                                                                         isNull, isDone);
2222                         break;
2223                 case T_DistinctExpr:
2224                         retDatum = ExecEvalDistinct((FuncExprState *) expression, econtext,
2225                                                                                 isNull);
2226                         break;
2227                 case T_ScalarArrayOpExpr:
2228                         retDatum = ExecEvalScalarArrayOp((ScalarArrayOpExprState *) expression,
2229                                                                                          econtext, isNull);
2230                         break;
2231                 case T_BoolExpr:
2232                         {
2233                                 BoolExprState *state = (BoolExprState *) expression;
2234
2235                                 switch (((BoolExpr *) expr)->boolop)
2236                                 {
2237                                         case AND_EXPR:
2238                                                 retDatum = ExecEvalAnd(state, econtext, isNull);
2239                                                 break;
2240                                         case OR_EXPR:
2241                                                 retDatum = ExecEvalOr(state, econtext, isNull);
2242                                                 break;
2243                                         case NOT_EXPR:
2244                                                 retDatum = ExecEvalNot(state, econtext, isNull);
2245                                                 break;
2246                                         default:
2247                                                 elog(ERROR, "unrecognized boolop: %d",
2248                                                          (int) ((BoolExpr *) expr)->boolop);
2249                                                 retDatum = 0;   /* keep compiler quiet */
2250                                                 break;
2251                                 }
2252                                 break;
2253                         }
2254                 case T_SubPlan:
2255                         retDatum = ExecSubPlan((SubPlanState *) expression,
2256                                                                    econtext,
2257                                                                    isNull);
2258                         break;
2259                 case T_FieldSelect:
2260                         retDatum = ExecEvalFieldSelect((GenericExprState *) expression,
2261                                                                                    econtext,
2262                                                                                    isNull,
2263                                                                                    isDone);
2264                         break;
2265                 case T_RelabelType:
2266                         retDatum = ExecEvalExpr(((GenericExprState *) expression)->arg,
2267                                                                         econtext,
2268                                                                         isNull,
2269                                                                         isDone);
2270                         break;
2271                 case T_CaseExpr:
2272                         retDatum = ExecEvalCase((CaseExprState *) expression,
2273                                                                         econtext,
2274                                                                         isNull,
2275                                                                         isDone);
2276                         break;
2277                 case T_ArrayExpr:
2278                         retDatum = ExecEvalArray((ArrayExprState *) expression,
2279                                                                          econtext,
2280                                                                          isNull);
2281                         break;
2282                 case T_CoalesceExpr:
2283                         retDatum = ExecEvalCoalesce((CoalesceExprState *) expression,
2284                                                                                 econtext,
2285                                                                                 isNull);
2286                         break;
2287                 case T_NullIfExpr:
2288                         retDatum = ExecEvalNullIf((FuncExprState *) expression,
2289                                                                           econtext,
2290                                                                           isNull);
2291                         break;
2292                 case T_NullTest:
2293                         retDatum = ExecEvalNullTest((GenericExprState *) expression,
2294                                                                                 econtext,
2295                                                                                 isNull,
2296                                                                                 isDone);
2297                         break;
2298                 case T_BooleanTest:
2299                         retDatum = ExecEvalBooleanTest((GenericExprState *) expression,
2300                                                                                    econtext,
2301                                                                                    isNull,
2302                                                                                    isDone);
2303                         break;
2304                 case T_CoerceToDomain:
2305                         retDatum = ExecEvalCoerceToDomain((CoerceToDomainState *) expression,
2306                                                                                           econtext,
2307                                                                                           isNull,
2308                                                                                           isDone);
2309                         break;
2310                 case T_CoerceToDomainValue:
2311                         retDatum = ExecEvalCoerceToDomainValue((CoerceToDomainValue *) expr,
2312                                                                                                    econtext,
2313                                                                                                    isNull);
2314                         break;
2315                 default:
2316                         elog(ERROR, "unrecognized node type: %d",
2317                                  (int) nodeTag(expression));
2318                         retDatum = 0;           /* keep compiler quiet */
2319                         break;
2320         }
2321
2322         return retDatum;
2323 }       /* ExecEvalExpr() */
2324
2325
2326 /*
2327  * Same as above, but get into the right allocation context explicitly.
2328  */
2329 Datum
2330 ExecEvalExprSwitchContext(ExprState *expression,
2331                                                   ExprContext *econtext,
2332                                                   bool *isNull,
2333                                                   ExprDoneCond *isDone)
2334 {
2335         Datum           retDatum;
2336         MemoryContext oldContext;
2337
2338         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
2339         retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
2340         MemoryContextSwitchTo(oldContext);
2341         return retDatum;
2342 }
2343
2344
2345 /*
2346  * ExecInitExpr: prepare an expression tree for execution
2347  *
2348  * This function builds and returns an ExprState tree paralleling the given
2349  * Expr node tree.      The ExprState tree can then be handed to ExecEvalExpr
2350  * for execution.  Because the Expr tree itself is read-only as far as
2351  * ExecInitExpr and ExecEvalExpr are concerned, several different executions
2352  * of the same plan tree can occur concurrently.
2353  *
2354  * This must be called in a memory context that will last as long as repeated
2355  * executions of the expression are needed.  Typically the context will be
2356  * the same as the per-query context of the associated ExprContext.
2357  *
2358  * Any Aggref and SubPlan nodes found in the tree are added to the lists
2359  * of such nodes held by the parent PlanState.  Otherwise, we do very little
2360  * initialization here other than building the state-node tree.  Any nontrivial
2361  * work associated with initializing runtime info for a node should happen
2362  * during the first actual evaluation of that node.  (This policy lets us
2363  * avoid work if the node is never actually evaluated.)
2364  *
2365  * Note: there is no ExecEndExpr function; we assume that any resource
2366  * cleanup needed will be handled by just releasing the memory context
2367  * in which the state tree is built.  Functions that require additional
2368  * cleanup work can register a shutdown callback in the ExprContext.
2369  *
2370  *      'node' is the root of the expression tree to examine
2371  *      'parent' is the PlanState node that owns the expression.
2372  *
2373  * 'parent' may be NULL if we are preparing an expression that is not
2374  * associated with a plan tree.  (If so, it can't have aggs or subplans.)
2375  * This case should usually come through ExecPrepareExpr, not directly here.
2376  */
2377 ExprState *
2378 ExecInitExpr(Expr *node, PlanState *parent)
2379 {
2380         ExprState  *state;
2381
2382         if (node == NULL)
2383                 return NULL;
2384         switch (nodeTag(node))
2385         {
2386                 case T_Var:
2387                 case T_Const:
2388                 case T_Param:
2389                 case T_CoerceToDomainValue:
2390                         /* No special setup needed for these node types */
2391                         state = (ExprState *) makeNode(ExprState);
2392                         break;
2393                 case T_Aggref:
2394                         {
2395                                 Aggref     *aggref = (Aggref *) node;
2396                                 AggrefExprState *astate = makeNode(AggrefExprState);
2397
2398                                 if (parent && IsA(parent, AggState))
2399                                 {
2400                                         AggState   *aggstate = (AggState *) parent;
2401                                         int                     naggs;
2402
2403                                         aggstate->aggs = lcons(astate, aggstate->aggs);
2404                                         naggs = ++aggstate->numaggs;
2405
2406                                         astate->target = ExecInitExpr(aggref->target, parent);
2407
2408                                         /*
2409                                          * Complain if the aggregate's argument contains any
2410                                          * aggregates; nested agg functions are semantically
2411                                          * nonsensical.  (This should have been caught
2412                                          * earlier, but we defend against it here anyway.)
2413                                          */
2414                                         if (naggs != aggstate->numaggs)
2415                                                 ereport(ERROR,
2416                                                                 (errcode(ERRCODE_GROUPING_ERROR),
2417                                                                  errmsg("aggregate function calls may not be nested")));
2418                                 }
2419                                 else
2420                                 {
2421                                         /* planner messed up */
2422                                         elog(ERROR, "aggref found in non-Agg plan node");
2423                                 }
2424                                 state = (ExprState *) astate;
2425                         }
2426                         break;
2427                 case T_ArrayRef:
2428                         {
2429                                 ArrayRef   *aref = (ArrayRef *) node;
2430                                 ArrayRefExprState *astate = makeNode(ArrayRefExprState);
2431
2432                                 astate->refupperindexpr = (List *)
2433                                         ExecInitExpr((Expr *) aref->refupperindexpr, parent);
2434                                 astate->reflowerindexpr = (List *)
2435                                         ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
2436                                 astate->refexpr = ExecInitExpr(aref->refexpr, parent);
2437                                 astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
2438                                                                                                         parent);
2439                                 /* do one-time catalog lookups for type info */
2440                                 astate->refattrlength = get_typlen(aref->refarraytype);
2441                                 get_typlenbyvalalign(aref->refelemtype,
2442                                                                          &astate->refelemlength,
2443                                                                          &astate->refelembyval,
2444                                                                          &astate->refelemalign);
2445                                 state = (ExprState *) astate;
2446                         }
2447                         break;
2448                 case T_FuncExpr:
2449                         {
2450                                 FuncExpr   *funcexpr = (FuncExpr *) node;
2451                                 FuncExprState *fstate = makeNode(FuncExprState);
2452
2453                                 fstate->args = (List *)
2454                                         ExecInitExpr((Expr *) funcexpr->args, parent);
2455                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
2456                                 state = (ExprState *) fstate;
2457                         }
2458                         break;
2459                 case T_OpExpr:
2460                         {
2461                                 OpExpr     *opexpr = (OpExpr *) node;
2462                                 FuncExprState *fstate = makeNode(FuncExprState);
2463
2464                                 fstate->args = (List *)
2465                                         ExecInitExpr((Expr *) opexpr->args, parent);
2466                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
2467                                 state = (ExprState *) fstate;
2468                         }
2469                         break;
2470                 case T_DistinctExpr:
2471                         {
2472                                 DistinctExpr *distinctexpr = (DistinctExpr *) node;
2473                                 FuncExprState *fstate = makeNode(FuncExprState);
2474
2475                                 fstate->args = (List *)
2476                                         ExecInitExpr((Expr *) distinctexpr->args, parent);
2477                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
2478                                 state = (ExprState *) fstate;
2479                         }
2480                         break;
2481                 case T_ScalarArrayOpExpr:
2482                         {
2483                                 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
2484                                 ScalarArrayOpExprState *sstate = makeNode(ScalarArrayOpExprState);
2485
2486                                 sstate->fxprstate.args = (List *)
2487                                         ExecInitExpr((Expr *) opexpr->args, parent);
2488                                 sstate->fxprstate.func.fn_oid = InvalidOid;             /* not initialized */
2489                                 sstate->element_type = InvalidOid;              /* ditto */
2490                                 state = (ExprState *) sstate;
2491                         }
2492                         break;
2493                 case T_BoolExpr:
2494                         {
2495                                 BoolExpr   *boolexpr = (BoolExpr *) node;
2496                                 BoolExprState *bstate = makeNode(BoolExprState);
2497
2498                                 bstate->args = (List *)
2499                                         ExecInitExpr((Expr *) boolexpr->args, parent);
2500                                 state = (ExprState *) bstate;
2501                         }
2502                         break;
2503                 case T_SubPlan:
2504                         {
2505                                 /* Keep this in sync with ExecInitExprInitPlan, below */
2506                                 SubPlan    *subplan = (SubPlan *) node;
2507                                 SubPlanState *sstate = makeNode(SubPlanState);
2508
2509                                 if (!parent)
2510                                         elog(ERROR, "SubPlan found with no parent plan");
2511
2512                                 /*
2513                                  * Here we just add the SubPlanState nodes to
2514                                  * parent->subPlan.  The subplans will be initialized
2515                                  * later.
2516                                  */
2517                                 parent->subPlan = lcons(sstate, parent->subPlan);
2518                                 sstate->sub_estate = NULL;
2519                                 sstate->planstate = NULL;
2520
2521                                 sstate->exprs = (List *)
2522                                         ExecInitExpr((Expr *) subplan->exprs, parent);
2523                                 sstate->args = (List *)
2524                                         ExecInitExpr((Expr *) subplan->args, parent);
2525
2526                                 state = (ExprState *) sstate;
2527                         }
2528                         break;
2529                 case T_FieldSelect:
2530                         {
2531                                 FieldSelect *fselect = (FieldSelect *) node;
2532                                 GenericExprState *gstate = makeNode(GenericExprState);
2533
2534                                 gstate->arg = ExecInitExpr(fselect->arg, parent);
2535                                 state = (ExprState *) gstate;
2536                         }
2537                         break;
2538                 case T_RelabelType:
2539                         {
2540                                 RelabelType *relabel = (RelabelType *) node;
2541                                 GenericExprState *gstate = makeNode(GenericExprState);
2542
2543                                 gstate->arg = ExecInitExpr(relabel->arg, parent);
2544                                 state = (ExprState *) gstate;
2545                         }
2546                         break;
2547                 case T_CaseExpr:
2548                         {
2549                                 CaseExpr   *caseexpr = (CaseExpr *) node;
2550                                 CaseExprState *cstate = makeNode(CaseExprState);
2551                                 FastList        outlist;
2552                                 List       *inlist;
2553
2554                                 FastListInit(&outlist);
2555                                 foreach(inlist, caseexpr->args)
2556                                 {
2557                                         CaseWhen   *when = (CaseWhen *) lfirst(inlist);
2558                                         CaseWhenState *wstate = makeNode(CaseWhenState);
2559
2560                                         Assert(IsA(when, CaseWhen));
2561                                         wstate->xprstate.expr = (Expr *) when;
2562                                         wstate->expr = ExecInitExpr(when->expr, parent);
2563                                         wstate->result = ExecInitExpr(when->result, parent);
2564                                         FastAppend(&outlist, wstate);
2565                                 }
2566                                 cstate->args = FastListValue(&outlist);
2567                                 /* caseexpr->arg should be null by now */
2568                                 Assert(caseexpr->arg == NULL);
2569                                 cstate->defresult = ExecInitExpr(caseexpr->defresult, parent);
2570                                 state = (ExprState *) cstate;
2571                         }
2572                         break;
2573                 case T_ArrayExpr:
2574                         {
2575                                 ArrayExpr  *arrayexpr = (ArrayExpr *) node;
2576                                 ArrayExprState *astate = makeNode(ArrayExprState);
2577                                 FastList        outlist;
2578                                 List       *inlist;
2579
2580                                 FastListInit(&outlist);
2581                                 foreach(inlist, arrayexpr->elements)
2582                                 {
2583                                         Expr       *e = (Expr *) lfirst(inlist);
2584                                         ExprState  *estate;
2585
2586                                         estate = ExecInitExpr(e, parent);
2587                                         FastAppend(&outlist, estate);
2588                                 }
2589                                 astate->elements = FastListValue(&outlist);
2590                                 /* do one-time catalog lookup for type info */
2591                                 get_typlenbyvalalign(arrayexpr->element_typeid,
2592                                                                          &astate->elemlength,
2593                                                                          &astate->elembyval,
2594                                                                          &astate->elemalign);
2595                                 state = (ExprState *) astate;
2596                         }
2597                         break;
2598                 case T_CoalesceExpr:
2599                         {
2600                                 CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
2601                                 CoalesceExprState *cstate = makeNode(CoalesceExprState);
2602                                 FastList        outlist;
2603                                 List       *inlist;
2604
2605                                 FastListInit(&outlist);
2606                                 foreach(inlist, coalesceexpr->args)
2607                                 {
2608                                         Expr       *e = (Expr *) lfirst(inlist);
2609                                         ExprState  *estate;
2610
2611                                         estate = ExecInitExpr(e, parent);
2612                                         FastAppend(&outlist, estate);
2613                                 }
2614                                 cstate->args = FastListValue(&outlist);
2615                                 state = (ExprState *) cstate;
2616                         }
2617                         break;
2618                 case T_NullIfExpr:
2619                         {
2620                                 NullIfExpr *nullifexpr = (NullIfExpr *) node;
2621                                 FuncExprState *fstate = makeNode(FuncExprState);
2622
2623                                 fstate->args = (List *)
2624                                         ExecInitExpr((Expr *) nullifexpr->args, parent);
2625                                 fstate->func.fn_oid = InvalidOid;               /* not initialized */
2626                                 state = (ExprState *) fstate;
2627                         }
2628                         break;
2629                 case T_NullTest:
2630                         {
2631                                 NullTest   *ntest = (NullTest *) node;
2632                                 GenericExprState *gstate = makeNode(GenericExprState);
2633
2634                                 gstate->arg = ExecInitExpr(ntest->arg, parent);
2635                                 state = (ExprState *) gstate;
2636                         }
2637                         break;
2638                 case T_BooleanTest:
2639                         {
2640                                 BooleanTest *btest = (BooleanTest *) node;
2641                                 GenericExprState *gstate = makeNode(GenericExprState);
2642
2643                                 gstate->arg = ExecInitExpr(btest->arg, parent);
2644                                 state = (ExprState *) gstate;
2645                         }
2646                         break;
2647                 case T_CoerceToDomain:
2648                         {
2649                                 CoerceToDomain *ctest = (CoerceToDomain *) node;
2650                                 CoerceToDomainState *cstate = makeNode(CoerceToDomainState);
2651
2652                                 cstate->arg = ExecInitExpr(ctest->arg, parent);
2653                                 cstate->constraints = GetDomainConstraints(ctest->resulttype);
2654                                 state = (ExprState *) cstate;
2655                         }
2656                         break;
2657                 case T_TargetEntry:
2658                         {
2659                                 TargetEntry *tle = (TargetEntry *) node;
2660                                 GenericExprState *gstate = makeNode(GenericExprState);
2661
2662                                 gstate->arg = ExecInitExpr(tle->expr, parent);
2663                                 state = (ExprState *) gstate;
2664                         }
2665                         break;
2666                 case T_List:
2667                         {
2668                                 FastList        outlist;
2669                                 List       *inlist;
2670
2671                                 FastListInit(&outlist);
2672                                 foreach(inlist, (List *) node)
2673                                 {
2674                                         FastAppend(&outlist,
2675                                                            ExecInitExpr((Expr *) lfirst(inlist),
2676                                                                                         parent));
2677                                 }
2678                                 /* Don't fall through to the "common" code below */
2679                                 return (ExprState *) FastListValue(&outlist);
2680                         }
2681                 default:
2682                         elog(ERROR, "unrecognized node type: %d",
2683                                  (int) nodeTag(node));
2684                         state = NULL;           /* keep compiler quiet */
2685                         break;
2686         }
2687
2688         /* Common code for all state-node types */
2689         state->expr = node;
2690
2691         return state;
2692 }
2693
2694 /*
2695  * ExecInitExprInitPlan --- initialize a subplan expr that's being handled
2696  * as an InitPlan.      This is identical to ExecInitExpr's handling of a regular
2697  * subplan expr, except we do NOT want to add the node to the parent's
2698  * subplan list.
2699  */
2700 SubPlanState *
2701 ExecInitExprInitPlan(SubPlan *node, PlanState *parent)
2702 {
2703         SubPlanState *sstate = makeNode(SubPlanState);
2704
2705         if (!parent)
2706                 elog(ERROR, "SubPlan found with no parent plan");
2707
2708         /* The subplan's state will be initialized later */
2709         sstate->sub_estate = NULL;
2710         sstate->planstate = NULL;
2711
2712         sstate->exprs = (List *) ExecInitExpr((Expr *) node->exprs, parent);
2713         sstate->args = (List *) ExecInitExpr((Expr *) node->args, parent);
2714
2715         sstate->xprstate.expr = (Expr *) node;
2716
2717         return sstate;
2718 }
2719
2720 /*
2721  * ExecPrepareExpr --- initialize for expression execution outside a normal
2722  * Plan tree context.
2723  *
2724  * This differs from ExecInitExpr in that we don't assume the caller is
2725  * already running in the EState's per-query context.  Also, we apply
2726  * fix_opfuncids() to the passed expression tree to be sure it is ready
2727  * to run.      (In ordinary Plan trees the planner will have fixed opfuncids,
2728  * but callers outside the executor will not have done this.)
2729  */
2730 ExprState *
2731 ExecPrepareExpr(Expr *node, EState *estate)
2732 {
2733         ExprState  *result;
2734         MemoryContext oldcontext;
2735
2736         fix_opfuncids((Node *) node);
2737
2738         oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
2739
2740         result = ExecInitExpr(node, NULL);
2741
2742         MemoryContextSwitchTo(oldcontext);
2743
2744         return result;
2745 }
2746
2747
2748 /* ----------------------------------------------------------------
2749  *                                       ExecQual / ExecTargetList / ExecProject
2750  * ----------------------------------------------------------------
2751  */
2752
2753 /* ----------------------------------------------------------------
2754  *              ExecQual
2755  *
2756  *              Evaluates a conjunctive boolean expression (qual list) and
2757  *              returns true iff none of the subexpressions are false.
2758  *              (We also return true if the list is empty.)
2759  *
2760  *      If some of the subexpressions yield NULL but none yield FALSE,
2761  *      then the result of the conjunction is NULL (ie, unknown)
2762  *      according to three-valued boolean logic.  In this case,
2763  *      we return the value specified by the "resultForNull" parameter.
2764  *
2765  *      Callers evaluating WHERE clauses should pass resultForNull=FALSE,
2766  *      since SQL specifies that tuples with null WHERE results do not
2767  *      get selected.  On the other hand, callers evaluating constraint
2768  *      conditions should pass resultForNull=TRUE, since SQL also specifies
2769  *      that NULL constraint conditions are not failures.
2770  *
2771  *      NOTE: it would not be correct to use this routine to evaluate an
2772  *      AND subclause of a boolean expression; for that purpose, a NULL
2773  *      result must be returned as NULL so that it can be properly treated
2774  *      in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
2775  *      This routine is only used in contexts where a complete expression
2776  *      is being evaluated and we know that NULL can be treated the same
2777  *      as one boolean result or the other.
2778  *
2779  * ----------------------------------------------------------------
2780  */
2781 bool
2782 ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
2783 {
2784         bool            result;
2785         MemoryContext oldContext;
2786         List       *qlist;
2787
2788         /*
2789          * debugging stuff
2790          */
2791         EV_printf("ExecQual: qual is ");
2792         EV_nodeDisplay(qual);
2793         EV_printf("\n");
2794
2795         IncrProcessed();
2796
2797         /*
2798          * Run in short-lived per-tuple context while computing expressions.
2799          */
2800         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
2801
2802         /*
2803          * Evaluate the qual conditions one at a time.  If we find a FALSE
2804          * result, we can stop evaluating and return FALSE --- the AND result
2805          * must be FALSE.  Also, if we find a NULL result when resultForNull
2806          * is FALSE, we can stop and return FALSE --- the AND result must be
2807          * FALSE or NULL in that case, and the caller doesn't care which.
2808          *
2809          * If we get to the end of the list, we can return TRUE.  This will
2810          * happen when the AND result is indeed TRUE, or when the AND result
2811          * is NULL (one or more NULL subresult, with all the rest TRUE) and
2812          * the caller has specified resultForNull = TRUE.
2813          */
2814         result = true;
2815
2816         foreach(qlist, qual)
2817         {
2818                 ExprState  *clause = (ExprState *) lfirst(qlist);
2819                 Datum           expr_value;
2820                 bool            isNull;
2821
2822                 expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
2823
2824                 if (isNull)
2825                 {
2826                         if (resultForNull == false)
2827                         {
2828                                 result = false; /* treat NULL as FALSE */
2829                                 break;
2830                         }
2831                 }
2832                 else
2833                 {
2834                         if (!DatumGetBool(expr_value))
2835                         {
2836                                 result = false; /* definitely FALSE */
2837                                 break;
2838                         }
2839                 }
2840         }
2841
2842         MemoryContextSwitchTo(oldContext);
2843
2844         return result;
2845 }
2846
2847 /*
2848  * Number of items in a tlist (including any resjunk items!)
2849  */
2850 int
2851 ExecTargetListLength(List *targetlist)
2852 {
2853         /* This used to be more complex, but fjoins are dead */
2854         return length(targetlist);
2855 }
2856
2857 /*
2858  * Number of items in a tlist, not including any resjunk items
2859  */
2860 int
2861 ExecCleanTargetListLength(List *targetlist)
2862 {
2863         int                     len = 0;
2864         List       *tl;
2865
2866         foreach(tl, targetlist)
2867         {
2868                 TargetEntry *curTle = (TargetEntry *) lfirst(tl);
2869
2870                 Assert(IsA(curTle, TargetEntry));
2871                 if (!curTle->resdom->resjunk)
2872                         len++;
2873         }
2874         return len;
2875 }
2876
2877 /* ----------------------------------------------------------------
2878  *              ExecTargetList
2879  *
2880  *              Evaluates a targetlist with respect to the given
2881  *              expression context and returns a tuple.
2882  *
2883  * The caller must pass workspace for the values and nulls arrays
2884  * as well as the itemIsDone array.  This convention saves palloc'ing
2885  * workspace on each call, and some callers may find it useful to examine
2886  * the values array directly.
2887  *
2888  * As with ExecEvalExpr, the caller should pass isDone = NULL if not
2889  * prepared to deal with sets of result tuples.  Otherwise, a return
2890  * of *isDone = ExprMultipleResult signifies a set element, and a return
2891  * of *isDone = ExprEndResult signifies end of the set of tuple.
2892  * ----------------------------------------------------------------
2893  */
2894 static HeapTuple
2895 ExecTargetList(List *targetlist,
2896                            TupleDesc targettype,
2897                            ExprContext *econtext,
2898                            Datum *values,
2899                            char *nulls,
2900                            ExprDoneCond *itemIsDone,
2901                            ExprDoneCond *isDone)
2902 {
2903         MemoryContext oldContext;
2904         List       *tl;
2905         bool            isNull;
2906         bool            haveDoneSets;
2907         static struct tupleDesc NullTupleDesc;          /* we assume this inits to
2908                                                                                                  * zeroes */
2909
2910         /*
2911          * debugging stuff
2912          */
2913         EV_printf("ExecTargetList: tl is ");
2914         EV_nodeDisplay(targetlist);
2915         EV_printf("\n");
2916
2917         /*
2918          * Run in short-lived per-tuple context while computing expressions.
2919          */
2920         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
2921
2922         /*
2923          * There used to be some klugy and demonstrably broken code here that
2924          * special-cased the situation where targetlist == NIL.  Now we just
2925          * fall through and return an empty-but-valid tuple.  We do, however,
2926          * have to cope with the possibility that targettype is NULL ---
2927          * heap_formtuple won't like that, so pass a dummy descriptor with
2928          * natts = 0 to deal with it.
2929          */
2930         if (targettype == NULL)
2931                 targettype = &NullTupleDesc;
2932
2933         /*
2934          * evaluate all the expressions in the target list
2935          */
2936         if (isDone)
2937                 *isDone = ExprSingleResult;             /* until proven otherwise */
2938
2939         haveDoneSets = false;           /* any exhausted set exprs in tlist? */
2940
2941         foreach(tl, targetlist)
2942         {
2943                 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
2944                 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
2945                 AttrNumber      resind = tle->resdom->resno - 1;
2946
2947                 values[resind] = ExecEvalExpr(gstate->arg,
2948                                                                           econtext,
2949                                                                           &isNull,
2950                                                                           &itemIsDone[resind]);
2951                 nulls[resind] = isNull ? 'n' : ' ';
2952
2953                 if (itemIsDone[resind] != ExprSingleResult)
2954                 {
2955                         /* We have a set-valued expression in the tlist */
2956                         if (isDone == NULL)
2957                                 ereport(ERROR,
2958                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2959                                                  errmsg("set-valued function called in context that cannot accept a set")));
2960                         if (itemIsDone[resind] == ExprMultipleResult)
2961                         {
2962                                 /* we have undone sets in the tlist, set flag */
2963                                 *isDone = ExprMultipleResult;
2964                         }
2965                         else
2966                         {
2967                                 /* we have done sets in the tlist, set flag for that */
2968                                 haveDoneSets = true;
2969                         }
2970                 }
2971         }
2972
2973         if (haveDoneSets)
2974         {
2975                 /*
2976                  * note: can't get here unless we verified isDone != NULL
2977                  */
2978                 if (*isDone == ExprSingleResult)
2979                 {
2980                         /*
2981                          * all sets are done, so report that tlist expansion is
2982                          * complete.
2983                          */
2984                         *isDone = ExprEndResult;
2985                         MemoryContextSwitchTo(oldContext);
2986                         return NULL;
2987                 }
2988                 else
2989                 {
2990                         /*
2991                          * We have some done and some undone sets.      Restart the done
2992                          * ones so that we can deliver a tuple (if possible).
2993                          */
2994                         foreach(tl, targetlist)
2995                         {
2996                                 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
2997                                 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
2998                                 AttrNumber      resind = tle->resdom->resno - 1;
2999
3000                                 if (itemIsDone[resind] == ExprEndResult)
3001                                 {
3002                                         values[resind] = ExecEvalExpr(gstate->arg,
3003                                                                                                   econtext,
3004                                                                                                   &isNull,
3005                                                                                                   &itemIsDone[resind]);
3006                                         nulls[resind] = isNull ? 'n' : ' ';
3007
3008                                         if (itemIsDone[resind] == ExprEndResult)
3009                                         {
3010                                                 /*
3011                                                  * Oh dear, this item is returning an empty set.
3012                                                  * Guess we can't make a tuple after all.
3013                                                  */
3014                                                 *isDone = ExprEndResult;
3015                                                 break;
3016                                         }
3017                                 }
3018                         }
3019
3020                         /*
3021                          * If we cannot make a tuple because some sets are empty, we
3022                          * still have to cycle the nonempty sets to completion, else
3023                          * resources will not be released from subplans etc.
3024                          *
3025                          * XXX is that still necessary?
3026                          */
3027                         if (*isDone == ExprEndResult)
3028                         {
3029                                 foreach(tl, targetlist)
3030                                 {
3031                                         GenericExprState *gstate = (GenericExprState *) lfirst(tl);
3032                                         TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
3033                                         AttrNumber      resind = tle->resdom->resno - 1;
3034
3035                                         while (itemIsDone[resind] == ExprMultipleResult)
3036                                         {
3037                                                 (void) ExecEvalExpr(gstate->arg,
3038                                                                                         econtext,
3039                                                                                         &isNull,
3040                                                                                         &itemIsDone[resind]);
3041                                         }
3042                                 }
3043
3044                                 MemoryContextSwitchTo(oldContext);
3045                                 return NULL;
3046                         }
3047                 }
3048         }
3049
3050         /*
3051          * form the new result tuple (in the caller's memory context!)
3052          */
3053         MemoryContextSwitchTo(oldContext);
3054
3055         return heap_formtuple(targettype, values, nulls);
3056 }
3057
3058 /* ----------------------------------------------------------------
3059  *              ExecProject
3060  *
3061  *              projects a tuple based on projection info and stores
3062  *              it in the specified tuple table slot.
3063  *
3064  *              Note: someday soon the executor can be extended to eliminate
3065  *                        redundant projections by storing pointers to datums
3066  *                        in the tuple table and then passing these around when
3067  *                        possible.  this should make things much quicker.
3068  *                        -cim 6/3/91
3069  * ----------------------------------------------------------------
3070  */
3071 TupleTableSlot *
3072 ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
3073 {
3074         TupleTableSlot *slot;
3075         TupleDesc       tupType;
3076         HeapTuple       newTuple;
3077
3078         /*
3079          * sanity checks
3080          */
3081         if (projInfo == NULL)
3082                 return (TupleTableSlot *) NULL;
3083
3084         /*
3085          * get the projection info we want
3086          */
3087         slot = projInfo->pi_slot;
3088         tupType = slot->ttc_tupleDescriptor;
3089
3090         /*
3091          * form a new result tuple (if possible --- result can be NULL)
3092          */
3093         newTuple = ExecTargetList(projInfo->pi_targetlist,
3094                                                           tupType,
3095                                                           projInfo->pi_exprContext,
3096                                                           projInfo->pi_tupValues,
3097                                                           projInfo->pi_tupNulls,
3098                                                           projInfo->pi_itemIsDone,
3099                                                           isDone);
3100
3101         /*
3102          * store the tuple in the projection slot and return the slot.
3103          */
3104         return ExecStoreTuple(newTuple,         /* tuple to store */
3105                                                   slot, /* slot to store in */
3106                                                   InvalidBuffer,                /* tuple has no buffer */
3107                                                   true);
3108 }