]> granicus.if.org Git - postgresql/blob - src/backend/executor/execQual.c
1aeb07a7a9ffda1f4620cf408e11dbce69526f6c
[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-2000, PostgreSQL, Inc
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.75 2000/07/22 03:34:27 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_language.h"
39 #include "executor/execFlatten.h"
40 #include "executor/execdebug.h"
41 #include "executor/functions.h"
42 #include "executor/nodeSubplan.h"
43 #include "utils/array.h"
44 #include "utils/builtins.h"
45 #include "utils/fmgroids.h"
46 #include "utils/fcache2.h"
47
48
49 /* static function decls */
50 static Datum ExecEvalAggref(Aggref *aggref, ExprContext *econtext, bool *isNull);
51 static Datum ExecEvalArrayRef(ArrayRef *arrayRef, ExprContext *econtext,
52                                  bool *isNull, bool *isDone);
53 static Datum ExecEvalOper(Expr *opClause, ExprContext *econtext,
54                          bool *isNull);
55 static Datum ExecEvalFunc(Expr *funcClause, ExprContext *econtext,
56                          bool *isNull, bool *isDone);
57 static void ExecEvalFuncArgs(FunctionCachePtr fcache, ExprContext *econtext,
58                                                          List *argList, FunctionCallInfo fcinfo,
59                                                          bool *argIsDone);
60 static Datum ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull);
61 static Datum ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull);
62 static Datum ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull);
63 static Datum ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull);
64 static Datum ExecMakeFunctionResult(Node *node, List *arguments,
65                                            ExprContext *econtext, bool *isNull, bool *isDone);
66
67 /*
68  *        ExecEvalArrayRef
69  *
70  *         This function takes an ArrayRef and returns the extracted Datum
71  *         if it's a simple reference, or the modified array value if it's
72  *         an array assignment (read array element insertion).
73  *
74  * NOTE: we deliberately refrain from applying DatumGetArrayTypeP() here,
75  * even though that might seem natural, because this code needs to support
76  * both varlena arrays and fixed-length array types.  DatumGetArrayTypeP()
77  * only works for the varlena kind.  The routines we call in arrayfuncs.c
78  * have to know the difference (that's what they need refattrlength for).
79  */
80 static Datum
81 ExecEvalArrayRef(ArrayRef *arrayRef,
82                                  ExprContext *econtext,
83                                  bool *isNull,
84                                  bool *isDone)
85 {
86         ArrayType  *array_source;
87         ArrayType  *resultArray;
88         List       *elt;
89         int                     i = 0,
90                                 j = 0;
91         IntArray        upper,
92                                 lower;
93         int                *lIndex;
94         bool            dummy;
95
96         *isNull = false;
97
98         if (arrayRef->refexpr != NULL)
99         {
100                 array_source = (ArrayType *)
101                         DatumGetPointer(ExecEvalExpr(arrayRef->refexpr,
102                                                                                  econtext,
103                                                                                  isNull,
104                                                                                  isDone));
105                 /* If refexpr yields NULL, result is always NULL, for now anyway */
106                 if (*isNull)
107                         return (Datum) NULL;
108         }
109         else
110         {
111
112                 /*
113                  * Null refexpr indicates we are doing an INSERT into an array
114                  * column. For now, we just take the refassgnexpr (which the
115                  * parser will have ensured is an array value) and return it
116                  * as-is, ignoring any subscripts that may have been supplied in
117                  * the INSERT column list. This is a kluge, but it's not real
118                  * clear what the semantics ought to be...
119                  */
120                 array_source = NULL;
121         }
122
123         foreach(elt, arrayRef->refupperindexpr)
124         {
125                 if (i >= MAXDIM)
126                         elog(ERROR, "ExecEvalArrayRef: can only handle %d dimensions",
127                                  MAXDIM);
128
129                 upper.indx[i++] = DatumGetInt32(ExecEvalExpr((Node *) lfirst(elt),
130                                                                                                          econtext,
131                                                                                                          isNull,
132                                                                                                          &dummy));
133                 /* If any index expr yields NULL, result is NULL */
134                 if (*isNull)
135                         return (Datum) NULL;
136         }
137
138         if (arrayRef->reflowerindexpr != NIL)
139         {
140                 foreach(elt, arrayRef->reflowerindexpr)
141                 {
142                         if (j >= MAXDIM)
143                                 elog(ERROR, "ExecEvalArrayRef: can only handle %d dimensions",
144                                          MAXDIM);
145
146                         lower.indx[j++] = DatumGetInt32(ExecEvalExpr((Node *) lfirst(elt),
147                                                                                                                  econtext,
148                                                                                                                  isNull,
149                                                                                                                  &dummy));
150                         /* If any index expr yields NULL, result is NULL */
151                         if (*isNull)
152                                 return (Datum) NULL;
153                 }
154                 if (i != j)
155                         elog(ERROR,
156                                  "ExecEvalArrayRef: upper and lower indices mismatch");
157                 lIndex = lower.indx;
158         }
159         else
160                 lIndex = NULL;
161
162         if (arrayRef->refassgnexpr != NULL)
163         {
164                 Datum           sourceData = ExecEvalExpr(arrayRef->refassgnexpr,
165                                                                                           econtext,
166                                                                                           isNull,
167                                                                                           &dummy);
168                 /* For now, can't cope with inserting NULL into an array */
169                 if (*isNull)
170                         return (Datum) NULL;
171
172                 if (array_source == NULL)
173                         return sourceData;      /* XXX do something else? */
174
175                 if (lIndex == NULL)
176                         resultArray = array_set(array_source, i,
177                                                                         upper.indx,
178                                                                         sourceData,
179                                                                         arrayRef->refelembyval,
180                                                                         arrayRef->refelemlength,
181                                                                         arrayRef->refattrlength,
182                                                                         isNull);
183                 else
184                         resultArray = array_set_slice(array_source, i,
185                                                                                   upper.indx, lower.indx,
186                                                                                   (ArrayType *) DatumGetPointer(sourceData),
187                                                                                   arrayRef->refelembyval,
188                                                                                   arrayRef->refelemlength,
189                                                                                   arrayRef->refattrlength,
190                                                                                   isNull);
191                 return PointerGetDatum(resultArray);
192         }
193
194         if (lIndex == NULL)
195                 return array_ref(array_source, i,
196                                                  upper.indx,
197                                                  arrayRef->refelembyval,
198                                                  arrayRef->refelemlength,
199                                                  arrayRef->refattrlength,
200                                                  isNull);
201         else
202         {
203                 resultArray = array_get_slice(array_source, i,
204                                                                           upper.indx, lower.indx,
205                                                                           arrayRef->refelembyval,
206                                                                           arrayRef->refelemlength,
207                                                                           arrayRef->refattrlength,
208                                                                           isNull);
209                 return PointerGetDatum(resultArray);
210         }
211 }
212
213
214 /* ----------------------------------------------------------------
215  *              ExecEvalAggref
216  *
217  *              Returns a Datum whose value is the value of the precomputed
218  *              aggregate found in the given expression context.
219  * ----------------------------------------------------------------
220  */
221 static Datum
222 ExecEvalAggref(Aggref *aggref, ExprContext *econtext, bool *isNull)
223 {
224         if (econtext->ecxt_aggvalues == NULL)           /* safety check */
225                 elog(ERROR, "ExecEvalAggref: no aggregates in this expression context");
226
227         *isNull = econtext->ecxt_aggnulls[aggref->aggno];
228         return econtext->ecxt_aggvalues[aggref->aggno];
229 }
230
231 /* ----------------------------------------------------------------
232  *              ExecEvalVar
233  *
234  *              Returns a Datum whose value is the value of a range
235  *              variable with respect to given expression context.
236  *
237  *
238  *              As an entry condition, we expect that the datatype the
239  *              plan expects to get (as told by our "variable" argument) is in
240  *              fact the datatype of the attribute the plan says to fetch (as
241  *              seen in the current context, identified by our "econtext"
242  *              argument).
243  *
244  *              If we fetch a Type A attribute and Caller treats it as if it
245  *              were Type B, there will be undefined results (e.g. crash).
246  *              One way these might mismatch now is that we're accessing a
247  *              catalog class and the type information in the pg_attribute
248  *              class does not match the hardcoded pg_attribute information
249  *              (in pg_attribute.h) for the class in question.
250  *
251  *              We have an Assert to make sure this entry condition is met.
252  *
253  * ---------------------------------------------------------------- */
254 static Datum
255 ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
256 {
257         Datum           result;
258         TupleTableSlot *slot;
259         AttrNumber      attnum;
260         HeapTuple       heapTuple;
261         TupleDesc       tuple_type;
262         bool            byval;
263         int16           len;
264
265         /*
266          * get the slot we want
267          */
268         switch (variable->varno)
269         {
270                 case INNER:                             /* get the tuple from the inner node */
271                         slot = econtext->ecxt_innertuple;
272                         break;
273
274                 case OUTER:                             /* get the tuple from the outer node */
275                         slot = econtext->ecxt_outertuple;
276                         break;
277
278                 default:                                /* get the tuple from the relation being
279                                                                  * scanned */
280                         slot = econtext->ecxt_scantuple;
281                         break;
282         }
283
284         /*
285          * extract tuple information from the slot
286          */
287         heapTuple = slot->val;
288         tuple_type = slot->ttc_tupleDescriptor;
289
290         attnum = variable->varattno;
291
292         /* (See prolog for explanation of this Assert) */
293         Assert(attnum <= 0 ||
294                    (attnum - 1 <= tuple_type->natts - 1 &&
295                         tuple_type->attrs[attnum - 1] != NULL &&
296                   variable->vartype == tuple_type->attrs[attnum - 1]->atttypid));
297
298         /*
299          * If the attribute number is invalid, then we are supposed to return
300          * the entire tuple, we give back a whole slot so that callers know
301          * what the tuple looks like.
302          */
303         if (attnum == InvalidAttrNumber)
304         {
305                 TupleTableSlot *tempSlot;
306                 TupleDesc       td;
307                 HeapTuple       tup;
308
309                 tempSlot = makeNode(TupleTableSlot);
310                 tempSlot->ttc_shouldFree = false;
311                 tempSlot->ttc_descIsNew = true;
312                 tempSlot->ttc_tupleDescriptor = (TupleDesc) NULL;
313                 tempSlot->ttc_buffer = InvalidBuffer;
314                 tempSlot->ttc_whichplan = -1;
315
316                 tup = heap_copytuple(heapTuple);
317                 td = CreateTupleDescCopy(tuple_type);
318
319                 ExecSetSlotDescriptor(tempSlot, td);
320
321                 ExecStoreTuple(tup, tempSlot, InvalidBuffer, true);
322                 return PointerGetDatum(tempSlot);
323         }
324
325         result = heap_getattr(heapTuple,        /* tuple containing attribute */
326                                                   attnum,               /* attribute number of desired
327                                                                                  * attribute */
328                                                   tuple_type,   /* tuple descriptor of tuple */
329                                                   isNull);              /* return: is attribute null? */
330
331         /*
332          * return null if att is null
333          */
334         if (*isNull)
335                 return (Datum) 0;
336
337         /*
338          * get length and type information.. ??? what should we do about
339          * variable length attributes - variable length attributes have their
340          * length stored in the first 4 bytes of the memory pointed to by the
341          * returned value.. If we can determine that the type is a variable
342          * length type, we can do the right thing. -cim 9/15/89
343          */
344         if (attnum < 0)
345         {
346
347                 /*
348                  * If this is a pseudo-att, we get the type and fake the length.
349                  * There ought to be a routine to return the real lengths, so
350                  * we'll mark this one ... XXX -mao
351                  */
352                 len = heap_sysattrlen(attnum);  /* XXX see -mao above */
353                 byval = heap_sysattrbyval(attnum);              /* XXX see -mao above */
354         }
355         else
356         {
357                 len = tuple_type->attrs[attnum - 1]->attlen;
358                 byval = tuple_type->attrs[attnum - 1]->attbyval ? true : false;
359         }
360
361         return result;
362 }
363
364 /* ----------------------------------------------------------------
365  *              ExecEvalParam
366  *
367  *              Returns the value of a parameter.  A param node contains
368  *              something like ($.name) and the expression context contains
369  *              the current parameter bindings (name = "sam") (age = 34)...
370  *              so our job is to replace the param node with the datum
371  *              containing the appropriate information ("sam").
372  *
373  *              Q: if we have a parameter ($.foo) without a binding, i.e.
374  *                 there is no (foo = xxx) in the parameter list info,
375  *                 is this a fatal error or should this be a "not available"
376  *                 (in which case we shoud return a Const node with the
377  *                      isnull flag) ?  -cim 10/13/89
378  *
379  *              Minor modification: Param nodes now have an extra field,
380  *              `paramkind' which specifies the type of parameter
381  *              (see params.h). So while searching the paramList for
382  *              a paramname/value pair, we have also to check for `kind'.
383  *
384  *              NOTE: The last entry in `paramList' is always an
385  *              entry with kind == PARAM_INVALID.
386  * ----------------------------------------------------------------
387  */
388 Datum
389 ExecEvalParam(Param *expression, ExprContext *econtext, bool *isNull)
390 {
391         char       *thisParameterName;
392         int                     thisParameterKind = expression->paramkind;
393         AttrNumber      thisParameterId = expression->paramid;
394         int                     matchFound;
395         ParamListInfo paramList;
396
397         if (thisParameterKind == PARAM_EXEC)
398         {
399                 ParamExecData *prm;
400
401                 prm = &(econtext->ecxt_param_exec_vals[thisParameterId]);
402                 if (prm->execPlan != NULL)
403                 {
404                         ExecSetParamPlan(prm->execPlan, econtext);
405                         /* ExecSetParamPlan should have processed this param... */
406                         Assert(prm->execPlan == NULL);
407                 }
408                 *isNull = prm->isnull;
409                 return prm->value;
410         }
411
412         thisParameterName = expression->paramname;
413         paramList = econtext->ecxt_param_list_info;
414
415         *isNull = false;
416
417         /*
418          * search the list with the parameter info to find a matching name. An
419          * entry with an InvalidName denotes the last element in the array.
420          */
421         matchFound = 0;
422         if (paramList != NULL)
423         {
424
425                 /*
426                  * search for an entry in 'paramList' that matches the
427                  * `expression'.
428                  */
429                 while (paramList->kind != PARAM_INVALID && !matchFound)
430                 {
431                         switch (thisParameterKind)
432                         {
433                                 case PARAM_NAMED:
434                                         if (thisParameterKind == paramList->kind &&
435                                                 strcmp(paramList->name, thisParameterName) == 0)
436                                                 matchFound = 1;
437                                         break;
438                                 case PARAM_NUM:
439                                         if (thisParameterKind == paramList->kind &&
440                                                 paramList->id == thisParameterId)
441                                                 matchFound = 1;
442                                         break;
443                                 case PARAM_OLD:
444                                 case PARAM_NEW:
445                                         if (thisParameterKind == paramList->kind &&
446                                                 paramList->id == thisParameterId)
447                                         {
448                                                 matchFound = 1;
449
450                                                 /*
451                                                  * sanity check
452                                                  */
453                                                 if (strcmp(paramList->name, thisParameterName) != 0)
454                                                 {
455                                                         elog(ERROR,
456                                                                  "ExecEvalParam: new/old params with same id & diff names");
457                                                 }
458                                         }
459                                         break;
460                                 default:
461
462                                         /*
463                                          * oops! this is not supposed to happen!
464                                          */
465                                         elog(ERROR, "ExecEvalParam: invalid paramkind %d",
466                                                  thisParameterKind);
467                         }
468                         if (!matchFound)
469                                 paramList++;
470                 }                                               /* while */
471         }                                                       /* if */
472
473         if (!matchFound)
474         {
475
476                 /*
477                  * ooops! we couldn't find this parameter in the parameter list.
478                  * Signal an error
479                  */
480                 elog(ERROR, "ExecEvalParam: Unknown value for parameter %s",
481                          thisParameterName);
482         }
483
484         /*
485          * return the value.
486          */
487         if (paramList->isnull)
488         {
489                 *isNull = true;
490                 return (Datum) 0;
491         }
492
493         if (expression->param_tlist != NIL)
494         {
495                 HeapTuple       tup;
496                 Datum           value;
497                 List       *tlist = expression->param_tlist;
498                 TargetEntry *tle = (TargetEntry *) lfirst(tlist);
499                 TupleTableSlot *slot = (TupleTableSlot *) paramList->value;
500
501                 tup = slot->val;
502                 value = ProjectAttribute(slot->ttc_tupleDescriptor,
503                                                                  tle, tup, isNull);
504                 return value;
505         }
506         return paramList->value;
507 }
508
509
510 /* ----------------------------------------------------------------
511  *              ExecEvalOper / ExecEvalFunc support routines
512  * ----------------------------------------------------------------
513  */
514
515 /*
516  *              GetAttributeByName
517  *              GetAttributeByNum
518  *
519  *              These are functions which return the value of the
520  *              named attribute out of the tuple from the arg slot.  User defined
521  *              C functions which take a tuple as an argument are expected
522  *              to use this.  Ex: overpaid(EMP) might call GetAttributeByNum().
523  *
524  * XXX these two functions are misdeclared: they should be declared to
525  * return Datum.  They are not used anywhere in the backend proper, and
526  * exist only for use by user-defined functions.  Should we change their
527  * definitions, at risk of breaking user code?
528  */
529 char *
530 GetAttributeByNum(TupleTableSlot *slot,
531                                   AttrNumber attrno,
532                                   bool *isNull)
533 {
534         Datum           retval;
535
536         if (!AttributeNumberIsValid(attrno))
537                 elog(ERROR, "GetAttributeByNum: Invalid attribute number");
538
539         if (!AttrNumberIsForUserDefinedAttr(attrno))
540                 elog(ERROR, "GetAttributeByNum: cannot access system attributes here");
541
542         if (isNull == (bool *) NULL)
543                 elog(ERROR, "GetAttributeByNum: a NULL isNull flag was passed");
544
545         if (TupIsNull(slot))
546         {
547                 *isNull = true;
548                 return (char *) NULL;
549         }
550
551         retval = heap_getattr(slot->val,
552                                                   attrno,
553                                                   slot->ttc_tupleDescriptor,
554                                                   isNull);
555         if (*isNull)
556                 return (char *) NULL;
557         return (char *) retval;
558 }
559
560 char *
561 GetAttributeByName(TupleTableSlot *slot, char *attname, bool *isNull)
562 {
563         AttrNumber      attrno;
564         TupleDesc       tupdesc;
565         Datum           retval;
566         int                     natts;
567         int                     i;
568
569         if (attname == NULL)
570                 elog(ERROR, "GetAttributeByName: Invalid attribute name");
571
572         if (isNull == (bool *) NULL)
573                 elog(ERROR, "GetAttributeByName: a NULL isNull flag was passed");
574
575         if (TupIsNull(slot))
576         {
577                 *isNull = true;
578                 return (char *) NULL;
579         }
580
581         tupdesc = slot->ttc_tupleDescriptor;
582         natts = slot->val->t_data->t_natts;
583
584         attrno = InvalidAttrNumber;
585         for (i = 0; i < tupdesc->natts; i++)
586         {
587                 if (namestrcmp(&(tupdesc->attrs[i]->attname), attname) == 0)
588                 {
589                         attrno = tupdesc->attrs[i]->attnum;
590                         break;
591                 }
592         }
593
594         if (attrno == InvalidAttrNumber)
595                 elog(ERROR, "GetAttributeByName: attribute %s not found", attname);
596
597         retval = heap_getattr(slot->val,
598                                                   attrno,
599                                                   tupdesc,
600                                                   isNull);
601         if (*isNull)
602                 return (char *) NULL;
603         return (char *) retval;
604 }
605
606
607 static void
608 ExecEvalFuncArgs(FunctionCachePtr fcache,
609                                  ExprContext *econtext,
610                                  List *argList,
611                                  FunctionCallInfo fcinfo,
612                                  bool *argIsDone)
613 {
614         int                     i;
615         List       *arg;
616
617         i = 0;
618         foreach(arg, argList)
619         {
620
621                 /*
622                  * evaluate the expression, in general functions cannot take sets
623                  * as arguments but we make an exception in the case of nested dot
624                  * expressions.  We have to watch out for this case here.
625                  */
626                 fcinfo->arg[i] = ExecEvalExpr((Node *) lfirst(arg),
627                                                                           econtext,
628                                                                           &fcinfo->argnull[i],
629                                                                           argIsDone);
630
631                 if (!(*argIsDone))
632                 {
633                         if (i != 0)
634                                 elog(ERROR, "functions can only take sets in their first argument");
635                         fcache->setArg = fcinfo->arg[0];
636                         fcache->hasSetArg = true;
637                 }
638                 i++;
639         }
640 }
641
642 /*
643  *              ExecMakeFunctionResult
644  */
645 static Datum
646 ExecMakeFunctionResult(Node *node,
647                                            List *arguments,
648                                            ExprContext *econtext,
649                                            bool *isNull,
650                                            bool *isDone)
651 {
652         FunctionCallInfoData    fcinfo;
653         FunctionCachePtr                fcache;
654         List                               *ftlist;
655         bool                                    funcisset;
656         Datum                                   result;
657         bool                                    argDone;
658
659         MemSet(&fcinfo, 0, sizeof(fcinfo));
660
661         /*
662          * This is kind of ugly, Func nodes now have targetlists so that we
663          * know when and what to project out from postquel function results.
664          * ExecMakeFunctionResult becomes a little bit more of a dual personality
665          * as a result.
666          */
667         if (IsA(node, Func))
668         {
669                 fcache = ((Func *) node)->func_fcache;
670                 ftlist = ((Func *) node)->func_tlist;
671                 funcisset = (((Func *) node)->funcid == F_SETEVAL);
672         }
673         else
674         {
675                 fcache = ((Oper *) node)->op_fcache;
676                 ftlist = NIL;
677                 funcisset = false;
678         }
679
680         fcinfo.flinfo = &fcache->func;
681         fcinfo.nargs = fcache->nargs;
682
683         /*
684          * arguments is a list of expressions to evaluate before passing to
685          * the function manager.  We collect the results of evaluating the
686          * expressions into the FunctionCallInfo struct.  Note we assume that
687          * fcache->nargs is the correct length of the arguments list!
688          */
689         if (fcache->nargs > 0)
690         {
691                 if (fcache->nargs > FUNC_MAX_ARGS)
692                         elog(ERROR, "ExecMakeFunctionResult: too many arguments");
693
694                 /*
695                  * If the setArg in the fcache is set we have an argument
696                  * returning a set of tuples (i.e. a nested dot expression).  We
697                  * don't want to evaluate the arguments again until the function
698                  * is done. hasSetArg will always be false until we eval the args
699                  * for the first time.
700                  */
701                 if (fcache->hasSetArg && fcache->setArg != (Datum) 0)
702                 {
703                         fcinfo.arg[0] = fcache->setArg;
704                         argDone = false;
705                 }
706                 else
707                         ExecEvalFuncArgs(fcache, econtext, arguments, &fcinfo, &argDone);
708
709                 if (fcache->hasSetArg && argDone)
710                 {
711                         /* can only get here if input is an empty set. */
712                         *isNull = true;
713                         *isDone = true;
714                         return (Datum) 0;
715                 }
716         }
717
718         /*
719          * If this function is really a set, we have to diddle with things. If
720          * the function has already been called at least once, then the setArg
721          * field of the fcache holds the OID of this set in pg_proc.  (This is
722          * not quite legit, since the setArg field is really for functions
723          * which take sets of tuples as input - set functions take no inputs
724          * at all.      But it's a nice place to stash this value, for now.)
725          *
726          * If this is the first call of the set's function, then the call to
727          * ExecEvalFuncArgs above just returned the OID of the pg_proc tuple
728          * which defines this set.      So replace the existing funcid in the
729          * funcnode with the set's OID.  Also, we want a new fcache which
730          * points to the right function, so get that, now that we have the
731          * right OID.  Also zero out fcinfo.arg, since the real set doesn't take
732          * any arguments.
733          */
734         if (funcisset)
735         {
736                 if (fcache->setArg)
737                 {
738                         ((Func *) node)->funcid = DatumGetObjectId(fcache->setArg);
739                 }
740                 else
741                 {
742                         ((Func *) node)->funcid = DatumGetObjectId(fcinfo.arg[0]);
743                         setFcache(node, DatumGetObjectId(fcinfo.arg[0]), NIL, econtext);
744                         fcache = ((Func *) node)->func_fcache;
745                         fcache->setArg = fcinfo.arg[0];
746                 }
747                 fcinfo.arg[0] = (Datum) 0;
748         }
749
750         /*
751          * now return the value gotten by calling the function manager,
752          * passing the function the evaluated parameter values.
753          */
754         if (fcache->language == SQLlanguageId)
755         {
756                 /*--------------------
757                  * This loop handles the situation where we are iterating through
758                  * all results in a nested dot function (whose argument function
759                  * returns a set of tuples) and the current function finally
760                  * finishes.  We need to get the next argument in the set and start
761                  * the function all over again.  We might have to do it more than
762                  * once, if the function produces no results for a particular argument.
763                  * This is getting unclean.
764                  *--------------------
765                  */
766                 for (;;)
767                 {
768                         /*
769                          * If function is strict, and there are any NULL arguments,
770                          * skip calling the function (at least for this set of args).
771                          */
772                         bool    callit = true;
773
774                         if (fcinfo.flinfo->fn_strict)
775                         {
776                                 int             i;
777
778                                 for (i = 0; i < fcinfo.nargs; i++)
779                                 {
780                                         if (fcinfo.argnull[i])
781                                         {
782                                                 callit = false;
783                                                 break;
784                                         }
785                                 }
786                         }
787
788                         if (callit)
789                         {
790                                 result = postquel_function(&fcinfo, fcache, ftlist, isDone);
791                                 *isNull = fcinfo.isnull;
792                         }
793                         else
794                         {
795                                 result = (Datum) 0;
796                                 *isNull = true;
797                                 *isDone = true;
798                         }
799
800                         if (!*isDone)
801                                 break;                  /* got a result from current argument */
802                         if (!fcache->hasSetArg)
803                                 break;                  /* input not a set, so done */
804
805                         /* OK, get the next argument... */
806                         ExecEvalFuncArgs(fcache, econtext, arguments, &fcinfo, &argDone);
807
808                         if (argDone)
809                         {
810
811                                 /*
812                                  * End of arguments, so reset the setArg flag and say
813                                  * "Done"
814                                  */
815                                 fcache->setArg = (Datum) 0;
816                                 fcache->hasSetArg = false;
817                                 *isDone = true;
818                                 *isNull = true;
819                                 result = (Datum) 0;
820                                 break;
821                         }
822
823                         /*
824                          * If we reach here, loop around to run the function on the
825                          * new argument.
826                          */
827                 }
828
829                 if (funcisset)
830                 {
831
832                         /*
833                          * reset the funcid so that next call to this routine will
834                          * still recognize this func as a set. Note that for now we
835                          * assume that the set function in pg_proc must be a Postquel
836                          * function - the funcid is not reset below for C functions.
837                          */
838                         ((Func *) node)->funcid = F_SETEVAL;
839
840                         /*
841                          * If we're done with the results of this function, get rid of
842                          * its func cache.
843                          */
844                         if (*isDone)
845                                 ((Func *) node)->func_fcache = NULL;
846                 }
847         }
848         else
849         {
850                 /* A non-SQL function cannot return a set, at present. */
851                 *isDone = true;
852
853                 /*
854                  * If function is strict, and there are any NULL arguments,
855                  * skip calling the function and return NULL.
856                  */
857                 if (fcinfo.flinfo->fn_strict)
858                 {
859                         int             i;
860
861                         for (i = 0; i < fcinfo.nargs; i++)
862                         {
863                                 if (fcinfo.argnull[i])
864                                 {
865                                         *isNull = true;
866                                         return (Datum) 0;
867                                 }
868                         }
869                 }
870                 result = FunctionCallInvoke(&fcinfo);
871                 *isNull = fcinfo.isnull;
872         }
873
874         return result;
875 }
876
877
878 /* ----------------------------------------------------------------
879  *              ExecEvalOper
880  *              ExecEvalFunc
881  *
882  *              Evaluate the functional result of a list of arguments by calling the
883  *              function manager.
884  * ----------------------------------------------------------------
885  */
886
887 /* ----------------------------------------------------------------
888  *              ExecEvalOper
889  * ----------------------------------------------------------------
890  */
891 static Datum
892 ExecEvalOper(Expr *opClause, ExprContext *econtext, bool *isNull)
893 {
894         Oper       *op;
895         List       *argList;
896         FunctionCachePtr fcache;
897         bool            isDone;
898
899         /*
900          * we extract the oid of the function associated with the op and then
901          * pass the work onto ExecMakeFunctionResult which evaluates the
902          * arguments and returns the result of calling the function on the
903          * evaluated arguments.
904          */
905         op = (Oper *) opClause->oper;
906         argList = opClause->args;
907
908         /*
909          * get the fcache from the Oper node. If it is NULL, then initialize
910          * it
911          */
912         fcache = op->op_fcache;
913         if (fcache == NULL)
914         {
915                 setFcache((Node *) op, op->opid, argList, econtext);
916                 fcache = op->op_fcache;
917         }
918
919         /*
920          * call ExecMakeFunctionResult() with a dummy isDone that we ignore.
921          * We don't have operator whose arguments are sets.
922          */
923         return ExecMakeFunctionResult((Node *) op, argList, econtext,
924                                                                   isNull, &isDone);
925 }
926
927 /* ----------------------------------------------------------------
928  *              ExecEvalFunc
929  * ----------------------------------------------------------------
930  */
931
932 static Datum
933 ExecEvalFunc(Expr *funcClause,
934                          ExprContext *econtext,
935                          bool *isNull,
936                          bool *isDone)
937 {
938         Func       *func;
939         List       *argList;
940         FunctionCachePtr fcache;
941
942         /*
943          * we extract the oid of the function associated with the func node and
944          * then pass the work onto ExecMakeFunctionResult which evaluates the
945          * arguments and returns the result of calling the function on the
946          * evaluated arguments.
947          *
948          * this is nearly identical to the ExecEvalOper code.
949          */
950         func = (Func *) funcClause->oper;
951         argList = funcClause->args;
952
953         /*
954          * get the fcache from the Func node. If it is NULL, then initialize
955          * it
956          */
957         fcache = func->func_fcache;
958         if (fcache == NULL)
959         {
960                 setFcache((Node *) func, func->funcid, argList, econtext);
961                 fcache = func->func_fcache;
962         }
963
964         return ExecMakeFunctionResult((Node *) func, argList, econtext,
965                                                                   isNull, isDone);
966 }
967
968 /* ----------------------------------------------------------------
969  *              ExecEvalNot
970  *              ExecEvalOr
971  *              ExecEvalAnd
972  *
973  *              Evaluate boolean expressions.  Evaluation of 'or' is
974  *              short-circuited when the first true (or null) value is found.
975  *
976  *              The query planner reformulates clause expressions in the
977  *              qualification to conjunctive normal form.  If we ever get
978  *              an AND to evaluate, we can be sure that it's not a top-level
979  *              clause in the qualification, but appears lower (as a function
980  *              argument, for example), or in the target list.  Not that you
981  *              need to know this, mind you...
982  * ----------------------------------------------------------------
983  */
984 static Datum
985 ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull)
986 {
987         Node       *clause;
988         Datum           expr_value;
989         bool            isDone;
990
991         clause = lfirst(notclause->args);
992
993         /*
994          * We don't iterate over sets in the quals, so pass in an isDone flag,
995          * but ignore it.
996          */
997         expr_value = ExecEvalExpr(clause, econtext, isNull, &isDone);
998
999         /*
1000          * if the expression evaluates to null, then we just cascade the null
1001          * back to whoever called us.
1002          */
1003         if (*isNull)
1004                 return expr_value;
1005
1006         /*
1007          * evaluation of 'not' is simple.. expr is false, then return 'true'
1008          * and vice versa.
1009          */
1010         return BoolGetDatum(! DatumGetBool(expr_value));
1011 }
1012
1013 /* ----------------------------------------------------------------
1014  *              ExecEvalOr
1015  * ----------------------------------------------------------------
1016  */
1017 static Datum
1018 ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
1019 {
1020         List       *clauses;
1021         List       *clause;
1022         bool            isDone;
1023         bool            AnyNull;
1024         Datum           clause_value;
1025
1026         clauses = orExpr->args;
1027         AnyNull = false;
1028
1029         /*
1030          * If any of the clauses is TRUE, the OR result is TRUE regardless of
1031          * the states of the rest of the clauses, so we can stop evaluating
1032          * and return TRUE immediately.  If none are TRUE and one or more is
1033          * NULL, we return NULL; otherwise we return FALSE.  This makes sense
1034          * when you interpret NULL as "don't know": if we have a TRUE then the
1035          * OR is TRUE even if we aren't sure about some of the other inputs.
1036          * If all the known inputs are FALSE, but we have one or more "don't
1037          * knows", then we have to report that we "don't know" what the OR's
1038          * result should be --- perhaps one of the "don't knows" would have
1039          * been TRUE if we'd known its value.  Only when all the inputs are
1040          * known to be FALSE can we state confidently that the OR's result is
1041          * FALSE.
1042          */
1043         foreach(clause, clauses)
1044         {
1045
1046                 /*
1047                  * We don't iterate over sets in the quals, so pass in an isDone
1048                  * flag, but ignore it.
1049                  */
1050                 clause_value = ExecEvalExpr((Node *) lfirst(clause),
1051                                                                         econtext,
1052                                                                         isNull,
1053                                                                         &isDone);
1054
1055                 /*
1056                  * if we have a non-null true result, then return it.
1057                  */
1058                 if (*isNull)
1059                         AnyNull = true;         /* remember we got a null */
1060                 else if (DatumGetBool(clause_value))
1061                         return clause_value;
1062         }
1063
1064         /* AnyNull is true if at least one clause evaluated to NULL */
1065         *isNull = AnyNull;
1066         return BoolGetDatum(false);
1067 }
1068
1069 /* ----------------------------------------------------------------
1070  *              ExecEvalAnd
1071  * ----------------------------------------------------------------
1072  */
1073 static Datum
1074 ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull)
1075 {
1076         List       *clauses;
1077         List       *clause;
1078         bool            isDone;
1079         bool            AnyNull;
1080         Datum           clause_value;
1081
1082         clauses = andExpr->args;
1083         AnyNull = false;
1084
1085         /*
1086          * If any of the clauses is FALSE, the AND result is FALSE regardless
1087          * of the states of the rest of the clauses, so we can stop evaluating
1088          * and return FALSE immediately.  If none are FALSE and one or more is
1089          * NULL, we return NULL; otherwise we return TRUE.      This makes sense
1090          * when you interpret NULL as "don't know", using the same sort of
1091          * reasoning as for OR, above.
1092          */
1093         foreach(clause, clauses)
1094         {
1095
1096                 /*
1097                  * We don't iterate over sets in the quals, so pass in an isDone
1098                  * flag, but ignore it.
1099                  */
1100                 clause_value = ExecEvalExpr((Node *) lfirst(clause),
1101                                                                         econtext,
1102                                                                         isNull,
1103                                                                         &isDone);
1104
1105                 /*
1106                  * if we have a non-null false result, then return it.
1107                  */
1108                 if (*isNull)
1109                         AnyNull = true;         /* remember we got a null */
1110                 else if (! DatumGetBool(clause_value))
1111                         return clause_value;
1112         }
1113
1114         /* AnyNull is true if at least one clause evaluated to NULL */
1115         *isNull = AnyNull;
1116         return BoolGetDatum(!AnyNull);
1117 }
1118
1119 /* ----------------------------------------------------------------
1120  *              ExecEvalCase
1121  *
1122  *              Evaluate a CASE clause. Will have boolean expressions
1123  *              inside the WHEN clauses, and will have expressions
1124  *              for results.
1125  *              - thomas 1998-11-09
1126  * ----------------------------------------------------------------
1127  */
1128 static Datum
1129 ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull)
1130 {
1131         List       *clauses;
1132         List       *clause;
1133         Datum           clause_value;
1134         bool            isDone;
1135
1136         clauses = caseExpr->args;
1137
1138         /*
1139          * we evaluate each of the WHEN clauses in turn, as soon as one is
1140          * true we return the corresponding result. If none are true then we
1141          * return the value of the default clause, or NULL if there is none.
1142          */
1143         foreach(clause, clauses)
1144         {
1145                 CaseWhen   *wclause = lfirst(clause);
1146
1147                 /*
1148                  * We don't iterate over sets in the quals, so pass in an isDone
1149                  * flag, but ignore it.
1150                  */
1151                 clause_value = ExecEvalExpr(wclause->expr,
1152                                                                         econtext,
1153                                                                         isNull,
1154                                                                         &isDone);
1155
1156                 /*
1157                  * if we have a true test, then we return the result, since the
1158                  * case statement is satisfied.  A NULL result from the test is
1159                  * not considered true.
1160                  */
1161                 if (DatumGetBool(clause_value) && !*isNull)
1162                 {
1163                         return ExecEvalExpr(wclause->result,
1164                                                                 econtext,
1165                                                                 isNull,
1166                                                                 &isDone);
1167                 }
1168         }
1169
1170         if (caseExpr->defresult)
1171         {
1172                 return ExecEvalExpr(caseExpr->defresult,
1173                                                         econtext,
1174                                                         isNull,
1175                                                         &isDone);
1176         }
1177
1178         *isNull = true;
1179         return (Datum) 0;
1180 }
1181
1182 /* ----------------------------------------------------------------
1183  *              ExecEvalExpr
1184  *
1185  *              Recursively evaluate a targetlist or qualification expression.
1186  *
1187  *              The caller should already have switched into the temporary
1188  *              memory context econtext->ecxt_per_tuple_memory.  The convenience
1189  *              entry point ExecEvalExprSwitchContext() is provided for callers
1190  *              who don't prefer to do the switch in an outer loop.  We do not
1191  *              do the switch here because it'd be a waste of cycles during
1192  *              recursive entries to ExecEvalExpr().
1193  *
1194  *              This routine is an inner loop routine and must be as fast
1195  *              as possible.
1196  * ----------------------------------------------------------------
1197  */
1198 Datum
1199 ExecEvalExpr(Node *expression,
1200                          ExprContext *econtext,
1201                          bool *isNull,
1202                          bool *isDone)
1203 {
1204         Datum           retDatum;
1205
1206         /* Set default values for result flags: non-null, not a set result */
1207         *isNull = false;
1208         *isDone = true;
1209
1210         /* Is this still necessary?  Doubtful... */
1211         if (expression == NULL)
1212         {
1213                 *isNull = true;
1214                 return (Datum) 0;
1215         }
1216
1217         /*
1218          * here we dispatch the work to the appropriate type of function given
1219          * the type of our expression.
1220          */
1221         switch (nodeTag(expression))
1222         {
1223                 case T_Var:
1224                         retDatum = ExecEvalVar((Var *) expression, econtext, isNull);
1225                         break;
1226                 case T_Const:
1227                         {
1228                                 Const      *con = (Const *) expression;
1229
1230                                 retDatum = con->constvalue;
1231                                 *isNull = con->constisnull;
1232                                 break;
1233                         }
1234                 case T_Param:
1235                         retDatum = ExecEvalParam((Param *) expression, econtext, isNull);
1236                         break;
1237                 case T_Iter:
1238                         retDatum = ExecEvalIter((Iter *) expression,
1239                                                                         econtext,
1240                                                                         isNull,
1241                                                                         isDone);
1242                         break;
1243                 case T_Aggref:
1244                         retDatum = ExecEvalAggref((Aggref *) expression, econtext, isNull);
1245                         break;
1246                 case T_ArrayRef:
1247                         retDatum = ExecEvalArrayRef((ArrayRef *) expression,
1248                                                                                 econtext,
1249                                                                                 isNull,
1250                                                                                 isDone);
1251                         break;
1252                 case T_Expr:
1253                         {
1254                                 Expr       *expr = (Expr *) expression;
1255
1256                                 switch (expr->opType)
1257                                 {
1258                                         case OP_EXPR:
1259                                                 retDatum = ExecEvalOper(expr, econtext, isNull);
1260                                                 break;
1261                                         case FUNC_EXPR:
1262                                                 retDatum = ExecEvalFunc(expr, econtext,
1263                                                                                                 isNull, isDone);
1264                                                 break;
1265                                         case OR_EXPR:
1266                                                 retDatum = ExecEvalOr(expr, econtext, isNull);
1267                                                 break;
1268                                         case AND_EXPR:
1269                                                 retDatum = ExecEvalAnd(expr, econtext, isNull);
1270                                                 break;
1271                                         case NOT_EXPR:
1272                                                 retDatum = ExecEvalNot(expr, econtext, isNull);
1273                                                 break;
1274                                         case SUBPLAN_EXPR:
1275                                                 retDatum = ExecSubPlan((SubPlan *) expr->oper,
1276                                                                                            expr->args, econtext,
1277                                                                                            isNull);
1278                                                 break;
1279                                         default:
1280                                                 elog(ERROR, "ExecEvalExpr: unknown expression type %d",
1281                                                          expr->opType);
1282                                                 retDatum = 0;   /* keep compiler quiet */
1283                                                 break;
1284                                 }
1285                                 break;
1286                         }
1287                 case T_RelabelType:
1288                         retDatum = ExecEvalExpr(((RelabelType *) expression)->arg,
1289                                                                         econtext,
1290                                                                         isNull,
1291                                                                         isDone);
1292                         break;
1293                 case T_CaseExpr:
1294                         retDatum = ExecEvalCase((CaseExpr *) expression, econtext, isNull);
1295                         break;
1296
1297                 default:
1298                         elog(ERROR, "ExecEvalExpr: unknown expression type %d",
1299                                  nodeTag(expression));
1300                         retDatum = 0;           /* keep compiler quiet */
1301                         break;
1302         }
1303
1304         return retDatum;
1305 }       /* ExecEvalExpr() */
1306
1307
1308 /*
1309  * Same as above, but get into the right allocation context explicitly.
1310  */
1311 Datum
1312 ExecEvalExprSwitchContext(Node *expression,
1313                                                   ExprContext *econtext,
1314                                                   bool *isNull,
1315                                                   bool *isDone)
1316 {
1317         Datum           retDatum;
1318         MemoryContext oldContext;
1319
1320         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1321         retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
1322         MemoryContextSwitchTo(oldContext);
1323         return retDatum;
1324 }
1325
1326
1327 /* ----------------------------------------------------------------
1328  *                                       ExecQual / ExecTargetList / ExecProject
1329  * ----------------------------------------------------------------
1330  */
1331
1332 /* ----------------------------------------------------------------
1333  *              ExecQual
1334  *
1335  *              Evaluates a conjunctive boolean expression (qual list) and
1336  *              returns true iff none of the subexpressions are false.
1337  *              (We also return true if the list is empty.)
1338  *
1339  *      If some of the subexpressions yield NULL but none yield FALSE,
1340  *      then the result of the conjunction is NULL (ie, unknown)
1341  *      according to three-valued boolean logic.  In this case,
1342  *      we return the value specified by the "resultForNull" parameter.
1343  *
1344  *      Callers evaluating WHERE clauses should pass resultForNull=FALSE,
1345  *      since SQL specifies that tuples with null WHERE results do not
1346  *      get selected.  On the other hand, callers evaluating constraint
1347  *      conditions should pass resultForNull=TRUE, since SQL also specifies
1348  *      that NULL constraint conditions are not failures.
1349  *
1350  *      NOTE: it would not be correct to use this routine to evaluate an
1351  *      AND subclause of a boolean expression; for that purpose, a NULL
1352  *      result must be returned as NULL so that it can be properly treated
1353  *      in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
1354  *      This routine is only used in contexts where a complete expression
1355  *      is being evaluated and we know that NULL can be treated the same
1356  *      as one boolean result or the other.
1357  *
1358  * ----------------------------------------------------------------
1359  */
1360 bool
1361 ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
1362 {
1363         bool            result;
1364         MemoryContext oldContext;
1365         List       *qlist;
1366
1367         /*
1368          * debugging stuff
1369          */
1370         EV_printf("ExecQual: qual is ");
1371         EV_nodeDisplay(qual);
1372         EV_printf("\n");
1373
1374         IncrProcessed();
1375
1376         /*
1377          * Run in short-lived per-tuple context while computing expressions.
1378          */
1379         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1380
1381         /*
1382          * Evaluate the qual conditions one at a time.  If we find a FALSE
1383          * result, we can stop evaluating and return FALSE --- the AND result
1384          * must be FALSE.  Also, if we find a NULL result when resultForNull
1385          * is FALSE, we can stop and return FALSE --- the AND result must be
1386          * FALSE or NULL in that case, and the caller doesn't care which.
1387          *
1388          * If we get to the end of the list, we can return TRUE.  This will
1389          * happen when the AND result is indeed TRUE, or when the AND result
1390          * is NULL (one or more NULL subresult, with all the rest TRUE) and
1391          * the caller has specified resultForNull = TRUE.
1392          */
1393         result = true;
1394
1395         foreach(qlist, qual)
1396         {
1397                 Node       *clause = (Node *) lfirst(qlist);
1398                 Datum           expr_value;
1399                 bool            isNull;
1400                 bool            isDone;
1401
1402                 /*
1403                  * pass isDone, but ignore it.  We don't iterate over multiple
1404                  * returns in the qualifications.
1405                  */
1406                 expr_value = ExecEvalExpr(clause, econtext, &isNull, &isDone);
1407
1408                 if (isNull)
1409                 {
1410                         if (resultForNull == false)
1411                         {
1412                                 result = false; /* treat NULL as FALSE */
1413                                 break;
1414                         }
1415                 }
1416                 else
1417                 {
1418                         if (! DatumGetBool(expr_value))
1419                         {
1420                                 result = false; /* definitely FALSE */
1421                                 break;
1422                         }
1423                 }
1424         }
1425
1426         MemoryContextSwitchTo(oldContext);
1427
1428         return result;
1429 }
1430
1431 int
1432 ExecTargetListLength(List *targetlist)
1433 {
1434         int                     len;
1435         List       *tl;
1436         TargetEntry *curTle;
1437
1438         len = 0;
1439         foreach(tl, targetlist)
1440         {
1441                 curTle = lfirst(tl);
1442
1443                 if (curTle->resdom != NULL)
1444                         len++;
1445                 else
1446                         len += curTle->fjoin->fj_nNodes;
1447         }
1448         return len;
1449 }
1450
1451 /* ----------------------------------------------------------------
1452  *              ExecTargetList
1453  *
1454  *              Evaluates a targetlist with respect to the current
1455  *              expression context and return a tuple.
1456  * ----------------------------------------------------------------
1457  */
1458 static HeapTuple
1459 ExecTargetList(List *targetlist,
1460                            int nodomains,
1461                            TupleDesc targettype,
1462                            Datum *values,
1463                            ExprContext *econtext,
1464                            bool *isDone)
1465 {
1466         MemoryContext oldContext;
1467         char            nulls_array[64];
1468         bool            fjNullArray[64];
1469         bool            itemIsDoneArray[64];
1470         char       *null_head;
1471         bool       *fjIsNull;
1472         bool       *itemIsDone;
1473         List       *tl;
1474         TargetEntry *tle;
1475         Node       *expr;
1476         Resdom     *resdom;
1477         AttrNumber      resind;
1478         Datum           constvalue;
1479         HeapTuple       newTuple;
1480         bool            isNull;
1481         bool            haveDoneIters;
1482         static struct tupleDesc NullTupleDesc;          /* we assume this inits to
1483                                                                                                  * zeroes */
1484
1485         /*
1486          * debugging stuff
1487          */
1488         EV_printf("ExecTargetList: tl is ");
1489         EV_nodeDisplay(targetlist);
1490         EV_printf("\n");
1491
1492         /*
1493          * Run in short-lived per-tuple context while computing expressions.
1494          */
1495         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1496
1497         /*
1498          * There used to be some klugy and demonstrably broken code here that
1499          * special-cased the situation where targetlist == NIL.  Now we just
1500          * fall through and return an empty-but-valid tuple.  We do, however,
1501          * have to cope with the possibility that targettype is NULL ---
1502          * heap_formtuple won't like that, so pass a dummy descriptor with
1503          * natts = 0 to deal with it.
1504          */
1505         if (targettype == NULL)
1506                 targettype = &NullTupleDesc;
1507
1508         /*
1509          * allocate an array of char's to hold the "null" information only if
1510          * we have a really large targetlist.  otherwise we use the stack.
1511          *
1512          * We also allocate a bool array that is used to hold fjoin result state,
1513          * and another that holds the isDone status for each targetlist item.
1514          */
1515         if (nodomains > 64)
1516         {
1517                 null_head = (char *) palloc(nodomains + 1);
1518                 fjIsNull = (bool *) palloc(nodomains + 1);
1519                 itemIsDone = (bool *) palloc(nodomains + 1);
1520         }
1521         else
1522         {
1523                 null_head = &nulls_array[0];
1524                 fjIsNull = &fjNullArray[0];
1525                 itemIsDone = &itemIsDoneArray[0];
1526         }
1527
1528         /*
1529          * evaluate all the expressions in the target list
1530          */
1531
1532         *isDone = true;                         /* until proven otherwise */
1533         haveDoneIters = false;          /* any isDone Iter exprs in tlist? */
1534
1535         foreach(tl, targetlist)
1536         {
1537
1538                 /*
1539                  * remember, a target list is a list of lists:
1540                  *
1541                  * ((<resdom | fjoin> expr) (<resdom | fjoin> expr) ...)
1542                  *
1543                  * tl is a pointer to successive cdr's of the targetlist tle is a
1544                  * pointer to the target list entry in tl
1545                  */
1546                 tle = lfirst(tl);
1547
1548                 if (tle->resdom != NULL)
1549                 {
1550                         expr = tle->expr;
1551                         resdom = tle->resdom;
1552                         resind = resdom->resno - 1;
1553
1554                         constvalue = ExecEvalExpr(expr,
1555                                                                           econtext,
1556                                                                           &isNull,
1557                                                                           &itemIsDone[resind]);
1558
1559                         values[resind] = constvalue;
1560
1561                         if (!isNull)
1562                                 null_head[resind] = ' ';
1563                         else
1564                                 null_head[resind] = 'n';
1565
1566                         if (IsA(expr, Iter))
1567                         {
1568                                 if (itemIsDone[resind])
1569                                         haveDoneIters = true;
1570                                 else
1571                                         *isDone = false;        /* we have undone Iters in the
1572                                                                                  * list */
1573                         }
1574                 }
1575                 else
1576                 {
1577                         int                     curNode;
1578                         Resdom     *fjRes;
1579                         List       *fjTlist = (List *) tle->expr;
1580                         Fjoin      *fjNode = tle->fjoin;
1581                         int                     nNodes = fjNode->fj_nNodes;
1582                         DatumPtr        results = fjNode->fj_results;
1583
1584                         ExecEvalFjoin(tle, econtext, fjIsNull, isDone);
1585
1586                         /* this is probably wrong: */
1587                         if (*isDone)
1588                         {
1589                                 newTuple = NULL;
1590                                 goto exit;
1591                         }
1592
1593                         /*
1594                          * get the result from the inner node
1595                          */
1596                         fjRes = (Resdom *) fjNode->fj_innerNode;
1597                         resind = fjRes->resno - 1;
1598                         if (fjIsNull[0])
1599                                 null_head[resind] = 'n';
1600                         else
1601                         {
1602                                 null_head[resind] = ' ';
1603                                 values[resind] = results[0];
1604                         }
1605
1606                         /*
1607                          * Get results from all of the outer nodes
1608                          */
1609                         for (curNode = 1;
1610                                  curNode < nNodes;
1611                                  curNode++, fjTlist = lnext(fjTlist))
1612                         {
1613 #ifdef NOT_USED                                 /* what is this?? */
1614                                 Node       *outernode = lfirst(fjTlist);
1615
1616                                 fjRes = (Resdom *) outernode->iterexpr;
1617 #endif
1618                                 resind = fjRes->resno - 1;
1619                                 if (fjIsNull[curNode])
1620                                         null_head[resind] = 'n';
1621                                 else
1622                                 {
1623                                         null_head[resind] = ' ';
1624                                         values[resind] = results[curNode];
1625                                 }
1626                         }
1627                 }
1628         }
1629
1630         if (haveDoneIters)
1631         {
1632                 if (*isDone)
1633                 {
1634
1635                         /*
1636                          * all Iters are done, so return a null indicating tlist set
1637                          * expansion is complete.
1638                          */
1639                         newTuple = NULL;
1640                         goto exit;
1641                 }
1642                 else
1643                 {
1644
1645                         /*
1646                          * We have some done and some undone Iters.  Restart the done
1647                          * ones so that we can deliver a tuple (if possible).
1648                          *
1649                          * XXX this code is a crock, because it only works for Iters at
1650                          * the top level of tlist expressions, and doesn't even work
1651                          * right for them: you should get all possible combinations of
1652                          * Iter results, but you won't unless the numbers of values
1653                          * returned by each are relatively prime.  Should have a
1654                          * mechanism more like aggregate functions, where we make a
1655                          * list of all Iters contained in the tlist and cycle through
1656                          * their values in a methodical fashion.  To do someday; can't
1657                          * get excited about fixing a Berkeley feature that's not in
1658                          * SQL92.  (The only reason we're doing this much is that we
1659                          * have to be sure all the Iters are run to completion, or
1660                          * their subplan executors will have unreleased resources,
1661                          * e.g. pinned buffers...)
1662                          */
1663                         foreach(tl, targetlist)
1664                         {
1665                                 tle = lfirst(tl);
1666
1667                                 if (tle->resdom != NULL)
1668                                 {
1669                                         expr = tle->expr;
1670                                         resdom = tle->resdom;
1671                                         resind = resdom->resno - 1;
1672
1673                                         if (IsA(expr, Iter) &&itemIsDone[resind])
1674                                         {
1675                                                 constvalue = ExecEvalExpr(expr,
1676                                                                                                   econtext,
1677                                                                                                   &isNull,
1678                                                                                                   &itemIsDone[resind]);
1679                                                 if (itemIsDone[resind])
1680                                                 {
1681
1682                                                         /*
1683                                                          * Oh dear, this Iter is returning an empty
1684                                                          * set. Guess we can't make a tuple after all.
1685                                                          */
1686                                                         *isDone = true;
1687                                                         newTuple = NULL;
1688                                                         goto exit;
1689                                                 }
1690
1691                                                 values[resind] = constvalue;
1692
1693                                                 if (!isNull)
1694                                                         null_head[resind] = ' ';
1695                                                 else
1696                                                         null_head[resind] = 'n';
1697                                         }
1698                                 }
1699                         }
1700                 }
1701         }
1702
1703         /*
1704          * form the new result tuple (in the caller's memory context!)
1705          */
1706         MemoryContextSwitchTo(oldContext);
1707
1708         newTuple = (HeapTuple) heap_formtuple(targettype, values, null_head);
1709
1710 exit:
1711
1712         /*
1713          * free the status arrays if we palloc'd them
1714          */
1715         if (nodomains > 64)
1716         {
1717                 pfree(null_head);
1718                 pfree(fjIsNull);
1719                 pfree(itemIsDone);
1720         }
1721
1722         /* make sure we are in the right context if we did "goto exit" */
1723         MemoryContextSwitchTo(oldContext);
1724
1725         return newTuple;
1726 }
1727
1728 /* ----------------------------------------------------------------
1729  *              ExecProject
1730  *
1731  *              projects a tuple based in projection info and stores
1732  *              it in the specified tuple table slot.
1733  *
1734  *              Note: someday soon the executor can be extended to eliminate
1735  *                        redundant projections by storing pointers to datums
1736  *                        in the tuple table and then passing these around when
1737  *                        possible.  this should make things much quicker.
1738  *                        -cim 6/3/91
1739  * ----------------------------------------------------------------
1740  */
1741 TupleTableSlot *
1742 ExecProject(ProjectionInfo *projInfo, bool *isDone)
1743 {
1744         TupleTableSlot *slot;
1745         List       *targetlist;
1746         int                     len;
1747         TupleDesc       tupType;
1748         Datum      *tupValue;
1749         ExprContext *econtext;
1750         HeapTuple       newTuple;
1751
1752         /*
1753          * sanity checks
1754          */
1755         if (projInfo == NULL)
1756                 return (TupleTableSlot *) NULL;
1757
1758         /*
1759          * get the projection info we want
1760          */
1761         slot = projInfo->pi_slot;
1762         targetlist = projInfo->pi_targetlist;
1763         len = projInfo->pi_len;
1764         tupType = slot->ttc_tupleDescriptor;
1765
1766         tupValue = projInfo->pi_tupValue;
1767         econtext = projInfo->pi_exprContext;
1768
1769         /*
1770          * form a new (result) tuple
1771          */
1772         newTuple = ExecTargetList(targetlist,
1773                                                           len,
1774                                                           tupType,
1775                                                           tupValue,
1776                                                           econtext,
1777                                                           isDone);
1778
1779         /*
1780          * store the tuple in the projection slot and return the slot.
1781          */
1782         return (TupleTableSlot *)
1783                 ExecStoreTuple(newTuple,/* tuple to store */
1784                                            slot,        /* slot to store in */
1785                                            InvalidBuffer,       /* tuple has no buffer */
1786                                            true);
1787 }