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