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