1 /*-------------------------------------------------------------------------
4 * Routines to evaluate qualification and targetlist expressions
6 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.109 2002/11/15 02:50:06 momjian Exp $
13 *-------------------------------------------------------------------------
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
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.
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
37 #include "access/heapam.h"
38 #include "catalog/pg_type.h"
39 #include "executor/execdebug.h"
40 #include "executor/functions.h"
41 #include "executor/nodeSubplan.h"
42 #include "miscadmin.h"
43 #include "utils/array.h"
44 #include "utils/builtins.h"
45 #include "utils/fcache.h"
46 #include "utils/lsyscache.h"
49 /* static function decls */
50 static Datum ExecEvalAggref(Aggref *aggref, ExprContext *econtext,
52 static Datum ExecEvalArrayRef(ArrayRef *arrayRef, ExprContext *econtext,
53 bool *isNull, ExprDoneCond *isDone);
54 static Datum ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull);
55 static Datum ExecEvalOper(Expr *opClause, ExprContext *econtext,
56 bool *isNull, ExprDoneCond *isDone);
57 static Datum ExecEvalDistinct(Expr *opClause, ExprContext *econtext,
58 bool *isNull, ExprDoneCond *isDone);
59 static Datum ExecEvalFunc(Expr *funcClause, ExprContext *econtext,
60 bool *isNull, ExprDoneCond *isDone);
61 static ExprDoneCond ExecEvalFuncArgs(FunctionCallInfo fcinfo,
62 List *argList, ExprContext *econtext);
63 static Datum ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull);
64 static Datum ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull);
65 static Datum ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull);
66 static Datum ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext,
67 bool *isNull, ExprDoneCond *isDone);
68 static Datum ExecEvalNullTest(NullTest *ntest, ExprContext *econtext,
69 bool *isNull, ExprDoneCond *isDone);
70 static Datum ExecEvalBooleanTest(BooleanTest *btest, ExprContext *econtext,
71 bool *isNull, ExprDoneCond *isDone);
72 static Datum ExecEvalConstraintTest(ConstraintTest *constraint,
73 ExprContext *econtext,
74 bool *isNull, ExprDoneCond *isDone);
75 static Datum ExecEvalConstraintTestValue(ConstraintTestValue *conVal,
76 ExprContext *econtext,
77 bool *isNull, ExprDoneCond *isDone);
83 * This function takes an ArrayRef and returns the extracted Datum
84 * if it's a simple reference, or the modified array value if it's
85 * an array assignment (i.e., array element or slice insertion).
87 * NOTE: if we get a NULL result from a subexpression, we return NULL when
88 * it's an array reference, or the unmodified source array when it's an
89 * array assignment. This may seem peculiar, but if we return NULL (as was
90 * done in versions up through 7.0) then an assignment like
91 * UPDATE table SET arrayfield[4] = NULL
92 * will result in setting the whole array to NULL, which is certainly not
93 * very desirable. By returning the source array we make the assignment
94 * into a no-op, instead. (Eventually we need to redesign arrays so that
95 * individual elements can be NULL, but for now, let's try to protect users
96 * from shooting themselves in the foot.)
98 * NOTE: we deliberately refrain from applying DatumGetArrayTypeP() here,
99 * even though that might seem natural, because this code needs to support
100 * both varlena arrays and fixed-length array types. DatumGetArrayTypeP()
101 * only works for the varlena kind. The routines we call in arrayfuncs.c
102 * have to know the difference (that's what they need refattrlength for).
106 ExecEvalArrayRef(ArrayRef *arrayRef,
107 ExprContext *econtext,
109 ExprDoneCond *isDone)
111 ArrayType *array_source;
112 ArrayType *resultArray;
113 bool isAssignment = (arrayRef->refassgnexpr != NULL);
121 if (arrayRef->refexpr != NULL)
123 array_source = (ArrayType *)
124 DatumGetPointer(ExecEvalExpr(arrayRef->refexpr,
130 * If refexpr yields NULL, result is always NULL, for now anyway.
131 * (This means you cannot assign to an element or slice of an
132 * array that's NULL; it'll just stay NULL.)
140 * Empty refexpr indicates we are doing an INSERT into an array
141 * column. For now, we just take the refassgnexpr (which the
142 * parser will have ensured is an array value) and return it
143 * as-is, ignoring any subscripts that may have been supplied in
144 * the INSERT column list. This is a kluge, but it's not real
145 * clear what the semantics ought to be...
150 foreach(elt, arrayRef->refupperindexpr)
153 elog(ERROR, "ExecEvalArrayRef: can only handle %d dimensions",
156 upper.indx[i++] = DatumGetInt32(ExecEvalExpr((Node *) lfirst(elt),
160 /* If any index expr yields NULL, result is NULL or source array */
163 if (!isAssignment || array_source == NULL)
166 return PointerGetDatum(array_source);
170 if (arrayRef->reflowerindexpr != NIL)
172 foreach(elt, arrayRef->reflowerindexpr)
175 elog(ERROR, "ExecEvalArrayRef: can only handle %d dimensions",
178 lower.indx[j++] = DatumGetInt32(ExecEvalExpr((Node *) lfirst(elt),
184 * If any index expr yields NULL, result is NULL or source
189 if (!isAssignment || array_source == NULL)
192 return PointerGetDatum(array_source);
197 "ExecEvalArrayRef: upper and lower indices mismatch");
205 Datum sourceData = ExecEvalExpr(arrayRef->refassgnexpr,
211 * For now, can't cope with inserting NULL into an array, so make
212 * it a no-op per discussion above...
216 if (array_source == NULL)
219 return PointerGetDatum(array_source);
222 if (array_source == NULL)
223 return sourceData; /* XXX do something else? */
226 resultArray = array_set(array_source, i,
229 arrayRef->refattrlength,
230 arrayRef->refelemlength,
231 arrayRef->refelembyval,
232 arrayRef->refelemalign,
235 resultArray = array_set_slice(array_source, i,
236 upper.indx, lower.indx,
237 (ArrayType *) DatumGetPointer(sourceData),
238 arrayRef->refattrlength,
239 arrayRef->refelemlength,
240 arrayRef->refelembyval,
241 arrayRef->refelemalign,
243 return PointerGetDatum(resultArray);
247 return array_ref(array_source, i, upper.indx,
248 arrayRef->refattrlength,
249 arrayRef->refelemlength,
250 arrayRef->refelembyval,
251 arrayRef->refelemalign,
255 resultArray = array_get_slice(array_source, i,
256 upper.indx, lower.indx,
257 arrayRef->refattrlength,
258 arrayRef->refelemlength,
259 arrayRef->refelembyval,
260 arrayRef->refelemalign,
262 return PointerGetDatum(resultArray);
267 /* ----------------------------------------------------------------
270 * Returns a Datum whose value is the value of the precomputed
271 * aggregate found in the given expression context.
272 * ----------------------------------------------------------------
275 ExecEvalAggref(Aggref *aggref, ExprContext *econtext, bool *isNull)
277 if (econtext->ecxt_aggvalues == NULL) /* safety check */
278 elog(ERROR, "ExecEvalAggref: no aggregates in this expression context");
280 *isNull = econtext->ecxt_aggnulls[aggref->aggno];
281 return econtext->ecxt_aggvalues[aggref->aggno];
284 /* ----------------------------------------------------------------
287 * Returns a Datum whose value is the value of a range
288 * variable with respect to given expression context.
291 * As an entry condition, we expect that the datatype the
292 * plan expects to get (as told by our "variable" argument) is in
293 * fact the datatype of the attribute the plan says to fetch (as
294 * seen in the current context, identified by our "econtext"
297 * If we fetch a Type A attribute and Caller treats it as if it
298 * were Type B, there will be undefined results (e.g. crash).
299 * One way these might mismatch now is that we're accessing a
300 * catalog class and the type information in the pg_attribute
301 * class does not match the hardcoded pg_attribute information
302 * (in pg_attribute.h) for the class in question.
304 * We have an Assert to make sure this entry condition is met.
306 * ---------------------------------------------------------------- */
308 ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
311 TupleTableSlot *slot;
314 TupleDesc tuple_type;
317 * get the slot we want
319 switch (variable->varno)
321 case INNER: /* get the tuple from the inner node */
322 slot = econtext->ecxt_innertuple;
325 case OUTER: /* get the tuple from the outer node */
326 slot = econtext->ecxt_outertuple;
329 default: /* get the tuple from the relation being
331 slot = econtext->ecxt_scantuple;
336 * extract tuple information from the slot
338 heapTuple = slot->val;
339 tuple_type = slot->ttc_tupleDescriptor;
341 attnum = variable->varattno;
343 /* (See prolog for explanation of this Assert) */
344 Assert(attnum <= 0 ||
345 (attnum - 1 <= tuple_type->natts - 1 &&
346 tuple_type->attrs[attnum - 1] != NULL &&
347 variable->vartype == tuple_type->attrs[attnum - 1]->atttypid));
350 * If the attribute number is invalid, then we are supposed to return
351 * the entire tuple; we give back a whole slot so that callers know
352 * what the tuple looks like.
354 * XXX this is a horrid crock: since the pointer to the slot might live
355 * longer than the current evaluation context, we are forced to copy
356 * the tuple and slot into a long-lived context --- we use
357 * TransactionCommandContext which should be safe enough. This
358 * represents a serious memory leak if many such tuples are processed
359 * in one command, however. We ought to redesign the representation
360 * of whole-tuple datums so that this is not necessary.
362 * We assume it's OK to point to the existing tupleDescriptor, rather
363 * than copy that too.
365 if (attnum == InvalidAttrNumber)
367 MemoryContext oldContext;
368 TupleTableSlot *tempSlot;
371 oldContext = MemoryContextSwitchTo(TransactionCommandContext);
372 tempSlot = MakeTupleTableSlot();
373 tup = heap_copytuple(heapTuple);
374 ExecStoreTuple(tup, tempSlot, InvalidBuffer, true);
375 ExecSetSlotDescriptor(tempSlot, tuple_type, false);
376 MemoryContextSwitchTo(oldContext);
377 return PointerGetDatum(tempSlot);
380 result = heap_getattr(heapTuple, /* tuple containing attribute */
381 attnum, /* attribute number of desired
383 tuple_type, /* tuple descriptor of tuple */
384 isNull); /* return: is attribute null? */
389 /* ----------------------------------------------------------------
392 * Returns the value of a parameter. A param node contains
393 * something like ($.name) and the expression context contains
394 * the current parameter bindings (name = "sam") (age = 34)...
395 * so our job is to replace the param node with the datum
396 * containing the appropriate information ("sam").
398 * Q: if we have a parameter ($.foo) without a binding, i.e.
399 * there is no (foo = xxx) in the parameter list info,
400 * is this a fatal error or should this be a "not available"
401 * (in which case we shoud return a Const node with the
402 * isnull flag) ? -cim 10/13/89
404 * Minor modification: Param nodes now have an extra field,
405 * `paramkind' which specifies the type of parameter
406 * (see params.h). So while searching the paramList for
407 * a paramname/value pair, we have also to check for `kind'.
409 * NOTE: The last entry in `paramList' is always an
410 * entry with kind == PARAM_INVALID.
411 * ----------------------------------------------------------------
414 ExecEvalParam(Param *expression, ExprContext *econtext, bool *isNull)
416 char *thisParameterName;
417 int thisParameterKind = expression->paramkind;
418 AttrNumber thisParameterId = expression->paramid;
420 ParamListInfo paramList;
422 if (thisParameterKind == PARAM_EXEC)
426 prm = &(econtext->ecxt_param_exec_vals[thisParameterId]);
427 if (prm->execPlan != NULL)
429 ExecSetParamPlan(prm->execPlan, econtext);
430 /* ExecSetParamPlan should have processed this param... */
431 Assert(prm->execPlan == NULL);
433 *isNull = prm->isnull;
437 thisParameterName = expression->paramname;
438 paramList = econtext->ecxt_param_list_info;
443 * search the list with the parameter info to find a matching name. An
444 * entry with an InvalidName denotes the last element in the array.
447 if (paramList != NULL)
450 * search for an entry in 'paramList' that matches the
453 while (paramList->kind != PARAM_INVALID && !matchFound)
455 switch (thisParameterKind)
458 if (thisParameterKind == paramList->kind &&
459 strcmp(paramList->name, thisParameterName) == 0)
463 if (thisParameterKind == paramList->kind &&
464 paramList->id == thisParameterId)
469 if (thisParameterKind == paramList->kind &&
470 paramList->id == thisParameterId)
477 if (strcmp(paramList->name, thisParameterName) != 0)
480 "ExecEvalParam: new/old params with same id & diff names");
487 * oops! this is not supposed to happen!
489 elog(ERROR, "ExecEvalParam: invalid paramkind %d",
500 * ooops! we couldn't find this parameter in the parameter list.
503 elog(ERROR, "ExecEvalParam: Unknown value for parameter %s",
510 *isNull = paramList->isnull;
511 return paramList->value;
515 /* ----------------------------------------------------------------
516 * ExecEvalOper / ExecEvalFunc support routines
517 * ----------------------------------------------------------------
524 * These are functions which return the value of the
525 * named attribute out of the tuple from the arg slot. User defined
526 * C functions which take a tuple as an argument are expected
527 * to use this. Ex: overpaid(EMP) might call GetAttributeByNum().
530 GetAttributeByNum(TupleTableSlot *slot,
536 if (!AttributeNumberIsValid(attrno))
537 elog(ERROR, "GetAttributeByNum: Invalid attribute number");
539 if (!AttrNumberIsForUserDefinedAttr(attrno))
540 elog(ERROR, "GetAttributeByNum: cannot access system attributes here");
542 if (isNull == (bool *) NULL)
543 elog(ERROR, "GetAttributeByNum: a NULL isNull flag was passed");
551 retval = heap_getattr(slot->val,
553 slot->ttc_tupleDescriptor,
562 GetAttributeByName(TupleTableSlot *slot, char *attname, bool *isNull)
571 elog(ERROR, "GetAttributeByName: Invalid attribute name");
573 if (isNull == (bool *) NULL)
574 elog(ERROR, "GetAttributeByName: a NULL isNull flag was passed");
582 tupdesc = slot->ttc_tupleDescriptor;
583 natts = slot->val->t_data->t_natts;
585 attrno = InvalidAttrNumber;
586 for (i = 0; i < tupdesc->natts; i++)
588 if (namestrcmp(&(tupdesc->attrs[i]->attname), attname) == 0)
590 attrno = tupdesc->attrs[i]->attnum;
595 if (attrno == InvalidAttrNumber)
596 elog(ERROR, "GetAttributeByName: attribute %s not found", attname);
598 retval = heap_getattr(slot->val,
609 * Evaluate arguments for a function.
612 ExecEvalFuncArgs(FunctionCallInfo fcinfo,
614 ExprContext *econtext)
616 ExprDoneCond argIsDone;
620 argIsDone = ExprSingleResult; /* default assumption */
623 foreach(arg, argList)
625 ExprDoneCond thisArgIsDone;
627 fcinfo->arg[i] = ExecEvalExpr((Node *) lfirst(arg),
632 if (thisArgIsDone != ExprSingleResult)
635 * We allow only one argument to have a set value; we'd need
636 * much more complexity to keep track of multiple set
637 * arguments (cf. ExecTargetList) and it doesn't seem worth
640 if (argIsDone != ExprSingleResult)
641 elog(ERROR, "Functions and operators can take only one set argument");
642 argIsDone = thisArgIsDone;
653 * ExecMakeFunctionResult
655 * Evaluate the arguments to a function and then the function itself.
658 ExecMakeFunctionResult(FunctionCachePtr fcache,
660 ExprContext *econtext,
662 ExprDoneCond *isDone)
665 FunctionCallInfoData fcinfo;
666 ReturnSetInfo rsinfo; /* for functions returning sets */
667 ExprDoneCond argDone;
672 * arguments is a list of expressions to evaluate before passing to
673 * the function manager. We skip the evaluation if it was already
674 * done in the previous call (ie, we are continuing the evaluation of
675 * a set-valued function). Otherwise, collect the current argument
676 * values into fcinfo.
678 if (!fcache->setArgsValid)
680 /* Need to prep callinfo structure */
681 MemSet(&fcinfo, 0, sizeof(fcinfo));
682 fcinfo.flinfo = &(fcache->func);
683 argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);
684 if (argDone == ExprEndResult)
686 /* input is an empty set, so return an empty set. */
689 *isDone = ExprEndResult;
691 elog(ERROR, "Set-valued function called in context that cannot accept a set");
694 hasSetArg = (argDone != ExprSingleResult);
698 /* Copy callinfo from previous evaluation */
699 memcpy(&fcinfo, &fcache->setArgs, sizeof(fcinfo));
700 hasSetArg = fcache->setHasSetArg;
701 /* Reset flag (we may set it again below) */
702 fcache->setArgsValid = false;
706 * If function returns set, prepare a resultinfo node for
709 if (fcache->func.fn_retset)
711 fcinfo.resultinfo = (Node *) &rsinfo;
712 rsinfo.type = T_ReturnSetInfo;
713 rsinfo.econtext = econtext;
714 rsinfo.expectedDesc = NULL;
715 rsinfo.allowedModes = (int) SFRM_ValuePerCall;
716 rsinfo.returnMode = SFRM_ValuePerCall;
717 /* isDone is filled below */
718 rsinfo.setResult = NULL;
719 rsinfo.setDesc = NULL;
723 * now return the value gotten by calling the function manager,
724 * passing the function the evaluated parameter values.
726 if (fcache->func.fn_retset || hasSetArg)
729 * We need to return a set result. Complain if caller not ready
733 elog(ERROR, "Set-valued function called in context that cannot accept a set");
736 * This loop handles the situation where we have both a set
737 * argument and a set-valued function. Once we have exhausted the
738 * function's value(s) for a particular argument value, we have to
739 * get the next argument value and start the function over again.
740 * We might have to do it more than once, if the function produces
741 * an empty result set for a particular input value.
746 * If function is strict, and there are any NULL arguments,
747 * skip calling the function (at least for this set of args).
751 if (fcache->func.fn_strict)
753 for (i = 0; i < fcinfo.nargs; i++)
755 if (fcinfo.argnull[i])
765 fcinfo.isnull = false;
766 rsinfo.isDone = ExprSingleResult;
767 result = FunctionCallInvoke(&fcinfo);
768 *isNull = fcinfo.isnull;
769 *isDone = rsinfo.isDone;
775 *isDone = ExprEndResult;
778 if (*isDone != ExprEndResult)
781 * Got a result from current argument. If function itself
782 * returns set, save the current argument values to re-use
785 if (fcache->func.fn_retset)
787 memcpy(&fcache->setArgs, &fcinfo, sizeof(fcinfo));
788 fcache->setHasSetArg = hasSetArg;
789 fcache->setArgsValid = true;
793 * Make sure we say we are returning a set, even if the
794 * function itself doesn't return sets.
796 *isDone = ExprMultipleResult;
800 /* Else, done with this argument */
802 break; /* input not a set, so done */
804 /* Re-eval args to get the next element of the input set */
805 argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);
807 if (argDone != ExprMultipleResult)
809 /* End of argument set, so we're done. */
811 *isDone = ExprEndResult;
817 * If we reach here, loop around to run the function on the
825 * Non-set case: much easier.
827 * If function is strict, and there are any NULL arguments, skip
828 * calling the function and return NULL.
830 if (fcache->func.fn_strict)
832 for (i = 0; i < fcinfo.nargs; i++)
834 if (fcinfo.argnull[i])
841 fcinfo.isnull = false;
842 result = FunctionCallInvoke(&fcinfo);
843 *isNull = fcinfo.isnull;
851 * ExecMakeTableFunctionResult
853 * Evaluate a table function, producing a materialized result in a Tuplestore
854 * object. (If function returns an empty set, we just return NULL instead.)
857 ExecMakeTableFunctionResult(Expr *funcexpr,
858 ExprContext *econtext,
859 TupleDesc expectedDesc,
860 TupleDesc *returnDesc)
862 Tuplestorestate *tupstore = NULL;
863 TupleDesc tupdesc = NULL;
866 FunctionCachePtr fcache;
867 FunctionCallInfoData fcinfo;
868 ReturnSetInfo rsinfo;
869 ExprDoneCond argDone;
870 MemoryContext callerContext;
871 MemoryContext oldcontext;
872 TupleTableSlot *slot;
873 bool first_time = true;
874 bool returnsTuple = false;
876 /* Extract data from function-call expression node */
877 if (!funcexpr || !IsA(funcexpr, Expr) ||funcexpr->opType != FUNC_EXPR)
878 elog(ERROR, "ExecMakeTableFunctionResult: expression is not a function call");
879 func = (Func *) funcexpr->oper;
880 argList = funcexpr->args;
883 * get the fcache from the Func node. If it is NULL, then initialize
886 fcache = func->func_fcache;
889 fcache = init_fcache(func->funcid, length(argList),
890 econtext->ecxt_per_query_memory);
891 func->func_fcache = fcache;
895 * Evaluate the function's argument list.
897 * Note: ideally, we'd do this in the per-tuple context, but then the
898 * argument values would disappear when we reset the context in the
899 * inner loop. So do it in caller context. Perhaps we should make a
900 * separate context just to hold the evaluated arguments?
902 MemSet(&fcinfo, 0, sizeof(fcinfo));
903 fcinfo.flinfo = &(fcache->func);
904 argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
905 /* We don't allow sets in the arguments of the table function */
906 if (argDone != ExprSingleResult)
907 elog(ERROR, "Set-valued function called in context that cannot accept a set");
910 * If function is strict, and there are any NULL arguments, skip
911 * calling the function and return NULL (actually an empty set).
913 if (fcache->func.fn_strict)
917 for (i = 0; i < fcinfo.nargs; i++)
919 if (fcinfo.argnull[i])
928 * Prepare a resultinfo node for communication. We always do this
929 * even if not expecting a set result, so that we can pass
932 fcinfo.resultinfo = (Node *) &rsinfo;
933 rsinfo.type = T_ReturnSetInfo;
934 rsinfo.econtext = econtext;
935 rsinfo.expectedDesc = expectedDesc;
936 rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
937 rsinfo.returnMode = SFRM_ValuePerCall;
938 /* isDone is filled below */
939 rsinfo.setResult = NULL;
940 rsinfo.setDesc = NULL;
943 * Switch to short-lived context for calling the function.
945 callerContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
948 * Loop to handle the ValuePerCall protocol.
956 * reset per-tuple memory context before each call of the
957 * function. This cleans up any local memory the function may leak
960 ResetExprContext(econtext);
962 /* Call the function one time */
963 fcinfo.isnull = false;
964 rsinfo.isDone = ExprSingleResult;
965 result = FunctionCallInvoke(&fcinfo);
967 /* Which protocol does function want to use? */
968 if (rsinfo.returnMode == SFRM_ValuePerCall)
971 * Check for end of result set.
973 * Note: if function returns an empty set, we don't build a
974 * tupdesc or tuplestore (since we can't get a tupdesc in the
975 * function-returning-tuple case)
977 if (rsinfo.isDone == ExprEndResult)
981 * If first time through, build tupdesc and tuplestore for
986 Oid funcrettype = funcexpr->typeOid;
988 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
989 if (funcrettype == RECORDOID ||
990 get_typtype(funcrettype) == 'c')
993 * Composite type, so function should have returned a
994 * TupleTableSlot; use its descriptor
996 slot = (TupleTableSlot *) DatumGetPointer(result);
997 if (fcinfo.isnull || !slot || !IsA(slot, TupleTableSlot) ||
998 !slot->ttc_tupleDescriptor)
999 elog(ERROR, "ExecMakeTableFunctionResult: Invalid result from function returning tuple");
1000 tupdesc = CreateTupleDescCopy(slot->ttc_tupleDescriptor);
1001 returnsTuple = true;
1006 * Scalar type, so make a single-column descriptor
1008 tupdesc = CreateTemplateTupleDesc(1, false);
1009 TupleDescInitEntry(tupdesc,
1017 tupstore = tuplestore_begin_heap(true, /* randomAccess */
1019 MemoryContextSwitchTo(oldcontext);
1020 rsinfo.setResult = tupstore;
1021 rsinfo.setDesc = tupdesc;
1025 * Store current resultset item.
1029 slot = (TupleTableSlot *) DatumGetPointer(result);
1030 if (fcinfo.isnull || !slot || !IsA(slot, TupleTableSlot) ||
1032 elog(ERROR, "ExecMakeTableFunctionResult: Invalid result from function returning tuple");
1039 nullflag = fcinfo.isnull ? 'n' : ' ';
1040 tuple = heap_formtuple(tupdesc, &result, &nullflag);
1043 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1044 tuplestore_puttuple(tupstore, tuple);
1045 MemoryContextSwitchTo(oldcontext);
1050 if (rsinfo.isDone != ExprMultipleResult)
1053 else if (rsinfo.returnMode == SFRM_Materialize)
1055 /* check we're on the same page as the function author */
1056 if (!first_time || rsinfo.isDone != ExprSingleResult)
1057 elog(ERROR, "ExecMakeTableFunctionResult: Materialize-mode protocol not followed");
1058 /* Done evaluating the set result */
1062 elog(ERROR, "ExecMakeTableFunctionResult: unknown returnMode %d",
1063 (int) rsinfo.returnMode);
1068 /* If we have a locally-created tupstore, close it up */
1071 MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1072 tuplestore_donestoring(tupstore);
1075 MemoryContextSwitchTo(callerContext);
1077 /* The returned pointers are those in rsinfo */
1078 *returnDesc = rsinfo.setDesc;
1079 return rsinfo.setResult;
1083 /* ----------------------------------------------------------------
1088 * Evaluate the functional result of a list of arguments by calling the
1090 * ----------------------------------------------------------------
1093 /* ----------------------------------------------------------------
1095 * ----------------------------------------------------------------
1098 ExecEvalOper(Expr *opClause,
1099 ExprContext *econtext,
1101 ExprDoneCond *isDone)
1105 FunctionCachePtr fcache;
1108 * we extract the oid of the function associated with the op and then
1109 * pass the work onto ExecMakeFunctionResult which evaluates the
1110 * arguments and returns the result of calling the function on the
1111 * evaluated arguments.
1113 op = (Oper *) opClause->oper;
1114 argList = opClause->args;
1117 * get the fcache from the Oper node. If it is NULL, then initialize
1120 fcache = op->op_fcache;
1123 fcache = init_fcache(op->opid, length(argList),
1124 econtext->ecxt_per_query_memory);
1125 op->op_fcache = fcache;
1128 return ExecMakeFunctionResult(fcache, argList, econtext,
1132 /* ----------------------------------------------------------------
1134 * ----------------------------------------------------------------
1138 ExecEvalFunc(Expr *funcClause,
1139 ExprContext *econtext,
1141 ExprDoneCond *isDone)
1145 FunctionCachePtr fcache;
1148 * we extract the oid of the function associated with the func node
1149 * and then pass the work onto ExecMakeFunctionResult which evaluates
1150 * the arguments and returns the result of calling the function on the
1151 * evaluated arguments.
1153 * this is nearly identical to the ExecEvalOper code.
1155 func = (Func *) funcClause->oper;
1156 argList = funcClause->args;
1159 * get the fcache from the Func node. If it is NULL, then initialize
1162 fcache = func->func_fcache;
1165 fcache = init_fcache(func->funcid, length(argList),
1166 econtext->ecxt_per_query_memory);
1167 func->func_fcache = fcache;
1170 return ExecMakeFunctionResult(fcache, argList, econtext,
1174 /* ----------------------------------------------------------------
1177 * IS DISTINCT FROM must evaluate arguments to determine whether
1178 * they are NULL; if either is NULL then the result is already
1179 * known. If neither is NULL, then proceed to evaluate the
1180 * function. Note that this is *always* derived from the equals
1181 * operator, but since we've already evaluated the arguments
1182 * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
1183 * ----------------------------------------------------------------
1186 ExecEvalDistinct(Expr *opClause,
1187 ExprContext *econtext,
1189 ExprDoneCond *isDone)
1192 FunctionCachePtr fcache;
1193 FunctionCallInfoData fcinfo;
1194 ExprDoneCond argDone;
1199 * we extract the oid of the function associated with the op and then
1200 * pass the work onto ExecMakeFunctionResult which evaluates the
1201 * arguments and returns the result of calling the function on the
1202 * evaluated arguments.
1204 op = (Oper *) opClause->oper;
1205 argList = opClause->args;
1208 * get the fcache from the Oper node. If it is NULL, then initialize
1211 fcache = op->op_fcache;
1214 fcache = init_fcache(op->opid, length(argList),
1215 econtext->ecxt_per_query_memory);
1216 op->op_fcache = fcache;
1218 Assert(fcache->func.fn_retset == FALSE);
1220 /* Need to prep callinfo structure */
1221 MemSet(&fcinfo, 0, sizeof(fcinfo));
1222 fcinfo.flinfo = &(fcache->func);
1223 argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
1224 Assert(fcinfo.nargs == 2);
1226 if (fcinfo.argnull[0] && fcinfo.argnull[1])
1228 /* Both NULL? Then is not distinct... */
1231 else if (fcinfo.argnull[0] || fcinfo.argnull[1])
1233 /* One is NULL? Then is distinct... */
1238 fcinfo.isnull = false;
1239 result = FunctionCallInvoke(&fcinfo);
1240 *isNull = fcinfo.isnull;
1242 result = (!DatumGetBool(result));
1245 return BoolGetDatum(result);
1248 /* ----------------------------------------------------------------
1253 * Evaluate boolean expressions. Evaluation of 'or' is
1254 * short-circuited when the first true (or null) value is found.
1256 * The query planner reformulates clause expressions in the
1257 * qualification to conjunctive normal form. If we ever get
1258 * an AND to evaluate, we can be sure that it's not a top-level
1259 * clause in the qualification, but appears lower (as a function
1260 * argument, for example), or in the target list. Not that you
1261 * need to know this, mind you...
1262 * ----------------------------------------------------------------
1265 ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull)
1270 clause = lfirst(notclause->args);
1272 expr_value = ExecEvalExpr(clause, econtext, isNull, NULL);
1275 * if the expression evaluates to null, then we just cascade the null
1276 * back to whoever called us.
1282 * evaluation of 'not' is simple.. expr is false, then return 'true'
1285 return BoolGetDatum(!DatumGetBool(expr_value));
1288 /* ----------------------------------------------------------------
1290 * ----------------------------------------------------------------
1293 ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
1300 clauses = orExpr->args;
1304 * If any of the clauses is TRUE, the OR result is TRUE regardless of
1305 * the states of the rest of the clauses, so we can stop evaluating
1306 * and return TRUE immediately. If none are TRUE and one or more is
1307 * NULL, we return NULL; otherwise we return FALSE. This makes sense
1308 * when you interpret NULL as "don't know": if we have a TRUE then the
1309 * OR is TRUE even if we aren't sure about some of the other inputs.
1310 * If all the known inputs are FALSE, but we have one or more "don't
1311 * knows", then we have to report that we "don't know" what the OR's
1312 * result should be --- perhaps one of the "don't knows" would have
1313 * been TRUE if we'd known its value. Only when all the inputs are
1314 * known to be FALSE can we state confidently that the OR's result is
1317 foreach(clause, clauses)
1319 clause_value = ExecEvalExpr((Node *) lfirst(clause),
1320 econtext, isNull, NULL);
1323 * if we have a non-null true result, then return it.
1326 AnyNull = true; /* remember we got a null */
1327 else if (DatumGetBool(clause_value))
1328 return clause_value;
1331 /* AnyNull is true if at least one clause evaluated to NULL */
1333 return BoolGetDatum(false);
1336 /* ----------------------------------------------------------------
1338 * ----------------------------------------------------------------
1341 ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull)
1348 clauses = andExpr->args;
1352 * If any of the clauses is FALSE, the AND result is FALSE regardless
1353 * of the states of the rest of the clauses, so we can stop evaluating
1354 * and return FALSE immediately. If none are FALSE and one or more is
1355 * NULL, we return NULL; otherwise we return TRUE. This makes sense
1356 * when you interpret NULL as "don't know", using the same sort of
1357 * reasoning as for OR, above.
1359 foreach(clause, clauses)
1361 clause_value = ExecEvalExpr((Node *) lfirst(clause),
1362 econtext, isNull, NULL);
1365 * if we have a non-null false result, then return it.
1368 AnyNull = true; /* remember we got a null */
1369 else if (!DatumGetBool(clause_value))
1370 return clause_value;
1373 /* AnyNull is true if at least one clause evaluated to NULL */
1375 return BoolGetDatum(!AnyNull);
1378 /* ----------------------------------------------------------------
1381 * Evaluate a CASE clause. Will have boolean expressions
1382 * inside the WHEN clauses, and will have expressions
1384 * - thomas 1998-11-09
1385 * ----------------------------------------------------------------
1388 ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext,
1389 bool *isNull, ExprDoneCond *isDone)
1395 clauses = caseExpr->args;
1398 * we evaluate each of the WHEN clauses in turn, as soon as one is
1399 * true we return the corresponding result. If none are true then we
1400 * return the value of the default clause, or NULL if there is none.
1402 foreach(clause, clauses)
1404 CaseWhen *wclause = lfirst(clause);
1406 clause_value = ExecEvalExpr(wclause->expr,
1412 * if we have a true test, then we return the result, since the
1413 * case statement is satisfied. A NULL result from the test is
1414 * not considered true.
1416 if (DatumGetBool(clause_value) && !*isNull)
1418 return ExecEvalExpr(wclause->result,
1425 if (caseExpr->defresult)
1427 return ExecEvalExpr(caseExpr->defresult,
1437 /* ----------------------------------------------------------------
1440 * Evaluate a NullTest node.
1441 * ----------------------------------------------------------------
1444 ExecEvalNullTest(NullTest *ntest,
1445 ExprContext *econtext,
1447 ExprDoneCond *isDone)
1451 result = ExecEvalExpr(ntest->arg, econtext, isNull, isDone);
1452 switch (ntest->nulltesttype)
1458 return BoolGetDatum(true);
1461 return BoolGetDatum(false);
1466 return BoolGetDatum(false);
1469 return BoolGetDatum(true);
1471 elog(ERROR, "ExecEvalNullTest: unexpected nulltesttype %d",
1472 (int) ntest->nulltesttype);
1473 return (Datum) 0; /* keep compiler quiet */
1477 /* ----------------------------------------------------------------
1478 * ExecEvalBooleanTest
1480 * Evaluate a BooleanTest node.
1481 * ----------------------------------------------------------------
1484 ExecEvalBooleanTest(BooleanTest *btest,
1485 ExprContext *econtext,
1487 ExprDoneCond *isDone)
1491 result = ExecEvalExpr(btest->arg, econtext, isNull, isDone);
1492 switch (btest->booltesttype)
1498 return BoolGetDatum(false);
1500 else if (DatumGetBool(result))
1501 return BoolGetDatum(true);
1503 return BoolGetDatum(false);
1508 return BoolGetDatum(true);
1510 else if (DatumGetBool(result))
1511 return BoolGetDatum(false);
1513 return BoolGetDatum(true);
1518 return BoolGetDatum(false);
1520 else if (DatumGetBool(result))
1521 return BoolGetDatum(false);
1523 return BoolGetDatum(true);
1528 return BoolGetDatum(true);
1530 else if (DatumGetBool(result))
1531 return BoolGetDatum(true);
1533 return BoolGetDatum(false);
1538 return BoolGetDatum(true);
1541 return BoolGetDatum(false);
1542 case IS_NOT_UNKNOWN:
1546 return BoolGetDatum(false);
1549 return BoolGetDatum(true);
1551 elog(ERROR, "ExecEvalBooleanTest: unexpected booltesttype %d",
1552 (int) btest->booltesttype);
1553 return (Datum) 0; /* keep compiler quiet */
1558 * ExecEvalConstraintTestValue
1560 * Return the value stored by constraintTest.
1563 ExecEvalConstraintTestValue(ConstraintTestValue *conVal, ExprContext *econtext,
1564 bool *isNull, ExprDoneCond *isDone)
1567 * If the Datum hasn't been set, then it's ExecEvalConstraintTest
1568 * hasn't been called.
1570 *isNull = econtext->domainValue_isNull;
1571 return econtext->domainValue_datum;
1575 * ExecEvalConstraintTest
1577 * Test the constraint against the data provided. If the data fits
1578 * within the constraint specifications, pass it through (return the
1579 * datum) otherwise throw an error.
1582 ExecEvalConstraintTest(ConstraintTest *constraint, ExprContext *econtext,
1583 bool *isNull, ExprDoneCond *isDone)
1587 result = ExecEvalExpr(constraint->arg, econtext, isNull, isDone);
1589 switch (constraint->testtype)
1591 case CONSTR_TEST_NOTNULL:
1593 elog(ERROR, "Domain %s does not allow NULL values",
1594 constraint->domname);
1596 case CONSTR_TEST_CHECK:
1600 /* Var with attnum == UnassignedAttrNum uses the result */
1601 econtext->domainValue_datum = result;
1602 econtext->domainValue_isNull = *isNull;
1604 conResult = ExecEvalExpr(constraint->check_expr, econtext, isNull, isDone);
1606 if (!DatumGetBool(conResult))
1607 elog(ERROR, "Domain %s constraint %s failed",
1608 constraint->name, constraint->domname);
1612 elog(ERROR, "ExecEvalConstraintTest: Constraint type unknown");
1616 /* If all has gone well (constraint did not fail) return the datum */
1620 /* ----------------------------------------------------------------
1621 * ExecEvalFieldSelect
1623 * Evaluate a FieldSelect node.
1624 * ----------------------------------------------------------------
1627 ExecEvalFieldSelect(FieldSelect *fselect,
1628 ExprContext *econtext,
1630 ExprDoneCond *isDone)
1633 TupleTableSlot *resSlot;
1635 result = ExecEvalExpr(fselect->arg, econtext, isNull, isDone);
1638 resSlot = (TupleTableSlot *) DatumGetPointer(result);
1639 Assert(resSlot != NULL && IsA(resSlot, TupleTableSlot));
1640 result = heap_getattr(resSlot->val,
1642 resSlot->ttc_tupleDescriptor,
1647 /* ----------------------------------------------------------------
1650 * Recursively evaluate a targetlist or qualification expression.
1653 * expression: the expression tree to evaluate
1654 * econtext: evaluation context information
1657 * return value: Datum value of result
1658 * *isNull: set to TRUE if result is NULL (actual return value is
1659 * meaningless if so); set to FALSE if non-null result
1660 * *isDone: set to indicator of set-result status
1662 * A caller that can only accept a singleton (non-set) result should pass
1663 * NULL for isDone; if the expression computes a set result then an elog()
1664 * error will be reported. If the caller does pass an isDone pointer then
1665 * *isDone is set to one of these three states:
1666 * ExprSingleResult singleton result (not a set)
1667 * ExprMultipleResult return value is one element of a set
1668 * ExprEndResult there are no more elements in the set
1669 * When ExprMultipleResult is returned, the caller should invoke
1670 * ExecEvalExpr() repeatedly until ExprEndResult is returned. ExprEndResult
1671 * is returned after the last real set element. For convenience isNull will
1672 * always be set TRUE when ExprEndResult is returned, but this should not be
1673 * taken as indicating a NULL element of the set. Note that these return
1674 * conventions allow us to distinguish among a singleton NULL, a NULL element
1675 * of a set, and an empty set.
1677 * The caller should already have switched into the temporary memory
1678 * context econtext->ecxt_per_tuple_memory. The convenience entry point
1679 * ExecEvalExprSwitchContext() is provided for callers who don't prefer to
1680 * do the switch in an outer loop. We do not do the switch here because
1681 * it'd be a waste of cycles during recursive entries to ExecEvalExpr().
1683 * This routine is an inner loop routine and must be as fast as possible.
1684 * ----------------------------------------------------------------
1687 ExecEvalExpr(Node *expression,
1688 ExprContext *econtext,
1690 ExprDoneCond *isDone)
1694 /* Set default values for result flags: non-null, not a set result */
1697 *isDone = ExprSingleResult;
1699 /* Is this still necessary? Doubtful... */
1700 if (expression == NULL)
1707 * here we dispatch the work to the appropriate type of function given
1708 * the type of our expression.
1710 switch (nodeTag(expression))
1713 retDatum = ExecEvalVar((Var *) expression, econtext, isNull);
1717 Const *con = (Const *) expression;
1719 retDatum = con->constvalue;
1720 *isNull = con->constisnull;
1724 retDatum = ExecEvalParam((Param *) expression, econtext, isNull);
1727 retDatum = ExecEvalAggref((Aggref *) expression, econtext, isNull);
1730 retDatum = ExecEvalArrayRef((ArrayRef *) expression,
1737 Expr *expr = (Expr *) expression;
1739 switch (expr->opType)
1742 retDatum = ExecEvalOper(expr, econtext,
1746 retDatum = ExecEvalFunc(expr, econtext,
1750 retDatum = ExecEvalOr(expr, econtext, isNull);
1753 retDatum = ExecEvalAnd(expr, econtext, isNull);
1756 retDatum = ExecEvalNot(expr, econtext, isNull);
1759 retDatum = ExecEvalDistinct(expr, econtext,
1763 retDatum = ExecSubPlan((SubPlan *) expr->oper,
1764 expr->args, econtext,
1768 elog(ERROR, "ExecEvalExpr: unknown expression type %d",
1770 retDatum = 0; /* keep compiler quiet */
1776 retDatum = ExecEvalFieldSelect((FieldSelect *) expression,
1782 retDatum = ExecEvalExpr(((RelabelType *) expression)->arg,
1788 retDatum = ExecEvalCase((CaseExpr *) expression,
1794 retDatum = ExecEvalNullTest((NullTest *) expression,
1800 retDatum = ExecEvalBooleanTest((BooleanTest *) expression,
1805 case T_ConstraintTest:
1806 retDatum = ExecEvalConstraintTest((ConstraintTest *) expression,
1811 case T_ConstraintTestValue:
1812 retDatum = ExecEvalConstraintTestValue((ConstraintTestValue *) expression,
1818 elog(ERROR, "ExecEvalExpr: unknown expression type %d",
1819 nodeTag(expression));
1820 retDatum = 0; /* keep compiler quiet */
1825 } /* ExecEvalExpr() */
1829 * Same as above, but get into the right allocation context explicitly.
1832 ExecEvalExprSwitchContext(Node *expression,
1833 ExprContext *econtext,
1835 ExprDoneCond *isDone)
1838 MemoryContext oldContext;
1840 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1841 retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
1842 MemoryContextSwitchTo(oldContext);
1847 /* ----------------------------------------------------------------
1848 * ExecQual / ExecTargetList / ExecProject
1849 * ----------------------------------------------------------------
1852 /* ----------------------------------------------------------------
1855 * Evaluates a conjunctive boolean expression (qual list) and
1856 * returns true iff none of the subexpressions are false.
1857 * (We also return true if the list is empty.)
1859 * If some of the subexpressions yield NULL but none yield FALSE,
1860 * then the result of the conjunction is NULL (ie, unknown)
1861 * according to three-valued boolean logic. In this case,
1862 * we return the value specified by the "resultForNull" parameter.
1864 * Callers evaluating WHERE clauses should pass resultForNull=FALSE,
1865 * since SQL specifies that tuples with null WHERE results do not
1866 * get selected. On the other hand, callers evaluating constraint
1867 * conditions should pass resultForNull=TRUE, since SQL also specifies
1868 * that NULL constraint conditions are not failures.
1870 * NOTE: it would not be correct to use this routine to evaluate an
1871 * AND subclause of a boolean expression; for that purpose, a NULL
1872 * result must be returned as NULL so that it can be properly treated
1873 * in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
1874 * This routine is only used in contexts where a complete expression
1875 * is being evaluated and we know that NULL can be treated the same
1876 * as one boolean result or the other.
1878 * ----------------------------------------------------------------
1881 ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
1884 MemoryContext oldContext;
1890 EV_printf("ExecQual: qual is ");
1891 EV_nodeDisplay(qual);
1897 * Run in short-lived per-tuple context while computing expressions.
1899 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1902 * Evaluate the qual conditions one at a time. If we find a FALSE
1903 * result, we can stop evaluating and return FALSE --- the AND result
1904 * must be FALSE. Also, if we find a NULL result when resultForNull
1905 * is FALSE, we can stop and return FALSE --- the AND result must be
1906 * FALSE or NULL in that case, and the caller doesn't care which.
1908 * If we get to the end of the list, we can return TRUE. This will
1909 * happen when the AND result is indeed TRUE, or when the AND result
1910 * is NULL (one or more NULL subresult, with all the rest TRUE) and
1911 * the caller has specified resultForNull = TRUE.
1915 foreach(qlist, qual)
1917 Node *clause = (Node *) lfirst(qlist);
1921 expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
1925 if (resultForNull == false)
1927 result = false; /* treat NULL as FALSE */
1933 if (!DatumGetBool(expr_value))
1935 result = false; /* definitely FALSE */
1941 MemoryContextSwitchTo(oldContext);
1947 * Number of items in a tlist (including any resjunk items!)
1950 ExecTargetListLength(List *targetlist)
1955 foreach(tl, targetlist)
1957 TargetEntry *curTle = (TargetEntry *) lfirst(tl);
1959 if (curTle->resdom != NULL)
1962 len += curTle->fjoin->fj_nNodes;
1968 * Number of items in a tlist, not including any resjunk items
1971 ExecCleanTargetListLength(List *targetlist)
1976 foreach(tl, targetlist)
1978 TargetEntry *curTle = (TargetEntry *) lfirst(tl);
1980 if (curTle->resdom != NULL)
1982 if (!curTle->resdom->resjunk)
1986 len += curTle->fjoin->fj_nNodes;
1991 /* ----------------------------------------------------------------
1994 * Evaluates a targetlist with respect to the current
1995 * expression context and return a tuple.
1997 * As with ExecEvalExpr, the caller should pass isDone = NULL if not
1998 * prepared to deal with sets of result tuples. Otherwise, a return
1999 * of *isDone = ExprMultipleResult signifies a set element, and a return
2000 * of *isDone = ExprEndResult signifies end of the set of tuple.
2001 * ----------------------------------------------------------------
2004 ExecTargetList(List *targetlist,
2006 TupleDesc targettype,
2008 ExprContext *econtext,
2009 ExprDoneCond *isDone)
2011 MemoryContext oldContext;
2013 #define NPREALLOCDOMAINS 64
2014 char nullsArray[NPREALLOCDOMAINS];
2015 bool fjIsNullArray[NPREALLOCDOMAINS];
2016 ExprDoneCond itemIsDoneArray[NPREALLOCDOMAINS];
2019 ExprDoneCond *itemIsDone;
2026 static struct tupleDesc NullTupleDesc; /* we assume this inits to
2032 EV_printf("ExecTargetList: tl is ");
2033 EV_nodeDisplay(targetlist);
2037 * Run in short-lived per-tuple context while computing expressions.
2039 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
2042 * There used to be some klugy and demonstrably broken code here that
2043 * special-cased the situation where targetlist == NIL. Now we just
2044 * fall through and return an empty-but-valid tuple. We do, however,
2045 * have to cope with the possibility that targettype is NULL ---
2046 * heap_formtuple won't like that, so pass a dummy descriptor with
2047 * natts = 0 to deal with it.
2049 if (targettype == NULL)
2050 targettype = &NullTupleDesc;
2053 * allocate an array of char's to hold the "null" information only if
2054 * we have a really large targetlist. otherwise we use the stack.
2056 * We also allocate a bool array that is used to hold fjoin result state,
2057 * and another array that holds the isDone status for each targetlist
2058 * item. The isDone status is needed so that we can iterate,
2059 * generating multiple tuples, when one or more tlist items return
2060 * sets. (We expect the caller to call us again if we return:
2062 * isDone = ExprMultipleResult.)
2064 if (nodomains > NPREALLOCDOMAINS)
2066 nulls = (char *) palloc(nodomains * sizeof(char));
2067 fjIsNull = (bool *) palloc(nodomains * sizeof(bool));
2068 itemIsDone = (ExprDoneCond *) palloc(nodomains * sizeof(ExprDoneCond));
2073 fjIsNull = fjIsNullArray;
2074 itemIsDone = itemIsDoneArray;
2078 * evaluate all the expressions in the target list
2082 *isDone = ExprSingleResult; /* until proven otherwise */
2084 haveDoneSets = false; /* any exhausted set exprs in tlist? */
2086 foreach(tl, targetlist)
2090 if (tle->resdom != NULL)
2092 resind = tle->resdom->resno - 1;
2094 values[resind] = ExecEvalExpr(tle->expr,
2097 &itemIsDone[resind]);
2098 nulls[resind] = isNull ? 'n' : ' ';
2100 if (itemIsDone[resind] != ExprSingleResult)
2102 /* We have a set-valued expression in the tlist */
2104 elog(ERROR, "Set-valued function called in context that cannot accept a set");
2105 if (itemIsDone[resind] == ExprMultipleResult)
2107 /* we have undone sets in the tlist, set flag */
2108 *isDone = ExprMultipleResult;
2112 /* we have done sets in the tlist, set flag for that */
2113 haveDoneSets = true;
2122 List *fjTlist = (List *) tle->expr;
2123 Fjoin *fjNode = tle->fjoin;
2124 int nNodes = fjNode->fj_nNodes;
2125 DatumPtr results = fjNode->fj_results;
2127 ExecEvalFjoin(tle, econtext, fjIsNull, isDone);
2130 * XXX this is wrong, but since fjoin code is completely
2131 * broken anyway, I'm not going to worry about it now --- tgl
2134 if (isDone && *isDone == ExprEndResult)
2136 MemoryContextSwitchTo(oldContext);
2142 * get the result from the inner node
2144 fjRes = (Resdom *) fjNode->fj_innerNode;
2145 resind = fjRes->resno - 1;
2146 values[resind] = results[0];
2147 nulls[resind] = fjIsNull[0] ? 'n' : ' ';
2150 * Get results from all of the outer nodes
2154 curNode++, fjTlist = lnext(fjTlist))
2156 Node *outernode = lfirst(fjTlist);
2158 fjRes = (Resdom *) outernode->iterexpr;
2159 resind = fjRes->resno - 1;
2160 values[resind] = results[curNode];
2161 nulls[resind] = fjIsNull[curNode] ? 'n' : ' ';
2164 elog(ERROR, "ExecTargetList: fjoin nodes not currently supported");
2172 * note: can't get here unless we verified isDone != NULL
2174 if (*isDone == ExprSingleResult)
2177 * all sets are done, so report that tlist expansion is
2180 *isDone = ExprEndResult;
2181 MemoryContextSwitchTo(oldContext);
2188 * We have some done and some undone sets. Restart the done
2189 * ones so that we can deliver a tuple (if possible).
2191 foreach(tl, targetlist)
2195 if (tle->resdom != NULL)
2197 resind = tle->resdom->resno - 1;
2199 if (itemIsDone[resind] == ExprEndResult)
2201 values[resind] = ExecEvalExpr(tle->expr,
2204 &itemIsDone[resind]);
2205 nulls[resind] = isNull ? 'n' : ' ';
2207 if (itemIsDone[resind] == ExprEndResult)
2210 * Oh dear, this item is returning an empty
2211 * set. Guess we can't make a tuple after all.
2213 *isDone = ExprEndResult;
2221 * If we cannot make a tuple because some sets are empty, we
2222 * still have to cycle the nonempty sets to completion, else
2223 * resources will not be released from subplans etc.
2225 if (*isDone == ExprEndResult)
2227 foreach(tl, targetlist)
2231 if (tle->resdom != NULL)
2233 resind = tle->resdom->resno - 1;
2235 while (itemIsDone[resind] == ExprMultipleResult)
2237 (void) ExecEvalExpr(tle->expr,
2240 &itemIsDone[resind]);
2245 MemoryContextSwitchTo(oldContext);
2253 * form the new result tuple (in the caller's memory context!)
2255 MemoryContextSwitchTo(oldContext);
2257 newTuple = (HeapTuple) heap_formtuple(targettype, values, nulls);
2262 * free the status arrays if we palloc'd them
2264 if (nodomains > NPREALLOCDOMAINS)
2274 /* ----------------------------------------------------------------
2277 * projects a tuple based on projection info and stores
2278 * it in the specified tuple table slot.
2280 * Note: someday soon the executor can be extended to eliminate
2281 * redundant projections by storing pointers to datums
2282 * in the tuple table and then passing these around when
2283 * possible. this should make things much quicker.
2285 * ----------------------------------------------------------------
2288 ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
2290 TupleTableSlot *slot;
2295 ExprContext *econtext;
2301 if (projInfo == NULL)
2302 return (TupleTableSlot *) NULL;
2305 * get the projection info we want
2307 slot = projInfo->pi_slot;
2308 targetlist = projInfo->pi_targetlist;
2309 len = projInfo->pi_len;
2310 tupType = slot->ttc_tupleDescriptor;
2312 tupValue = projInfo->pi_tupValue;
2313 econtext = projInfo->pi_exprContext;
2316 * form a new result tuple (if possible --- result can be NULL)
2318 newTuple = ExecTargetList(targetlist,
2326 * store the tuple in the projection slot and return the slot.
2328 return ExecStoreTuple(newTuple, /* tuple to store */
2329 slot, /* slot to store in */
2330 InvalidBuffer, /* tuple has no buffer */