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