1 /*-------------------------------------------------------------------------
4 * Routines to evaluate qualification and targetlist expressions
6 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.172 2005/03/14 04:41:12 tgl Exp $
13 *-------------------------------------------------------------------------
17 * ExecEvalExpr - (now a macro) evaluate an expression, 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 * The more heavily used ExecEvalExpr routines, such as ExecEvalVar(),
24 * are hotspots. Making these faster will speed up the entire system.
26 * ExecProject() 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
31 * During expression evaluation, we check_stack_depth only in
32 * ExecMakeFunctionResult rather than at every single node. This
33 * is a compromise that trades off precision of the stack limit setting
39 #include "access/heapam.h"
40 #include "catalog/pg_type.h"
41 #include "commands/typecmds.h"
42 #include "executor/execdebug.h"
43 #include "executor/functions.h"
44 #include "executor/nodeSubplan.h"
46 #include "miscadmin.h"
47 #include "nodes/makefuncs.h"
48 #include "optimizer/planmain.h"
49 #include "parser/parse_expr.h"
50 #include "utils/acl.h"
51 #include "utils/array.h"
52 #include "utils/builtins.h"
53 #include "utils/lsyscache.h"
54 #include "utils/typcache.h"
57 /* static function decls */
58 static Datum ExecEvalArrayRef(ArrayRefExprState *astate,
59 ExprContext *econtext,
60 bool *isNull, ExprDoneCond *isDone);
61 static Datum ExecEvalAggref(AggrefExprState *aggref,
62 ExprContext *econtext,
63 bool *isNull, ExprDoneCond *isDone);
64 static Datum ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
65 bool *isNull, ExprDoneCond *isDone);
66 static Datum ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
67 bool *isNull, ExprDoneCond *isDone);
68 static Datum ExecEvalParam(ExprState *exprstate, ExprContext *econtext,
69 bool *isNull, ExprDoneCond *isDone);
70 static ExprDoneCond ExecEvalFuncArgs(FunctionCallInfo fcinfo,
71 List *argList, ExprContext *econtext);
72 static Datum ExecMakeFunctionResultNoSets(FuncExprState *fcache,
73 ExprContext *econtext,
74 bool *isNull, ExprDoneCond *isDone);
75 static Datum ExecEvalFunc(FuncExprState *fcache, ExprContext *econtext,
76 bool *isNull, ExprDoneCond *isDone);
77 static Datum ExecEvalOper(FuncExprState *fcache, ExprContext *econtext,
78 bool *isNull, ExprDoneCond *isDone);
79 static Datum ExecEvalDistinct(FuncExprState *fcache, ExprContext *econtext,
80 bool *isNull, ExprDoneCond *isDone);
81 static Datum ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
82 ExprContext *econtext,
83 bool *isNull, ExprDoneCond *isDone);
84 static Datum ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
85 bool *isNull, ExprDoneCond *isDone);
86 static Datum ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
87 bool *isNull, ExprDoneCond *isDone);
88 static Datum ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
89 bool *isNull, ExprDoneCond *isDone);
90 static Datum ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
91 ExprContext *econtext,
92 bool *isNull, ExprDoneCond *isDone);
93 static Datum ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
94 bool *isNull, ExprDoneCond *isDone);
95 static Datum ExecEvalCaseTestExpr(ExprState *exprstate,
96 ExprContext *econtext,
97 bool *isNull, ExprDoneCond *isDone);
98 static Datum ExecEvalArray(ArrayExprState *astate,
99 ExprContext *econtext,
100 bool *isNull, ExprDoneCond *isDone);
101 static Datum ExecEvalRow(RowExprState *rstate,
102 ExprContext *econtext,
103 bool *isNull, ExprDoneCond *isDone);
104 static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr,
105 ExprContext *econtext,
106 bool *isNull, ExprDoneCond *isDone);
107 static Datum ExecEvalNullIf(FuncExprState *nullIfExpr,
108 ExprContext *econtext,
109 bool *isNull, ExprDoneCond *isDone);
110 static Datum ExecEvalNullTest(GenericExprState *nstate,
111 ExprContext *econtext,
112 bool *isNull, ExprDoneCond *isDone);
113 static Datum ExecEvalBooleanTest(GenericExprState *bstate,
114 ExprContext *econtext,
115 bool *isNull, ExprDoneCond *isDone);
116 static Datum ExecEvalCoerceToDomain(CoerceToDomainState *cstate,
117 ExprContext *econtext,
118 bool *isNull, ExprDoneCond *isDone);
119 static Datum ExecEvalCoerceToDomainValue(ExprState *exprstate,
120 ExprContext *econtext,
121 bool *isNull, ExprDoneCond *isDone);
122 static Datum ExecEvalFieldSelect(FieldSelectState *fstate,
123 ExprContext *econtext,
124 bool *isNull, ExprDoneCond *isDone);
125 static Datum ExecEvalFieldStore(FieldStoreState *fstate,
126 ExprContext *econtext,
127 bool *isNull, ExprDoneCond *isDone);
128 static Datum ExecEvalRelabelType(GenericExprState *exprstate,
129 ExprContext *econtext,
130 bool *isNull, ExprDoneCond *isDone);
133 /* ----------------------------------------------------------------
134 * ExecEvalExpr routines
136 * Recursively evaluate a targetlist or qualification expression.
138 * Each of the following routines having the signature
139 * Datum ExecEvalFoo(ExprState *expression,
140 * ExprContext *econtext,
142 * ExprDoneCond *isDone);
143 * is responsible for evaluating one type or subtype of ExprState node.
144 * They are normally called via the ExecEvalExpr macro, which makes use of
145 * the function pointer set up when the ExprState node was built by
146 * ExecInitExpr. (In some cases, we change this pointer later to avoid
147 * re-executing one-time overhead.)
149 * Note: for notational simplicity we declare these functions as taking the
150 * specific type of ExprState that they work on. This requires casting when
151 * assigning the function pointer in ExecInitExpr. Be careful that the
152 * function signature is declared correctly, because the cast suppresses
153 * automatic checking!
156 * All these functions share this calling convention:
159 * expression: the expression state tree to evaluate
160 * econtext: evaluation context information
163 * return value: Datum value of result
164 * *isNull: set to TRUE if result is NULL (actual return value is
165 * meaningless if so); set to FALSE if non-null result
166 * *isDone: set to indicator of set-result status
168 * A caller that can only accept a singleton (non-set) result should pass
169 * NULL for isDone; if the expression computes a set result then an error
170 * will be reported via ereport. If the caller does pass an isDone pointer
171 * then *isDone is set to one of these three states:
172 * ExprSingleResult singleton result (not a set)
173 * ExprMultipleResult return value is one element of a set
174 * ExprEndResult there are no more elements in the set
175 * When ExprMultipleResult is returned, the caller should invoke
176 * ExecEvalExpr() repeatedly until ExprEndResult is returned. ExprEndResult
177 * is returned after the last real set element. For convenience isNull will
178 * always be set TRUE when ExprEndResult is returned, but this should not be
179 * taken as indicating a NULL element of the set. Note that these return
180 * conventions allow us to distinguish among a singleton NULL, a NULL element
181 * of a set, and an empty set.
183 * The caller should already have switched into the temporary memory
184 * context econtext->ecxt_per_tuple_memory. The convenience entry point
185 * ExecEvalExprSwitchContext() is provided for callers who don't prefer to
186 * do the switch in an outer loop. We do not do the switch in these routines
187 * because it'd be a waste of cycles during nested expression evaluation.
188 * ----------------------------------------------------------------
195 * This function takes an ArrayRef and returns the extracted Datum
196 * if it's a simple reference, or the modified array value if it's
197 * an array assignment (i.e., array element or slice insertion).
199 * NOTE: if we get a NULL result from a subexpression, we return NULL when
200 * it's an array reference, or the unmodified source array when it's an
201 * array assignment. This may seem peculiar, but if we return NULL (as was
202 * done in versions up through 7.0) then an assignment like
203 * UPDATE table SET arrayfield[4] = NULL
204 * will result in setting the whole array to NULL, which is certainly not
205 * very desirable. By returning the source array we make the assignment
206 * into a no-op, instead. (Eventually we need to redesign arrays so that
207 * individual elements can be NULL, but for now, let's try to protect users
208 * from shooting themselves in the foot.)
210 * NOTE: we deliberately refrain from applying DatumGetArrayTypeP() here,
211 * even though that might seem natural, because this code needs to support
212 * both varlena arrays and fixed-length array types. DatumGetArrayTypeP()
213 * only works for the varlena kind. The routines we call in arrayfuncs.c
214 * have to know the difference (that's what they need refattrlength for).
218 ExecEvalArrayRef(ArrayRefExprState *astate,
219 ExprContext *econtext,
221 ExprDoneCond *isDone)
223 ArrayRef *arrayRef = (ArrayRef *) astate->xprstate.expr;
224 ArrayType *array_source;
225 ArrayType *resultArray;
226 bool isAssignment = (arrayRef->refassgnexpr != NULL);
235 array_source = (ArrayType *)
236 DatumGetPointer(ExecEvalExpr(astate->refexpr,
242 * If refexpr yields NULL, and it's a fetch, then result is NULL. In
243 * the assignment case, we'll cons up something below.
247 if (isDone && *isDone == ExprEndResult)
248 return (Datum) NULL; /* end of set result */
253 foreach(l, astate->refupperindexpr)
255 ExprState *eltstate = (ExprState *) lfirst(l);
259 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
260 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
263 upper.indx[i++] = DatumGetInt32(ExecEvalExpr(eltstate,
267 /* If any index expr yields NULL, result is NULL or source array */
275 return PointerGetDatum(array_source);
279 if (astate->reflowerindexpr != NIL)
281 foreach(l, astate->reflowerindexpr)
283 ExprState *eltstate = (ExprState *) lfirst(l);
287 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
288 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
291 lower.indx[j++] = DatumGetInt32(ExecEvalExpr(eltstate,
297 * If any index expr yields NULL, result is NULL or source
307 return PointerGetDatum(array_source);
310 /* this can't happen unless parser messed up */
312 elog(ERROR, "upper and lower index lists are not same length");
323 * Evaluate the value to be assigned into the array.
325 * XXX At some point we'll need to look into making the old value of
326 * the array element available via CaseTestExpr, as is done by
327 * ExecEvalFieldStore. This is not needed now but will be needed
328 * to support arrays of composite types; in an assignment to a
329 * field of an array member, the parser would generate a
330 * FieldStore that expects to fetch its input tuple via
333 sourceData = ExecEvalExpr(astate->refassgnexpr,
339 * For now, can't cope with inserting NULL into an array, so make
340 * it a no-op per discussion above...
343 return PointerGetDatum(array_source);
346 * For an assignment, if all the subscripts and the input
347 * expression are non-null but the original array is null, then
348 * substitute an empty (zero-dimensional) array and proceed with
349 * the assignment. This only works for varlena arrays, though; for
350 * fixed-length array types we punt and return the null input
355 if (astate->refattrlength > 0) /* fixed-length array? */
356 return PointerGetDatum(array_source);
358 array_source = construct_md_array(NULL, 0, NULL, NULL,
359 arrayRef->refelemtype,
360 astate->refelemlength,
361 astate->refelembyval,
362 astate->refelemalign);
367 resultArray = array_set(array_source, i,
370 astate->refattrlength,
371 astate->refelemlength,
372 astate->refelembyval,
373 astate->refelemalign,
376 resultArray = array_set_slice(array_source, i,
377 upper.indx, lower.indx,
378 (ArrayType *) DatumGetPointer(sourceData),
379 astate->refattrlength,
380 astate->refelemlength,
381 astate->refelembyval,
382 astate->refelemalign,
384 return PointerGetDatum(resultArray);
388 return array_ref(array_source, i, upper.indx,
389 astate->refattrlength,
390 astate->refelemlength,
391 astate->refelembyval,
392 astate->refelemalign,
396 resultArray = array_get_slice(array_source, i,
397 upper.indx, lower.indx,
398 astate->refattrlength,
399 astate->refelemlength,
400 astate->refelembyval,
401 astate->refelemalign,
403 return PointerGetDatum(resultArray);
408 /* ----------------------------------------------------------------
411 * Returns a Datum whose value is the value of the precomputed
412 * aggregate found in the given expression context.
413 * ----------------------------------------------------------------
416 ExecEvalAggref(AggrefExprState *aggref, ExprContext *econtext,
417 bool *isNull, ExprDoneCond *isDone)
420 *isDone = ExprSingleResult;
422 if (econtext->ecxt_aggvalues == NULL) /* safety check */
423 elog(ERROR, "no aggregates in this expression context");
425 *isNull = econtext->ecxt_aggnulls[aggref->aggno];
426 return econtext->ecxt_aggvalues[aggref->aggno];
429 /* ----------------------------------------------------------------
432 * Returns a Datum whose value is the value of a range
433 * variable with respect to given expression context.
434 * ----------------------------------------------------------------
437 ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
438 bool *isNull, ExprDoneCond *isDone)
440 Var *variable = (Var *) exprstate->expr;
441 TupleTableSlot *slot;
445 *isDone = ExprSingleResult;
448 * Get the slot and attribute number we want
450 * The asserts check that references to system attributes only appear at
451 * the level of a relation scan; at higher levels, system attributes
452 * must be treated as ordinary variables (since we no longer have
453 * access to the original tuple).
455 attnum = variable->varattno;
457 switch (variable->varno)
459 case INNER: /* get the tuple from the inner node */
460 slot = econtext->ecxt_innertuple;
464 case OUTER: /* get the tuple from the outer node */
465 slot = econtext->ecxt_outertuple;
469 default: /* get the tuple from the relation being
471 slot = econtext->ecxt_scantuple;
475 #ifdef USE_ASSERT_CHECKING
477 * Some checks that are only applied for user attribute numbers (bogus
478 * system attnums will be caught inside slot_getattr).
482 TupleDesc tuple_type = slot->ttc_tupleDescriptor;
485 * This assert checks that the attnum is valid.
487 Assert(attnum <= tuple_type->natts);
490 * This assert checks that the datatype the plan expects to get
491 * (as told by our "variable" argument) is in fact the datatype of
492 * the attribute being fetched (as seen in the current context,
493 * identified by our "econtext" argument). Otherwise crashes are
496 * Note that we can't check dropped columns, since their atttypid has
499 Assert(variable->vartype == tuple_type->attrs[attnum - 1]->atttypid ||
500 tuple_type->attrs[attnum - 1]->attisdropped);
502 #endif /* USE_ASSERT_CHECKING */
504 return slot_getattr(slot, attnum, isNull);
507 /* ----------------------------------------------------------------
510 * Returns the value of a constant.
512 * Note that for pass-by-ref datatypes, we return a pointer to the
513 * actual constant node. This is one of the reasons why functions
514 * must treat their input arguments as read-only.
515 * ----------------------------------------------------------------
518 ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
519 bool *isNull, ExprDoneCond *isDone)
521 Const *con = (Const *) exprstate->expr;
524 *isDone = ExprSingleResult;
526 *isNull = con->constisnull;
527 return con->constvalue;
530 /* ----------------------------------------------------------------
533 * Returns the value of a parameter. A param node contains
534 * something like ($.name) and the expression context contains
535 * the current parameter bindings (name = "sam") (age = 34)...
536 * so our job is to find and return the appropriate datum ("sam").
538 * Q: if we have a parameter ($.foo) without a binding, i.e.
539 * there is no (foo = xxx) in the parameter list info,
540 * is this a fatal error or should this be a "not available"
541 * (in which case we could return NULL)? -cim 10/13/89
542 * ----------------------------------------------------------------
545 ExecEvalParam(ExprState *exprstate, ExprContext *econtext,
546 bool *isNull, ExprDoneCond *isDone)
548 Param *expression = (Param *) exprstate->expr;
549 int thisParamKind = expression->paramkind;
550 AttrNumber thisParamId = expression->paramid;
553 *isDone = ExprSingleResult;
555 if (thisParamKind == PARAM_EXEC)
558 * PARAM_EXEC params (internal executor parameters) are stored in
559 * the ecxt_param_exec_vals array, and can be accessed by array
564 prm = &(econtext->ecxt_param_exec_vals[thisParamId]);
565 if (prm->execPlan != NULL)
567 /* Parameter not evaluated yet, so go do it */
568 ExecSetParamPlan(prm->execPlan, econtext);
569 /* ExecSetParamPlan should have processed this param... */
570 Assert(prm->execPlan == NULL);
572 *isNull = prm->isnull;
578 * All other parameter types must be sought in
579 * ecxt_param_list_info.
581 ParamListInfo paramInfo;
583 paramInfo = lookupParam(econtext->ecxt_param_list_info,
585 expression->paramname,
588 Assert(paramInfo->ptype == expression->paramtype);
589 *isNull = paramInfo->isnull;
590 return paramInfo->value;
595 /* ----------------------------------------------------------------
596 * ExecEvalOper / ExecEvalFunc support routines
597 * ----------------------------------------------------------------
604 * These functions return the value of the requested attribute
605 * out of the given tuple Datum.
606 * C functions which take a tuple as an argument are expected
607 * to use these. Ex: overpaid(EMP) might call GetAttributeByNum().
608 * Note: these are actually rather slow because they do a typcache
609 * lookup on each call.
612 GetAttributeByNum(HeapTupleHeader tuple,
620 HeapTupleData tmptup;
622 if (!AttributeNumberIsValid(attrno))
623 elog(ERROR, "invalid attribute number %d", attrno);
626 elog(ERROR, "a NULL isNull pointer was passed");
630 /* Kinda bogus but compatible with old behavior... */
635 tupType = HeapTupleHeaderGetTypeId(tuple);
636 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
637 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
640 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set
641 * all the fields in the struct just in case user tries to inspect
644 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
645 ItemPointerSetInvalid(&(tmptup.t_self));
646 tmptup.t_tableOid = InvalidOid;
647 tmptup.t_data = tuple;
649 result = heap_getattr(&tmptup,
657 GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
664 HeapTupleData tmptup;
668 elog(ERROR, "invalid attribute name");
671 elog(ERROR, "a NULL isNull pointer was passed");
675 /* Kinda bogus but compatible with old behavior... */
680 tupType = HeapTupleHeaderGetTypeId(tuple);
681 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
682 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
684 attrno = InvalidAttrNumber;
685 for (i = 0; i < tupDesc->natts; i++)
687 if (namestrcmp(&(tupDesc->attrs[i]->attname), attname) == 0)
689 attrno = tupDesc->attrs[i]->attnum;
694 if (attrno == InvalidAttrNumber)
695 elog(ERROR, "attribute \"%s\" does not exist", attname);
698 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set
699 * all the fields in the struct just in case user tries to inspect
702 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
703 ItemPointerSetInvalid(&(tmptup.t_self));
704 tmptup.t_tableOid = InvalidOid;
705 tmptup.t_data = tuple;
707 result = heap_getattr(&tmptup,
715 * init_fcache - initialize a FuncExprState node during first use
718 init_fcache(Oid foid, FuncExprState *fcache, MemoryContext fcacheCxt)
722 /* Check permission to call function */
723 aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
724 if (aclresult != ACLCHECK_OK)
725 aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(foid));
727 /* Safety check (should never fail, as parser should check sooner) */
728 if (list_length(fcache->args) > FUNC_MAX_ARGS)
729 elog(ERROR, "too many arguments");
731 /* Set up the primary fmgr lookup information */
732 fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
734 /* Initialize additional info */
735 fcache->setArgsValid = false;
736 fcache->shutdown_reg = false;
737 fcache->func.fn_expr = (Node *) fcache->xprstate.expr;
741 * callback function in case a FuncExpr returning a set needs to be shut down
742 * before it has been run to completion
745 ShutdownFuncExpr(Datum arg)
747 FuncExprState *fcache = (FuncExprState *) DatumGetPointer(arg);
749 /* Clear any active set-argument state */
750 fcache->setArgsValid = false;
752 /* execUtils will deregister the callback... */
753 fcache->shutdown_reg = false;
757 * Evaluate arguments for a function.
760 ExecEvalFuncArgs(FunctionCallInfo fcinfo,
762 ExprContext *econtext)
764 ExprDoneCond argIsDone;
768 argIsDone = ExprSingleResult; /* default assumption */
771 foreach(arg, argList)
773 ExprState *argstate = (ExprState *) lfirst(arg);
774 ExprDoneCond thisArgIsDone;
776 fcinfo->arg[i] = ExecEvalExpr(argstate,
781 if (thisArgIsDone != ExprSingleResult)
784 * We allow only one argument to have a set value; we'd need
785 * much more complexity to keep track of multiple set
786 * arguments (cf. ExecTargetList) and it doesn't seem worth
789 if (argIsDone != ExprSingleResult)
791 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
792 errmsg("functions and operators can take at most one set argument")));
793 argIsDone = thisArgIsDone;
804 * ExecMakeFunctionResult
806 * Evaluate the arguments to a function and then the function itself.
809 ExecMakeFunctionResult(FuncExprState *fcache,
810 ExprContext *econtext,
812 ExprDoneCond *isDone)
814 List *arguments = fcache->args;
816 FunctionCallInfoData fcinfo;
817 ReturnSetInfo rsinfo; /* for functions returning sets */
818 ExprDoneCond argDone;
822 /* Guard against stack overflow due to overly complex expressions */
826 * arguments is a list of expressions to evaluate before passing to
827 * the function manager. We skip the evaluation if it was already
828 * done in the previous call (ie, we are continuing the evaluation of
829 * a set-valued function). Otherwise, collect the current argument
830 * values into fcinfo.
832 if (!fcache->setArgsValid)
834 /* Need to prep callinfo structure */
835 MemSet(&fcinfo, 0, sizeof(fcinfo));
836 fcinfo.flinfo = &(fcache->func);
837 argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);
838 if (argDone == ExprEndResult)
840 /* input is an empty set, so return an empty set. */
843 *isDone = ExprEndResult;
846 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
847 errmsg("set-valued function called in context that cannot accept a set")));
850 hasSetArg = (argDone != ExprSingleResult);
854 /* Copy callinfo from previous evaluation */
855 memcpy(&fcinfo, &fcache->setArgs, sizeof(fcinfo));
856 hasSetArg = fcache->setHasSetArg;
857 /* Reset flag (we may set it again below) */
858 fcache->setArgsValid = false;
862 * If function returns set, prepare a resultinfo node for
865 if (fcache->func.fn_retset)
867 fcinfo.resultinfo = (Node *) &rsinfo;
868 rsinfo.type = T_ReturnSetInfo;
869 rsinfo.econtext = econtext;
870 rsinfo.expectedDesc = NULL;
871 rsinfo.allowedModes = (int) SFRM_ValuePerCall;
872 rsinfo.returnMode = SFRM_ValuePerCall;
873 /* isDone is filled below */
874 rsinfo.setResult = NULL;
875 rsinfo.setDesc = NULL;
879 * now return the value gotten by calling the function manager,
880 * passing the function the evaluated parameter values.
882 if (fcache->func.fn_retset || hasSetArg)
885 * We need to return a set result. Complain if caller not ready
890 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
891 errmsg("set-valued function called in context that cannot accept a set")));
894 * This loop handles the situation where we have both a set
895 * argument and a set-valued function. Once we have exhausted the
896 * function's value(s) for a particular argument value, we have to
897 * get the next argument value and start the function over again.
898 * We might have to do it more than once, if the function produces
899 * an empty result set for a particular input value.
904 * If function is strict, and there are any NULL arguments,
905 * skip calling the function (at least for this set of args).
909 if (fcache->func.fn_strict)
911 for (i = 0; i < fcinfo.nargs; i++)
913 if (fcinfo.argnull[i])
923 fcinfo.isnull = false;
924 rsinfo.isDone = ExprSingleResult;
925 result = FunctionCallInvoke(&fcinfo);
926 *isNull = fcinfo.isnull;
927 *isDone = rsinfo.isDone;
933 *isDone = ExprEndResult;
936 if (*isDone != ExprEndResult)
939 * Got a result from current argument. If function itself
940 * returns set, save the current argument values to re-use
943 if (fcache->func.fn_retset)
945 memcpy(&fcache->setArgs, &fcinfo, sizeof(fcinfo));
946 fcache->setHasSetArg = hasSetArg;
947 fcache->setArgsValid = true;
948 /* Register cleanup callback if we didn't already */
949 if (!fcache->shutdown_reg)
951 RegisterExprContextCallback(econtext,
953 PointerGetDatum(fcache));
954 fcache->shutdown_reg = true;
959 * Make sure we say we are returning a set, even if the
960 * function itself doesn't return sets.
962 *isDone = ExprMultipleResult;
966 /* Else, done with this argument */
968 break; /* input not a set, so done */
970 /* Re-eval args to get the next element of the input set */
971 argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);
973 if (argDone != ExprMultipleResult)
975 /* End of argument set, so we're done. */
977 *isDone = ExprEndResult;
983 * If we reach here, loop around to run the function on the
991 * Non-set case: much easier.
993 * We change the ExprState function pointer to use the simpler
994 * ExecMakeFunctionResultNoSets on subsequent calls. This amounts
995 * to assuming that no argument can return a set if it didn't do
998 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResultNoSets;
1001 *isDone = ExprSingleResult;
1004 * If function is strict, and there are any NULL arguments, skip
1005 * calling the function and return NULL.
1007 if (fcache->func.fn_strict)
1009 for (i = 0; i < fcinfo.nargs; i++)
1011 if (fcinfo.argnull[i])
1018 fcinfo.isnull = false;
1019 result = FunctionCallInvoke(&fcinfo);
1020 *isNull = fcinfo.isnull;
1027 * ExecMakeFunctionResultNoSets
1029 * Simplified version of ExecMakeFunctionResult that can only handle
1030 * non-set cases. Hand-tuned for speed.
1033 ExecMakeFunctionResultNoSets(FuncExprState *fcache,
1034 ExprContext *econtext,
1036 ExprDoneCond *isDone)
1040 FunctionCallInfoData fcinfo;
1043 /* Guard against stack overflow due to overly complex expressions */
1044 check_stack_depth();
1047 *isDone = ExprSingleResult;
1049 MemSet(&fcinfo, 0, sizeof(fcinfo));
1050 fcinfo.flinfo = &(fcache->func);
1052 /* inlined, simplified version of ExecEvalFuncArgs */
1054 foreach(arg, fcache->args)
1056 ExprState *argstate = (ExprState *) lfirst(arg);
1057 ExprDoneCond thisArgIsDone;
1059 fcinfo.arg[i] = ExecEvalExpr(argstate,
1064 if (thisArgIsDone != ExprSingleResult)
1066 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1067 errmsg("set-valued function called in context that cannot accept a set")));
1073 * If function is strict, and there are any NULL arguments, skip
1074 * calling the function and return NULL.
1076 if (fcache->func.fn_strict)
1080 if (fcinfo.argnull[i])
1087 /* fcinfo.isnull = false; */ /* handled by MemSet */
1088 result = FunctionCallInvoke(&fcinfo);
1089 *isNull = fcinfo.isnull;
1096 * ExecMakeTableFunctionResult
1098 * Evaluate a table function, producing a materialized result in a Tuplestore
1099 * object. *returnDesc is set to the tupledesc actually returned by the
1100 * function, or NULL if it didn't provide one.
1103 ExecMakeTableFunctionResult(ExprState *funcexpr,
1104 ExprContext *econtext,
1105 TupleDesc expectedDesc,
1106 TupleDesc *returnDesc)
1108 Tuplestorestate *tupstore = NULL;
1109 TupleDesc tupdesc = NULL;
1112 bool returnsSet = false;
1113 FunctionCallInfoData fcinfo;
1114 ReturnSetInfo rsinfo;
1115 HeapTupleData tmptup;
1116 MemoryContext callerContext;
1117 MemoryContext oldcontext;
1118 bool direct_function_call;
1119 bool first_time = true;
1121 callerContext = CurrentMemoryContext;
1123 funcrettype = exprType((Node *) funcexpr->expr);
1125 returnsTuple = (funcrettype == RECORDOID ||
1126 get_typtype(funcrettype) == 'c');
1129 * Prepare a resultinfo node for communication. We always do this
1130 * even if not expecting a set result, so that we can pass
1131 * expectedDesc. In the generic-expression case, the expression
1132 * doesn't actually get to see the resultinfo, but set it up anyway
1133 * because we use some of the fields as our own state variables.
1135 MemSet(&fcinfo, 0, sizeof(fcinfo));
1136 fcinfo.resultinfo = (Node *) &rsinfo;
1137 rsinfo.type = T_ReturnSetInfo;
1138 rsinfo.econtext = econtext;
1139 rsinfo.expectedDesc = expectedDesc;
1140 rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
1141 rsinfo.returnMode = SFRM_ValuePerCall;
1142 /* isDone is filled below */
1143 rsinfo.setResult = NULL;
1144 rsinfo.setDesc = NULL;
1147 * Normally the passed expression tree will be a FuncExprState, since
1148 * the grammar only allows a function call at the top level of a table
1149 * function reference. However, if the function doesn't return set
1150 * then the planner might have replaced the function call via
1151 * constant-folding or inlining. So if we see any other kind of
1152 * expression node, execute it via the general ExecEvalExpr() code;
1153 * the only difference is that we don't get a chance to pass a special
1154 * ReturnSetInfo to any functions buried in the expression.
1156 if (funcexpr && IsA(funcexpr, FuncExprState) &&
1157 IsA(funcexpr->expr, FuncExpr))
1159 FuncExprState *fcache = (FuncExprState *) funcexpr;
1160 ExprDoneCond argDone;
1163 * This path is similar to ExecMakeFunctionResult.
1165 direct_function_call = true;
1168 * Initialize function cache if first time through
1170 if (fcache->func.fn_oid == InvalidOid)
1172 FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
1174 init_fcache(func->funcid, fcache, econtext->ecxt_per_query_memory);
1176 returnsSet = fcache->func.fn_retset;
1179 * Evaluate the function's argument list.
1181 * Note: ideally, we'd do this in the per-tuple context, but then the
1182 * argument values would disappear when we reset the context in
1183 * the inner loop. So do it in caller context. Perhaps we should
1184 * make a separate context just to hold the evaluated arguments?
1186 fcinfo.flinfo = &(fcache->func);
1187 argDone = ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
1188 /* We don't allow sets in the arguments of the table function */
1189 if (argDone != ExprSingleResult)
1191 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1192 errmsg("set-valued function called in context that cannot accept a set")));
1195 * If function is strict, and there are any NULL arguments, skip
1196 * calling the function and act like it returned NULL (or an empty
1197 * set, in the returns-set case).
1199 if (fcache->func.fn_strict)
1203 for (i = 0; i < fcinfo.nargs; i++)
1205 if (fcinfo.argnull[i])
1206 goto no_function_result;
1212 /* Treat funcexpr as a generic expression */
1213 direct_function_call = false;
1217 * Switch to short-lived context for calling the function or
1220 MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1223 * Loop to handle the ValuePerCall protocol (which is also the same
1224 * behavior needed in the generic ExecEvalExpr path).
1232 * reset per-tuple memory context before each call of the function
1233 * or expression. This cleans up any local memory the function may
1236 ResetExprContext(econtext);
1238 /* Call the function or expression one time */
1239 if (direct_function_call)
1241 fcinfo.isnull = false;
1242 rsinfo.isDone = ExprSingleResult;
1243 result = FunctionCallInvoke(&fcinfo);
1247 result = ExecEvalExpr(funcexpr, econtext,
1248 &fcinfo.isnull, &rsinfo.isDone);
1251 /* Which protocol does function want to use? */
1252 if (rsinfo.returnMode == SFRM_ValuePerCall)
1255 * Check for end of result set.
1257 if (rsinfo.isDone == ExprEndResult)
1261 * Can't do anything very useful with NULL rowtype values.
1262 * For a function returning set, we consider this a protocol
1263 * violation (but another alternative would be to just ignore
1264 * the result and "continue" to get another row). For a function
1265 * not returning set, we fall out of the loop; we'll cons up
1266 * an all-nulls result row below.
1268 if (returnsTuple && fcinfo.isnull)
1273 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1274 errmsg("function returning set of rows cannot return null value")));
1278 * If first time through, build tupdesc and tuplestore for
1283 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1287 * Use the type info embedded in the rowtype Datum to
1288 * look up the needed tupdesc. Make a copy for the
1293 td = DatumGetHeapTupleHeader(result);
1294 tupdesc = lookup_rowtype_tupdesc(HeapTupleHeaderGetTypeId(td),
1295 HeapTupleHeaderGetTypMod(td));
1296 tupdesc = CreateTupleDescCopy(tupdesc);
1301 * Scalar type, so make a single-column descriptor
1303 tupdesc = CreateTemplateTupleDesc(1, false);
1304 TupleDescInitEntry(tupdesc,
1311 tupstore = tuplestore_begin_heap(true, false, work_mem);
1312 MemoryContextSwitchTo(oldcontext);
1313 rsinfo.setResult = tupstore;
1314 rsinfo.setDesc = tupdesc;
1318 * Store current resultset item.
1324 td = DatumGetHeapTupleHeader(result);
1327 * tuplestore_puttuple needs a HeapTuple not a bare
1328 * HeapTupleHeader, but it doesn't need all the fields.
1330 tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
1338 nullflag = fcinfo.isnull ? 'n' : ' ';
1339 tuple = heap_formtuple(tupdesc, &result, &nullflag);
1342 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1343 tuplestore_puttuple(tupstore, tuple);
1344 MemoryContextSwitchTo(oldcontext);
1349 if (rsinfo.isDone != ExprMultipleResult)
1352 else if (rsinfo.returnMode == SFRM_Materialize)
1354 /* check we're on the same page as the function author */
1355 if (!first_time || rsinfo.isDone != ExprSingleResult)
1357 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1358 errmsg("table-function protocol for materialize mode was not followed")));
1359 /* Done evaluating the set result */
1364 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1365 errmsg("unrecognized table-function returnMode: %d",
1366 (int) rsinfo.returnMode)));
1374 * If we got nothing from the function (ie, an empty-set or NULL result),
1375 * we have to create the tuplestore to return, and if it's a
1376 * non-set-returning function then insert a single all-nulls row.
1378 if (rsinfo.setResult == NULL)
1380 MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1381 tupstore = tuplestore_begin_heap(true, false, work_mem);
1382 rsinfo.setResult = tupstore;
1385 int natts = expectedDesc->natts;
1390 MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1391 nulldatums = (Datum *) palloc0(natts * sizeof(Datum));
1392 nullflags = (char *) palloc(natts * sizeof(char));
1393 memset(nullflags, 'n', natts * sizeof(char));
1394 tuple = heap_formtuple(expectedDesc, nulldatums, nullflags);
1395 MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1396 tuplestore_puttuple(tupstore, tuple);
1400 MemoryContextSwitchTo(callerContext);
1402 /* The returned pointers are those in rsinfo */
1403 *returnDesc = rsinfo.setDesc;
1404 return rsinfo.setResult;
1408 /* ----------------------------------------------------------------
1412 * Evaluate the functional result of a list of arguments by calling the
1414 * ----------------------------------------------------------------
1417 /* ----------------------------------------------------------------
1419 * ----------------------------------------------------------------
1422 ExecEvalFunc(FuncExprState *fcache,
1423 ExprContext *econtext,
1425 ExprDoneCond *isDone)
1427 /* This is called only the first time through */
1428 FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
1430 /* Initialize function lookup info */
1431 init_fcache(func->funcid, fcache, econtext->ecxt_per_query_memory);
1433 /* Go directly to ExecMakeFunctionResult on subsequent uses */
1434 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
1436 return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
1439 /* ----------------------------------------------------------------
1441 * ----------------------------------------------------------------
1444 ExecEvalOper(FuncExprState *fcache,
1445 ExprContext *econtext,
1447 ExprDoneCond *isDone)
1449 /* This is called only the first time through */
1450 OpExpr *op = (OpExpr *) fcache->xprstate.expr;
1452 /* Initialize function lookup info */
1453 init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory);
1455 /* Go directly to ExecMakeFunctionResult on subsequent uses */
1456 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
1458 return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
1461 /* ----------------------------------------------------------------
1464 * IS DISTINCT FROM must evaluate arguments to determine whether
1465 * they are NULL; if either is NULL then the result is already
1466 * known. If neither is NULL, then proceed to evaluate the
1467 * function. Note that this is *always* derived from the equals
1468 * operator, but since we need special processing of the arguments
1469 * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
1470 * ----------------------------------------------------------------
1473 ExecEvalDistinct(FuncExprState *fcache,
1474 ExprContext *econtext,
1476 ExprDoneCond *isDone)
1479 FunctionCallInfoData fcinfo;
1480 ExprDoneCond argDone;
1483 /* Set default values for result flags: non-null, not a set result */
1486 *isDone = ExprSingleResult;
1489 * Initialize function cache if first time through
1491 if (fcache->func.fn_oid == InvalidOid)
1493 DistinctExpr *op = (DistinctExpr *) fcache->xprstate.expr;
1495 init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory);
1496 Assert(!fcache->func.fn_retset);
1500 * extract info from fcache
1502 argList = fcache->args;
1504 /* Need to prep callinfo structure */
1505 MemSet(&fcinfo, 0, sizeof(fcinfo));
1506 fcinfo.flinfo = &(fcache->func);
1507 argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
1508 if (argDone != ExprSingleResult)
1510 (errcode(ERRCODE_DATATYPE_MISMATCH),
1511 errmsg("IS DISTINCT FROM does not support set arguments")));
1512 Assert(fcinfo.nargs == 2);
1514 if (fcinfo.argnull[0] && fcinfo.argnull[1])
1516 /* Both NULL? Then is not distinct... */
1517 result = BoolGetDatum(FALSE);
1519 else if (fcinfo.argnull[0] || fcinfo.argnull[1])
1521 /* Only one is NULL? Then is distinct... */
1522 result = BoolGetDatum(TRUE);
1526 fcinfo.isnull = false;
1527 result = FunctionCallInvoke(&fcinfo);
1528 *isNull = fcinfo.isnull;
1529 /* Must invert result of "=" */
1530 result = BoolGetDatum(!DatumGetBool(result));
1537 * ExecEvalScalarArrayOp
1539 * Evaluate "scalar op ANY/ALL (array)". The operator always yields boolean,
1540 * and we combine the results across all array elements using OR and AND
1541 * (for ANY and ALL respectively). Of course we short-circuit as soon as
1542 * the result is known.
1545 ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
1546 ExprContext *econtext,
1547 bool *isNull, ExprDoneCond *isDone)
1549 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) sstate->fxprstate.xprstate.expr;
1550 bool useOr = opexpr->useOr;
1555 FunctionCallInfoData fcinfo;
1556 ExprDoneCond argDone;
1563 /* Set default values for result flags: non-null, not a set result */
1566 *isDone = ExprSingleResult;
1569 * Initialize function cache if first time through
1571 if (sstate->fxprstate.func.fn_oid == InvalidOid)
1573 init_fcache(opexpr->opfuncid, &sstate->fxprstate,
1574 econtext->ecxt_per_query_memory);
1575 Assert(!sstate->fxprstate.func.fn_retset);
1578 /* Need to prep callinfo structure */
1579 MemSet(&fcinfo, 0, sizeof(fcinfo));
1580 fcinfo.flinfo = &(sstate->fxprstate.func);
1581 argDone = ExecEvalFuncArgs(&fcinfo, sstate->fxprstate.args, econtext);
1582 if (argDone != ExprSingleResult)
1584 (errcode(ERRCODE_DATATYPE_MISMATCH),
1585 errmsg("op ANY/ALL (array) does not support set arguments")));
1586 Assert(fcinfo.nargs == 2);
1589 * If the array is NULL then we return NULL --- it's not very
1590 * meaningful to do anything else, even if the operator isn't strict.
1592 if (fcinfo.argnull[1])
1597 /* Else okay to fetch and detoast the array */
1598 arr = DatumGetArrayTypeP(fcinfo.arg[1]);
1601 * If the array is empty, we return either FALSE or TRUE per the useOr
1602 * flag. This is correct even if the scalar is NULL; since we would
1603 * evaluate the operator zero times, it matters not whether it would
1604 * want to return NULL.
1606 nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
1608 return BoolGetDatum(!useOr);
1611 * If the scalar is NULL, and the function is strict, return NULL.
1612 * This is just to avoid having to test for strictness inside the
1613 * loop. (XXX but if arrays could have null elements, we'd need a
1616 if (fcinfo.argnull[0] && sstate->fxprstate.func.fn_strict)
1623 * We arrange to look up info about the element type only once per
1624 * series of calls, assuming the element type doesn't change
1627 if (sstate->element_type != ARR_ELEMTYPE(arr))
1629 get_typlenbyvalalign(ARR_ELEMTYPE(arr),
1633 sstate->element_type = ARR_ELEMTYPE(arr);
1635 typlen = sstate->typlen;
1636 typbyval = sstate->typbyval;
1637 typalign = sstate->typalign;
1639 result = BoolGetDatum(!useOr);
1642 /* Loop over the array elements */
1643 s = (char *) ARR_DATA_PTR(arr);
1644 for (i = 0; i < nitems; i++)
1649 /* Get array element */
1650 elt = fetch_att(s, typbyval, typlen);
1652 s = att_addlength(s, typlen, PointerGetDatum(s));
1653 s = (char *) att_align(s, typalign);
1655 /* Call comparison function */
1656 fcinfo.arg[1] = elt;
1657 fcinfo.argnull[1] = false;
1658 fcinfo.isnull = false;
1659 thisresult = FunctionCallInvoke(&fcinfo);
1661 /* Combine results per OR or AND semantics */
1666 if (DatumGetBool(thisresult))
1668 result = BoolGetDatum(true);
1670 break; /* needn't look at any more elements */
1675 if (!DatumGetBool(thisresult))
1677 result = BoolGetDatum(false);
1679 break; /* needn't look at any more elements */
1684 *isNull = resultnull;
1688 /* ----------------------------------------------------------------
1693 * Evaluate boolean expressions, with appropriate short-circuiting.
1695 * The query planner reformulates clause expressions in the
1696 * qualification to conjunctive normal form. If we ever get
1697 * an AND to evaluate, we can be sure that it's not a top-level
1698 * clause in the qualification, but appears lower (as a function
1699 * argument, for example), or in the target list. Not that you
1700 * need to know this, mind you...
1701 * ----------------------------------------------------------------
1704 ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
1705 bool *isNull, ExprDoneCond *isDone)
1707 ExprState *clause = linitial(notclause->args);
1711 *isDone = ExprSingleResult;
1713 expr_value = ExecEvalExpr(clause, econtext, isNull, NULL);
1716 * if the expression evaluates to null, then we just cascade the null
1717 * back to whoever called us.
1723 * evaluation of 'not' is simple.. expr is false, then return 'true'
1726 return BoolGetDatum(!DatumGetBool(expr_value));
1729 /* ----------------------------------------------------------------
1731 * ----------------------------------------------------------------
1734 ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
1735 bool *isNull, ExprDoneCond *isDone)
1737 List *clauses = orExpr->args;
1742 *isDone = ExprSingleResult;
1747 * If any of the clauses is TRUE, the OR result is TRUE regardless of
1748 * the states of the rest of the clauses, so we can stop evaluating
1749 * and return TRUE immediately. If none are TRUE and one or more is
1750 * NULL, we return NULL; otherwise we return FALSE. This makes sense
1751 * when you interpret NULL as "don't know": if we have a TRUE then the
1752 * OR is TRUE even if we aren't sure about some of the other inputs.
1753 * If all the known inputs are FALSE, but we have one or more "don't
1754 * knows", then we have to report that we "don't know" what the OR's
1755 * result should be --- perhaps one of the "don't knows" would have
1756 * been TRUE if we'd known its value. Only when all the inputs are
1757 * known to be FALSE can we state confidently that the OR's result is
1760 foreach(clause, clauses)
1762 ExprState *clausestate = (ExprState *) lfirst(clause);
1765 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
1768 * if we have a non-null true result, then return it.
1771 AnyNull = true; /* remember we got a null */
1772 else if (DatumGetBool(clause_value))
1773 return clause_value;
1776 /* AnyNull is true if at least one clause evaluated to NULL */
1778 return BoolGetDatum(false);
1781 /* ----------------------------------------------------------------
1783 * ----------------------------------------------------------------
1786 ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
1787 bool *isNull, ExprDoneCond *isDone)
1789 List *clauses = andExpr->args;
1794 *isDone = ExprSingleResult;
1799 * If any of the clauses is FALSE, the AND result is FALSE regardless
1800 * of the states of the rest of the clauses, so we can stop evaluating
1801 * and return FALSE immediately. If none are FALSE and one or more is
1802 * NULL, we return NULL; otherwise we return TRUE. This makes sense
1803 * when you interpret NULL as "don't know", using the same sort of
1804 * reasoning as for OR, above.
1807 foreach(clause, clauses)
1809 ExprState *clausestate = (ExprState *) lfirst(clause);
1812 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
1815 * if we have a non-null false result, then return it.
1818 AnyNull = true; /* remember we got a null */
1819 else if (!DatumGetBool(clause_value))
1820 return clause_value;
1823 /* AnyNull is true if at least one clause evaluated to NULL */
1825 return BoolGetDatum(!AnyNull);
1828 /* ----------------------------------------------------------------
1829 * ExecEvalConvertRowtype
1831 * Evaluate a rowtype coercion operation. This may require
1832 * rearranging field positions.
1833 * ----------------------------------------------------------------
1836 ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
1837 ExprContext *econtext,
1838 bool *isNull, ExprDoneCond *isDone)
1842 HeapTupleHeader tuple;
1843 HeapTupleData tmptup;
1844 AttrNumber *attrMap = cstate->attrMap;
1845 Datum *invalues = cstate->invalues;
1846 char *innulls = cstate->innulls;
1847 Datum *outvalues = cstate->outvalues;
1848 char *outnulls = cstate->outnulls;
1850 int outnatts = cstate->outdesc->natts;
1852 tupDatum = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
1854 /* this test covers the isDone exception too: */
1858 tuple = DatumGetHeapTupleHeader(tupDatum);
1860 Assert(HeapTupleHeaderGetTypeId(tuple) == cstate->indesc->tdtypeid);
1861 Assert(HeapTupleHeaderGetTypMod(tuple) == cstate->indesc->tdtypmod);
1864 * heap_deformtuple needs a HeapTuple not a bare HeapTupleHeader.
1866 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1867 tmptup.t_data = tuple;
1870 * Extract all the values of the old tuple, offsetting the arrays
1871 * so that invalues[0] is NULL and invalues[1] is the first
1872 * source attribute; this exactly matches the numbering convention
1875 heap_deformtuple(&tmptup, cstate->indesc, invalues + 1, innulls + 1);
1876 invalues[0] = (Datum) 0;
1880 * Transpose into proper fields of the new tuple.
1882 for (i = 0; i < outnatts; i++)
1886 outvalues[i] = invalues[j];
1887 outnulls[i] = innulls[j];
1891 * Now form the new tuple.
1893 result = heap_formtuple(cstate->outdesc, outvalues, outnulls);
1895 return HeapTupleGetDatum(result);
1898 /* ----------------------------------------------------------------
1901 * Evaluate a CASE clause. Will have boolean expressions
1902 * inside the WHEN clauses, and will have expressions
1904 * - thomas 1998-11-09
1905 * ----------------------------------------------------------------
1908 ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
1909 bool *isNull, ExprDoneCond *isDone)
1911 List *clauses = caseExpr->args;
1917 *isDone = ExprSingleResult;
1920 * If there's a test expression, we have to evaluate it and save the
1921 * value where the CaseTestExpr placeholders can find it. We must save
1922 * and restore prior setting of econtext's caseValue fields, in case
1923 * this node is itself within a larger CASE.
1925 save_datum = econtext->caseValue_datum;
1926 save_isNull = econtext->caseValue_isNull;
1930 econtext->caseValue_datum = ExecEvalExpr(caseExpr->arg,
1932 &econtext->caseValue_isNull,
1937 * we evaluate each of the WHEN clauses in turn, as soon as one is
1938 * true we return the corresponding result. If none are true then we
1939 * return the value of the default clause, or NULL if there is none.
1941 foreach(clause, clauses)
1943 CaseWhenState *wclause = lfirst(clause);
1946 clause_value = ExecEvalExpr(wclause->expr,
1952 * if we have a true test, then we return the result, since the
1953 * case statement is satisfied. A NULL result from the test is
1954 * not considered true.
1956 if (DatumGetBool(clause_value) && !*isNull)
1958 econtext->caseValue_datum = save_datum;
1959 econtext->caseValue_isNull = save_isNull;
1960 return ExecEvalExpr(wclause->result,
1967 econtext->caseValue_datum = save_datum;
1968 econtext->caseValue_isNull = save_isNull;
1970 if (caseExpr->defresult)
1972 return ExecEvalExpr(caseExpr->defresult,
1983 * ExecEvalCaseTestExpr
1985 * Return the value stored by CASE.
1988 ExecEvalCaseTestExpr(ExprState *exprstate,
1989 ExprContext *econtext,
1990 bool *isNull, ExprDoneCond *isDone)
1993 *isDone = ExprSingleResult;
1994 *isNull = econtext->caseValue_isNull;
1995 return econtext->caseValue_datum;
1998 /* ----------------------------------------------------------------
1999 * ExecEvalArray - ARRAY[] expressions
2001 * NOTE: currently, if any input value is NULL then we return a NULL array,
2002 * so the ARRAY[] construct can be considered strict. Eventually this will
2003 * change; when it does, be sure to fix contain_nonstrict_functions().
2004 * ----------------------------------------------------------------
2007 ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
2008 bool *isNull, ExprDoneCond *isDone)
2010 ArrayExpr *arrayExpr = (ArrayExpr *) astate->xprstate.expr;
2013 Oid element_type = arrayExpr->element_typeid;
2018 /* Set default values for result flags: non-null, not a set result */
2021 *isDone = ExprSingleResult;
2023 if (!arrayExpr->multidims)
2025 /* Elements are presumably of scalar type */
2031 nelems = list_length(astate->elements);
2033 /* Shouldn't happen here, but if length is 0, return NULL */
2040 dvalues = (Datum *) palloc(nelems * sizeof(Datum));
2042 /* loop through and build array of datums */
2043 foreach(element, astate->elements)
2045 ExprState *e = (ExprState *) lfirst(element);
2048 dvalues[i++] = ExecEvalExpr(e, econtext, &eisnull, NULL);
2056 /* setup for 1-D array of the given length */
2060 result = construct_md_array(dvalues, ndims, dims, lbs,
2068 /* Must be nested array expressions */
2070 Size ndatabytes = 0;
2072 int outer_nelems = list_length(astate->elements);
2074 int *elem_dims = NULL;
2075 int *elem_lbs = NULL;
2076 bool firstone = true;
2079 /* loop through and get data area from each element */
2080 foreach(element, astate->elements)
2082 ExprState *e = (ExprState *) lfirst(element);
2086 int elem_ndatabytes;
2088 arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
2095 array = DatumGetArrayTypeP(arraydatum);
2097 /* run-time double-check on element type */
2098 if (element_type != ARR_ELEMTYPE(array))
2100 (errcode(ERRCODE_DATATYPE_MISMATCH),
2101 errmsg("cannot merge incompatible arrays"),
2102 errdetail("Array with element type %s cannot be "
2103 "included in ARRAY construct with element type %s.",
2104 format_type_be(ARR_ELEMTYPE(array)),
2105 format_type_be(element_type))));
2109 /* Get sub-array details from first member */
2110 elem_ndims = ARR_NDIM(array);
2111 ndims = elem_ndims + 1;
2112 if (ndims <= 0 || ndims > MAXDIM)
2114 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2115 errmsg("number of array dimensions (%d) exceeds " \
2116 "the maximum allowed (%d)", ndims, MAXDIM)));
2118 elem_dims = (int *) palloc(elem_ndims * sizeof(int));
2119 memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
2120 elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
2121 memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
2127 /* Check other sub-arrays are compatible */
2128 if (elem_ndims != ARR_NDIM(array) ||
2129 memcmp(elem_dims, ARR_DIMS(array),
2130 elem_ndims * sizeof(int)) != 0 ||
2131 memcmp(elem_lbs, ARR_LBOUND(array),
2132 elem_ndims * sizeof(int)) != 0)
2134 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2135 errmsg("multidimensional arrays must have array "
2136 "expressions with matching dimensions")));
2139 elem_ndatabytes = ARR_SIZE(array) - ARR_OVERHEAD(elem_ndims);
2140 ndatabytes += elem_ndatabytes;
2142 dat = (char *) palloc(ndatabytes);
2144 dat = (char *) repalloc(dat, ndatabytes);
2146 memcpy(dat + (ndatabytes - elem_ndatabytes),
2147 ARR_DATA_PTR(array),
2151 /* setup for multi-D array */
2152 dims[0] = outer_nelems;
2154 for (i = 1; i < ndims; i++)
2156 dims[i] = elem_dims[i - 1];
2157 lbs[i] = elem_lbs[i - 1];
2160 nbytes = ndatabytes + ARR_OVERHEAD(ndims);
2161 result = (ArrayType *) palloc(nbytes);
2163 result->size = nbytes;
2164 result->ndim = ndims;
2166 result->elemtype = element_type;
2167 memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
2168 memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
2170 memcpy(ARR_DATA_PTR(result), dat, ndatabytes);
2176 return PointerGetDatum(result);
2179 /* ----------------------------------------------------------------
2180 * ExecEvalRow - ROW() expressions
2181 * ----------------------------------------------------------------
2184 ExecEvalRow(RowExprState *rstate,
2185 ExprContext *econtext,
2186 bool *isNull, ExprDoneCond *isDone)
2195 /* Set default values for result flags: non-null, not a set result */
2198 *isDone = ExprSingleResult;
2200 /* Allocate workspace */
2201 natts = rstate->tupdesc->natts;
2202 values = (Datum *) palloc0(natts * sizeof(Datum));
2203 nulls = (char *) palloc(natts * sizeof(char));
2205 /* preset to nulls in case rowtype has some later-added columns */
2206 memset(nulls, 'n', natts * sizeof(char));
2208 /* Evaluate field values */
2210 foreach(arg, rstate->args)
2212 ExprState *e = (ExprState *) lfirst(arg);
2215 values[i] = ExecEvalExpr(e, econtext, &eisnull, NULL);
2216 nulls[i] = eisnull ? 'n' : ' ';
2220 tuple = heap_formtuple(rstate->tupdesc, values, nulls);
2225 return HeapTupleGetDatum(tuple);
2228 /* ----------------------------------------------------------------
2230 * ----------------------------------------------------------------
2233 ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
2234 bool *isNull, ExprDoneCond *isDone)
2239 *isDone = ExprSingleResult;
2241 /* Simply loop through until something NOT NULL is found */
2242 foreach(arg, coalesceExpr->args)
2244 ExprState *e = (ExprState *) lfirst(arg);
2247 value = ExecEvalExpr(e, econtext, isNull, NULL);
2252 /* Else return NULL */
2257 /* ----------------------------------------------------------------
2260 * Note that this is *always* derived from the equals operator,
2261 * but since we need special processing of the arguments
2262 * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
2263 * ----------------------------------------------------------------
2266 ExecEvalNullIf(FuncExprState *nullIfExpr,
2267 ExprContext *econtext,
2268 bool *isNull, ExprDoneCond *isDone)
2271 FunctionCallInfoData fcinfo;
2272 ExprDoneCond argDone;
2276 *isDone = ExprSingleResult;
2279 * Initialize function cache if first time through
2281 if (nullIfExpr->func.fn_oid == InvalidOid)
2283 NullIfExpr *op = (NullIfExpr *) nullIfExpr->xprstate.expr;
2285 init_fcache(op->opfuncid, nullIfExpr, econtext->ecxt_per_query_memory);
2286 Assert(!nullIfExpr->func.fn_retset);
2290 * extract info from nullIfExpr
2292 argList = nullIfExpr->args;
2294 /* Need to prep callinfo structure */
2295 MemSet(&fcinfo, 0, sizeof(fcinfo));
2296 fcinfo.flinfo = &(nullIfExpr->func);
2297 argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
2298 if (argDone != ExprSingleResult)
2300 (errcode(ERRCODE_DATATYPE_MISMATCH),
2301 errmsg("NULLIF does not support set arguments")));
2302 Assert(fcinfo.nargs == 2);
2304 /* if either argument is NULL they can't be equal */
2305 if (!fcinfo.argnull[0] && !fcinfo.argnull[1])
2307 fcinfo.isnull = false;
2308 result = FunctionCallInvoke(&fcinfo);
2309 /* if the arguments are equal return null */
2310 if (!fcinfo.isnull && DatumGetBool(result))
2317 /* else return first argument */
2318 *isNull = fcinfo.argnull[0];
2319 return fcinfo.arg[0];
2322 /* ----------------------------------------------------------------
2325 * Evaluate a NullTest node.
2326 * ----------------------------------------------------------------
2329 ExecEvalNullTest(GenericExprState *nstate,
2330 ExprContext *econtext,
2332 ExprDoneCond *isDone)
2334 NullTest *ntest = (NullTest *) nstate->xprstate.expr;
2337 result = ExecEvalExpr(nstate->arg, econtext, isNull, isDone);
2339 if (isDone && *isDone == ExprEndResult)
2340 return result; /* nothing to check */
2342 switch (ntest->nulltesttype)
2348 return BoolGetDatum(true);
2351 return BoolGetDatum(false);
2356 return BoolGetDatum(false);
2359 return BoolGetDatum(true);
2361 elog(ERROR, "unrecognized nulltesttype: %d",
2362 (int) ntest->nulltesttype);
2363 return (Datum) 0; /* keep compiler quiet */
2367 /* ----------------------------------------------------------------
2368 * ExecEvalBooleanTest
2370 * Evaluate a BooleanTest node.
2371 * ----------------------------------------------------------------
2374 ExecEvalBooleanTest(GenericExprState *bstate,
2375 ExprContext *econtext,
2377 ExprDoneCond *isDone)
2379 BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;
2382 result = ExecEvalExpr(bstate->arg, econtext, isNull, isDone);
2384 if (isDone && *isDone == ExprEndResult)
2385 return result; /* nothing to check */
2387 switch (btest->booltesttype)
2393 return BoolGetDatum(false);
2395 else if (DatumGetBool(result))
2396 return BoolGetDatum(true);
2398 return BoolGetDatum(false);
2403 return BoolGetDatum(true);
2405 else if (DatumGetBool(result))
2406 return BoolGetDatum(false);
2408 return BoolGetDatum(true);
2413 return BoolGetDatum(false);
2415 else if (DatumGetBool(result))
2416 return BoolGetDatum(false);
2418 return BoolGetDatum(true);
2423 return BoolGetDatum(true);
2425 else if (DatumGetBool(result))
2426 return BoolGetDatum(true);
2428 return BoolGetDatum(false);
2433 return BoolGetDatum(true);
2436 return BoolGetDatum(false);
2437 case IS_NOT_UNKNOWN:
2441 return BoolGetDatum(false);
2444 return BoolGetDatum(true);
2446 elog(ERROR, "unrecognized booltesttype: %d",
2447 (int) btest->booltesttype);
2448 return (Datum) 0; /* keep compiler quiet */
2453 * ExecEvalCoerceToDomain
2455 * Test the provided data against the domain constraint(s). If the data
2456 * passes the constraint specifications, pass it through (return the
2457 * datum) otherwise throw an error.
2460 ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
2461 bool *isNull, ExprDoneCond *isDone)
2463 CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
2467 result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
2469 if (isDone && *isDone == ExprEndResult)
2470 return result; /* nothing to check */
2472 foreach(l, cstate->constraints)
2474 DomainConstraintState *con = (DomainConstraintState *) lfirst(l);
2476 switch (con->constrainttype)
2478 case DOM_CONSTRAINT_NOTNULL:
2481 (errcode(ERRCODE_NOT_NULL_VIOLATION),
2482 errmsg("domain %s does not allow null values",
2483 format_type_be(ctest->resulttype))));
2485 case DOM_CONSTRAINT_CHECK:
2493 * Set up value to be returned by CoerceToDomainValue
2494 * nodes. We must save and restore prior setting of
2495 * econtext's domainValue fields, in case this node is
2496 * itself within a check expression for another
2499 save_datum = econtext->domainValue_datum;
2500 save_isNull = econtext->domainValue_isNull;
2502 econtext->domainValue_datum = result;
2503 econtext->domainValue_isNull = *isNull;
2505 conResult = ExecEvalExpr(con->check_expr,
2506 econtext, &conIsNull, NULL);
2509 !DatumGetBool(conResult))
2511 (errcode(ERRCODE_CHECK_VIOLATION),
2512 errmsg("value for domain %s violates check constraint \"%s\"",
2513 format_type_be(ctest->resulttype),
2515 econtext->domainValue_datum = save_datum;
2516 econtext->domainValue_isNull = save_isNull;
2521 elog(ERROR, "unrecognized constraint type: %d",
2522 (int) con->constrainttype);
2527 /* If all has gone well (constraints did not fail) return the datum */
2532 * ExecEvalCoerceToDomainValue
2534 * Return the value stored by CoerceToDomain.
2537 ExecEvalCoerceToDomainValue(ExprState *exprstate,
2538 ExprContext *econtext,
2539 bool *isNull, ExprDoneCond *isDone)
2542 *isDone = ExprSingleResult;
2543 *isNull = econtext->domainValue_isNull;
2544 return econtext->domainValue_datum;
2547 /* ----------------------------------------------------------------
2548 * ExecEvalFieldSelect
2550 * Evaluate a FieldSelect node.
2551 * ----------------------------------------------------------------
2554 ExecEvalFieldSelect(FieldSelectState *fstate,
2555 ExprContext *econtext,
2557 ExprDoneCond *isDone)
2559 FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
2562 HeapTupleHeader tuple;
2566 HeapTupleData tmptup;
2568 tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
2570 /* this test covers the isDone exception too: */
2574 tuple = DatumGetHeapTupleHeader(tupDatum);
2576 tupType = HeapTupleHeaderGetTypeId(tuple);
2577 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
2579 /* Lookup tupdesc if first time through or if type changes */
2580 tupDesc = fstate->argdesc;
2581 if (tupDesc == NULL ||
2582 tupType != tupDesc->tdtypeid ||
2583 tupTypmod != tupDesc->tdtypmod)
2585 MemoryContext oldcontext;
2587 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
2588 /* Copy the tupdesc into query storage for safety */
2589 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2590 tupDesc = CreateTupleDescCopy(tupDesc);
2591 if (fstate->argdesc)
2592 FreeTupleDesc(fstate->argdesc);
2593 fstate->argdesc = tupDesc;
2594 MemoryContextSwitchTo(oldcontext);
2598 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set
2599 * all the fields in the struct just in case user tries to inspect
2602 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2603 ItemPointerSetInvalid(&(tmptup.t_self));
2604 tmptup.t_tableOid = InvalidOid;
2605 tmptup.t_data = tuple;
2607 result = heap_getattr(&tmptup,
2614 /* ----------------------------------------------------------------
2615 * ExecEvalFieldStore
2617 * Evaluate a FieldStore node.
2618 * ----------------------------------------------------------------
2621 ExecEvalFieldStore(FieldStoreState *fstate,
2622 ExprContext *econtext,
2624 ExprDoneCond *isDone)
2626 FieldStore *fstore = (FieldStore *) fstate->xprstate.expr;
2637 tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
2639 if (isDone && *isDone == ExprEndResult)
2642 /* Lookup tupdesc if first time through or if type changes */
2643 tupDesc = fstate->argdesc;
2644 if (tupDesc == NULL ||
2645 fstore->resulttype != tupDesc->tdtypeid)
2647 MemoryContext oldcontext;
2649 tupDesc = lookup_rowtype_tupdesc(fstore->resulttype, -1);
2650 /* Copy the tupdesc into query storage for safety */
2651 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2652 tupDesc = CreateTupleDescCopy(tupDesc);
2653 if (fstate->argdesc)
2654 FreeTupleDesc(fstate->argdesc);
2655 fstate->argdesc = tupDesc;
2656 MemoryContextSwitchTo(oldcontext);
2659 /* Allocate workspace */
2660 values = (Datum *) palloc(tupDesc->natts * sizeof(Datum));
2661 nulls = (char *) palloc(tupDesc->natts * sizeof(char));
2666 * heap_deformtuple needs a HeapTuple not a bare HeapTupleHeader.
2667 * We set all the fields in the struct just in case.
2669 HeapTupleHeader tuphdr;
2670 HeapTupleData tmptup;
2672 tuphdr = DatumGetHeapTupleHeader(tupDatum);
2673 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuphdr);
2674 ItemPointerSetInvalid(&(tmptup.t_self));
2675 tmptup.t_tableOid = InvalidOid;
2676 tmptup.t_data = tuphdr;
2678 heap_deformtuple(&tmptup, tupDesc, values, nulls);
2682 /* Convert null input tuple into an all-nulls row */
2683 memset(nulls, 'n', tupDesc->natts * sizeof(char));
2686 /* Result is never null */
2689 save_datum = econtext->caseValue_datum;
2690 save_isNull = econtext->caseValue_isNull;
2692 forboth(l1, fstate->newvals, l2, fstore->fieldnums)
2694 ExprState *newval = (ExprState *) lfirst(l1);
2695 AttrNumber fieldnum = lfirst_int(l2);
2698 Assert(fieldnum > 0 && fieldnum <= tupDesc->natts);
2701 * Use the CaseTestExpr mechanism to pass down the old value of
2702 * the field being replaced; this is useful in case we have a
2703 * nested field update situation. It's safe to reuse the CASE
2704 * mechanism because there cannot be a CASE between here and where
2705 * the value would be needed.
2707 econtext->caseValue_datum = values[fieldnum - 1];
2708 econtext->caseValue_isNull = (nulls[fieldnum - 1] == 'n');
2710 values[fieldnum - 1] = ExecEvalExpr(newval,
2714 nulls[fieldnum - 1] = eisnull ? 'n' : ' ';
2717 econtext->caseValue_datum = save_datum;
2718 econtext->caseValue_isNull = save_isNull;
2720 tuple = heap_formtuple(tupDesc, values, nulls);
2725 return HeapTupleGetDatum(tuple);
2728 /* ----------------------------------------------------------------
2729 * ExecEvalRelabelType
2731 * Evaluate a RelabelType node.
2732 * ----------------------------------------------------------------
2735 ExecEvalRelabelType(GenericExprState *exprstate,
2736 ExprContext *econtext,
2737 bool *isNull, ExprDoneCond *isDone)
2739 return ExecEvalExpr(exprstate->arg, econtext, isNull, isDone);
2744 * ExecEvalExprSwitchContext
2746 * Same as ExecEvalExpr, but get into the right allocation context explicitly.
2749 ExecEvalExprSwitchContext(ExprState *expression,
2750 ExprContext *econtext,
2752 ExprDoneCond *isDone)
2755 MemoryContext oldContext;
2757 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
2758 retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
2759 MemoryContextSwitchTo(oldContext);
2765 * ExecInitExpr: prepare an expression tree for execution
2767 * This function builds and returns an ExprState tree paralleling the given
2768 * Expr node tree. The ExprState tree can then be handed to ExecEvalExpr
2769 * for execution. Because the Expr tree itself is read-only as far as
2770 * ExecInitExpr and ExecEvalExpr are concerned, several different executions
2771 * of the same plan tree can occur concurrently.
2773 * This must be called in a memory context that will last as long as repeated
2774 * executions of the expression are needed. Typically the context will be
2775 * the same as the per-query context of the associated ExprContext.
2777 * Any Aggref and SubPlan nodes found in the tree are added to the lists
2778 * of such nodes held by the parent PlanState. Otherwise, we do very little
2779 * initialization here other than building the state-node tree. Any nontrivial
2780 * work associated with initializing runtime info for a node should happen
2781 * during the first actual evaluation of that node. (This policy lets us
2782 * avoid work if the node is never actually evaluated.)
2784 * Note: there is no ExecEndExpr function; we assume that any resource
2785 * cleanup needed will be handled by just releasing the memory context
2786 * in which the state tree is built. Functions that require additional
2787 * cleanup work can register a shutdown callback in the ExprContext.
2789 * 'node' is the root of the expression tree to examine
2790 * 'parent' is the PlanState node that owns the expression.
2792 * 'parent' may be NULL if we are preparing an expression that is not
2793 * associated with a plan tree. (If so, it can't have aggs or subplans.)
2794 * This case should usually come through ExecPrepareExpr, not directly here.
2797 ExecInitExpr(Expr *node, PlanState *parent)
2804 /* Guard against stack overflow due to overly complex expressions */
2805 check_stack_depth();
2807 switch (nodeTag(node))
2810 state = (ExprState *) makeNode(ExprState);
2811 state->evalfunc = ExecEvalVar;
2814 state = (ExprState *) makeNode(ExprState);
2815 state->evalfunc = ExecEvalConst;
2818 state = (ExprState *) makeNode(ExprState);
2819 state->evalfunc = ExecEvalParam;
2821 case T_CoerceToDomainValue:
2822 state = (ExprState *) makeNode(ExprState);
2823 state->evalfunc = ExecEvalCoerceToDomainValue;
2825 case T_CaseTestExpr:
2826 state = (ExprState *) makeNode(ExprState);
2827 state->evalfunc = ExecEvalCaseTestExpr;
2831 Aggref *aggref = (Aggref *) node;
2832 AggrefExprState *astate = makeNode(AggrefExprState);
2834 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAggref;
2835 if (parent && IsA(parent, AggState))
2837 AggState *aggstate = (AggState *) parent;
2840 aggstate->aggs = lcons(astate, aggstate->aggs);
2841 naggs = ++aggstate->numaggs;
2843 astate->target = ExecInitExpr(aggref->target, parent);
2846 * Complain if the aggregate's argument contains any
2847 * aggregates; nested agg functions are semantically
2848 * nonsensical. (This should have been caught
2849 * earlier, but we defend against it here anyway.)
2851 if (naggs != aggstate->numaggs)
2853 (errcode(ERRCODE_GROUPING_ERROR),
2854 errmsg("aggregate function calls may not be nested")));
2858 /* planner messed up */
2859 elog(ERROR, "aggref found in non-Agg plan node");
2861 state = (ExprState *) astate;
2866 ArrayRef *aref = (ArrayRef *) node;
2867 ArrayRefExprState *astate = makeNode(ArrayRefExprState);
2869 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayRef;
2870 astate->refupperindexpr = (List *)
2871 ExecInitExpr((Expr *) aref->refupperindexpr, parent);
2872 astate->reflowerindexpr = (List *)
2873 ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
2874 astate->refexpr = ExecInitExpr(aref->refexpr, parent);
2875 astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
2877 /* do one-time catalog lookups for type info */
2878 astate->refattrlength = get_typlen(aref->refarraytype);
2879 get_typlenbyvalalign(aref->refelemtype,
2880 &astate->refelemlength,
2881 &astate->refelembyval,
2882 &astate->refelemalign);
2883 state = (ExprState *) astate;
2888 FuncExpr *funcexpr = (FuncExpr *) node;
2889 FuncExprState *fstate = makeNode(FuncExprState);
2891 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFunc;
2892 fstate->args = (List *)
2893 ExecInitExpr((Expr *) funcexpr->args, parent);
2894 fstate->func.fn_oid = InvalidOid; /* not initialized */
2895 state = (ExprState *) fstate;
2900 OpExpr *opexpr = (OpExpr *) node;
2901 FuncExprState *fstate = makeNode(FuncExprState);
2903 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOper;
2904 fstate->args = (List *)
2905 ExecInitExpr((Expr *) opexpr->args, parent);
2906 fstate->func.fn_oid = InvalidOid; /* not initialized */
2907 state = (ExprState *) fstate;
2910 case T_DistinctExpr:
2912 DistinctExpr *distinctexpr = (DistinctExpr *) node;
2913 FuncExprState *fstate = makeNode(FuncExprState);
2915 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalDistinct;
2916 fstate->args = (List *)
2917 ExecInitExpr((Expr *) distinctexpr->args, parent);
2918 fstate->func.fn_oid = InvalidOid; /* not initialized */
2919 state = (ExprState *) fstate;
2922 case T_ScalarArrayOpExpr:
2924 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
2925 ScalarArrayOpExprState *sstate = makeNode(ScalarArrayOpExprState);
2927 sstate->fxprstate.xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalScalarArrayOp;
2928 sstate->fxprstate.args = (List *)
2929 ExecInitExpr((Expr *) opexpr->args, parent);
2930 sstate->fxprstate.func.fn_oid = InvalidOid; /* not initialized */
2931 sstate->element_type = InvalidOid; /* ditto */
2932 state = (ExprState *) sstate;
2937 BoolExpr *boolexpr = (BoolExpr *) node;
2938 BoolExprState *bstate = makeNode(BoolExprState);
2940 switch (boolexpr->boolop)
2943 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAnd;
2946 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOr;
2949 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNot;
2952 elog(ERROR, "unrecognized boolop: %d",
2953 (int) boolexpr->boolop);
2956 bstate->args = (List *)
2957 ExecInitExpr((Expr *) boolexpr->args, parent);
2958 state = (ExprState *) bstate;
2963 /* Keep this in sync with ExecInitExprInitPlan, below */
2964 SubPlan *subplan = (SubPlan *) node;
2965 SubPlanState *sstate = makeNode(SubPlanState);
2967 sstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecSubPlan;
2970 elog(ERROR, "SubPlan found with no parent plan");
2973 * Here we just add the SubPlanState nodes to
2974 * parent->subPlan. The subplans will be initialized
2977 parent->subPlan = lcons(sstate, parent->subPlan);
2978 sstate->sub_estate = NULL;
2979 sstate->planstate = NULL;
2981 sstate->exprs = (List *)
2982 ExecInitExpr((Expr *) subplan->exprs, parent);
2983 sstate->args = (List *)
2984 ExecInitExpr((Expr *) subplan->args, parent);
2986 state = (ExprState *) sstate;
2991 FieldSelect *fselect = (FieldSelect *) node;
2992 FieldSelectState *fstate = makeNode(FieldSelectState);
2994 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldSelect;
2995 fstate->arg = ExecInitExpr(fselect->arg, parent);
2996 fstate->argdesc = NULL;
2997 state = (ExprState *) fstate;
3002 FieldStore *fstore = (FieldStore *) node;
3003 FieldStoreState *fstate = makeNode(FieldStoreState);
3005 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldStore;
3006 fstate->arg = ExecInitExpr(fstore->arg, parent);
3007 fstate->newvals = (List *) ExecInitExpr((Expr *) fstore->newvals, parent);
3008 fstate->argdesc = NULL;
3009 state = (ExprState *) fstate;
3014 RelabelType *relabel = (RelabelType *) node;
3015 GenericExprState *gstate = makeNode(GenericExprState);
3017 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRelabelType;
3018 gstate->arg = ExecInitExpr(relabel->arg, parent);
3019 state = (ExprState *) gstate;
3022 case T_ConvertRowtypeExpr:
3024 ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) node;
3025 ConvertRowtypeExprState *cstate = makeNode(ConvertRowtypeExprState);
3029 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalConvertRowtype;
3030 cstate->arg = ExecInitExpr(convert->arg, parent);
3031 /* save copies of needed tuple descriptors */
3032 cstate->indesc = lookup_rowtype_tupdesc(exprType((Node *) convert->arg), -1);
3033 cstate->indesc = CreateTupleDescCopy(cstate->indesc);
3034 cstate->outdesc = lookup_rowtype_tupdesc(convert->resulttype, -1);
3035 cstate->outdesc = CreateTupleDescCopy(cstate->outdesc);
3036 /* prepare map from old to new attribute numbers */
3037 n = cstate->outdesc->natts;
3038 cstate->attrMap = (AttrNumber *) palloc0(n * sizeof(AttrNumber));
3039 for (i = 0; i < n; i++)
3041 Form_pg_attribute att = cstate->outdesc->attrs[i];
3047 if (att->attisdropped)
3048 continue; /* attrMap[i] is already 0 */
3049 attname = NameStr(att->attname);
3050 atttypid = att->atttypid;
3051 atttypmod = att->atttypmod;
3052 for (j = 0; j < cstate->indesc->natts; j++)
3054 att = cstate->indesc->attrs[j];
3055 if (att->attisdropped)
3057 if (strcmp(attname, NameStr(att->attname)) == 0)
3059 /* Found it, check type */
3060 if (atttypid != att->atttypid || atttypmod != att->atttypmod)
3061 elog(ERROR, "attribute \"%s\" of type %s does not match corresponding attribute of type %s",
3063 format_type_be(cstate->indesc->tdtypeid),
3064 format_type_be(cstate->outdesc->tdtypeid));
3065 cstate->attrMap[i] = (AttrNumber) (j + 1);
3069 if (cstate->attrMap[i] == 0)
3070 elog(ERROR, "attribute \"%s\" of type %s does not exist",
3072 format_type_be(cstate->indesc->tdtypeid));
3074 /* preallocate workspace for Datum arrays */
3075 n = cstate->indesc->natts + 1; /* +1 for NULL */
3076 cstate->invalues = (Datum *) palloc(n * sizeof(Datum));
3077 cstate->innulls = (char *) palloc(n * sizeof(char));
3078 n = cstate->outdesc->natts;
3079 cstate->outvalues = (Datum *) palloc(n * sizeof(Datum));
3080 cstate->outnulls = (char *) palloc(n * sizeof(char));
3081 state = (ExprState *) cstate;
3086 CaseExpr *caseexpr = (CaseExpr *) node;
3087 CaseExprState *cstate = makeNode(CaseExprState);
3088 List *outlist = NIL;
3091 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCase;
3092 cstate->arg = ExecInitExpr(caseexpr->arg, parent);
3093 foreach(l, caseexpr->args)
3095 CaseWhen *when = (CaseWhen *) lfirst(l);
3096 CaseWhenState *wstate = makeNode(CaseWhenState);
3098 Assert(IsA(when, CaseWhen));
3099 wstate->xprstate.evalfunc = NULL; /* not used */
3100 wstate->xprstate.expr = (Expr *) when;
3101 wstate->expr = ExecInitExpr(when->expr, parent);
3102 wstate->result = ExecInitExpr(when->result, parent);
3103 outlist = lappend(outlist, wstate);
3105 cstate->args = outlist;
3106 cstate->defresult = ExecInitExpr(caseexpr->defresult, parent);
3107 state = (ExprState *) cstate;
3112 ArrayExpr *arrayexpr = (ArrayExpr *) node;
3113 ArrayExprState *astate = makeNode(ArrayExprState);
3114 List *outlist = NIL;
3117 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArray;
3118 foreach(l, arrayexpr->elements)
3120 Expr *e = (Expr *) lfirst(l);
3123 estate = ExecInitExpr(e, parent);
3124 outlist = lappend(outlist, estate);
3126 astate->elements = outlist;
3127 /* do one-time catalog lookup for type info */
3128 get_typlenbyvalalign(arrayexpr->element_typeid,
3129 &astate->elemlength,
3131 &astate->elemalign);
3132 state = (ExprState *) astate;
3137 RowExpr *rowexpr = (RowExpr *) node;
3138 RowExprState *rstate = makeNode(RowExprState);
3139 Form_pg_attribute *attrs;
3140 List *outlist = NIL;
3144 rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRow;
3145 /* Build tupdesc to describe result tuples */
3146 if (rowexpr->row_typeid == RECORDOID)
3148 /* generic record, use runtime type assignment */
3149 rstate->tupdesc = ExecTypeFromExprList(rowexpr->args);
3150 rstate->tupdesc = BlessTupleDesc(rstate->tupdesc);
3154 /* it's been cast to a named type, use that */
3155 rstate->tupdesc = lookup_rowtype_tupdesc(rowexpr->row_typeid, -1);
3156 rstate->tupdesc = CreateTupleDescCopy(rstate->tupdesc);
3158 /* Set up evaluation, skipping any deleted columns */
3159 Assert(list_length(rowexpr->args) <= rstate->tupdesc->natts);
3160 attrs = rstate->tupdesc->attrs;
3162 foreach(l, rowexpr->args)
3164 Expr *e = (Expr *) lfirst(l);
3167 if (!attrs[i]->attisdropped)
3170 * Guard against ALTER COLUMN TYPE on rowtype
3171 * since the RowExpr was created. XXX should we
3172 * check typmod too? Not sure we can be sure
3173 * it'll be the same.
3175 if (exprType((Node *) e) != attrs[i]->atttypid)
3177 (errcode(ERRCODE_DATATYPE_MISMATCH),
3178 errmsg("ROW() column has type %s instead of type %s",
3179 format_type_be(exprType((Node *) e)),
3180 format_type_be(attrs[i]->atttypid))));
3185 * Ignore original expression and insert a NULL.
3186 * We don't really care what type of NULL it is,
3187 * so always make an int4 NULL.
3189 e = (Expr *) makeNullConst(INT4OID);
3191 estate = ExecInitExpr(e, parent);
3192 outlist = lappend(outlist, estate);
3195 rstate->args = outlist;
3196 state = (ExprState *) rstate;
3199 case T_CoalesceExpr:
3201 CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
3202 CoalesceExprState *cstate = makeNode(CoalesceExprState);
3203 List *outlist = NIL;
3206 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoalesce;
3207 foreach(l, coalesceexpr->args)
3209 Expr *e = (Expr *) lfirst(l);
3212 estate = ExecInitExpr(e, parent);
3213 outlist = lappend(outlist, estate);
3215 cstate->args = outlist;
3216 state = (ExprState *) cstate;
3221 NullIfExpr *nullifexpr = (NullIfExpr *) node;
3222 FuncExprState *fstate = makeNode(FuncExprState);
3224 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullIf;
3225 fstate->args = (List *)
3226 ExecInitExpr((Expr *) nullifexpr->args, parent);
3227 fstate->func.fn_oid = InvalidOid; /* not initialized */
3228 state = (ExprState *) fstate;
3233 NullTest *ntest = (NullTest *) node;
3234 GenericExprState *gstate = makeNode(GenericExprState);
3236 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullTest;
3237 gstate->arg = ExecInitExpr(ntest->arg, parent);
3238 state = (ExprState *) gstate;
3243 BooleanTest *btest = (BooleanTest *) node;
3244 GenericExprState *gstate = makeNode(GenericExprState);
3246 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalBooleanTest;
3247 gstate->arg = ExecInitExpr(btest->arg, parent);
3248 state = (ExprState *) gstate;
3251 case T_CoerceToDomain:
3253 CoerceToDomain *ctest = (CoerceToDomain *) node;
3254 CoerceToDomainState *cstate = makeNode(CoerceToDomainState);
3256 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceToDomain;
3257 cstate->arg = ExecInitExpr(ctest->arg, parent);
3258 cstate->constraints = GetDomainConstraints(ctest->resulttype);
3259 state = (ExprState *) cstate;
3264 TargetEntry *tle = (TargetEntry *) node;
3265 GenericExprState *gstate = makeNode(GenericExprState);
3267 gstate->xprstate.evalfunc = NULL; /* not used */
3268 gstate->arg = ExecInitExpr(tle->expr, parent);
3269 state = (ExprState *) gstate;
3274 List *outlist = NIL;
3277 foreach(l, (List *) node)
3279 outlist = lappend(outlist,
3280 ExecInitExpr((Expr *) lfirst(l),
3283 /* Don't fall through to the "common" code below */
3284 return (ExprState *) outlist;
3287 elog(ERROR, "unrecognized node type: %d",
3288 (int) nodeTag(node));
3289 state = NULL; /* keep compiler quiet */
3293 /* Common code for all state-node types */
3300 * ExecInitExprInitPlan --- initialize a subplan expr that's being handled
3301 * as an InitPlan. This is identical to ExecInitExpr's handling of a regular
3302 * subplan expr, except we do NOT want to add the node to the parent's
3306 ExecInitExprInitPlan(SubPlan *node, PlanState *parent)
3308 SubPlanState *sstate = makeNode(SubPlanState);
3311 elog(ERROR, "SubPlan found with no parent plan");
3313 /* The subplan's state will be initialized later */
3314 sstate->sub_estate = NULL;
3315 sstate->planstate = NULL;
3317 sstate->exprs = (List *) ExecInitExpr((Expr *) node->exprs, parent);
3318 sstate->args = (List *) ExecInitExpr((Expr *) node->args, parent);
3320 sstate->xprstate.expr = (Expr *) node;
3326 * ExecPrepareExpr --- initialize for expression execution outside a normal
3327 * Plan tree context.
3329 * This differs from ExecInitExpr in that we don't assume the caller is
3330 * already running in the EState's per-query context. Also, we apply
3331 * fix_opfuncids() to the passed expression tree to be sure it is ready
3332 * to run. (In ordinary Plan trees the planner will have fixed opfuncids,
3333 * but callers outside the executor will not have done this.)
3336 ExecPrepareExpr(Expr *node, EState *estate)
3339 MemoryContext oldcontext;
3341 fix_opfuncids((Node *) node);
3343 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
3345 result = ExecInitExpr(node, NULL);
3347 MemoryContextSwitchTo(oldcontext);
3353 /* ----------------------------------------------------------------
3354 * ExecQual / ExecTargetList / ExecProject
3355 * ----------------------------------------------------------------
3358 /* ----------------------------------------------------------------
3361 * Evaluates a conjunctive boolean expression (qual list) and
3362 * returns true iff none of the subexpressions are false.
3363 * (We also return true if the list is empty.)
3365 * If some of the subexpressions yield NULL but none yield FALSE,
3366 * then the result of the conjunction is NULL (ie, unknown)
3367 * according to three-valued boolean logic. In this case,
3368 * we return the value specified by the "resultForNull" parameter.
3370 * Callers evaluating WHERE clauses should pass resultForNull=FALSE,
3371 * since SQL specifies that tuples with null WHERE results do not
3372 * get selected. On the other hand, callers evaluating constraint
3373 * conditions should pass resultForNull=TRUE, since SQL also specifies
3374 * that NULL constraint conditions are not failures.
3376 * NOTE: it would not be correct to use this routine to evaluate an
3377 * AND subclause of a boolean expression; for that purpose, a NULL
3378 * result must be returned as NULL so that it can be properly treated
3379 * in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
3380 * This routine is only used in contexts where a complete expression
3381 * is being evaluated and we know that NULL can be treated the same
3382 * as one boolean result or the other.
3384 * ----------------------------------------------------------------
3387 ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
3390 MemoryContext oldContext;
3396 EV_printf("ExecQual: qual is ");
3397 EV_nodeDisplay(qual);
3403 * Run in short-lived per-tuple context while computing expressions.
3405 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
3408 * Evaluate the qual conditions one at a time. If we find a FALSE
3409 * result, we can stop evaluating and return FALSE --- the AND result
3410 * must be FALSE. Also, if we find a NULL result when resultForNull
3411 * is FALSE, we can stop and return FALSE --- the AND result must be
3412 * FALSE or NULL in that case, and the caller doesn't care which.
3414 * If we get to the end of the list, we can return TRUE. This will
3415 * happen when the AND result is indeed TRUE, or when the AND result
3416 * is NULL (one or more NULL subresult, with all the rest TRUE) and
3417 * the caller has specified resultForNull = TRUE.
3423 ExprState *clause = (ExprState *) lfirst(l);
3427 expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
3431 if (resultForNull == false)
3433 result = false; /* treat NULL as FALSE */
3439 if (!DatumGetBool(expr_value))
3441 result = false; /* definitely FALSE */
3447 MemoryContextSwitchTo(oldContext);
3453 * Number of items in a tlist (including any resjunk items!)
3456 ExecTargetListLength(List *targetlist)
3458 /* This used to be more complex, but fjoins are dead */
3459 return list_length(targetlist);
3463 * Number of items in a tlist, not including any resjunk items
3466 ExecCleanTargetListLength(List *targetlist)
3471 foreach(tl, targetlist)
3473 TargetEntry *curTle = (TargetEntry *) lfirst(tl);
3475 Assert(IsA(curTle, TargetEntry));
3476 if (!curTle->resdom->resjunk)
3482 /* ----------------------------------------------------------------
3485 * Evaluates a targetlist with respect to the given
3486 * expression context and returns a tuple.
3488 * The caller must pass workspace for the values and nulls arrays
3489 * as well as the itemIsDone array. This convention saves palloc'ing
3490 * workspace on each call, and some callers may find it useful to examine
3491 * the values array directly.
3493 * As with ExecEvalExpr, the caller should pass isDone = NULL if not
3494 * prepared to deal with sets of result tuples. Otherwise, a return
3495 * of *isDone = ExprMultipleResult signifies a set element, and a return
3496 * of *isDone = ExprEndResult signifies end of the set of tuple.
3497 * ----------------------------------------------------------------
3500 ExecTargetList(List *targetlist,
3501 TupleDesc targettype,
3502 ExprContext *econtext,
3505 ExprDoneCond *itemIsDone,
3506 ExprDoneCond *isDone)
3508 MemoryContext oldContext;
3516 EV_printf("ExecTargetList: tl is ");
3517 EV_nodeDisplay(targetlist);
3521 * Run in short-lived per-tuple context while computing expressions.
3523 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
3526 * There used to be some klugy and demonstrably broken code here that
3527 * special-cased the situation where targetlist == NIL. Now we just
3528 * fall through and return an empty-but-valid tuple.
3532 * evaluate all the expressions in the target list
3535 *isDone = ExprSingleResult; /* until proven otherwise */
3537 haveDoneSets = false; /* any exhausted set exprs in tlist? */
3539 foreach(tl, targetlist)
3541 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
3542 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
3543 AttrNumber resind = tle->resdom->resno - 1;
3545 values[resind] = ExecEvalExpr(gstate->arg,
3548 &itemIsDone[resind]);
3549 nulls[resind] = isNull ? 'n' : ' ';
3551 if (itemIsDone[resind] != ExprSingleResult)
3553 /* We have a set-valued expression in the tlist */
3556 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3557 errmsg("set-valued function called in context that cannot accept a set")));
3558 if (itemIsDone[resind] == ExprMultipleResult)
3560 /* we have undone sets in the tlist, set flag */
3561 *isDone = ExprMultipleResult;
3565 /* we have done sets in the tlist, set flag for that */
3566 haveDoneSets = true;
3574 * note: can't get here unless we verified isDone != NULL
3576 if (*isDone == ExprSingleResult)
3579 * all sets are done, so report that tlist expansion is
3582 *isDone = ExprEndResult;
3583 MemoryContextSwitchTo(oldContext);
3589 * We have some done and some undone sets. Restart the done
3590 * ones so that we can deliver a tuple (if possible).
3592 foreach(tl, targetlist)
3594 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
3595 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
3596 AttrNumber resind = tle->resdom->resno - 1;
3598 if (itemIsDone[resind] == ExprEndResult)
3600 values[resind] = ExecEvalExpr(gstate->arg,
3603 &itemIsDone[resind]);
3604 nulls[resind] = isNull ? 'n' : ' ';
3606 if (itemIsDone[resind] == ExprEndResult)
3609 * Oh dear, this item is returning an empty set.
3610 * Guess we can't make a tuple after all.
3612 *isDone = ExprEndResult;
3619 * If we cannot make a tuple because some sets are empty, we
3620 * still have to cycle the nonempty sets to completion, else
3621 * resources will not be released from subplans etc.
3623 * XXX is that still necessary?
3625 if (*isDone == ExprEndResult)
3627 foreach(tl, targetlist)
3629 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
3630 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
3631 AttrNumber resind = tle->resdom->resno - 1;
3633 while (itemIsDone[resind] == ExprMultipleResult)
3635 (void) ExecEvalExpr(gstate->arg,
3638 &itemIsDone[resind]);
3642 MemoryContextSwitchTo(oldContext);
3649 * form the new result tuple (in the caller's memory context!)
3651 MemoryContextSwitchTo(oldContext);
3653 return heap_formtuple(targettype, values, nulls);
3656 /* ----------------------------------------------------------------
3659 * projects a tuple based on projection info and stores
3660 * it in the specified tuple table slot.
3662 * Note: someday soon the executor can be extended to eliminate
3663 * redundant projections by storing pointers to datums
3664 * in the tuple table and then passing these around when
3665 * possible. this should make things much quicker.
3667 * ----------------------------------------------------------------
3670 ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
3672 TupleTableSlot *slot;
3679 if (projInfo == NULL)
3683 * get the projection info we want
3685 slot = projInfo->pi_slot;
3686 tupType = slot->ttc_tupleDescriptor;
3689 * form a new result tuple (if possible --- result can be NULL)
3691 newTuple = ExecTargetList(projInfo->pi_targetlist,
3693 projInfo->pi_exprContext,
3694 projInfo->pi_tupValues,
3695 projInfo->pi_tupNulls,
3696 projInfo->pi_itemIsDone,
3700 * store the tuple in the projection slot and return the slot.
3702 return ExecStoreTuple(newTuple, /* tuple to store */
3703 slot, /* slot to store in */
3704 InvalidBuffer, /* tuple has no buffer */