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.174 2005/03/22 20:13:06 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->tts_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 InitFunctionCallInfoData(fcinfo, &(fcache->func), 0, NULL, NULL);
836 argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);
837 if (argDone == ExprEndResult)
839 /* input is an empty set, so return an empty set. */
842 *isDone = ExprEndResult;
845 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
846 errmsg("set-valued function called in context that cannot accept a set")));
849 hasSetArg = (argDone != ExprSingleResult);
853 /* Copy callinfo from previous evaluation */
854 memcpy(&fcinfo, &fcache->setArgs, sizeof(fcinfo));
855 hasSetArg = fcache->setHasSetArg;
856 /* Reset flag (we may set it again below) */
857 fcache->setArgsValid = false;
861 * If function returns set, prepare a resultinfo node for
864 if (fcache->func.fn_retset)
866 fcinfo.resultinfo = (Node *) &rsinfo;
867 rsinfo.type = T_ReturnSetInfo;
868 rsinfo.econtext = econtext;
869 rsinfo.expectedDesc = NULL;
870 rsinfo.allowedModes = (int) SFRM_ValuePerCall;
871 rsinfo.returnMode = SFRM_ValuePerCall;
872 /* isDone is filled below */
873 rsinfo.setResult = NULL;
874 rsinfo.setDesc = NULL;
878 * now return the value gotten by calling the function manager,
879 * passing the function the evaluated parameter values.
881 if (fcache->func.fn_retset || hasSetArg)
884 * We need to return a set result. Complain if caller not ready
889 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
890 errmsg("set-valued function called in context that cannot accept a set")));
893 * This loop handles the situation where we have both a set
894 * argument and a set-valued function. Once we have exhausted the
895 * function's value(s) for a particular argument value, we have to
896 * get the next argument value and start the function over again.
897 * We might have to do it more than once, if the function produces
898 * an empty result set for a particular input value.
903 * If function is strict, and there are any NULL arguments,
904 * skip calling the function (at least for this set of args).
908 if (fcache->func.fn_strict)
910 for (i = 0; i < fcinfo.nargs; i++)
912 if (fcinfo.argnull[i])
922 fcinfo.isnull = false;
923 rsinfo.isDone = ExprSingleResult;
924 result = FunctionCallInvoke(&fcinfo);
925 *isNull = fcinfo.isnull;
926 *isDone = rsinfo.isDone;
932 *isDone = ExprEndResult;
935 if (*isDone != ExprEndResult)
938 * Got a result from current argument. If function itself
939 * returns set, save the current argument values to re-use
942 if (fcache->func.fn_retset)
944 memcpy(&fcache->setArgs, &fcinfo, sizeof(fcinfo));
945 fcache->setHasSetArg = hasSetArg;
946 fcache->setArgsValid = true;
947 /* Register cleanup callback if we didn't already */
948 if (!fcache->shutdown_reg)
950 RegisterExprContextCallback(econtext,
952 PointerGetDatum(fcache));
953 fcache->shutdown_reg = true;
958 * Make sure we say we are returning a set, even if the
959 * function itself doesn't return sets.
961 *isDone = ExprMultipleResult;
965 /* Else, done with this argument */
967 break; /* input not a set, so done */
969 /* Re-eval args to get the next element of the input set */
970 argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);
972 if (argDone != ExprMultipleResult)
974 /* End of argument set, so we're done. */
976 *isDone = ExprEndResult;
982 * If we reach here, loop around to run the function on the
990 * Non-set case: much easier.
992 * We change the ExprState function pointer to use the simpler
993 * ExecMakeFunctionResultNoSets on subsequent calls. This amounts
994 * to assuming that no argument can return a set if it didn't do
997 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResultNoSets;
1000 *isDone = ExprSingleResult;
1003 * If function is strict, and there are any NULL arguments, skip
1004 * calling the function and return NULL.
1006 if (fcache->func.fn_strict)
1008 for (i = 0; i < fcinfo.nargs; i++)
1010 if (fcinfo.argnull[i])
1017 fcinfo.isnull = false;
1018 result = FunctionCallInvoke(&fcinfo);
1019 *isNull = fcinfo.isnull;
1026 * ExecMakeFunctionResultNoSets
1028 * Simplified version of ExecMakeFunctionResult that can only handle
1029 * non-set cases. Hand-tuned for speed.
1032 ExecMakeFunctionResultNoSets(FuncExprState *fcache,
1033 ExprContext *econtext,
1035 ExprDoneCond *isDone)
1039 FunctionCallInfoData fcinfo;
1042 /* Guard against stack overflow due to overly complex expressions */
1043 check_stack_depth();
1046 *isDone = ExprSingleResult;
1048 /* inlined, simplified version of ExecEvalFuncArgs */
1050 foreach(arg, fcache->args)
1052 ExprState *argstate = (ExprState *) lfirst(arg);
1053 ExprDoneCond thisArgIsDone;
1055 fcinfo.arg[i] = ExecEvalExpr(argstate,
1060 if (thisArgIsDone != ExprSingleResult)
1062 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1063 errmsg("set-valued function called in context that cannot accept a set")));
1067 InitFunctionCallInfoData(fcinfo, &(fcache->func), i, NULL, NULL);
1070 * If function is strict, and there are any NULL arguments, skip
1071 * calling the function and return NULL.
1073 if (fcache->func.fn_strict)
1077 if (fcinfo.argnull[i])
1084 /* fcinfo.isnull = false; */ /* handled by InitFunctionCallInfoData */
1085 result = FunctionCallInvoke(&fcinfo);
1086 *isNull = fcinfo.isnull;
1093 * ExecMakeTableFunctionResult
1095 * Evaluate a table function, producing a materialized result in a Tuplestore
1096 * object. *returnDesc is set to the tupledesc actually returned by the
1097 * function, or NULL if it didn't provide one.
1100 ExecMakeTableFunctionResult(ExprState *funcexpr,
1101 ExprContext *econtext,
1102 TupleDesc expectedDesc,
1103 TupleDesc *returnDesc)
1105 Tuplestorestate *tupstore = NULL;
1106 TupleDesc tupdesc = NULL;
1109 bool returnsSet = false;
1110 FunctionCallInfoData fcinfo;
1111 ReturnSetInfo rsinfo;
1112 HeapTupleData tmptup;
1113 MemoryContext callerContext;
1114 MemoryContext oldcontext;
1115 bool direct_function_call;
1116 bool first_time = true;
1118 callerContext = CurrentMemoryContext;
1120 funcrettype = exprType((Node *) funcexpr->expr);
1122 returnsTuple = (funcrettype == RECORDOID ||
1123 get_typtype(funcrettype) == 'c');
1126 * Prepare a resultinfo node for communication. We always do this
1127 * even if not expecting a set result, so that we can pass
1128 * expectedDesc. In the generic-expression case, the expression
1129 * doesn't actually get to see the resultinfo, but set it up anyway
1130 * because we use some of the fields as our own state variables.
1132 InitFunctionCallInfoData(fcinfo, NULL, 0, NULL, (Node *) &rsinfo);
1133 rsinfo.type = T_ReturnSetInfo;
1134 rsinfo.econtext = econtext;
1135 rsinfo.expectedDesc = expectedDesc;
1136 rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
1137 rsinfo.returnMode = SFRM_ValuePerCall;
1138 /* isDone is filled below */
1139 rsinfo.setResult = NULL;
1140 rsinfo.setDesc = NULL;
1143 * Normally the passed expression tree will be a FuncExprState, since
1144 * the grammar only allows a function call at the top level of a table
1145 * function reference. However, if the function doesn't return set
1146 * then the planner might have replaced the function call via
1147 * constant-folding or inlining. So if we see any other kind of
1148 * expression node, execute it via the general ExecEvalExpr() code;
1149 * the only difference is that we don't get a chance to pass a special
1150 * ReturnSetInfo to any functions buried in the expression.
1152 if (funcexpr && IsA(funcexpr, FuncExprState) &&
1153 IsA(funcexpr->expr, FuncExpr))
1155 FuncExprState *fcache = (FuncExprState *) funcexpr;
1156 ExprDoneCond argDone;
1159 * This path is similar to ExecMakeFunctionResult.
1161 direct_function_call = true;
1164 * Initialize function cache if first time through
1166 if (fcache->func.fn_oid == InvalidOid)
1168 FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
1170 init_fcache(func->funcid, fcache, econtext->ecxt_per_query_memory);
1172 returnsSet = fcache->func.fn_retset;
1175 * Evaluate the function's argument list.
1177 * Note: ideally, we'd do this in the per-tuple context, but then the
1178 * argument values would disappear when we reset the context in
1179 * the inner loop. So do it in caller context. Perhaps we should
1180 * make a separate context just to hold the evaluated arguments?
1182 fcinfo.flinfo = &(fcache->func);
1183 argDone = ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
1184 /* We don't allow sets in the arguments of the table function */
1185 if (argDone != ExprSingleResult)
1187 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1188 errmsg("set-valued function called in context that cannot accept a set")));
1191 * If function is strict, and there are any NULL arguments, skip
1192 * calling the function and act like it returned NULL (or an empty
1193 * set, in the returns-set case).
1195 if (fcache->func.fn_strict)
1199 for (i = 0; i < fcinfo.nargs; i++)
1201 if (fcinfo.argnull[i])
1202 goto no_function_result;
1208 /* Treat funcexpr as a generic expression */
1209 direct_function_call = false;
1213 * Switch to short-lived context for calling the function or
1216 MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1219 * Loop to handle the ValuePerCall protocol (which is also the same
1220 * behavior needed in the generic ExecEvalExpr path).
1228 * reset per-tuple memory context before each call of the function
1229 * or expression. This cleans up any local memory the function may
1232 ResetExprContext(econtext);
1234 /* Call the function or expression one time */
1235 if (direct_function_call)
1237 fcinfo.isnull = false;
1238 rsinfo.isDone = ExprSingleResult;
1239 result = FunctionCallInvoke(&fcinfo);
1243 result = ExecEvalExpr(funcexpr, econtext,
1244 &fcinfo.isnull, &rsinfo.isDone);
1247 /* Which protocol does function want to use? */
1248 if (rsinfo.returnMode == SFRM_ValuePerCall)
1251 * Check for end of result set.
1253 if (rsinfo.isDone == ExprEndResult)
1257 * Can't do anything very useful with NULL rowtype values.
1258 * For a function returning set, we consider this a protocol
1259 * violation (but another alternative would be to just ignore
1260 * the result and "continue" to get another row). For a function
1261 * not returning set, we fall out of the loop; we'll cons up
1262 * an all-nulls result row below.
1264 if (returnsTuple && fcinfo.isnull)
1269 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1270 errmsg("function returning set of rows cannot return null value")));
1274 * If first time through, build tupdesc and tuplestore for
1279 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1283 * Use the type info embedded in the rowtype Datum to
1284 * look up the needed tupdesc. Make a copy for the
1289 td = DatumGetHeapTupleHeader(result);
1290 tupdesc = lookup_rowtype_tupdesc(HeapTupleHeaderGetTypeId(td),
1291 HeapTupleHeaderGetTypMod(td));
1292 tupdesc = CreateTupleDescCopy(tupdesc);
1297 * Scalar type, so make a single-column descriptor
1299 tupdesc = CreateTemplateTupleDesc(1, false);
1300 TupleDescInitEntry(tupdesc,
1307 tupstore = tuplestore_begin_heap(true, false, work_mem);
1308 MemoryContextSwitchTo(oldcontext);
1309 rsinfo.setResult = tupstore;
1310 rsinfo.setDesc = tupdesc;
1314 * Store current resultset item.
1320 td = DatumGetHeapTupleHeader(result);
1323 * tuplestore_puttuple needs a HeapTuple not a bare
1324 * HeapTupleHeader, but it doesn't need all the fields.
1326 tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
1332 tuple = heap_form_tuple(tupdesc, &result, &fcinfo.isnull);
1335 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1336 tuplestore_puttuple(tupstore, tuple);
1337 MemoryContextSwitchTo(oldcontext);
1342 if (rsinfo.isDone != ExprMultipleResult)
1345 else if (rsinfo.returnMode == SFRM_Materialize)
1347 /* check we're on the same page as the function author */
1348 if (!first_time || rsinfo.isDone != ExprSingleResult)
1350 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1351 errmsg("table-function protocol for materialize mode was not followed")));
1352 /* Done evaluating the set result */
1357 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1358 errmsg("unrecognized table-function returnMode: %d",
1359 (int) rsinfo.returnMode)));
1367 * If we got nothing from the function (ie, an empty-set or NULL result),
1368 * we have to create the tuplestore to return, and if it's a
1369 * non-set-returning function then insert a single all-nulls row.
1371 if (rsinfo.setResult == NULL)
1373 MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1374 tupstore = tuplestore_begin_heap(true, false, work_mem);
1375 rsinfo.setResult = tupstore;
1378 int natts = expectedDesc->natts;
1383 MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1384 nulldatums = (Datum *) palloc0(natts * sizeof(Datum));
1385 nullflags = (bool *) palloc(natts * sizeof(bool));
1386 memset(nullflags, true, natts * sizeof(bool));
1387 tuple = heap_form_tuple(expectedDesc, nulldatums, nullflags);
1388 MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1389 tuplestore_puttuple(tupstore, tuple);
1393 MemoryContextSwitchTo(callerContext);
1395 /* The returned pointers are those in rsinfo */
1396 *returnDesc = rsinfo.setDesc;
1397 return rsinfo.setResult;
1401 /* ----------------------------------------------------------------
1405 * Evaluate the functional result of a list of arguments by calling the
1407 * ----------------------------------------------------------------
1410 /* ----------------------------------------------------------------
1412 * ----------------------------------------------------------------
1415 ExecEvalFunc(FuncExprState *fcache,
1416 ExprContext *econtext,
1418 ExprDoneCond *isDone)
1420 /* This is called only the first time through */
1421 FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
1423 /* Initialize function lookup info */
1424 init_fcache(func->funcid, fcache, econtext->ecxt_per_query_memory);
1426 /* Go directly to ExecMakeFunctionResult on subsequent uses */
1427 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
1429 return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
1432 /* ----------------------------------------------------------------
1434 * ----------------------------------------------------------------
1437 ExecEvalOper(FuncExprState *fcache,
1438 ExprContext *econtext,
1440 ExprDoneCond *isDone)
1442 /* This is called only the first time through */
1443 OpExpr *op = (OpExpr *) fcache->xprstate.expr;
1445 /* Initialize function lookup info */
1446 init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory);
1448 /* Go directly to ExecMakeFunctionResult on subsequent uses */
1449 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
1451 return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
1454 /* ----------------------------------------------------------------
1457 * IS DISTINCT FROM must evaluate arguments to determine whether
1458 * they are NULL; if either is NULL then the result is already
1459 * known. If neither is NULL, then proceed to evaluate the
1460 * function. Note that this is *always* derived from the equals
1461 * operator, but since we need special processing of the arguments
1462 * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
1463 * ----------------------------------------------------------------
1466 ExecEvalDistinct(FuncExprState *fcache,
1467 ExprContext *econtext,
1469 ExprDoneCond *isDone)
1472 FunctionCallInfoData fcinfo;
1473 ExprDoneCond argDone;
1476 /* Set default values for result flags: non-null, not a set result */
1479 *isDone = ExprSingleResult;
1482 * Initialize function cache if first time through
1484 if (fcache->func.fn_oid == InvalidOid)
1486 DistinctExpr *op = (DistinctExpr *) fcache->xprstate.expr;
1488 init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory);
1489 Assert(!fcache->func.fn_retset);
1493 * extract info from fcache
1495 argList = fcache->args;
1497 /* Need to prep callinfo structure */
1498 InitFunctionCallInfoData(fcinfo, &(fcache->func), 0, NULL, NULL);
1499 argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
1500 if (argDone != ExprSingleResult)
1502 (errcode(ERRCODE_DATATYPE_MISMATCH),
1503 errmsg("IS DISTINCT FROM does not support set arguments")));
1504 Assert(fcinfo.nargs == 2);
1506 if (fcinfo.argnull[0] && fcinfo.argnull[1])
1508 /* Both NULL? Then is not distinct... */
1509 result = BoolGetDatum(FALSE);
1511 else if (fcinfo.argnull[0] || fcinfo.argnull[1])
1513 /* Only one is NULL? Then is distinct... */
1514 result = BoolGetDatum(TRUE);
1518 fcinfo.isnull = false;
1519 result = FunctionCallInvoke(&fcinfo);
1520 *isNull = fcinfo.isnull;
1521 /* Must invert result of "=" */
1522 result = BoolGetDatum(!DatumGetBool(result));
1529 * ExecEvalScalarArrayOp
1531 * Evaluate "scalar op ANY/ALL (array)". The operator always yields boolean,
1532 * and we combine the results across all array elements using OR and AND
1533 * (for ANY and ALL respectively). Of course we short-circuit as soon as
1534 * the result is known.
1537 ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
1538 ExprContext *econtext,
1539 bool *isNull, ExprDoneCond *isDone)
1541 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) sstate->fxprstate.xprstate.expr;
1542 bool useOr = opexpr->useOr;
1547 FunctionCallInfoData fcinfo;
1548 ExprDoneCond argDone;
1555 /* Set default values for result flags: non-null, not a set result */
1558 *isDone = ExprSingleResult;
1561 * Initialize function cache if first time through
1563 if (sstate->fxprstate.func.fn_oid == InvalidOid)
1565 init_fcache(opexpr->opfuncid, &sstate->fxprstate,
1566 econtext->ecxt_per_query_memory);
1567 Assert(!sstate->fxprstate.func.fn_retset);
1570 /* Need to prep callinfo structure */
1571 InitFunctionCallInfoData(fcinfo, &(sstate->fxprstate.func), 0, NULL, NULL);
1572 argDone = ExecEvalFuncArgs(&fcinfo, sstate->fxprstate.args, econtext);
1573 if (argDone != ExprSingleResult)
1575 (errcode(ERRCODE_DATATYPE_MISMATCH),
1576 errmsg("op ANY/ALL (array) does not support set arguments")));
1577 Assert(fcinfo.nargs == 2);
1580 * If the array is NULL then we return NULL --- it's not very
1581 * meaningful to do anything else, even if the operator isn't strict.
1583 if (fcinfo.argnull[1])
1588 /* Else okay to fetch and detoast the array */
1589 arr = DatumGetArrayTypeP(fcinfo.arg[1]);
1592 * If the array is empty, we return either FALSE or TRUE per the useOr
1593 * flag. This is correct even if the scalar is NULL; since we would
1594 * evaluate the operator zero times, it matters not whether it would
1595 * want to return NULL.
1597 nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
1599 return BoolGetDatum(!useOr);
1602 * If the scalar is NULL, and the function is strict, return NULL.
1603 * This is just to avoid having to test for strictness inside the
1604 * loop. (XXX but if arrays could have null elements, we'd need a
1607 if (fcinfo.argnull[0] && sstate->fxprstate.func.fn_strict)
1614 * We arrange to look up info about the element type only once per
1615 * series of calls, assuming the element type doesn't change
1618 if (sstate->element_type != ARR_ELEMTYPE(arr))
1620 get_typlenbyvalalign(ARR_ELEMTYPE(arr),
1624 sstate->element_type = ARR_ELEMTYPE(arr);
1626 typlen = sstate->typlen;
1627 typbyval = sstate->typbyval;
1628 typalign = sstate->typalign;
1630 result = BoolGetDatum(!useOr);
1633 /* Loop over the array elements */
1634 s = (char *) ARR_DATA_PTR(arr);
1635 for (i = 0; i < nitems; i++)
1640 /* Get array element */
1641 elt = fetch_att(s, typbyval, typlen);
1643 s = att_addlength(s, typlen, PointerGetDatum(s));
1644 s = (char *) att_align(s, typalign);
1646 /* Call comparison function */
1647 fcinfo.arg[1] = elt;
1648 fcinfo.argnull[1] = false;
1649 fcinfo.isnull = false;
1650 thisresult = FunctionCallInvoke(&fcinfo);
1652 /* Combine results per OR or AND semantics */
1657 if (DatumGetBool(thisresult))
1659 result = BoolGetDatum(true);
1661 break; /* needn't look at any more elements */
1666 if (!DatumGetBool(thisresult))
1668 result = BoolGetDatum(false);
1670 break; /* needn't look at any more elements */
1675 *isNull = resultnull;
1679 /* ----------------------------------------------------------------
1684 * Evaluate boolean expressions, with appropriate short-circuiting.
1686 * The query planner reformulates clause expressions in the
1687 * qualification to conjunctive normal form. If we ever get
1688 * an AND to evaluate, we can be sure that it's not a top-level
1689 * clause in the qualification, but appears lower (as a function
1690 * argument, for example), or in the target list. Not that you
1691 * need to know this, mind you...
1692 * ----------------------------------------------------------------
1695 ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
1696 bool *isNull, ExprDoneCond *isDone)
1698 ExprState *clause = linitial(notclause->args);
1702 *isDone = ExprSingleResult;
1704 expr_value = ExecEvalExpr(clause, econtext, isNull, NULL);
1707 * if the expression evaluates to null, then we just cascade the null
1708 * back to whoever called us.
1714 * evaluation of 'not' is simple.. expr is false, then return 'true'
1717 return BoolGetDatum(!DatumGetBool(expr_value));
1720 /* ----------------------------------------------------------------
1722 * ----------------------------------------------------------------
1725 ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
1726 bool *isNull, ExprDoneCond *isDone)
1728 List *clauses = orExpr->args;
1733 *isDone = ExprSingleResult;
1738 * If any of the clauses is TRUE, the OR result is TRUE regardless of
1739 * the states of the rest of the clauses, so we can stop evaluating
1740 * and return TRUE immediately. If none are TRUE and one or more is
1741 * NULL, we return NULL; otherwise we return FALSE. This makes sense
1742 * when you interpret NULL as "don't know": if we have a TRUE then the
1743 * OR is TRUE even if we aren't sure about some of the other inputs.
1744 * If all the known inputs are FALSE, but we have one or more "don't
1745 * knows", then we have to report that we "don't know" what the OR's
1746 * result should be --- perhaps one of the "don't knows" would have
1747 * been TRUE if we'd known its value. Only when all the inputs are
1748 * known to be FALSE can we state confidently that the OR's result is
1751 foreach(clause, clauses)
1753 ExprState *clausestate = (ExprState *) lfirst(clause);
1756 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
1759 * if we have a non-null true result, then return it.
1762 AnyNull = true; /* remember we got a null */
1763 else if (DatumGetBool(clause_value))
1764 return clause_value;
1767 /* AnyNull is true if at least one clause evaluated to NULL */
1769 return BoolGetDatum(false);
1772 /* ----------------------------------------------------------------
1774 * ----------------------------------------------------------------
1777 ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
1778 bool *isNull, ExprDoneCond *isDone)
1780 List *clauses = andExpr->args;
1785 *isDone = ExprSingleResult;
1790 * If any of the clauses is FALSE, the AND result is FALSE regardless
1791 * of the states of the rest of the clauses, so we can stop evaluating
1792 * and return FALSE immediately. If none are FALSE and one or more is
1793 * NULL, we return NULL; otherwise we return TRUE. This makes sense
1794 * when you interpret NULL as "don't know", using the same sort of
1795 * reasoning as for OR, above.
1798 foreach(clause, clauses)
1800 ExprState *clausestate = (ExprState *) lfirst(clause);
1803 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
1806 * if we have a non-null false result, then return it.
1809 AnyNull = true; /* remember we got a null */
1810 else if (!DatumGetBool(clause_value))
1811 return clause_value;
1814 /* AnyNull is true if at least one clause evaluated to NULL */
1816 return BoolGetDatum(!AnyNull);
1819 /* ----------------------------------------------------------------
1820 * ExecEvalConvertRowtype
1822 * Evaluate a rowtype coercion operation. This may require
1823 * rearranging field positions.
1824 * ----------------------------------------------------------------
1827 ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
1828 ExprContext *econtext,
1829 bool *isNull, ExprDoneCond *isDone)
1833 HeapTupleHeader tuple;
1834 HeapTupleData tmptup;
1835 AttrNumber *attrMap = cstate->attrMap;
1836 Datum *invalues = cstate->invalues;
1837 bool *inisnull = cstate->inisnull;
1838 Datum *outvalues = cstate->outvalues;
1839 bool *outisnull = cstate->outisnull;
1841 int outnatts = cstate->outdesc->natts;
1843 tupDatum = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
1845 /* this test covers the isDone exception too: */
1849 tuple = DatumGetHeapTupleHeader(tupDatum);
1851 Assert(HeapTupleHeaderGetTypeId(tuple) == cstate->indesc->tdtypeid);
1852 Assert(HeapTupleHeaderGetTypMod(tuple) == cstate->indesc->tdtypmod);
1855 * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader.
1857 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1858 tmptup.t_data = tuple;
1861 * Extract all the values of the old tuple, offsetting the arrays
1862 * so that invalues[0] is NULL and invalues[1] is the first
1863 * source attribute; this exactly matches the numbering convention
1866 heap_deform_tuple(&tmptup, cstate->indesc, invalues + 1, inisnull + 1);
1867 invalues[0] = (Datum) 0;
1871 * Transpose into proper fields of the new tuple.
1873 for (i = 0; i < outnatts; i++)
1877 outvalues[i] = invalues[j];
1878 outisnull[i] = inisnull[j];
1882 * Now form the new tuple.
1884 result = heap_form_tuple(cstate->outdesc, outvalues, outisnull);
1886 return HeapTupleGetDatum(result);
1889 /* ----------------------------------------------------------------
1892 * Evaluate a CASE clause. Will have boolean expressions
1893 * inside the WHEN clauses, and will have expressions
1895 * - thomas 1998-11-09
1896 * ----------------------------------------------------------------
1899 ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
1900 bool *isNull, ExprDoneCond *isDone)
1902 List *clauses = caseExpr->args;
1908 *isDone = ExprSingleResult;
1911 * If there's a test expression, we have to evaluate it and save the
1912 * value where the CaseTestExpr placeholders can find it. We must save
1913 * and restore prior setting of econtext's caseValue fields, in case
1914 * this node is itself within a larger CASE.
1916 save_datum = econtext->caseValue_datum;
1917 save_isNull = econtext->caseValue_isNull;
1921 econtext->caseValue_datum = ExecEvalExpr(caseExpr->arg,
1923 &econtext->caseValue_isNull,
1928 * we evaluate each of the WHEN clauses in turn, as soon as one is
1929 * true we return the corresponding result. If none are true then we
1930 * return the value of the default clause, or NULL if there is none.
1932 foreach(clause, clauses)
1934 CaseWhenState *wclause = lfirst(clause);
1937 clause_value = ExecEvalExpr(wclause->expr,
1943 * if we have a true test, then we return the result, since the
1944 * case statement is satisfied. A NULL result from the test is
1945 * not considered true.
1947 if (DatumGetBool(clause_value) && !*isNull)
1949 econtext->caseValue_datum = save_datum;
1950 econtext->caseValue_isNull = save_isNull;
1951 return ExecEvalExpr(wclause->result,
1958 econtext->caseValue_datum = save_datum;
1959 econtext->caseValue_isNull = save_isNull;
1961 if (caseExpr->defresult)
1963 return ExecEvalExpr(caseExpr->defresult,
1974 * ExecEvalCaseTestExpr
1976 * Return the value stored by CASE.
1979 ExecEvalCaseTestExpr(ExprState *exprstate,
1980 ExprContext *econtext,
1981 bool *isNull, ExprDoneCond *isDone)
1984 *isDone = ExprSingleResult;
1985 *isNull = econtext->caseValue_isNull;
1986 return econtext->caseValue_datum;
1989 /* ----------------------------------------------------------------
1990 * ExecEvalArray - ARRAY[] expressions
1992 * NOTE: currently, if any input value is NULL then we return a NULL array,
1993 * so the ARRAY[] construct can be considered strict. Eventually this will
1994 * change; when it does, be sure to fix contain_nonstrict_functions().
1995 * ----------------------------------------------------------------
1998 ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
1999 bool *isNull, ExprDoneCond *isDone)
2001 ArrayExpr *arrayExpr = (ArrayExpr *) astate->xprstate.expr;
2004 Oid element_type = arrayExpr->element_typeid;
2009 /* Set default values for result flags: non-null, not a set result */
2012 *isDone = ExprSingleResult;
2014 if (!arrayExpr->multidims)
2016 /* Elements are presumably of scalar type */
2022 nelems = list_length(astate->elements);
2024 /* Shouldn't happen here, but if length is 0, return NULL */
2031 dvalues = (Datum *) palloc(nelems * sizeof(Datum));
2033 /* loop through and build array of datums */
2034 foreach(element, astate->elements)
2036 ExprState *e = (ExprState *) lfirst(element);
2039 dvalues[i++] = ExecEvalExpr(e, econtext, &eisnull, NULL);
2047 /* setup for 1-D array of the given length */
2051 result = construct_md_array(dvalues, ndims, dims, lbs,
2059 /* Must be nested array expressions */
2061 Size ndatabytes = 0;
2063 int outer_nelems = list_length(astate->elements);
2065 int *elem_dims = NULL;
2066 int *elem_lbs = NULL;
2067 bool firstone = true;
2070 /* loop through and get data area from each element */
2071 foreach(element, astate->elements)
2073 ExprState *e = (ExprState *) lfirst(element);
2077 int elem_ndatabytes;
2079 arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
2086 array = DatumGetArrayTypeP(arraydatum);
2088 /* run-time double-check on element type */
2089 if (element_type != ARR_ELEMTYPE(array))
2091 (errcode(ERRCODE_DATATYPE_MISMATCH),
2092 errmsg("cannot merge incompatible arrays"),
2093 errdetail("Array with element type %s cannot be "
2094 "included in ARRAY construct with element type %s.",
2095 format_type_be(ARR_ELEMTYPE(array)),
2096 format_type_be(element_type))));
2100 /* Get sub-array details from first member */
2101 elem_ndims = ARR_NDIM(array);
2102 ndims = elem_ndims + 1;
2103 if (ndims <= 0 || ndims > MAXDIM)
2105 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2106 errmsg("number of array dimensions (%d) exceeds " \
2107 "the maximum allowed (%d)", ndims, MAXDIM)));
2109 elem_dims = (int *) palloc(elem_ndims * sizeof(int));
2110 memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
2111 elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
2112 memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
2118 /* Check other sub-arrays are compatible */
2119 if (elem_ndims != ARR_NDIM(array) ||
2120 memcmp(elem_dims, ARR_DIMS(array),
2121 elem_ndims * sizeof(int)) != 0 ||
2122 memcmp(elem_lbs, ARR_LBOUND(array),
2123 elem_ndims * sizeof(int)) != 0)
2125 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2126 errmsg("multidimensional arrays must have array "
2127 "expressions with matching dimensions")));
2130 elem_ndatabytes = ARR_SIZE(array) - ARR_OVERHEAD(elem_ndims);
2131 ndatabytes += elem_ndatabytes;
2133 dat = (char *) palloc(ndatabytes);
2135 dat = (char *) repalloc(dat, ndatabytes);
2137 memcpy(dat + (ndatabytes - elem_ndatabytes),
2138 ARR_DATA_PTR(array),
2142 /* setup for multi-D array */
2143 dims[0] = outer_nelems;
2145 for (i = 1; i < ndims; i++)
2147 dims[i] = elem_dims[i - 1];
2148 lbs[i] = elem_lbs[i - 1];
2151 nbytes = ndatabytes + ARR_OVERHEAD(ndims);
2152 result = (ArrayType *) palloc(nbytes);
2154 result->size = nbytes;
2155 result->ndim = ndims;
2157 result->elemtype = element_type;
2158 memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
2159 memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
2161 memcpy(ARR_DATA_PTR(result), dat, ndatabytes);
2167 return PointerGetDatum(result);
2170 /* ----------------------------------------------------------------
2171 * ExecEvalRow - ROW() expressions
2172 * ----------------------------------------------------------------
2175 ExecEvalRow(RowExprState *rstate,
2176 ExprContext *econtext,
2177 bool *isNull, ExprDoneCond *isDone)
2186 /* Set default values for result flags: non-null, not a set result */
2189 *isDone = ExprSingleResult;
2191 /* Allocate workspace */
2192 natts = rstate->tupdesc->natts;
2193 values = (Datum *) palloc0(natts * sizeof(Datum));
2194 isnull = (bool *) palloc(natts * sizeof(bool));
2196 /* preset to nulls in case rowtype has some later-added columns */
2197 memset(isnull, true, natts * sizeof(bool));
2199 /* Evaluate field values */
2201 foreach(arg, rstate->args)
2203 ExprState *e = (ExprState *) lfirst(arg);
2205 values[i] = ExecEvalExpr(e, econtext, &isnull[i], NULL);
2209 tuple = heap_form_tuple(rstate->tupdesc, values, isnull);
2214 return HeapTupleGetDatum(tuple);
2217 /* ----------------------------------------------------------------
2219 * ----------------------------------------------------------------
2222 ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
2223 bool *isNull, ExprDoneCond *isDone)
2228 *isDone = ExprSingleResult;
2230 /* Simply loop through until something NOT NULL is found */
2231 foreach(arg, coalesceExpr->args)
2233 ExprState *e = (ExprState *) lfirst(arg);
2236 value = ExecEvalExpr(e, econtext, isNull, NULL);
2241 /* Else return NULL */
2246 /* ----------------------------------------------------------------
2249 * Note that this is *always* derived from the equals operator,
2250 * but since we need special processing of the arguments
2251 * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
2252 * ----------------------------------------------------------------
2255 ExecEvalNullIf(FuncExprState *nullIfExpr,
2256 ExprContext *econtext,
2257 bool *isNull, ExprDoneCond *isDone)
2260 FunctionCallInfoData fcinfo;
2261 ExprDoneCond argDone;
2265 *isDone = ExprSingleResult;
2268 * Initialize function cache if first time through
2270 if (nullIfExpr->func.fn_oid == InvalidOid)
2272 NullIfExpr *op = (NullIfExpr *) nullIfExpr->xprstate.expr;
2274 init_fcache(op->opfuncid, nullIfExpr, econtext->ecxt_per_query_memory);
2275 Assert(!nullIfExpr->func.fn_retset);
2279 * extract info from nullIfExpr
2281 argList = nullIfExpr->args;
2283 /* Need to prep callinfo structure */
2284 InitFunctionCallInfoData(fcinfo, &(nullIfExpr->func), 0, NULL, NULL);
2285 argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
2286 if (argDone != ExprSingleResult)
2288 (errcode(ERRCODE_DATATYPE_MISMATCH),
2289 errmsg("NULLIF does not support set arguments")));
2290 Assert(fcinfo.nargs == 2);
2292 /* if either argument is NULL they can't be equal */
2293 if (!fcinfo.argnull[0] && !fcinfo.argnull[1])
2295 fcinfo.isnull = false;
2296 result = FunctionCallInvoke(&fcinfo);
2297 /* if the arguments are equal return null */
2298 if (!fcinfo.isnull && DatumGetBool(result))
2305 /* else return first argument */
2306 *isNull = fcinfo.argnull[0];
2307 return fcinfo.arg[0];
2310 /* ----------------------------------------------------------------
2313 * Evaluate a NullTest node.
2314 * ----------------------------------------------------------------
2317 ExecEvalNullTest(GenericExprState *nstate,
2318 ExprContext *econtext,
2320 ExprDoneCond *isDone)
2322 NullTest *ntest = (NullTest *) nstate->xprstate.expr;
2325 result = ExecEvalExpr(nstate->arg, econtext, isNull, isDone);
2327 if (isDone && *isDone == ExprEndResult)
2328 return result; /* nothing to check */
2330 switch (ntest->nulltesttype)
2336 return BoolGetDatum(true);
2339 return BoolGetDatum(false);
2344 return BoolGetDatum(false);
2347 return BoolGetDatum(true);
2349 elog(ERROR, "unrecognized nulltesttype: %d",
2350 (int) ntest->nulltesttype);
2351 return (Datum) 0; /* keep compiler quiet */
2355 /* ----------------------------------------------------------------
2356 * ExecEvalBooleanTest
2358 * Evaluate a BooleanTest node.
2359 * ----------------------------------------------------------------
2362 ExecEvalBooleanTest(GenericExprState *bstate,
2363 ExprContext *econtext,
2365 ExprDoneCond *isDone)
2367 BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;
2370 result = ExecEvalExpr(bstate->arg, econtext, isNull, isDone);
2372 if (isDone && *isDone == ExprEndResult)
2373 return result; /* nothing to check */
2375 switch (btest->booltesttype)
2381 return BoolGetDatum(false);
2383 else if (DatumGetBool(result))
2384 return BoolGetDatum(true);
2386 return BoolGetDatum(false);
2391 return BoolGetDatum(true);
2393 else if (DatumGetBool(result))
2394 return BoolGetDatum(false);
2396 return BoolGetDatum(true);
2401 return BoolGetDatum(false);
2403 else if (DatumGetBool(result))
2404 return BoolGetDatum(false);
2406 return BoolGetDatum(true);
2411 return BoolGetDatum(true);
2413 else if (DatumGetBool(result))
2414 return BoolGetDatum(true);
2416 return BoolGetDatum(false);
2421 return BoolGetDatum(true);
2424 return BoolGetDatum(false);
2425 case IS_NOT_UNKNOWN:
2429 return BoolGetDatum(false);
2432 return BoolGetDatum(true);
2434 elog(ERROR, "unrecognized booltesttype: %d",
2435 (int) btest->booltesttype);
2436 return (Datum) 0; /* keep compiler quiet */
2441 * ExecEvalCoerceToDomain
2443 * Test the provided data against the domain constraint(s). If the data
2444 * passes the constraint specifications, pass it through (return the
2445 * datum) otherwise throw an error.
2448 ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
2449 bool *isNull, ExprDoneCond *isDone)
2451 CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
2455 result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
2457 if (isDone && *isDone == ExprEndResult)
2458 return result; /* nothing to check */
2460 foreach(l, cstate->constraints)
2462 DomainConstraintState *con = (DomainConstraintState *) lfirst(l);
2464 switch (con->constrainttype)
2466 case DOM_CONSTRAINT_NOTNULL:
2469 (errcode(ERRCODE_NOT_NULL_VIOLATION),
2470 errmsg("domain %s does not allow null values",
2471 format_type_be(ctest->resulttype))));
2473 case DOM_CONSTRAINT_CHECK:
2481 * Set up value to be returned by CoerceToDomainValue
2482 * nodes. We must save and restore prior setting of
2483 * econtext's domainValue fields, in case this node is
2484 * itself within a check expression for another
2487 save_datum = econtext->domainValue_datum;
2488 save_isNull = econtext->domainValue_isNull;
2490 econtext->domainValue_datum = result;
2491 econtext->domainValue_isNull = *isNull;
2493 conResult = ExecEvalExpr(con->check_expr,
2494 econtext, &conIsNull, NULL);
2497 !DatumGetBool(conResult))
2499 (errcode(ERRCODE_CHECK_VIOLATION),
2500 errmsg("value for domain %s violates check constraint \"%s\"",
2501 format_type_be(ctest->resulttype),
2503 econtext->domainValue_datum = save_datum;
2504 econtext->domainValue_isNull = save_isNull;
2509 elog(ERROR, "unrecognized constraint type: %d",
2510 (int) con->constrainttype);
2515 /* If all has gone well (constraints did not fail) return the datum */
2520 * ExecEvalCoerceToDomainValue
2522 * Return the value stored by CoerceToDomain.
2525 ExecEvalCoerceToDomainValue(ExprState *exprstate,
2526 ExprContext *econtext,
2527 bool *isNull, ExprDoneCond *isDone)
2530 *isDone = ExprSingleResult;
2531 *isNull = econtext->domainValue_isNull;
2532 return econtext->domainValue_datum;
2535 /* ----------------------------------------------------------------
2536 * ExecEvalFieldSelect
2538 * Evaluate a FieldSelect node.
2539 * ----------------------------------------------------------------
2542 ExecEvalFieldSelect(FieldSelectState *fstate,
2543 ExprContext *econtext,
2545 ExprDoneCond *isDone)
2547 FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
2550 HeapTupleHeader tuple;
2554 HeapTupleData tmptup;
2556 tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
2558 /* this test covers the isDone exception too: */
2562 tuple = DatumGetHeapTupleHeader(tupDatum);
2564 tupType = HeapTupleHeaderGetTypeId(tuple);
2565 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
2567 /* Lookup tupdesc if first time through or if type changes */
2568 tupDesc = fstate->argdesc;
2569 if (tupDesc == NULL ||
2570 tupType != tupDesc->tdtypeid ||
2571 tupTypmod != tupDesc->tdtypmod)
2573 MemoryContext oldcontext;
2575 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
2576 /* Copy the tupdesc into query storage for safety */
2577 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2578 tupDesc = CreateTupleDescCopy(tupDesc);
2579 if (fstate->argdesc)
2580 FreeTupleDesc(fstate->argdesc);
2581 fstate->argdesc = tupDesc;
2582 MemoryContextSwitchTo(oldcontext);
2586 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set
2587 * all the fields in the struct just in case user tries to inspect
2590 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2591 ItemPointerSetInvalid(&(tmptup.t_self));
2592 tmptup.t_tableOid = InvalidOid;
2593 tmptup.t_data = tuple;
2595 result = heap_getattr(&tmptup,
2602 /* ----------------------------------------------------------------
2603 * ExecEvalFieldStore
2605 * Evaluate a FieldStore node.
2606 * ----------------------------------------------------------------
2609 ExecEvalFieldStore(FieldStoreState *fstate,
2610 ExprContext *econtext,
2612 ExprDoneCond *isDone)
2614 FieldStore *fstore = (FieldStore *) fstate->xprstate.expr;
2625 tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
2627 if (isDone && *isDone == ExprEndResult)
2630 /* Lookup tupdesc if first time through or if type changes */
2631 tupDesc = fstate->argdesc;
2632 if (tupDesc == NULL ||
2633 fstore->resulttype != tupDesc->tdtypeid)
2635 MemoryContext oldcontext;
2637 tupDesc = lookup_rowtype_tupdesc(fstore->resulttype, -1);
2638 /* Copy the tupdesc into query storage for safety */
2639 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2640 tupDesc = CreateTupleDescCopy(tupDesc);
2641 if (fstate->argdesc)
2642 FreeTupleDesc(fstate->argdesc);
2643 fstate->argdesc = tupDesc;
2644 MemoryContextSwitchTo(oldcontext);
2647 /* Allocate workspace */
2648 values = (Datum *) palloc(tupDesc->natts * sizeof(Datum));
2649 isnull = (bool *) palloc(tupDesc->natts * sizeof(bool));
2654 * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader.
2655 * We set all the fields in the struct just in case.
2657 HeapTupleHeader tuphdr;
2658 HeapTupleData tmptup;
2660 tuphdr = DatumGetHeapTupleHeader(tupDatum);
2661 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuphdr);
2662 ItemPointerSetInvalid(&(tmptup.t_self));
2663 tmptup.t_tableOid = InvalidOid;
2664 tmptup.t_data = tuphdr;
2666 heap_deform_tuple(&tmptup, tupDesc, values, isnull);
2670 /* Convert null input tuple into an all-nulls row */
2671 memset(isnull, true, tupDesc->natts * sizeof(bool));
2674 /* Result is never null */
2677 save_datum = econtext->caseValue_datum;
2678 save_isNull = econtext->caseValue_isNull;
2680 forboth(l1, fstate->newvals, l2, fstore->fieldnums)
2682 ExprState *newval = (ExprState *) lfirst(l1);
2683 AttrNumber fieldnum = lfirst_int(l2);
2685 Assert(fieldnum > 0 && fieldnum <= tupDesc->natts);
2688 * Use the CaseTestExpr mechanism to pass down the old value of
2689 * the field being replaced; this is useful in case we have a
2690 * nested field update situation. It's safe to reuse the CASE
2691 * mechanism because there cannot be a CASE between here and where
2692 * the value would be needed.
2694 econtext->caseValue_datum = values[fieldnum - 1];
2695 econtext->caseValue_isNull = isnull[fieldnum - 1];
2697 values[fieldnum - 1] = ExecEvalExpr(newval,
2699 &isnull[fieldnum - 1],
2703 econtext->caseValue_datum = save_datum;
2704 econtext->caseValue_isNull = save_isNull;
2706 tuple = heap_form_tuple(tupDesc, values, isnull);
2711 return HeapTupleGetDatum(tuple);
2714 /* ----------------------------------------------------------------
2715 * ExecEvalRelabelType
2717 * Evaluate a RelabelType node.
2718 * ----------------------------------------------------------------
2721 ExecEvalRelabelType(GenericExprState *exprstate,
2722 ExprContext *econtext,
2723 bool *isNull, ExprDoneCond *isDone)
2725 return ExecEvalExpr(exprstate->arg, econtext, isNull, isDone);
2730 * ExecEvalExprSwitchContext
2732 * Same as ExecEvalExpr, but get into the right allocation context explicitly.
2735 ExecEvalExprSwitchContext(ExprState *expression,
2736 ExprContext *econtext,
2738 ExprDoneCond *isDone)
2741 MemoryContext oldContext;
2743 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
2744 retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
2745 MemoryContextSwitchTo(oldContext);
2751 * ExecInitExpr: prepare an expression tree for execution
2753 * This function builds and returns an ExprState tree paralleling the given
2754 * Expr node tree. The ExprState tree can then be handed to ExecEvalExpr
2755 * for execution. Because the Expr tree itself is read-only as far as
2756 * ExecInitExpr and ExecEvalExpr are concerned, several different executions
2757 * of the same plan tree can occur concurrently.
2759 * This must be called in a memory context that will last as long as repeated
2760 * executions of the expression are needed. Typically the context will be
2761 * the same as the per-query context of the associated ExprContext.
2763 * Any Aggref and SubPlan nodes found in the tree are added to the lists
2764 * of such nodes held by the parent PlanState. Otherwise, we do very little
2765 * initialization here other than building the state-node tree. Any nontrivial
2766 * work associated with initializing runtime info for a node should happen
2767 * during the first actual evaluation of that node. (This policy lets us
2768 * avoid work if the node is never actually evaluated.)
2770 * Note: there is no ExecEndExpr function; we assume that any resource
2771 * cleanup needed will be handled by just releasing the memory context
2772 * in which the state tree is built. Functions that require additional
2773 * cleanup work can register a shutdown callback in the ExprContext.
2775 * 'node' is the root of the expression tree to examine
2776 * 'parent' is the PlanState node that owns the expression.
2778 * 'parent' may be NULL if we are preparing an expression that is not
2779 * associated with a plan tree. (If so, it can't have aggs or subplans.)
2780 * This case should usually come through ExecPrepareExpr, not directly here.
2783 ExecInitExpr(Expr *node, PlanState *parent)
2790 /* Guard against stack overflow due to overly complex expressions */
2791 check_stack_depth();
2793 switch (nodeTag(node))
2796 state = (ExprState *) makeNode(ExprState);
2797 state->evalfunc = ExecEvalVar;
2800 state = (ExprState *) makeNode(ExprState);
2801 state->evalfunc = ExecEvalConst;
2804 state = (ExprState *) makeNode(ExprState);
2805 state->evalfunc = ExecEvalParam;
2807 case T_CoerceToDomainValue:
2808 state = (ExprState *) makeNode(ExprState);
2809 state->evalfunc = ExecEvalCoerceToDomainValue;
2811 case T_CaseTestExpr:
2812 state = (ExprState *) makeNode(ExprState);
2813 state->evalfunc = ExecEvalCaseTestExpr;
2817 Aggref *aggref = (Aggref *) node;
2818 AggrefExprState *astate = makeNode(AggrefExprState);
2820 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAggref;
2821 if (parent && IsA(parent, AggState))
2823 AggState *aggstate = (AggState *) parent;
2826 aggstate->aggs = lcons(astate, aggstate->aggs);
2827 naggs = ++aggstate->numaggs;
2829 astate->target = ExecInitExpr(aggref->target, parent);
2832 * Complain if the aggregate's argument contains any
2833 * aggregates; nested agg functions are semantically
2834 * nonsensical. (This should have been caught
2835 * earlier, but we defend against it here anyway.)
2837 if (naggs != aggstate->numaggs)
2839 (errcode(ERRCODE_GROUPING_ERROR),
2840 errmsg("aggregate function calls may not be nested")));
2844 /* planner messed up */
2845 elog(ERROR, "aggref found in non-Agg plan node");
2847 state = (ExprState *) astate;
2852 ArrayRef *aref = (ArrayRef *) node;
2853 ArrayRefExprState *astate = makeNode(ArrayRefExprState);
2855 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayRef;
2856 astate->refupperindexpr = (List *)
2857 ExecInitExpr((Expr *) aref->refupperindexpr, parent);
2858 astate->reflowerindexpr = (List *)
2859 ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
2860 astate->refexpr = ExecInitExpr(aref->refexpr, parent);
2861 astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
2863 /* do one-time catalog lookups for type info */
2864 astate->refattrlength = get_typlen(aref->refarraytype);
2865 get_typlenbyvalalign(aref->refelemtype,
2866 &astate->refelemlength,
2867 &astate->refelembyval,
2868 &astate->refelemalign);
2869 state = (ExprState *) astate;
2874 FuncExpr *funcexpr = (FuncExpr *) node;
2875 FuncExprState *fstate = makeNode(FuncExprState);
2877 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFunc;
2878 fstate->args = (List *)
2879 ExecInitExpr((Expr *) funcexpr->args, parent);
2880 fstate->func.fn_oid = InvalidOid; /* not initialized */
2881 state = (ExprState *) fstate;
2886 OpExpr *opexpr = (OpExpr *) node;
2887 FuncExprState *fstate = makeNode(FuncExprState);
2889 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOper;
2890 fstate->args = (List *)
2891 ExecInitExpr((Expr *) opexpr->args, parent);
2892 fstate->func.fn_oid = InvalidOid; /* not initialized */
2893 state = (ExprState *) fstate;
2896 case T_DistinctExpr:
2898 DistinctExpr *distinctexpr = (DistinctExpr *) node;
2899 FuncExprState *fstate = makeNode(FuncExprState);
2901 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalDistinct;
2902 fstate->args = (List *)
2903 ExecInitExpr((Expr *) distinctexpr->args, parent);
2904 fstate->func.fn_oid = InvalidOid; /* not initialized */
2905 state = (ExprState *) fstate;
2908 case T_ScalarArrayOpExpr:
2910 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
2911 ScalarArrayOpExprState *sstate = makeNode(ScalarArrayOpExprState);
2913 sstate->fxprstate.xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalScalarArrayOp;
2914 sstate->fxprstate.args = (List *)
2915 ExecInitExpr((Expr *) opexpr->args, parent);
2916 sstate->fxprstate.func.fn_oid = InvalidOid; /* not initialized */
2917 sstate->element_type = InvalidOid; /* ditto */
2918 state = (ExprState *) sstate;
2923 BoolExpr *boolexpr = (BoolExpr *) node;
2924 BoolExprState *bstate = makeNode(BoolExprState);
2926 switch (boolexpr->boolop)
2929 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAnd;
2932 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOr;
2935 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNot;
2938 elog(ERROR, "unrecognized boolop: %d",
2939 (int) boolexpr->boolop);
2942 bstate->args = (List *)
2943 ExecInitExpr((Expr *) boolexpr->args, parent);
2944 state = (ExprState *) bstate;
2949 /* Keep this in sync with ExecInitExprInitPlan, below */
2950 SubPlan *subplan = (SubPlan *) node;
2951 SubPlanState *sstate = makeNode(SubPlanState);
2953 sstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecSubPlan;
2956 elog(ERROR, "SubPlan found with no parent plan");
2959 * Here we just add the SubPlanState nodes to
2960 * parent->subPlan. The subplans will be initialized
2963 parent->subPlan = lcons(sstate, parent->subPlan);
2964 sstate->sub_estate = NULL;
2965 sstate->planstate = NULL;
2967 sstate->exprs = (List *)
2968 ExecInitExpr((Expr *) subplan->exprs, parent);
2969 sstate->args = (List *)
2970 ExecInitExpr((Expr *) subplan->args, parent);
2972 state = (ExprState *) sstate;
2977 FieldSelect *fselect = (FieldSelect *) node;
2978 FieldSelectState *fstate = makeNode(FieldSelectState);
2980 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldSelect;
2981 fstate->arg = ExecInitExpr(fselect->arg, parent);
2982 fstate->argdesc = NULL;
2983 state = (ExprState *) fstate;
2988 FieldStore *fstore = (FieldStore *) node;
2989 FieldStoreState *fstate = makeNode(FieldStoreState);
2991 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldStore;
2992 fstate->arg = ExecInitExpr(fstore->arg, parent);
2993 fstate->newvals = (List *) ExecInitExpr((Expr *) fstore->newvals, parent);
2994 fstate->argdesc = NULL;
2995 state = (ExprState *) fstate;
3000 RelabelType *relabel = (RelabelType *) node;
3001 GenericExprState *gstate = makeNode(GenericExprState);
3003 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRelabelType;
3004 gstate->arg = ExecInitExpr(relabel->arg, parent);
3005 state = (ExprState *) gstate;
3008 case T_ConvertRowtypeExpr:
3010 ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) node;
3011 ConvertRowtypeExprState *cstate = makeNode(ConvertRowtypeExprState);
3015 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalConvertRowtype;
3016 cstate->arg = ExecInitExpr(convert->arg, parent);
3017 /* save copies of needed tuple descriptors */
3018 cstate->indesc = lookup_rowtype_tupdesc(exprType((Node *) convert->arg), -1);
3019 cstate->indesc = CreateTupleDescCopy(cstate->indesc);
3020 cstate->outdesc = lookup_rowtype_tupdesc(convert->resulttype, -1);
3021 cstate->outdesc = CreateTupleDescCopy(cstate->outdesc);
3022 /* prepare map from old to new attribute numbers */
3023 n = cstate->outdesc->natts;
3024 cstate->attrMap = (AttrNumber *) palloc0(n * sizeof(AttrNumber));
3025 for (i = 0; i < n; i++)
3027 Form_pg_attribute att = cstate->outdesc->attrs[i];
3033 if (att->attisdropped)
3034 continue; /* attrMap[i] is already 0 */
3035 attname = NameStr(att->attname);
3036 atttypid = att->atttypid;
3037 atttypmod = att->atttypmod;
3038 for (j = 0; j < cstate->indesc->natts; j++)
3040 att = cstate->indesc->attrs[j];
3041 if (att->attisdropped)
3043 if (strcmp(attname, NameStr(att->attname)) == 0)
3045 /* Found it, check type */
3046 if (atttypid != att->atttypid || atttypmod != att->atttypmod)
3047 elog(ERROR, "attribute \"%s\" of type %s does not match corresponding attribute of type %s",
3049 format_type_be(cstate->indesc->tdtypeid),
3050 format_type_be(cstate->outdesc->tdtypeid));
3051 cstate->attrMap[i] = (AttrNumber) (j + 1);
3055 if (cstate->attrMap[i] == 0)
3056 elog(ERROR, "attribute \"%s\" of type %s does not exist",
3058 format_type_be(cstate->indesc->tdtypeid));
3060 /* preallocate workspace for Datum arrays */
3061 n = cstate->indesc->natts + 1; /* +1 for NULL */
3062 cstate->invalues = (Datum *) palloc(n * sizeof(Datum));
3063 cstate->inisnull = (bool *) palloc(n * sizeof(bool));
3064 n = cstate->outdesc->natts;
3065 cstate->outvalues = (Datum *) palloc(n * sizeof(Datum));
3066 cstate->outisnull = (bool *) palloc(n * sizeof(bool));
3067 state = (ExprState *) cstate;
3072 CaseExpr *caseexpr = (CaseExpr *) node;
3073 CaseExprState *cstate = makeNode(CaseExprState);
3074 List *outlist = NIL;
3077 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCase;
3078 cstate->arg = ExecInitExpr(caseexpr->arg, parent);
3079 foreach(l, caseexpr->args)
3081 CaseWhen *when = (CaseWhen *) lfirst(l);
3082 CaseWhenState *wstate = makeNode(CaseWhenState);
3084 Assert(IsA(when, CaseWhen));
3085 wstate->xprstate.evalfunc = NULL; /* not used */
3086 wstate->xprstate.expr = (Expr *) when;
3087 wstate->expr = ExecInitExpr(when->expr, parent);
3088 wstate->result = ExecInitExpr(when->result, parent);
3089 outlist = lappend(outlist, wstate);
3091 cstate->args = outlist;
3092 cstate->defresult = ExecInitExpr(caseexpr->defresult, parent);
3093 state = (ExprState *) cstate;
3098 ArrayExpr *arrayexpr = (ArrayExpr *) node;
3099 ArrayExprState *astate = makeNode(ArrayExprState);
3100 List *outlist = NIL;
3103 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArray;
3104 foreach(l, arrayexpr->elements)
3106 Expr *e = (Expr *) lfirst(l);
3109 estate = ExecInitExpr(e, parent);
3110 outlist = lappend(outlist, estate);
3112 astate->elements = outlist;
3113 /* do one-time catalog lookup for type info */
3114 get_typlenbyvalalign(arrayexpr->element_typeid,
3115 &astate->elemlength,
3117 &astate->elemalign);
3118 state = (ExprState *) astate;
3123 RowExpr *rowexpr = (RowExpr *) node;
3124 RowExprState *rstate = makeNode(RowExprState);
3125 Form_pg_attribute *attrs;
3126 List *outlist = NIL;
3130 rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRow;
3131 /* Build tupdesc to describe result tuples */
3132 if (rowexpr->row_typeid == RECORDOID)
3134 /* generic record, use runtime type assignment */
3135 rstate->tupdesc = ExecTypeFromExprList(rowexpr->args);
3136 rstate->tupdesc = BlessTupleDesc(rstate->tupdesc);
3140 /* it's been cast to a named type, use that */
3141 rstate->tupdesc = lookup_rowtype_tupdesc(rowexpr->row_typeid, -1);
3142 rstate->tupdesc = CreateTupleDescCopy(rstate->tupdesc);
3144 /* Set up evaluation, skipping any deleted columns */
3145 Assert(list_length(rowexpr->args) <= rstate->tupdesc->natts);
3146 attrs = rstate->tupdesc->attrs;
3148 foreach(l, rowexpr->args)
3150 Expr *e = (Expr *) lfirst(l);
3153 if (!attrs[i]->attisdropped)
3156 * Guard against ALTER COLUMN TYPE on rowtype
3157 * since the RowExpr was created. XXX should we
3158 * check typmod too? Not sure we can be sure
3159 * it'll be the same.
3161 if (exprType((Node *) e) != attrs[i]->atttypid)
3163 (errcode(ERRCODE_DATATYPE_MISMATCH),
3164 errmsg("ROW() column has type %s instead of type %s",
3165 format_type_be(exprType((Node *) e)),
3166 format_type_be(attrs[i]->atttypid))));
3171 * Ignore original expression and insert a NULL.
3172 * We don't really care what type of NULL it is,
3173 * so always make an int4 NULL.
3175 e = (Expr *) makeNullConst(INT4OID);
3177 estate = ExecInitExpr(e, parent);
3178 outlist = lappend(outlist, estate);
3181 rstate->args = outlist;
3182 state = (ExprState *) rstate;
3185 case T_CoalesceExpr:
3187 CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
3188 CoalesceExprState *cstate = makeNode(CoalesceExprState);
3189 List *outlist = NIL;
3192 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoalesce;
3193 foreach(l, coalesceexpr->args)
3195 Expr *e = (Expr *) lfirst(l);
3198 estate = ExecInitExpr(e, parent);
3199 outlist = lappend(outlist, estate);
3201 cstate->args = outlist;
3202 state = (ExprState *) cstate;
3207 NullIfExpr *nullifexpr = (NullIfExpr *) node;
3208 FuncExprState *fstate = makeNode(FuncExprState);
3210 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullIf;
3211 fstate->args = (List *)
3212 ExecInitExpr((Expr *) nullifexpr->args, parent);
3213 fstate->func.fn_oid = InvalidOid; /* not initialized */
3214 state = (ExprState *) fstate;
3219 NullTest *ntest = (NullTest *) node;
3220 GenericExprState *gstate = makeNode(GenericExprState);
3222 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullTest;
3223 gstate->arg = ExecInitExpr(ntest->arg, parent);
3224 state = (ExprState *) gstate;
3229 BooleanTest *btest = (BooleanTest *) node;
3230 GenericExprState *gstate = makeNode(GenericExprState);
3232 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalBooleanTest;
3233 gstate->arg = ExecInitExpr(btest->arg, parent);
3234 state = (ExprState *) gstate;
3237 case T_CoerceToDomain:
3239 CoerceToDomain *ctest = (CoerceToDomain *) node;
3240 CoerceToDomainState *cstate = makeNode(CoerceToDomainState);
3242 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceToDomain;
3243 cstate->arg = ExecInitExpr(ctest->arg, parent);
3244 cstate->constraints = GetDomainConstraints(ctest->resulttype);
3245 state = (ExprState *) cstate;
3250 TargetEntry *tle = (TargetEntry *) node;
3251 GenericExprState *gstate = makeNode(GenericExprState);
3253 gstate->xprstate.evalfunc = NULL; /* not used */
3254 gstate->arg = ExecInitExpr(tle->expr, parent);
3255 state = (ExprState *) gstate;
3260 List *outlist = NIL;
3263 foreach(l, (List *) node)
3265 outlist = lappend(outlist,
3266 ExecInitExpr((Expr *) lfirst(l),
3269 /* Don't fall through to the "common" code below */
3270 return (ExprState *) outlist;
3273 elog(ERROR, "unrecognized node type: %d",
3274 (int) nodeTag(node));
3275 state = NULL; /* keep compiler quiet */
3279 /* Common code for all state-node types */
3286 * ExecInitExprInitPlan --- initialize a subplan expr that's being handled
3287 * as an InitPlan. This is identical to ExecInitExpr's handling of a regular
3288 * subplan expr, except we do NOT want to add the node to the parent's
3292 ExecInitExprInitPlan(SubPlan *node, PlanState *parent)
3294 SubPlanState *sstate = makeNode(SubPlanState);
3297 elog(ERROR, "SubPlan found with no parent plan");
3299 /* The subplan's state will be initialized later */
3300 sstate->sub_estate = NULL;
3301 sstate->planstate = NULL;
3303 sstate->exprs = (List *) ExecInitExpr((Expr *) node->exprs, parent);
3304 sstate->args = (List *) ExecInitExpr((Expr *) node->args, parent);
3306 sstate->xprstate.expr = (Expr *) node;
3312 * ExecPrepareExpr --- initialize for expression execution outside a normal
3313 * Plan tree context.
3315 * This differs from ExecInitExpr in that we don't assume the caller is
3316 * already running in the EState's per-query context. Also, we apply
3317 * fix_opfuncids() to the passed expression tree to be sure it is ready
3318 * to run. (In ordinary Plan trees the planner will have fixed opfuncids,
3319 * but callers outside the executor will not have done this.)
3322 ExecPrepareExpr(Expr *node, EState *estate)
3325 MemoryContext oldcontext;
3327 fix_opfuncids((Node *) node);
3329 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
3331 result = ExecInitExpr(node, NULL);
3333 MemoryContextSwitchTo(oldcontext);
3339 /* ----------------------------------------------------------------
3340 * ExecQual / ExecTargetList / ExecProject
3341 * ----------------------------------------------------------------
3344 /* ----------------------------------------------------------------
3347 * Evaluates a conjunctive boolean expression (qual list) and
3348 * returns true iff none of the subexpressions are false.
3349 * (We also return true if the list is empty.)
3351 * If some of the subexpressions yield NULL but none yield FALSE,
3352 * then the result of the conjunction is NULL (ie, unknown)
3353 * according to three-valued boolean logic. In this case,
3354 * we return the value specified by the "resultForNull" parameter.
3356 * Callers evaluating WHERE clauses should pass resultForNull=FALSE,
3357 * since SQL specifies that tuples with null WHERE results do not
3358 * get selected. On the other hand, callers evaluating constraint
3359 * conditions should pass resultForNull=TRUE, since SQL also specifies
3360 * that NULL constraint conditions are not failures.
3362 * NOTE: it would not be correct to use this routine to evaluate an
3363 * AND subclause of a boolean expression; for that purpose, a NULL
3364 * result must be returned as NULL so that it can be properly treated
3365 * in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
3366 * This routine is only used in contexts where a complete expression
3367 * is being evaluated and we know that NULL can be treated the same
3368 * as one boolean result or the other.
3370 * ----------------------------------------------------------------
3373 ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
3376 MemoryContext oldContext;
3382 EV_printf("ExecQual: qual is ");
3383 EV_nodeDisplay(qual);
3389 * Run in short-lived per-tuple context while computing expressions.
3391 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
3394 * Evaluate the qual conditions one at a time. If we find a FALSE
3395 * result, we can stop evaluating and return FALSE --- the AND result
3396 * must be FALSE. Also, if we find a NULL result when resultForNull
3397 * is FALSE, we can stop and return FALSE --- the AND result must be
3398 * FALSE or NULL in that case, and the caller doesn't care which.
3400 * If we get to the end of the list, we can return TRUE. This will
3401 * happen when the AND result is indeed TRUE, or when the AND result
3402 * is NULL (one or more NULL subresult, with all the rest TRUE) and
3403 * the caller has specified resultForNull = TRUE.
3409 ExprState *clause = (ExprState *) lfirst(l);
3413 expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
3417 if (resultForNull == false)
3419 result = false; /* treat NULL as FALSE */
3425 if (!DatumGetBool(expr_value))
3427 result = false; /* definitely FALSE */
3433 MemoryContextSwitchTo(oldContext);
3439 * Number of items in a tlist (including any resjunk items!)
3442 ExecTargetListLength(List *targetlist)
3444 /* This used to be more complex, but fjoins are dead */
3445 return list_length(targetlist);
3449 * Number of items in a tlist, not including any resjunk items
3452 ExecCleanTargetListLength(List *targetlist)
3457 foreach(tl, targetlist)
3459 TargetEntry *curTle = (TargetEntry *) lfirst(tl);
3461 Assert(IsA(curTle, TargetEntry));
3462 if (!curTle->resdom->resjunk)
3470 * Evaluates a targetlist with respect to the given
3471 * expression context. Returns TRUE if we were able to create
3472 * a result, FALSE if we have exhausted a set-valued expression.
3474 * Results are stored into the passed values and isnull arrays.
3475 * The caller must provide an itemIsDone array that persists across calls.
3477 * As with ExecEvalExpr, the caller should pass isDone = NULL if not
3478 * prepared to deal with sets of result tuples. Otherwise, a return
3479 * of *isDone = ExprMultipleResult signifies a set element, and a return
3480 * of *isDone = ExprEndResult signifies end of the set of tuple.
3483 ExecTargetList(List *targetlist,
3484 ExprContext *econtext,
3487 ExprDoneCond *itemIsDone,
3488 ExprDoneCond *isDone)
3490 MemoryContext oldContext;
3495 * Run in short-lived per-tuple context while computing expressions.
3497 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
3500 * evaluate all the expressions in the target list
3503 *isDone = ExprSingleResult; /* until proven otherwise */
3505 haveDoneSets = false; /* any exhausted set exprs in tlist? */
3507 foreach(tl, targetlist)
3509 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
3510 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
3511 AttrNumber resind = tle->resdom->resno - 1;
3513 values[resind] = ExecEvalExpr(gstate->arg,
3516 &itemIsDone[resind]);
3518 if (itemIsDone[resind] != ExprSingleResult)
3520 /* We have a set-valued expression in the tlist */
3523 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3524 errmsg("set-valued function called in context that cannot accept a set")));
3525 if (itemIsDone[resind] == ExprMultipleResult)
3527 /* we have undone sets in the tlist, set flag */
3528 *isDone = ExprMultipleResult;
3532 /* we have done sets in the tlist, set flag for that */
3533 haveDoneSets = true;
3541 * note: can't get here unless we verified isDone != NULL
3543 if (*isDone == ExprSingleResult)
3546 * all sets are done, so report that tlist expansion is
3549 *isDone = ExprEndResult;
3550 MemoryContextSwitchTo(oldContext);
3556 * We have some done and some undone sets. Restart the done
3557 * ones so that we can deliver a tuple (if possible).
3559 foreach(tl, targetlist)
3561 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
3562 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
3563 AttrNumber resind = tle->resdom->resno - 1;
3565 if (itemIsDone[resind] == ExprEndResult)
3567 values[resind] = ExecEvalExpr(gstate->arg,
3570 &itemIsDone[resind]);
3572 if (itemIsDone[resind] == ExprEndResult)
3575 * Oh dear, this item is returning an empty set.
3576 * Guess we can't make a tuple after all.
3578 *isDone = ExprEndResult;
3585 * If we cannot make a tuple because some sets are empty, we
3586 * still have to cycle the nonempty sets to completion, else
3587 * resources will not be released from subplans etc.
3589 * XXX is that still necessary?
3591 if (*isDone == ExprEndResult)
3593 foreach(tl, targetlist)
3595 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
3596 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
3597 AttrNumber resind = tle->resdom->resno - 1;
3599 while (itemIsDone[resind] == ExprMultipleResult)
3601 values[resind] = ExecEvalExpr(gstate->arg,
3604 &itemIsDone[resind]);
3608 MemoryContextSwitchTo(oldContext);
3614 /* Report success */
3615 MemoryContextSwitchTo(oldContext);
3622 * Evaluates a simple-Variable-list projection.
3624 * Results are stored into the passed values and isnull arrays.
3627 ExecVariableList(ProjectionInfo *projInfo,
3631 ExprContext *econtext = projInfo->pi_exprContext;
3632 int *varSlotOffsets = projInfo->pi_varSlotOffsets;
3633 int *varNumbers = projInfo->pi_varNumbers;
3637 * Force extraction of all input values that we need.
3639 if (projInfo->pi_lastInnerVar > 0)
3640 slot_getsomeattrs(econtext->ecxt_innertuple,
3641 projInfo->pi_lastInnerVar);
3642 if (projInfo->pi_lastOuterVar > 0)
3643 slot_getsomeattrs(econtext->ecxt_outertuple,
3644 projInfo->pi_lastOuterVar);
3645 if (projInfo->pi_lastScanVar > 0)
3646 slot_getsomeattrs(econtext->ecxt_scantuple,
3647 projInfo->pi_lastScanVar);
3650 * Assign to result by direct extraction of fields from source
3651 * slots ... a mite ugly, but fast ...
3653 for (i = list_length(projInfo->pi_targetlist) - 1; i >= 0; i--)
3655 char *slotptr = ((char *) econtext) + varSlotOffsets[i];
3656 TupleTableSlot *varSlot = *((TupleTableSlot **) slotptr);
3657 int varNumber = varNumbers[i] - 1;
3659 values[i] = varSlot->tts_values[varNumber];
3660 isnull[i] = varSlot->tts_isnull[varNumber];
3667 * projects a tuple based on projection info and stores
3668 * it in the previously specified tuple table slot.
3670 * Note: the result is always a virtual tuple; therefore it
3671 * may reference the contents of the exprContext's scan tuples
3672 * and/or temporary results constructed in the exprContext.
3673 * If the caller wishes the result to be valid longer than that
3674 * data will be valid, he must call ExecMaterializeSlot on the
3678 ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
3680 TupleTableSlot *slot;
3685 Assert(projInfo != NULL);
3688 * get the projection info we want
3690 slot = projInfo->pi_slot;
3693 * Clear any former contents of the result slot. This makes it
3694 * safe for us to use the slot's Datum/isnull arrays as workspace.
3695 * (Also, we can return the slot as-is if we decide no rows can
3698 ExecClearTuple(slot);
3701 * form a new result tuple (if possible); if successful, mark the result
3702 * slot as containing a valid virtual tuple
3704 if (projInfo->pi_isVarList)
3706 /* simple Var list: this always succeeds with one result row */
3708 *isDone = ExprSingleResult;
3709 ExecVariableList(projInfo,
3712 ExecStoreVirtualTuple(slot);
3716 if (ExecTargetList(projInfo->pi_targetlist,
3717 projInfo->pi_exprContext,
3720 projInfo->pi_itemIsDone,
3722 ExecStoreVirtualTuple(slot);