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