1 /*-------------------------------------------------------------------------
4 * Routines to evaluate qualification and targetlist expressions
6 * Portions Copyright (c) 1996-2006, 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.199 2006/11/17 16:46:27 petere 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 "access/nbtree.h"
41 #include "catalog/pg_type.h"
42 #include "commands/typecmds.h"
43 #include "executor/execdebug.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/builtins.h"
52 #include "utils/lsyscache.h"
53 #include "utils/memutils.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 ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext,
67 bool *isNull, ExprDoneCond *isDone);
68 static Datum ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
69 bool *isNull, ExprDoneCond *isDone);
70 static Datum ExecEvalParam(ExprState *exprstate, ExprContext *econtext,
71 bool *isNull, ExprDoneCond *isDone);
72 static void ShutdownFuncExpr(Datum arg);
73 static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod,
74 TupleDesc *cache_field, ExprContext *econtext);
75 static void ShutdownTupleDescRef(Datum arg);
76 static ExprDoneCond ExecEvalFuncArgs(FunctionCallInfo fcinfo,
77 List *argList, ExprContext *econtext);
78 static Datum ExecMakeFunctionResultNoSets(FuncExprState *fcache,
79 ExprContext *econtext,
80 bool *isNull, ExprDoneCond *isDone);
81 static Datum ExecEvalFunc(FuncExprState *fcache, ExprContext *econtext,
82 bool *isNull, ExprDoneCond *isDone);
83 static Datum ExecEvalOper(FuncExprState *fcache, ExprContext *econtext,
84 bool *isNull, ExprDoneCond *isDone);
85 static Datum ExecEvalDistinct(FuncExprState *fcache, ExprContext *econtext,
86 bool *isNull, ExprDoneCond *isDone);
87 static Datum ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
88 ExprContext *econtext,
89 bool *isNull, ExprDoneCond *isDone);
90 static Datum ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
91 bool *isNull, ExprDoneCond *isDone);
92 static Datum ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
93 bool *isNull, ExprDoneCond *isDone);
94 static Datum ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
95 bool *isNull, ExprDoneCond *isDone);
96 static Datum ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
97 ExprContext *econtext,
98 bool *isNull, ExprDoneCond *isDone);
99 static Datum ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
100 bool *isNull, ExprDoneCond *isDone);
101 static Datum ExecEvalCaseTestExpr(ExprState *exprstate,
102 ExprContext *econtext,
103 bool *isNull, ExprDoneCond *isDone);
104 static Datum ExecEvalArray(ArrayExprState *astate,
105 ExprContext *econtext,
106 bool *isNull, ExprDoneCond *isDone);
107 static Datum ExecEvalRow(RowExprState *rstate,
108 ExprContext *econtext,
109 bool *isNull, ExprDoneCond *isDone);
110 static Datum ExecEvalRowCompare(RowCompareExprState *rstate,
111 ExprContext *econtext,
112 bool *isNull, ExprDoneCond *isDone);
113 static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr,
114 ExprContext *econtext,
115 bool *isNull, ExprDoneCond *isDone);
116 static Datum ExecEvalMinMax(MinMaxExprState *minmaxExpr,
117 ExprContext *econtext,
118 bool *isNull, ExprDoneCond *isDone);
119 static Datum ExecEvalNullIf(FuncExprState *nullIfExpr,
120 ExprContext *econtext,
121 bool *isNull, ExprDoneCond *isDone);
122 static Datum ExecEvalNullTest(NullTestState *nstate,
123 ExprContext *econtext,
124 bool *isNull, ExprDoneCond *isDone);
125 static Datum ExecEvalBooleanTest(GenericExprState *bstate,
126 ExprContext *econtext,
127 bool *isNull, ExprDoneCond *isDone);
128 static Datum ExecEvalCoerceToDomain(CoerceToDomainState *cstate,
129 ExprContext *econtext,
130 bool *isNull, ExprDoneCond *isDone);
131 static Datum ExecEvalCoerceToDomainValue(ExprState *exprstate,
132 ExprContext *econtext,
133 bool *isNull, ExprDoneCond *isDone);
134 static Datum ExecEvalFieldSelect(FieldSelectState *fstate,
135 ExprContext *econtext,
136 bool *isNull, ExprDoneCond *isDone);
137 static Datum ExecEvalFieldStore(FieldStoreState *fstate,
138 ExprContext *econtext,
139 bool *isNull, ExprDoneCond *isDone);
140 static Datum ExecEvalRelabelType(GenericExprState *exprstate,
141 ExprContext *econtext,
142 bool *isNull, ExprDoneCond *isDone);
145 /* ----------------------------------------------------------------
146 * ExecEvalExpr routines
148 * Recursively evaluate a targetlist or qualification expression.
150 * Each of the following routines having the signature
151 * Datum ExecEvalFoo(ExprState *expression,
152 * ExprContext *econtext,
154 * ExprDoneCond *isDone);
155 * is responsible for evaluating one type or subtype of ExprState node.
156 * They are normally called via the ExecEvalExpr macro, which makes use of
157 * the function pointer set up when the ExprState node was built by
158 * ExecInitExpr. (In some cases, we change this pointer later to avoid
159 * re-executing one-time overhead.)
161 * Note: for notational simplicity we declare these functions as taking the
162 * specific type of ExprState that they work on. This requires casting when
163 * assigning the function pointer in ExecInitExpr. Be careful that the
164 * function signature is declared correctly, because the cast suppresses
165 * automatic checking!
168 * All these functions share this calling convention:
171 * expression: the expression state tree to evaluate
172 * econtext: evaluation context information
175 * return value: Datum value of result
176 * *isNull: set to TRUE if result is NULL (actual return value is
177 * meaningless if so); set to FALSE if non-null result
178 * *isDone: set to indicator of set-result status
180 * A caller that can only accept a singleton (non-set) result should pass
181 * NULL for isDone; if the expression computes a set result then an error
182 * will be reported via ereport. If the caller does pass an isDone pointer
183 * then *isDone is set to one of these three states:
184 * ExprSingleResult singleton result (not a set)
185 * ExprMultipleResult return value is one element of a set
186 * ExprEndResult there are no more elements in the set
187 * When ExprMultipleResult is returned, the caller should invoke
188 * ExecEvalExpr() repeatedly until ExprEndResult is returned. ExprEndResult
189 * is returned after the last real set element. For convenience isNull will
190 * always be set TRUE when ExprEndResult is returned, but this should not be
191 * taken as indicating a NULL element of the set. Note that these return
192 * conventions allow us to distinguish among a singleton NULL, a NULL element
193 * of a set, and an empty set.
195 * The caller should already have switched into the temporary memory
196 * context econtext->ecxt_per_tuple_memory. The convenience entry point
197 * ExecEvalExprSwitchContext() is provided for callers who don't prefer to
198 * do the switch in an outer loop. We do not do the switch in these routines
199 * because it'd be a waste of cycles during nested expression evaluation.
200 * ----------------------------------------------------------------
207 * This function takes an ArrayRef and returns the extracted Datum
208 * if it's a simple reference, or the modified array value if it's
209 * an array assignment (i.e., array element or slice insertion).
211 * NOTE: if we get a NULL result from a subscript expression, we return NULL
212 * when it's an array reference, or raise an error when it's an assignment.
214 * NOTE: we deliberately refrain from applying DatumGetArrayTypeP() here,
215 * even though that might seem natural, because this code needs to support
216 * both varlena arrays and fixed-length array types. DatumGetArrayTypeP()
217 * only works for the varlena kind. The routines we call in arrayfuncs.c
218 * have to know the difference (that's what they need refattrlength for).
222 ExecEvalArrayRef(ArrayRefExprState *astate,
223 ExprContext *econtext,
225 ExprDoneCond *isDone)
227 ArrayRef *arrayRef = (ArrayRef *) astate->xprstate.expr;
228 ArrayType *array_source;
229 ArrayType *resultArray;
230 bool isAssignment = (arrayRef->refassgnexpr != NULL);
239 array_source = (ArrayType *)
240 DatumGetPointer(ExecEvalExpr(astate->refexpr,
246 * If refexpr yields NULL, and it's a fetch, then result is NULL. In the
247 * assignment case, we'll cons up something below.
251 if (isDone && *isDone == ExprEndResult)
252 return (Datum) NULL; /* end of set result */
257 foreach(l, astate->refupperindexpr)
259 ExprState *eltstate = (ExprState *) lfirst(l);
263 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
264 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
267 upper.indx[i++] = DatumGetInt32(ExecEvalExpr(eltstate,
271 /* If any index expr yields NULL, result is NULL or error */
276 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
277 errmsg("array subscript in assignment must not be null")));
283 if (astate->reflowerindexpr != NIL)
285 foreach(l, astate->reflowerindexpr)
287 ExprState *eltstate = (ExprState *) lfirst(l);
291 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
292 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
295 lower.indx[j++] = DatumGetInt32(ExecEvalExpr(eltstate,
299 /* If any index expr yields NULL, result is NULL or error */
304 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
305 errmsg("array subscript in assignment must not be null")));
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 to
328 * support arrays of composite types; in an assignment to a field of
329 * an array member, the parser would generate a FieldStore that
330 * expects to fetch its input tuple via CaseTestExpr.
332 sourceData = ExecEvalExpr(astate->refassgnexpr,
338 * For an assignment to a fixed-length array type, both the original
339 * array and the value to be assigned into it must be non-NULL, else
340 * we punt and return the original array.
342 if (astate->refattrlength > 0) /* fixed-length array? */
343 if (eisnull || *isNull)
344 return PointerGetDatum(array_source);
347 * For assignment to varlena arrays, we handle a NULL original array
348 * by substituting an empty (zero-dimensional) array; insertion of the
349 * new element will result in a singleton array value. It does not
350 * matter whether the new element is NULL.
354 array_source = construct_empty_array(arrayRef->refelemtype);
359 resultArray = array_set(array_source, i,
363 astate->refattrlength,
364 astate->refelemlength,
365 astate->refelembyval,
366 astate->refelemalign);
368 resultArray = array_set_slice(array_source, i,
369 upper.indx, lower.indx,
370 (ArrayType *) DatumGetPointer(sourceData),
372 astate->refattrlength,
373 astate->refelemlength,
374 astate->refelembyval,
375 astate->refelemalign);
376 return PointerGetDatum(resultArray);
380 return array_ref(array_source, i, upper.indx,
381 astate->refattrlength,
382 astate->refelemlength,
383 astate->refelembyval,
384 astate->refelemalign,
388 resultArray = array_get_slice(array_source, i,
389 upper.indx, lower.indx,
390 astate->refattrlength,
391 astate->refelemlength,
392 astate->refelembyval,
393 astate->refelemalign);
394 return PointerGetDatum(resultArray);
399 /* ----------------------------------------------------------------
402 * Returns a Datum whose value is the value of the precomputed
403 * aggregate found in the given expression context.
404 * ----------------------------------------------------------------
407 ExecEvalAggref(AggrefExprState *aggref, ExprContext *econtext,
408 bool *isNull, ExprDoneCond *isDone)
411 *isDone = ExprSingleResult;
413 if (econtext->ecxt_aggvalues == NULL) /* safety check */
414 elog(ERROR, "no aggregates in this expression context");
416 *isNull = econtext->ecxt_aggnulls[aggref->aggno];
417 return econtext->ecxt_aggvalues[aggref->aggno];
420 /* ----------------------------------------------------------------
423 * Returns a Datum whose value is the value of a range
424 * variable with respect to given expression context.
425 * ----------------------------------------------------------------
428 ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
429 bool *isNull, ExprDoneCond *isDone)
431 Var *variable = (Var *) exprstate->expr;
432 TupleTableSlot *slot;
436 *isDone = ExprSingleResult;
439 * Get the slot and attribute number we want
441 * The asserts check that references to system attributes only appear at
442 * the level of a relation scan; at higher levels, system attributes must
443 * be treated as ordinary variables (since we no longer have access to the
446 attnum = variable->varattno;
448 switch (variable->varno)
450 case INNER: /* get the tuple from the inner node */
451 slot = econtext->ecxt_innertuple;
455 case OUTER: /* get the tuple from the outer node */
456 slot = econtext->ecxt_outertuple;
460 default: /* get the tuple from the relation being
462 slot = econtext->ecxt_scantuple;
466 #ifdef USE_ASSERT_CHECKING
469 * Some checks that are only applied for user attribute numbers (bogus
470 * system attnums will be caught inside slot_getattr).
474 TupleDesc tuple_type = slot->tts_tupleDescriptor;
477 * This assert checks that the attnum is valid.
479 Assert(attnum <= tuple_type->natts);
482 * This assert checks that the datatype the plan expects to get (as
483 * told by our "variable" argument) is in fact the datatype of the
484 * attribute being fetched (as seen in the current context, identified
485 * by our "econtext" argument). Otherwise crashes are likely.
487 * Note that we can't check dropped columns, since their atttypid has
490 Assert(variable->vartype == tuple_type->attrs[attnum - 1]->atttypid ||
491 tuple_type->attrs[attnum - 1]->attisdropped);
493 #endif /* USE_ASSERT_CHECKING */
495 return slot_getattr(slot, attnum, isNull);
498 /* ----------------------------------------------------------------
499 * ExecEvalWholeRowVar
501 * Returns a Datum for a whole-row variable.
503 * This could be folded into ExecEvalVar, but we make it a separate
504 * routine so as not to slow down ExecEvalVar with tests for this
506 * ----------------------------------------------------------------
509 ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext,
510 bool *isNull, ExprDoneCond *isDone)
512 Var *variable = (Var *) exprstate->expr;
513 TupleTableSlot *slot;
516 HeapTupleHeader dtuple;
519 *isDone = ExprSingleResult;
522 Assert(variable->varattno == InvalidAttrNumber);
525 * Whole-row Vars can only appear at the level of a relation scan, never
528 Assert(variable->varno != INNER);
529 Assert(variable->varno != OUTER);
530 slot = econtext->ecxt_scantuple;
532 tuple = ExecFetchSlotTuple(slot);
533 tupleDesc = slot->tts_tupleDescriptor;
536 * We have to make a copy of the tuple so we can safely insert the Datum
537 * overhead fields, which are not set in on-disk tuples.
539 dtuple = (HeapTupleHeader) palloc(tuple->t_len);
540 memcpy((char *) dtuple, (char *) tuple->t_data, tuple->t_len);
542 HeapTupleHeaderSetDatumLength(dtuple, tuple->t_len);
545 * If the Var identifies a named composite type, label the tuple with that
546 * type; otherwise use what is in the tupleDesc.
548 * It's likely that the slot's tupleDesc is a record type; if so, make
549 * sure it's been "blessed", so that the Datum can be interpreted later.
551 if (variable->vartype != RECORDOID)
553 HeapTupleHeaderSetTypeId(dtuple, variable->vartype);
554 HeapTupleHeaderSetTypMod(dtuple, variable->vartypmod);
558 if (tupleDesc->tdtypeid == RECORDOID &&
559 tupleDesc->tdtypmod < 0)
560 assign_record_type_typmod(tupleDesc);
561 HeapTupleHeaderSetTypeId(dtuple, tupleDesc->tdtypeid);
562 HeapTupleHeaderSetTypMod(dtuple, tupleDesc->tdtypmod);
565 return PointerGetDatum(dtuple);
568 /* ----------------------------------------------------------------
571 * Returns the value of a constant.
573 * Note that for pass-by-ref datatypes, we return a pointer to the
574 * actual constant node. This is one of the reasons why functions
575 * must treat their input arguments as read-only.
576 * ----------------------------------------------------------------
579 ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
580 bool *isNull, ExprDoneCond *isDone)
582 Const *con = (Const *) exprstate->expr;
585 *isDone = ExprSingleResult;
587 *isNull = con->constisnull;
588 return con->constvalue;
591 /* ----------------------------------------------------------------
594 * Returns the value of a parameter. A param node contains
595 * something like ($.name) and the expression context contains
596 * the current parameter bindings (name = "sam") (age = 34)...
597 * so our job is to find and return the appropriate datum ("sam").
598 * ----------------------------------------------------------------
601 ExecEvalParam(ExprState *exprstate, ExprContext *econtext,
602 bool *isNull, ExprDoneCond *isDone)
604 Param *expression = (Param *) exprstate->expr;
605 int thisParamId = expression->paramid;
608 *isDone = ExprSingleResult;
610 if (expression->paramkind == PARAM_EXEC)
613 * PARAM_EXEC params (internal executor parameters) are stored in the
614 * ecxt_param_exec_vals array, and can be accessed by array index.
618 prm = &(econtext->ecxt_param_exec_vals[thisParamId]);
619 if (prm->execPlan != NULL)
621 /* Parameter not evaluated yet, so go do it */
622 ExecSetParamPlan(prm->execPlan, econtext);
623 /* ExecSetParamPlan should have processed this param... */
624 Assert(prm->execPlan == NULL);
626 *isNull = prm->isnull;
632 * PARAM_EXTERN parameters must be sought in ecxt_param_list_info.
634 ParamListInfo paramInfo = econtext->ecxt_param_list_info;
636 Assert(expression->paramkind == PARAM_EXTERN);
638 thisParamId > 0 && thisParamId <= paramInfo->numParams)
640 ParamExternData *prm = ¶mInfo->params[thisParamId - 1];
642 if (OidIsValid(prm->ptype))
644 Assert(prm->ptype == expression->paramtype);
645 *isNull = prm->isnull;
650 (errcode(ERRCODE_UNDEFINED_OBJECT),
651 errmsg("no value found for parameter %d", thisParamId)));
652 return (Datum) 0; /* keep compiler quiet */
657 /* ----------------------------------------------------------------
658 * ExecEvalOper / ExecEvalFunc support routines
659 * ----------------------------------------------------------------
666 * These functions return the value of the requested attribute
667 * out of the given tuple Datum.
668 * C functions which take a tuple as an argument are expected
669 * to use these. Ex: overpaid(EMP) might call GetAttributeByNum().
670 * Note: these are actually rather slow because they do a typcache
671 * lookup on each call.
674 GetAttributeByNum(HeapTupleHeader tuple,
682 HeapTupleData tmptup;
684 if (!AttributeNumberIsValid(attrno))
685 elog(ERROR, "invalid attribute number %d", attrno);
688 elog(ERROR, "a NULL isNull pointer was passed");
692 /* Kinda bogus but compatible with old behavior... */
697 tupType = HeapTupleHeaderGetTypeId(tuple);
698 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
699 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
702 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
703 * the fields in the struct just in case user tries to inspect system
706 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
707 ItemPointerSetInvalid(&(tmptup.t_self));
708 tmptup.t_tableOid = InvalidOid;
709 tmptup.t_data = tuple;
711 result = heap_getattr(&tmptup,
716 ReleaseTupleDesc(tupDesc);
722 GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
729 HeapTupleData tmptup;
733 elog(ERROR, "invalid attribute name");
736 elog(ERROR, "a NULL isNull pointer was passed");
740 /* Kinda bogus but compatible with old behavior... */
745 tupType = HeapTupleHeaderGetTypeId(tuple);
746 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
747 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
749 attrno = InvalidAttrNumber;
750 for (i = 0; i < tupDesc->natts; i++)
752 if (namestrcmp(&(tupDesc->attrs[i]->attname), attname) == 0)
754 attrno = tupDesc->attrs[i]->attnum;
759 if (attrno == InvalidAttrNumber)
760 elog(ERROR, "attribute \"%s\" does not exist", attname);
763 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
764 * the fields in the struct just in case user tries to inspect system
767 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
768 ItemPointerSetInvalid(&(tmptup.t_self));
769 tmptup.t_tableOid = InvalidOid;
770 tmptup.t_data = tuple;
772 result = heap_getattr(&tmptup,
777 ReleaseTupleDesc(tupDesc);
783 * init_fcache - initialize a FuncExprState node during first use
786 init_fcache(Oid foid, FuncExprState *fcache, MemoryContext fcacheCxt)
790 /* Check permission to call function */
791 aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
792 if (aclresult != ACLCHECK_OK)
793 aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(foid));
796 * Safety check on nargs. Under normal circumstances this should never
797 * fail, as parser should check sooner. But possibly it might fail if
798 * server has been compiled with FUNC_MAX_ARGS smaller than some functions
799 * declared in pg_proc?
801 if (list_length(fcache->args) > FUNC_MAX_ARGS)
803 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
804 errmsg("cannot pass more than %d arguments to a function",
807 /* Set up the primary fmgr lookup information */
808 fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
810 /* Initialize additional info */
811 fcache->setArgsValid = false;
812 fcache->shutdown_reg = false;
813 fcache->func.fn_expr = (Node *) fcache->xprstate.expr;
817 * callback function in case a FuncExpr returning a set needs to be shut down
818 * before it has been run to completion
821 ShutdownFuncExpr(Datum arg)
823 FuncExprState *fcache = (FuncExprState *) DatumGetPointer(arg);
825 /* Clear any active set-argument state */
826 fcache->setArgsValid = false;
828 /* execUtils will deregister the callback... */
829 fcache->shutdown_reg = false;
833 * get_cached_rowtype: utility function to lookup a rowtype tupdesc
835 * type_id, typmod: identity of the rowtype
836 * cache_field: where to cache the TupleDesc pointer in expression state node
837 * (field must be initialized to NULL)
838 * econtext: expression context we are executing in
840 * NOTE: because the shutdown callback will be called during plan rescan,
841 * must be prepared to re-do this during any node execution; cannot call
842 * just once during expression initialization
845 get_cached_rowtype(Oid type_id, int32 typmod,
846 TupleDesc *cache_field, ExprContext *econtext)
848 TupleDesc tupDesc = *cache_field;
850 /* Do lookup if no cached value or if requested type changed */
851 if (tupDesc == NULL ||
852 type_id != tupDesc->tdtypeid ||
853 typmod != tupDesc->tdtypmod)
855 tupDesc = lookup_rowtype_tupdesc(type_id, typmod);
859 /* Release old tupdesc; but callback is already registered */
860 ReleaseTupleDesc(*cache_field);
864 /* Need to register shutdown callback to release tupdesc */
865 RegisterExprContextCallback(econtext,
866 ShutdownTupleDescRef,
867 PointerGetDatum(cache_field));
869 *cache_field = tupDesc;
875 * Callback function to release a tupdesc refcount at expression tree shutdown
878 ShutdownTupleDescRef(Datum arg)
880 TupleDesc *cache_field = (TupleDesc *) DatumGetPointer(arg);
883 ReleaseTupleDesc(*cache_field);
888 * Evaluate arguments for a function.
891 ExecEvalFuncArgs(FunctionCallInfo fcinfo,
893 ExprContext *econtext)
895 ExprDoneCond argIsDone;
899 argIsDone = ExprSingleResult; /* default assumption */
902 foreach(arg, argList)
904 ExprState *argstate = (ExprState *) lfirst(arg);
905 ExprDoneCond thisArgIsDone;
907 fcinfo->arg[i] = ExecEvalExpr(argstate,
912 if (thisArgIsDone != ExprSingleResult)
915 * We allow only one argument to have a set value; we'd need much
916 * more complexity to keep track of multiple set arguments (cf.
917 * ExecTargetList) and it doesn't seem worth it.
919 if (argIsDone != ExprSingleResult)
921 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
922 errmsg("functions and operators can take at most one set argument")));
923 argIsDone = thisArgIsDone;
934 * ExecMakeFunctionResult
936 * Evaluate the arguments to a function and then the function itself.
939 ExecMakeFunctionResult(FuncExprState *fcache,
940 ExprContext *econtext,
942 ExprDoneCond *isDone)
944 List *arguments = fcache->args;
946 FunctionCallInfoData fcinfo;
947 ReturnSetInfo rsinfo; /* for functions returning sets */
948 ExprDoneCond argDone;
952 /* Guard against stack overflow due to overly complex expressions */
956 * arguments is a list of expressions to evaluate before passing to the
957 * function manager. We skip the evaluation if it was already done in the
958 * previous call (ie, we are continuing the evaluation of a set-valued
959 * function). Otherwise, collect the current argument values into fcinfo.
961 if (!fcache->setArgsValid)
963 /* Need to prep callinfo structure */
964 InitFunctionCallInfoData(fcinfo, &(fcache->func), 0, NULL, NULL);
965 argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);
966 if (argDone == ExprEndResult)
968 /* input is an empty set, so return an empty set. */
971 *isDone = ExprEndResult;
974 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
975 errmsg("set-valued function called in context that cannot accept a set")));
978 hasSetArg = (argDone != ExprSingleResult);
982 /* Copy callinfo from previous evaluation */
983 memcpy(&fcinfo, &fcache->setArgs, sizeof(fcinfo));
984 hasSetArg = fcache->setHasSetArg;
985 /* Reset flag (we may set it again below) */
986 fcache->setArgsValid = false;
990 * If function returns set, prepare a resultinfo node for communication
992 if (fcache->func.fn_retset)
994 fcinfo.resultinfo = (Node *) &rsinfo;
995 rsinfo.type = T_ReturnSetInfo;
996 rsinfo.econtext = econtext;
997 rsinfo.expectedDesc = NULL;
998 rsinfo.allowedModes = (int) SFRM_ValuePerCall;
999 rsinfo.returnMode = SFRM_ValuePerCall;
1000 /* isDone is filled below */
1001 rsinfo.setResult = NULL;
1002 rsinfo.setDesc = NULL;
1006 * now return the value gotten by calling the function manager, passing
1007 * the function the evaluated parameter values.
1009 if (fcache->func.fn_retset || hasSetArg)
1012 * We need to return a set result. Complain if caller not ready to
1017 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1018 errmsg("set-valued function called in context that cannot accept a set")));
1021 * This loop handles the situation where we have both a set argument
1022 * and a set-valued function. Once we have exhausted the function's
1023 * value(s) for a particular argument value, we have to get the next
1024 * argument value and start the function over again. We might have to
1025 * do it more than once, if the function produces an empty result set
1026 * for a particular input value.
1031 * If function is strict, and there are any NULL arguments, skip
1032 * calling the function (at least for this set of args).
1036 if (fcache->func.fn_strict)
1038 for (i = 0; i < fcinfo.nargs; i++)
1040 if (fcinfo.argnull[i])
1050 fcinfo.isnull = false;
1051 rsinfo.isDone = ExprSingleResult;
1052 result = FunctionCallInvoke(&fcinfo);
1053 *isNull = fcinfo.isnull;
1054 *isDone = rsinfo.isDone;
1060 *isDone = ExprEndResult;
1063 if (*isDone != ExprEndResult)
1066 * Got a result from current argument. If function itself
1067 * returns set, save the current argument values to re-use on
1070 if (fcache->func.fn_retset && *isDone == ExprMultipleResult)
1072 memcpy(&fcache->setArgs, &fcinfo, sizeof(fcinfo));
1073 fcache->setHasSetArg = hasSetArg;
1074 fcache->setArgsValid = true;
1075 /* Register cleanup callback if we didn't already */
1076 if (!fcache->shutdown_reg)
1078 RegisterExprContextCallback(econtext,
1080 PointerGetDatum(fcache));
1081 fcache->shutdown_reg = true;
1086 * Make sure we say we are returning a set, even if the
1087 * function itself doesn't return sets.
1090 *isDone = ExprMultipleResult;
1094 /* Else, done with this argument */
1096 break; /* input not a set, so done */
1098 /* Re-eval args to get the next element of the input set */
1099 argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);
1101 if (argDone != ExprMultipleResult)
1103 /* End of argument set, so we're done. */
1105 *isDone = ExprEndResult;
1111 * If we reach here, loop around to run the function on the new
1119 * Non-set case: much easier.
1121 * We change the ExprState function pointer to use the simpler
1122 * ExecMakeFunctionResultNoSets on subsequent calls. This amounts to
1123 * assuming that no argument can return a set if it didn't do so the
1126 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResultNoSets;
1129 *isDone = ExprSingleResult;
1132 * If function is strict, and there are any NULL arguments, skip
1133 * calling the function and return NULL.
1135 if (fcache->func.fn_strict)
1137 for (i = 0; i < fcinfo.nargs; i++)
1139 if (fcinfo.argnull[i])
1146 fcinfo.isnull = false;
1147 result = FunctionCallInvoke(&fcinfo);
1148 *isNull = fcinfo.isnull;
1155 * ExecMakeFunctionResultNoSets
1157 * Simplified version of ExecMakeFunctionResult that can only handle
1158 * non-set cases. Hand-tuned for speed.
1161 ExecMakeFunctionResultNoSets(FuncExprState *fcache,
1162 ExprContext *econtext,
1164 ExprDoneCond *isDone)
1168 FunctionCallInfoData fcinfo;
1171 /* Guard against stack overflow due to overly complex expressions */
1172 check_stack_depth();
1175 *isDone = ExprSingleResult;
1177 /* inlined, simplified version of ExecEvalFuncArgs */
1179 foreach(arg, fcache->args)
1181 ExprState *argstate = (ExprState *) lfirst(arg);
1183 fcinfo.arg[i] = ExecEvalExpr(argstate,
1190 InitFunctionCallInfoData(fcinfo, &(fcache->func), i, NULL, NULL);
1193 * If function is strict, and there are any NULL arguments, skip calling
1194 * the function and return NULL.
1196 if (fcache->func.fn_strict)
1200 if (fcinfo.argnull[i])
1207 /* fcinfo.isnull = false; */ /* handled by InitFunctionCallInfoData */
1208 result = FunctionCallInvoke(&fcinfo);
1209 *isNull = fcinfo.isnull;
1216 * ExecMakeTableFunctionResult
1218 * Evaluate a table function, producing a materialized result in a Tuplestore
1219 * object. *returnDesc is set to the tupledesc actually returned by the
1220 * function, or NULL if it didn't provide one.
1223 ExecMakeTableFunctionResult(ExprState *funcexpr,
1224 ExprContext *econtext,
1225 TupleDesc expectedDesc,
1226 TupleDesc *returnDesc)
1228 Tuplestorestate *tupstore = NULL;
1229 TupleDesc tupdesc = NULL;
1232 bool returnsSet = false;
1233 FunctionCallInfoData fcinfo;
1234 ReturnSetInfo rsinfo;
1235 HeapTupleData tmptup;
1236 MemoryContext callerContext;
1237 MemoryContext oldcontext;
1238 bool direct_function_call;
1239 bool first_time = true;
1241 callerContext = CurrentMemoryContext;
1243 funcrettype = exprType((Node *) funcexpr->expr);
1245 returnsTuple = type_is_rowtype(funcrettype);
1248 * Prepare a resultinfo node for communication. We always do this even if
1249 * not expecting a set result, so that we can pass expectedDesc. In the
1250 * generic-expression case, the expression doesn't actually get to see the
1251 * resultinfo, but set it up anyway because we use some of the fields as
1252 * our own state variables.
1254 InitFunctionCallInfoData(fcinfo, NULL, 0, NULL, (Node *) &rsinfo);
1255 rsinfo.type = T_ReturnSetInfo;
1256 rsinfo.econtext = econtext;
1257 rsinfo.expectedDesc = expectedDesc;
1258 rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
1259 rsinfo.returnMode = SFRM_ValuePerCall;
1260 /* isDone is filled below */
1261 rsinfo.setResult = NULL;
1262 rsinfo.setDesc = NULL;
1265 * Normally the passed expression tree will be a FuncExprState, since the
1266 * grammar only allows a function call at the top level of a table
1267 * function reference. However, if the function doesn't return set then
1268 * the planner might have replaced the function call via constant-folding
1269 * or inlining. So if we see any other kind of expression node, execute
1270 * it via the general ExecEvalExpr() code; the only difference is that we
1271 * don't get a chance to pass a special ReturnSetInfo to any functions
1272 * buried in the expression.
1274 if (funcexpr && IsA(funcexpr, FuncExprState) &&
1275 IsA(funcexpr->expr, FuncExpr))
1277 FuncExprState *fcache = (FuncExprState *) funcexpr;
1278 ExprDoneCond argDone;
1281 * This path is similar to ExecMakeFunctionResult.
1283 direct_function_call = true;
1286 * Initialize function cache if first time through
1288 if (fcache->func.fn_oid == InvalidOid)
1290 FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
1292 init_fcache(func->funcid, fcache, econtext->ecxt_per_query_memory);
1294 returnsSet = fcache->func.fn_retset;
1297 * Evaluate the function's argument list.
1299 * Note: ideally, we'd do this in the per-tuple context, but then the
1300 * argument values would disappear when we reset the context in the
1301 * inner loop. So do it in caller context. Perhaps we should make a
1302 * separate context just to hold the evaluated arguments?
1304 fcinfo.flinfo = &(fcache->func);
1305 argDone = ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
1306 /* We don't allow sets in the arguments of the table function */
1307 if (argDone != ExprSingleResult)
1309 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1310 errmsg("set-valued function called in context that cannot accept a set")));
1313 * If function is strict, and there are any NULL arguments, skip
1314 * calling the function and act like it returned NULL (or an empty
1315 * set, in the returns-set case).
1317 if (fcache->func.fn_strict)
1321 for (i = 0; i < fcinfo.nargs; i++)
1323 if (fcinfo.argnull[i])
1324 goto no_function_result;
1330 /* Treat funcexpr as a generic expression */
1331 direct_function_call = false;
1335 * Switch to short-lived context for calling the function or expression.
1337 MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1340 * Loop to handle the ValuePerCall protocol (which is also the same
1341 * behavior needed in the generic ExecEvalExpr path).
1348 CHECK_FOR_INTERRUPTS();
1351 * reset per-tuple memory context before each call of the function or
1352 * expression. This cleans up any local memory the function may leak
1355 ResetExprContext(econtext);
1357 /* Call the function or expression one time */
1358 if (direct_function_call)
1360 fcinfo.isnull = false;
1361 rsinfo.isDone = ExprSingleResult;
1362 result = FunctionCallInvoke(&fcinfo);
1366 result = ExecEvalExpr(funcexpr, econtext,
1367 &fcinfo.isnull, &rsinfo.isDone);
1370 /* Which protocol does function want to use? */
1371 if (rsinfo.returnMode == SFRM_ValuePerCall)
1374 * Check for end of result set.
1376 if (rsinfo.isDone == ExprEndResult)
1380 * Can't do anything very useful with NULL rowtype values. For a
1381 * function returning set, we consider this a protocol violation
1382 * (but another alternative would be to just ignore the result and
1383 * "continue" to get another row). For a function not returning
1384 * set, we fall out of the loop; we'll cons up an all-nulls result
1387 if (returnsTuple && fcinfo.isnull)
1392 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1393 errmsg("function returning set of rows cannot return null value")));
1397 * If first time through, build tupdesc and tuplestore for result
1401 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1405 * Use the type info embedded in the rowtype Datum to look
1406 * up the needed tupdesc. Make a copy for the query.
1410 td = DatumGetHeapTupleHeader(result);
1411 tupdesc = lookup_rowtype_tupdesc_copy(HeapTupleHeaderGetTypeId(td),
1412 HeapTupleHeaderGetTypMod(td));
1417 * Scalar type, so make a single-column descriptor
1419 tupdesc = CreateTemplateTupleDesc(1, false);
1420 TupleDescInitEntry(tupdesc,
1427 tupstore = tuplestore_begin_heap(true, false, work_mem);
1428 MemoryContextSwitchTo(oldcontext);
1429 rsinfo.setResult = tupstore;
1430 rsinfo.setDesc = tupdesc;
1434 * Store current resultset item.
1440 td = DatumGetHeapTupleHeader(result);
1443 * tuplestore_puttuple needs a HeapTuple not a bare
1444 * HeapTupleHeader, but it doesn't need all the fields.
1446 tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
1452 tuple = heap_form_tuple(tupdesc, &result, &fcinfo.isnull);
1455 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1456 tuplestore_puttuple(tupstore, tuple);
1457 MemoryContextSwitchTo(oldcontext);
1462 if (rsinfo.isDone != ExprMultipleResult)
1465 else if (rsinfo.returnMode == SFRM_Materialize)
1467 /* check we're on the same page as the function author */
1468 if (!first_time || rsinfo.isDone != ExprSingleResult)
1470 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1471 errmsg("table-function protocol for materialize mode was not followed")));
1472 /* Done evaluating the set result */
1477 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1478 errmsg("unrecognized table-function returnMode: %d",
1479 (int) rsinfo.returnMode)));
1487 * If we got nothing from the function (ie, an empty-set or NULL result),
1488 * we have to create the tuplestore to return, and if it's a
1489 * non-set-returning function then insert a single all-nulls row.
1491 if (rsinfo.setResult == NULL)
1493 MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1494 tupstore = tuplestore_begin_heap(true, false, work_mem);
1495 rsinfo.setResult = tupstore;
1498 int natts = expectedDesc->natts;
1503 MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1504 nulldatums = (Datum *) palloc0(natts * sizeof(Datum));
1505 nullflags = (bool *) palloc(natts * sizeof(bool));
1506 memset(nullflags, true, natts * sizeof(bool));
1507 tuple = heap_form_tuple(expectedDesc, nulldatums, nullflags);
1508 MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1509 tuplestore_puttuple(tupstore, tuple);
1513 MemoryContextSwitchTo(callerContext);
1515 /* The returned pointers are those in rsinfo */
1516 *returnDesc = rsinfo.setDesc;
1517 return rsinfo.setResult;
1521 /* ----------------------------------------------------------------
1525 * Evaluate the functional result of a list of arguments by calling the
1527 * ----------------------------------------------------------------
1530 /* ----------------------------------------------------------------
1532 * ----------------------------------------------------------------
1535 ExecEvalFunc(FuncExprState *fcache,
1536 ExprContext *econtext,
1538 ExprDoneCond *isDone)
1540 /* This is called only the first time through */
1541 FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
1543 /* Initialize function lookup info */
1544 init_fcache(func->funcid, fcache, econtext->ecxt_per_query_memory);
1546 /* Go directly to ExecMakeFunctionResult on subsequent uses */
1547 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
1549 return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
1552 /* ----------------------------------------------------------------
1554 * ----------------------------------------------------------------
1557 ExecEvalOper(FuncExprState *fcache,
1558 ExprContext *econtext,
1560 ExprDoneCond *isDone)
1562 /* This is called only the first time through */
1563 OpExpr *op = (OpExpr *) fcache->xprstate.expr;
1565 /* Initialize function lookup info */
1566 init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory);
1568 /* Go directly to ExecMakeFunctionResult on subsequent uses */
1569 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
1571 return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
1574 /* ----------------------------------------------------------------
1577 * IS DISTINCT FROM must evaluate arguments to determine whether
1578 * they are NULL; if either is NULL then the result is already
1579 * known. If neither is NULL, then proceed to evaluate the
1580 * function. Note that this is *always* derived from the equals
1581 * operator, but since we need special processing of the arguments
1582 * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
1583 * ----------------------------------------------------------------
1586 ExecEvalDistinct(FuncExprState *fcache,
1587 ExprContext *econtext,
1589 ExprDoneCond *isDone)
1592 FunctionCallInfoData fcinfo;
1593 ExprDoneCond argDone;
1596 /* Set default values for result flags: non-null, not a set result */
1599 *isDone = ExprSingleResult;
1602 * Initialize function cache if first time through
1604 if (fcache->func.fn_oid == InvalidOid)
1606 DistinctExpr *op = (DistinctExpr *) fcache->xprstate.expr;
1608 init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory);
1609 Assert(!fcache->func.fn_retset);
1613 * extract info from fcache
1615 argList = fcache->args;
1617 /* Need to prep callinfo structure */
1618 InitFunctionCallInfoData(fcinfo, &(fcache->func), 0, NULL, NULL);
1619 argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
1620 if (argDone != ExprSingleResult)
1622 (errcode(ERRCODE_DATATYPE_MISMATCH),
1623 errmsg("IS DISTINCT FROM does not support set arguments")));
1624 Assert(fcinfo.nargs == 2);
1626 if (fcinfo.argnull[0] && fcinfo.argnull[1])
1628 /* Both NULL? Then is not distinct... */
1629 result = BoolGetDatum(FALSE);
1631 else if (fcinfo.argnull[0] || fcinfo.argnull[1])
1633 /* Only one is NULL? Then is distinct... */
1634 result = BoolGetDatum(TRUE);
1638 fcinfo.isnull = false;
1639 result = FunctionCallInvoke(&fcinfo);
1640 *isNull = fcinfo.isnull;
1641 /* Must invert result of "=" */
1642 result = BoolGetDatum(!DatumGetBool(result));
1649 * ExecEvalScalarArrayOp
1651 * Evaluate "scalar op ANY/ALL (array)". The operator always yields boolean,
1652 * and we combine the results across all array elements using OR and AND
1653 * (for ANY and ALL respectively). Of course we short-circuit as soon as
1654 * the result is known.
1657 ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
1658 ExprContext *econtext,
1659 bool *isNull, ExprDoneCond *isDone)
1661 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) sstate->fxprstate.xprstate.expr;
1662 bool useOr = opexpr->useOr;
1667 FunctionCallInfoData fcinfo;
1668 ExprDoneCond argDone;
1677 /* Set default values for result flags: non-null, not a set result */
1680 *isDone = ExprSingleResult;
1683 * Initialize function cache if first time through
1685 if (sstate->fxprstate.func.fn_oid == InvalidOid)
1687 init_fcache(opexpr->opfuncid, &sstate->fxprstate,
1688 econtext->ecxt_per_query_memory);
1689 Assert(!sstate->fxprstate.func.fn_retset);
1692 /* Need to prep callinfo structure */
1693 InitFunctionCallInfoData(fcinfo, &(sstate->fxprstate.func), 0, NULL, NULL);
1694 argDone = ExecEvalFuncArgs(&fcinfo, sstate->fxprstate.args, econtext);
1695 if (argDone != ExprSingleResult)
1697 (errcode(ERRCODE_DATATYPE_MISMATCH),
1698 errmsg("op ANY/ALL (array) does not support set arguments")));
1699 Assert(fcinfo.nargs == 2);
1702 * If the array is NULL then we return NULL --- it's not very meaningful
1703 * to do anything else, even if the operator isn't strict.
1705 if (fcinfo.argnull[1])
1710 /* Else okay to fetch and detoast the array */
1711 arr = DatumGetArrayTypeP(fcinfo.arg[1]);
1714 * If the array is empty, we return either FALSE or TRUE per the useOr
1715 * flag. This is correct even if the scalar is NULL; since we would
1716 * evaluate the operator zero times, it matters not whether it would want
1719 nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
1721 return BoolGetDatum(!useOr);
1724 * If the scalar is NULL, and the function is strict, return NULL; no
1725 * point in iterating the loop.
1727 if (fcinfo.argnull[0] && sstate->fxprstate.func.fn_strict)
1734 * We arrange to look up info about the element type only once per series
1735 * of calls, assuming the element type doesn't change underneath us.
1737 if (sstate->element_type != ARR_ELEMTYPE(arr))
1739 get_typlenbyvalalign(ARR_ELEMTYPE(arr),
1743 sstate->element_type = ARR_ELEMTYPE(arr);
1745 typlen = sstate->typlen;
1746 typbyval = sstate->typbyval;
1747 typalign = sstate->typalign;
1749 result = BoolGetDatum(!useOr);
1752 /* Loop over the array elements */
1753 s = (char *) ARR_DATA_PTR(arr);
1754 bitmap = ARR_NULLBITMAP(arr);
1757 for (i = 0; i < nitems; i++)
1762 /* Get array element, checking for NULL */
1763 if (bitmap && (*bitmap & bitmask) == 0)
1765 fcinfo.arg[1] = (Datum) 0;
1766 fcinfo.argnull[1] = true;
1770 elt = fetch_att(s, typbyval, typlen);
1771 s = att_addlength(s, typlen, PointerGetDatum(s));
1772 s = (char *) att_align(s, typalign);
1773 fcinfo.arg[1] = elt;
1774 fcinfo.argnull[1] = false;
1777 /* Call comparison function */
1778 if (fcinfo.argnull[1] && sstate->fxprstate.func.fn_strict)
1780 fcinfo.isnull = true;
1781 thisresult = (Datum) 0;
1785 fcinfo.isnull = false;
1786 thisresult = FunctionCallInvoke(&fcinfo);
1789 /* Combine results per OR or AND semantics */
1794 if (DatumGetBool(thisresult))
1796 result = BoolGetDatum(true);
1798 break; /* needn't look at any more elements */
1803 if (!DatumGetBool(thisresult))
1805 result = BoolGetDatum(false);
1807 break; /* needn't look at any more elements */
1811 /* advance bitmap pointer if any */
1815 if (bitmask == 0x100)
1823 *isNull = resultnull;
1827 /* ----------------------------------------------------------------
1832 * Evaluate boolean expressions, with appropriate short-circuiting.
1834 * The query planner reformulates clause expressions in the
1835 * qualification to conjunctive normal form. If we ever get
1836 * an AND to evaluate, we can be sure that it's not a top-level
1837 * clause in the qualification, but appears lower (as a function
1838 * argument, for example), or in the target list. Not that you
1839 * need to know this, mind you...
1840 * ----------------------------------------------------------------
1843 ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
1844 bool *isNull, ExprDoneCond *isDone)
1846 ExprState *clause = linitial(notclause->args);
1850 *isDone = ExprSingleResult;
1852 expr_value = ExecEvalExpr(clause, econtext, isNull, NULL);
1855 * if the expression evaluates to null, then we just cascade the null back
1856 * to whoever called us.
1862 * evaluation of 'not' is simple.. expr is false, then return 'true' and
1865 return BoolGetDatum(!DatumGetBool(expr_value));
1868 /* ----------------------------------------------------------------
1870 * ----------------------------------------------------------------
1873 ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
1874 bool *isNull, ExprDoneCond *isDone)
1876 List *clauses = orExpr->args;
1881 *isDone = ExprSingleResult;
1886 * If any of the clauses is TRUE, the OR result is TRUE regardless of the
1887 * states of the rest of the clauses, so we can stop evaluating and return
1888 * TRUE immediately. If none are TRUE and one or more is NULL, we return
1889 * NULL; otherwise we return FALSE. This makes sense when you interpret
1890 * NULL as "don't know": if we have a TRUE then the OR is TRUE even if we
1891 * aren't sure about some of the other inputs. If all the known inputs are
1892 * FALSE, but we have one or more "don't knows", then we have to report
1893 * that we "don't know" what the OR's result should be --- perhaps one of
1894 * the "don't knows" would have been TRUE if we'd known its value. Only
1895 * when all the inputs are known to be FALSE can we state confidently that
1896 * the OR's result is FALSE.
1898 foreach(clause, clauses)
1900 ExprState *clausestate = (ExprState *) lfirst(clause);
1903 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
1906 * if we have a non-null true result, then return it.
1909 AnyNull = true; /* remember we got a null */
1910 else if (DatumGetBool(clause_value))
1911 return clause_value;
1914 /* AnyNull is true if at least one clause evaluated to NULL */
1916 return BoolGetDatum(false);
1919 /* ----------------------------------------------------------------
1921 * ----------------------------------------------------------------
1924 ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
1925 bool *isNull, ExprDoneCond *isDone)
1927 List *clauses = andExpr->args;
1932 *isDone = ExprSingleResult;
1937 * If any of the clauses is FALSE, the AND result is FALSE regardless of
1938 * the states of the rest of the clauses, so we can stop evaluating and
1939 * return FALSE immediately. If none are FALSE and one or more is NULL,
1940 * we return NULL; otherwise we return TRUE. This makes sense when you
1941 * interpret NULL as "don't know", using the same sort of reasoning as for
1945 foreach(clause, clauses)
1947 ExprState *clausestate = (ExprState *) lfirst(clause);
1950 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
1953 * if we have a non-null false result, then return it.
1956 AnyNull = true; /* remember we got a null */
1957 else if (!DatumGetBool(clause_value))
1958 return clause_value;
1961 /* AnyNull is true if at least one clause evaluated to NULL */
1963 return BoolGetDatum(!AnyNull);
1966 /* ----------------------------------------------------------------
1967 * ExecEvalConvertRowtype
1969 * Evaluate a rowtype coercion operation. This may require
1970 * rearranging field positions.
1971 * ----------------------------------------------------------------
1974 ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
1975 ExprContext *econtext,
1976 bool *isNull, ExprDoneCond *isDone)
1978 ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) cstate->xprstate.expr;
1981 HeapTupleHeader tuple;
1982 HeapTupleData tmptup;
1983 AttrNumber *attrMap;
1991 tupDatum = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
1993 /* this test covers the isDone exception too: */
1997 tuple = DatumGetHeapTupleHeader(tupDatum);
1999 /* Lookup tupdescs if first time through or after rescan */
2000 if (cstate->indesc == NULL)
2001 get_cached_rowtype(exprType((Node *) convert->arg), -1,
2002 &cstate->indesc, econtext);
2003 if (cstate->outdesc == NULL)
2004 get_cached_rowtype(convert->resulttype, -1,
2005 &cstate->outdesc, econtext);
2007 Assert(HeapTupleHeaderGetTypeId(tuple) == cstate->indesc->tdtypeid);
2008 Assert(HeapTupleHeaderGetTypMod(tuple) == cstate->indesc->tdtypmod);
2010 /* if first time through, initialize */
2011 if (cstate->attrMap == NULL)
2013 MemoryContext old_cxt;
2016 /* allocate state in long-lived memory context */
2017 old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2019 /* prepare map from old to new attribute numbers */
2020 n = cstate->outdesc->natts;
2021 cstate->attrMap = (AttrNumber *) palloc0(n * sizeof(AttrNumber));
2022 for (i = 0; i < n; i++)
2024 Form_pg_attribute att = cstate->outdesc->attrs[i];
2030 if (att->attisdropped)
2031 continue; /* attrMap[i] is already 0 */
2032 attname = NameStr(att->attname);
2033 atttypid = att->atttypid;
2034 atttypmod = att->atttypmod;
2035 for (j = 0; j < cstate->indesc->natts; j++)
2037 att = cstate->indesc->attrs[j];
2038 if (att->attisdropped)
2040 if (strcmp(attname, NameStr(att->attname)) == 0)
2042 /* Found it, check type */
2043 if (atttypid != att->atttypid || atttypmod != att->atttypmod)
2044 elog(ERROR, "attribute \"%s\" of type %s does not match corresponding attribute of type %s",
2046 format_type_be(cstate->indesc->tdtypeid),
2047 format_type_be(cstate->outdesc->tdtypeid));
2048 cstate->attrMap[i] = (AttrNumber) (j + 1);
2052 if (cstate->attrMap[i] == 0)
2053 elog(ERROR, "attribute \"%s\" of type %s does not exist",
2055 format_type_be(cstate->indesc->tdtypeid));
2057 /* preallocate workspace for Datum arrays */
2058 n = cstate->indesc->natts + 1; /* +1 for NULL */
2059 cstate->invalues = (Datum *) palloc(n * sizeof(Datum));
2060 cstate->inisnull = (bool *) palloc(n * sizeof(bool));
2061 n = cstate->outdesc->natts;
2062 cstate->outvalues = (Datum *) palloc(n * sizeof(Datum));
2063 cstate->outisnull = (bool *) palloc(n * sizeof(bool));
2065 MemoryContextSwitchTo(old_cxt);
2068 attrMap = cstate->attrMap;
2069 invalues = cstate->invalues;
2070 inisnull = cstate->inisnull;
2071 outvalues = cstate->outvalues;
2072 outisnull = cstate->outisnull;
2073 outnatts = cstate->outdesc->natts;
2076 * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader.
2078 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2079 tmptup.t_data = tuple;
2082 * Extract all the values of the old tuple, offsetting the arrays so that
2083 * invalues[0] is NULL and invalues[1] is the first source attribute; this
2084 * exactly matches the numbering convention in attrMap.
2086 heap_deform_tuple(&tmptup, cstate->indesc, invalues + 1, inisnull + 1);
2087 invalues[0] = (Datum) 0;
2091 * Transpose into proper fields of the new tuple.
2093 for (i = 0; i < outnatts; i++)
2097 outvalues[i] = invalues[j];
2098 outisnull[i] = inisnull[j];
2102 * Now form the new tuple.
2104 result = heap_form_tuple(cstate->outdesc, outvalues, outisnull);
2106 return HeapTupleGetDatum(result);
2109 /* ----------------------------------------------------------------
2112 * Evaluate a CASE clause. Will have boolean expressions
2113 * inside the WHEN clauses, and will have expressions
2115 * - thomas 1998-11-09
2116 * ----------------------------------------------------------------
2119 ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
2120 bool *isNull, ExprDoneCond *isDone)
2122 List *clauses = caseExpr->args;
2128 *isDone = ExprSingleResult;
2131 * If there's a test expression, we have to evaluate it and save the value
2132 * where the CaseTestExpr placeholders can find it. We must save and
2133 * restore prior setting of econtext's caseValue fields, in case this node
2134 * is itself within a larger CASE.
2136 save_datum = econtext->caseValue_datum;
2137 save_isNull = econtext->caseValue_isNull;
2141 econtext->caseValue_datum = ExecEvalExpr(caseExpr->arg,
2143 &econtext->caseValue_isNull,
2148 * we evaluate each of the WHEN clauses in turn, as soon as one is true we
2149 * return the corresponding result. If none are true then we return the
2150 * value of the default clause, or NULL if there is none.
2152 foreach(clause, clauses)
2154 CaseWhenState *wclause = lfirst(clause);
2157 clause_value = ExecEvalExpr(wclause->expr,
2163 * if we have a true test, then we return the result, since the case
2164 * statement is satisfied. A NULL result from the test is not
2167 if (DatumGetBool(clause_value) && !*isNull)
2169 econtext->caseValue_datum = save_datum;
2170 econtext->caseValue_isNull = save_isNull;
2171 return ExecEvalExpr(wclause->result,
2178 econtext->caseValue_datum = save_datum;
2179 econtext->caseValue_isNull = save_isNull;
2181 if (caseExpr->defresult)
2183 return ExecEvalExpr(caseExpr->defresult,
2194 * ExecEvalCaseTestExpr
2196 * Return the value stored by CASE.
2199 ExecEvalCaseTestExpr(ExprState *exprstate,
2200 ExprContext *econtext,
2201 bool *isNull, ExprDoneCond *isDone)
2204 *isDone = ExprSingleResult;
2205 *isNull = econtext->caseValue_isNull;
2206 return econtext->caseValue_datum;
2209 /* ----------------------------------------------------------------
2210 * ExecEvalArray - ARRAY[] expressions
2211 * ----------------------------------------------------------------
2214 ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
2215 bool *isNull, ExprDoneCond *isDone)
2217 ArrayExpr *arrayExpr = (ArrayExpr *) astate->xprstate.expr;
2220 Oid element_type = arrayExpr->element_typeid;
2225 /* Set default values for result flags: non-null, not a set result */
2228 *isDone = ExprSingleResult;
2230 if (!arrayExpr->multidims)
2232 /* Elements are presumably of scalar type */
2239 nelems = list_length(astate->elements);
2241 /* Shouldn't happen here, but if length is 0, return empty array */
2243 return PointerGetDatum(construct_empty_array(element_type));
2245 dvalues = (Datum *) palloc(nelems * sizeof(Datum));
2246 dnulls = (bool *) palloc(nelems * sizeof(bool));
2248 /* loop through and build array of datums */
2249 foreach(element, astate->elements)
2251 ExprState *e = (ExprState *) lfirst(element);
2253 dvalues[i] = ExecEvalExpr(e, econtext, &dnulls[i], NULL);
2257 /* setup for 1-D array of the given length */
2261 result = construct_md_array(dvalues, dnulls, ndims, dims, lbs,
2269 /* Must be nested array expressions */
2272 int outer_nelems = 0;
2274 int *elem_dims = NULL;
2275 int *elem_lbs = NULL;
2276 bool firstone = true;
2277 bool havenulls = false;
2278 bool haveempty = false;
2288 i = list_length(astate->elements);
2289 subdata = (char **) palloc(i * sizeof(char *));
2290 subbitmaps = (bits8 **) palloc(i * sizeof(bits8 *));
2291 subbytes = (int *) palloc(i * sizeof(int));
2292 subnitems = (int *) palloc(i * sizeof(int));
2294 /* loop through and get data area from each element */
2295 foreach(element, astate->elements)
2297 ExprState *e = (ExprState *) lfirst(element);
2303 arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
2304 /* temporarily ignore null subarrays */
2311 array = DatumGetArrayTypeP(arraydatum);
2313 /* run-time double-check on element type */
2314 if (element_type != ARR_ELEMTYPE(array))
2316 (errcode(ERRCODE_DATATYPE_MISMATCH),
2317 errmsg("cannot merge incompatible arrays"),
2318 errdetail("Array with element type %s cannot be "
2319 "included in ARRAY construct with element type %s.",
2320 format_type_be(ARR_ELEMTYPE(array)),
2321 format_type_be(element_type))));
2323 this_ndims = ARR_NDIM(array);
2324 /* temporarily ignore zero-dimensional subarrays */
2325 if (this_ndims <= 0)
2333 /* Get sub-array details from first member */
2334 elem_ndims = this_ndims;
2335 ndims = elem_ndims + 1;
2336 if (ndims <= 0 || ndims > MAXDIM)
2338 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2339 errmsg("number of array dimensions (%d) exceeds " \
2340 "the maximum allowed (%d)", ndims, MAXDIM)));
2342 elem_dims = (int *) palloc(elem_ndims * sizeof(int));
2343 memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
2344 elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
2345 memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
2351 /* Check other sub-arrays are compatible */
2352 if (elem_ndims != this_ndims ||
2353 memcmp(elem_dims, ARR_DIMS(array),
2354 elem_ndims * sizeof(int)) != 0 ||
2355 memcmp(elem_lbs, ARR_LBOUND(array),
2356 elem_ndims * sizeof(int)) != 0)
2358 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2359 errmsg("multidimensional arrays must have array "
2360 "expressions with matching dimensions")));
2363 subdata[outer_nelems] = ARR_DATA_PTR(array);
2364 subbitmaps[outer_nelems] = ARR_NULLBITMAP(array);
2365 subbytes[outer_nelems] = ARR_SIZE(array) - ARR_DATA_OFFSET(array);
2366 nbytes += subbytes[outer_nelems];
2367 subnitems[outer_nelems] = ArrayGetNItems(this_ndims,
2369 nitems += subnitems[outer_nelems];
2370 havenulls |= ARR_HASNULL(array);
2375 * If all items were null or empty arrays, return an empty array;
2376 * otherwise, if some were and some weren't, raise error. (Note:
2377 * we must special-case this somehow to avoid trying to generate
2378 * a 1-D array formed from empty arrays. It's not ideal...)
2382 if (ndims == 0) /* didn't find any nonempty array */
2383 return PointerGetDatum(construct_empty_array(element_type));
2385 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2386 errmsg("multidimensional arrays must have array "
2387 "expressions with matching dimensions")));
2390 /* setup for multi-D array */
2391 dims[0] = outer_nelems;
2393 for (i = 1; i < ndims; i++)
2395 dims[i] = elem_dims[i - 1];
2396 lbs[i] = elem_lbs[i - 1];
2401 dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nitems);
2402 nbytes += dataoffset;
2406 dataoffset = 0; /* marker for no null bitmap */
2407 nbytes += ARR_OVERHEAD_NONULLS(ndims);
2410 result = (ArrayType *) palloc(nbytes);
2411 result->size = nbytes;
2412 result->ndim = ndims;
2413 result->dataoffset = dataoffset;
2414 result->elemtype = element_type;
2415 memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
2416 memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
2418 dat = ARR_DATA_PTR(result);
2420 for (i = 0; i < outer_nelems; i++)
2422 memcpy(dat, subdata[i], subbytes[i]);
2425 array_bitmap_copy(ARR_NULLBITMAP(result), iitem,
2428 iitem += subnitems[i];
2432 return PointerGetDatum(result);
2435 /* ----------------------------------------------------------------
2436 * ExecEvalRow - ROW() expressions
2437 * ----------------------------------------------------------------
2440 ExecEvalRow(RowExprState *rstate,
2441 ExprContext *econtext,
2442 bool *isNull, ExprDoneCond *isDone)
2451 /* Set default values for result flags: non-null, not a set result */
2454 *isDone = ExprSingleResult;
2456 /* Allocate workspace */
2457 natts = rstate->tupdesc->natts;
2458 values = (Datum *) palloc0(natts * sizeof(Datum));
2459 isnull = (bool *) palloc(natts * sizeof(bool));
2461 /* preset to nulls in case rowtype has some later-added columns */
2462 memset(isnull, true, natts * sizeof(bool));
2464 /* Evaluate field values */
2466 foreach(arg, rstate->args)
2468 ExprState *e = (ExprState *) lfirst(arg);
2470 values[i] = ExecEvalExpr(e, econtext, &isnull[i], NULL);
2474 tuple = heap_form_tuple(rstate->tupdesc, values, isnull);
2479 return HeapTupleGetDatum(tuple);
2482 /* ----------------------------------------------------------------
2483 * ExecEvalRowCompare - ROW() comparison-op ROW()
2484 * ----------------------------------------------------------------
2487 ExecEvalRowCompare(RowCompareExprState *rstate,
2488 ExprContext *econtext,
2489 bool *isNull, ExprDoneCond *isDone)
2492 RowCompareType rctype = ((RowCompareExpr *) rstate->xprstate.expr)->rctype;
2493 int32 cmpresult = 0;
2499 *isDone = ExprSingleResult;
2500 *isNull = true; /* until we get a result */
2503 forboth(l, rstate->largs, r, rstate->rargs)
2505 ExprState *le = (ExprState *) lfirst(l);
2506 ExprState *re = (ExprState *) lfirst(r);
2507 FunctionCallInfoData locfcinfo;
2509 InitFunctionCallInfoData(locfcinfo, &(rstate->funcs[i]), 2,
2511 locfcinfo.arg[0] = ExecEvalExpr(le, econtext,
2512 &locfcinfo.argnull[0], NULL);
2513 locfcinfo.arg[1] = ExecEvalExpr(re, econtext,
2514 &locfcinfo.argnull[1], NULL);
2515 if (rstate->funcs[i].fn_strict &&
2516 (locfcinfo.argnull[0] || locfcinfo.argnull[1]))
2517 return (Datum) 0; /* force NULL result */
2518 locfcinfo.isnull = false;
2519 cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
2520 if (locfcinfo.isnull)
2521 return (Datum) 0; /* force NULL result */
2523 break; /* no need to compare remaining columns */
2529 /* EQ and NE cases aren't allowed here */
2531 result = (cmpresult < 0);
2534 result = (cmpresult <= 0);
2537 result = (cmpresult >= 0);
2540 result = (cmpresult > 0);
2543 elog(ERROR, "unrecognized RowCompareType: %d", (int) rctype);
2544 result = 0; /* keep compiler quiet */
2549 return BoolGetDatum(result);
2552 /* ----------------------------------------------------------------
2554 * ----------------------------------------------------------------
2557 ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
2558 bool *isNull, ExprDoneCond *isDone)
2563 *isDone = ExprSingleResult;
2565 /* Simply loop through until something NOT NULL is found */
2566 foreach(arg, coalesceExpr->args)
2568 ExprState *e = (ExprState *) lfirst(arg);
2571 value = ExecEvalExpr(e, econtext, isNull, NULL);
2576 /* Else return NULL */
2581 /* ----------------------------------------------------------------
2583 * ----------------------------------------------------------------
2586 ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
2587 bool *isNull, ExprDoneCond *isDone)
2589 Datum result = (Datum) 0;
2590 MinMaxOp op = ((MinMaxExpr *) minmaxExpr->xprstate.expr)->op;
2591 FunctionCallInfoData locfcinfo;
2595 *isDone = ExprSingleResult;
2596 *isNull = true; /* until we get a result */
2598 InitFunctionCallInfoData(locfcinfo, &minmaxExpr->cfunc, 2, NULL, NULL);
2599 locfcinfo.argnull[0] = false;
2600 locfcinfo.argnull[1] = false;
2602 foreach(arg, minmaxExpr->args)
2604 ExprState *e = (ExprState *) lfirst(arg);
2609 value = ExecEvalExpr(e, econtext, &valueIsNull, NULL);
2611 continue; /* ignore NULL inputs */
2615 /* first nonnull input, adopt value */
2621 /* apply comparison function */
2622 locfcinfo.arg[0] = result;
2623 locfcinfo.arg[1] = value;
2624 locfcinfo.isnull = false;
2625 cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
2626 if (locfcinfo.isnull) /* probably should not happen */
2628 if (cmpresult > 0 && op == IS_LEAST)
2630 else if (cmpresult < 0 && op == IS_GREATEST)
2638 /* ----------------------------------------------------------------
2641 * Note that this is *always* derived from the equals operator,
2642 * but since we need special processing of the arguments
2643 * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
2644 * ----------------------------------------------------------------
2647 ExecEvalNullIf(FuncExprState *nullIfExpr,
2648 ExprContext *econtext,
2649 bool *isNull, ExprDoneCond *isDone)
2652 FunctionCallInfoData fcinfo;
2653 ExprDoneCond argDone;
2657 *isDone = ExprSingleResult;
2660 * Initialize function cache if first time through
2662 if (nullIfExpr->func.fn_oid == InvalidOid)
2664 NullIfExpr *op = (NullIfExpr *) nullIfExpr->xprstate.expr;
2666 init_fcache(op->opfuncid, nullIfExpr, econtext->ecxt_per_query_memory);
2667 Assert(!nullIfExpr->func.fn_retset);
2671 * extract info from nullIfExpr
2673 argList = nullIfExpr->args;
2675 /* Need to prep callinfo structure */
2676 InitFunctionCallInfoData(fcinfo, &(nullIfExpr->func), 0, NULL, NULL);
2677 argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
2678 if (argDone != ExprSingleResult)
2680 (errcode(ERRCODE_DATATYPE_MISMATCH),
2681 errmsg("NULLIF does not support set arguments")));
2682 Assert(fcinfo.nargs == 2);
2684 /* if either argument is NULL they can't be equal */
2685 if (!fcinfo.argnull[0] && !fcinfo.argnull[1])
2687 fcinfo.isnull = false;
2688 result = FunctionCallInvoke(&fcinfo);
2689 /* if the arguments are equal return null */
2690 if (!fcinfo.isnull && DatumGetBool(result))
2697 /* else return first argument */
2698 *isNull = fcinfo.argnull[0];
2699 return fcinfo.arg[0];
2702 /* ----------------------------------------------------------------
2705 * Evaluate a NullTest node.
2706 * ----------------------------------------------------------------
2709 ExecEvalNullTest(NullTestState *nstate,
2710 ExprContext *econtext,
2712 ExprDoneCond *isDone)
2714 NullTest *ntest = (NullTest *) nstate->xprstate.expr;
2717 result = ExecEvalExpr(nstate->arg, econtext, isNull, isDone);
2719 if (isDone && *isDone == ExprEndResult)
2720 return result; /* nothing to check */
2722 if (nstate->argisrow && !(*isNull))
2724 HeapTupleHeader tuple;
2728 HeapTupleData tmptup;
2731 tuple = DatumGetHeapTupleHeader(result);
2733 tupType = HeapTupleHeaderGetTypeId(tuple);
2734 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
2736 /* Lookup tupdesc if first time through or if type changes */
2737 tupDesc = get_cached_rowtype(tupType, tupTypmod,
2738 &nstate->argdesc, econtext);
2741 * heap_attisnull needs a HeapTuple not a bare HeapTupleHeader.
2743 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2744 tmptup.t_data = tuple;
2746 for (att = 1; att <= tupDesc->natts; att++)
2748 /* ignore dropped columns */
2749 if (tupDesc->attrs[att - 1]->attisdropped)
2751 if (heap_attisnull(&tmptup, att))
2753 /* null field disproves IS NOT NULL */
2754 if (ntest->nulltesttype == IS_NOT_NULL)
2755 return BoolGetDatum(false);
2759 /* non-null field disproves IS NULL */
2760 if (ntest->nulltesttype == IS_NULL)
2761 return BoolGetDatum(false);
2765 return BoolGetDatum(true);
2769 /* Simple scalar-argument case, or a null rowtype datum */
2770 switch (ntest->nulltesttype)
2776 return BoolGetDatum(true);
2779 return BoolGetDatum(false);
2784 return BoolGetDatum(false);
2787 return BoolGetDatum(true);
2789 elog(ERROR, "unrecognized nulltesttype: %d",
2790 (int) ntest->nulltesttype);
2791 return (Datum) 0; /* keep compiler quiet */
2796 /* ----------------------------------------------------------------
2797 * ExecEvalBooleanTest
2799 * Evaluate a BooleanTest node.
2800 * ----------------------------------------------------------------
2803 ExecEvalBooleanTest(GenericExprState *bstate,
2804 ExprContext *econtext,
2806 ExprDoneCond *isDone)
2808 BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;
2811 result = ExecEvalExpr(bstate->arg, econtext, isNull, isDone);
2813 if (isDone && *isDone == ExprEndResult)
2814 return result; /* nothing to check */
2816 switch (btest->booltesttype)
2822 return BoolGetDatum(false);
2824 else if (DatumGetBool(result))
2825 return BoolGetDatum(true);
2827 return BoolGetDatum(false);
2832 return BoolGetDatum(true);
2834 else if (DatumGetBool(result))
2835 return BoolGetDatum(false);
2837 return BoolGetDatum(true);
2842 return BoolGetDatum(false);
2844 else if (DatumGetBool(result))
2845 return BoolGetDatum(false);
2847 return BoolGetDatum(true);
2852 return BoolGetDatum(true);
2854 else if (DatumGetBool(result))
2855 return BoolGetDatum(true);
2857 return BoolGetDatum(false);
2862 return BoolGetDatum(true);
2865 return BoolGetDatum(false);
2866 case IS_NOT_UNKNOWN:
2870 return BoolGetDatum(false);
2873 return BoolGetDatum(true);
2875 elog(ERROR, "unrecognized booltesttype: %d",
2876 (int) btest->booltesttype);
2877 return (Datum) 0; /* keep compiler quiet */
2882 * ExecEvalCoerceToDomain
2884 * Test the provided data against the domain constraint(s). If the data
2885 * passes the constraint specifications, pass it through (return the
2886 * datum) otherwise throw an error.
2889 ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
2890 bool *isNull, ExprDoneCond *isDone)
2892 CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
2896 result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
2898 if (isDone && *isDone == ExprEndResult)
2899 return result; /* nothing to check */
2901 foreach(l, cstate->constraints)
2903 DomainConstraintState *con = (DomainConstraintState *) lfirst(l);
2905 switch (con->constrainttype)
2907 case DOM_CONSTRAINT_NOTNULL:
2910 (errcode(ERRCODE_NOT_NULL_VIOLATION),
2911 errmsg("domain %s does not allow null values",
2912 format_type_be(ctest->resulttype))));
2914 case DOM_CONSTRAINT_CHECK:
2922 * Set up value to be returned by CoerceToDomainValue
2923 * nodes. We must save and restore prior setting of
2924 * econtext's domainValue fields, in case this node is
2925 * itself within a check expression for another domain.
2927 save_datum = econtext->domainValue_datum;
2928 save_isNull = econtext->domainValue_isNull;
2930 econtext->domainValue_datum = result;
2931 econtext->domainValue_isNull = *isNull;
2933 conResult = ExecEvalExpr(con->check_expr,
2934 econtext, &conIsNull, NULL);
2937 !DatumGetBool(conResult))
2939 (errcode(ERRCODE_CHECK_VIOLATION),
2940 errmsg("value for domain %s violates check constraint \"%s\"",
2941 format_type_be(ctest->resulttype),
2943 econtext->domainValue_datum = save_datum;
2944 econtext->domainValue_isNull = save_isNull;
2949 elog(ERROR, "unrecognized constraint type: %d",
2950 (int) con->constrainttype);
2955 /* If all has gone well (constraints did not fail) return the datum */
2960 * ExecEvalCoerceToDomainValue
2962 * Return the value stored by CoerceToDomain.
2965 ExecEvalCoerceToDomainValue(ExprState *exprstate,
2966 ExprContext *econtext,
2967 bool *isNull, ExprDoneCond *isDone)
2970 *isDone = ExprSingleResult;
2971 *isNull = econtext->domainValue_isNull;
2972 return econtext->domainValue_datum;
2975 /* ----------------------------------------------------------------
2976 * ExecEvalFieldSelect
2978 * Evaluate a FieldSelect node.
2979 * ----------------------------------------------------------------
2982 ExecEvalFieldSelect(FieldSelectState *fstate,
2983 ExprContext *econtext,
2985 ExprDoneCond *isDone)
2987 FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
2990 HeapTupleHeader tuple;
2994 HeapTupleData tmptup;
2996 tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
2998 /* this test covers the isDone exception too: */
3002 tuple = DatumGetHeapTupleHeader(tupDatum);
3004 tupType = HeapTupleHeaderGetTypeId(tuple);
3005 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3007 /* Lookup tupdesc if first time through or if type changes */
3008 tupDesc = get_cached_rowtype(tupType, tupTypmod,
3009 &fstate->argdesc, econtext);
3012 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
3013 * the fields in the struct just in case user tries to inspect system
3016 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3017 ItemPointerSetInvalid(&(tmptup.t_self));
3018 tmptup.t_tableOid = InvalidOid;
3019 tmptup.t_data = tuple;
3021 result = heap_getattr(&tmptup,
3028 /* ----------------------------------------------------------------
3029 * ExecEvalFieldStore
3031 * Evaluate a FieldStore node.
3032 * ----------------------------------------------------------------
3035 ExecEvalFieldStore(FieldStoreState *fstate,
3036 ExprContext *econtext,
3038 ExprDoneCond *isDone)
3040 FieldStore *fstore = (FieldStore *) fstate->xprstate.expr;
3051 tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
3053 if (isDone && *isDone == ExprEndResult)
3056 /* Lookup tupdesc if first time through or after rescan */
3057 tupDesc = get_cached_rowtype(fstore->resulttype, -1,
3058 &fstate->argdesc, econtext);
3060 /* Allocate workspace */
3061 values = (Datum *) palloc(tupDesc->natts * sizeof(Datum));
3062 isnull = (bool *) palloc(tupDesc->natts * sizeof(bool));
3067 * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader. We
3068 * set all the fields in the struct just in case.
3070 HeapTupleHeader tuphdr;
3071 HeapTupleData tmptup;
3073 tuphdr = DatumGetHeapTupleHeader(tupDatum);
3074 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuphdr);
3075 ItemPointerSetInvalid(&(tmptup.t_self));
3076 tmptup.t_tableOid = InvalidOid;
3077 tmptup.t_data = tuphdr;
3079 heap_deform_tuple(&tmptup, tupDesc, values, isnull);
3083 /* Convert null input tuple into an all-nulls row */
3084 memset(isnull, true, tupDesc->natts * sizeof(bool));
3087 /* Result is never null */
3090 save_datum = econtext->caseValue_datum;
3091 save_isNull = econtext->caseValue_isNull;
3093 forboth(l1, fstate->newvals, l2, fstore->fieldnums)
3095 ExprState *newval = (ExprState *) lfirst(l1);
3096 AttrNumber fieldnum = lfirst_int(l2);
3098 Assert(fieldnum > 0 && fieldnum <= tupDesc->natts);
3101 * Use the CaseTestExpr mechanism to pass down the old value of the
3102 * field being replaced; this is useful in case we have a nested field
3103 * update situation. It's safe to reuse the CASE mechanism because
3104 * there cannot be a CASE between here and where the value would be
3107 econtext->caseValue_datum = values[fieldnum - 1];
3108 econtext->caseValue_isNull = isnull[fieldnum - 1];
3110 values[fieldnum - 1] = ExecEvalExpr(newval,
3112 &isnull[fieldnum - 1],
3116 econtext->caseValue_datum = save_datum;
3117 econtext->caseValue_isNull = save_isNull;
3119 tuple = heap_form_tuple(tupDesc, values, isnull);
3124 return HeapTupleGetDatum(tuple);
3127 /* ----------------------------------------------------------------
3128 * ExecEvalRelabelType
3130 * Evaluate a RelabelType node.
3131 * ----------------------------------------------------------------
3134 ExecEvalRelabelType(GenericExprState *exprstate,
3135 ExprContext *econtext,
3136 bool *isNull, ExprDoneCond *isDone)
3138 return ExecEvalExpr(exprstate->arg, econtext, isNull, isDone);
3143 * ExecEvalExprSwitchContext
3145 * Same as ExecEvalExpr, but get into the right allocation context explicitly.
3148 ExecEvalExprSwitchContext(ExprState *expression,
3149 ExprContext *econtext,
3151 ExprDoneCond *isDone)
3154 MemoryContext oldContext;
3156 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
3157 retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
3158 MemoryContextSwitchTo(oldContext);
3164 * ExecInitExpr: prepare an expression tree for execution
3166 * This function builds and returns an ExprState tree paralleling the given
3167 * Expr node tree. The ExprState tree can then be handed to ExecEvalExpr
3168 * for execution. Because the Expr tree itself is read-only as far as
3169 * ExecInitExpr and ExecEvalExpr are concerned, several different executions
3170 * of the same plan tree can occur concurrently.
3172 * This must be called in a memory context that will last as long as repeated
3173 * executions of the expression are needed. Typically the context will be
3174 * the same as the per-query context of the associated ExprContext.
3176 * Any Aggref and SubPlan nodes found in the tree are added to the lists
3177 * of such nodes held by the parent PlanState. Otherwise, we do very little
3178 * initialization here other than building the state-node tree. Any nontrivial
3179 * work associated with initializing runtime info for a node should happen
3180 * during the first actual evaluation of that node. (This policy lets us
3181 * avoid work if the node is never actually evaluated.)
3183 * Note: there is no ExecEndExpr function; we assume that any resource
3184 * cleanup needed will be handled by just releasing the memory context
3185 * in which the state tree is built. Functions that require additional
3186 * cleanup work can register a shutdown callback in the ExprContext.
3188 * 'node' is the root of the expression tree to examine
3189 * 'parent' is the PlanState node that owns the expression.
3191 * 'parent' may be NULL if we are preparing an expression that is not
3192 * associated with a plan tree. (If so, it can't have aggs or subplans.)
3193 * This case should usually come through ExecPrepareExpr, not directly here.
3196 ExecInitExpr(Expr *node, PlanState *parent)
3203 /* Guard against stack overflow due to overly complex expressions */
3204 check_stack_depth();
3206 switch (nodeTag(node))
3210 Var *var = (Var *) node;
3212 state = (ExprState *) makeNode(ExprState);
3213 if (var->varattno != InvalidAttrNumber)
3214 state->evalfunc = ExecEvalVar;
3216 state->evalfunc = ExecEvalWholeRowVar;
3220 state = (ExprState *) makeNode(ExprState);
3221 state->evalfunc = ExecEvalConst;
3224 state = (ExprState *) makeNode(ExprState);
3225 state->evalfunc = ExecEvalParam;
3227 case T_CoerceToDomainValue:
3228 state = (ExprState *) makeNode(ExprState);
3229 state->evalfunc = ExecEvalCoerceToDomainValue;
3231 case T_CaseTestExpr:
3232 state = (ExprState *) makeNode(ExprState);
3233 state->evalfunc = ExecEvalCaseTestExpr;
3237 Aggref *aggref = (Aggref *) node;
3238 AggrefExprState *astate = makeNode(AggrefExprState);
3240 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAggref;
3241 if (parent && IsA(parent, AggState))
3243 AggState *aggstate = (AggState *) parent;
3246 aggstate->aggs = lcons(astate, aggstate->aggs);
3247 naggs = ++aggstate->numaggs;
3249 astate->args = (List *) ExecInitExpr((Expr *) aggref->args,
3253 * Complain if the aggregate's arguments contain any
3254 * aggregates; nested agg functions are semantically
3255 * nonsensical. (This should have been caught earlier,
3256 * but we defend against it here anyway.)
3258 if (naggs != aggstate->numaggs)
3260 (errcode(ERRCODE_GROUPING_ERROR),
3261 errmsg("aggregate function calls may not be nested")));
3265 /* planner messed up */
3266 elog(ERROR, "aggref found in non-Agg plan node");
3268 state = (ExprState *) astate;
3273 ArrayRef *aref = (ArrayRef *) node;
3274 ArrayRefExprState *astate = makeNode(ArrayRefExprState);
3276 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayRef;
3277 astate->refupperindexpr = (List *)
3278 ExecInitExpr((Expr *) aref->refupperindexpr, parent);
3279 astate->reflowerindexpr = (List *)
3280 ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
3281 astate->refexpr = ExecInitExpr(aref->refexpr, parent);
3282 astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
3284 /* do one-time catalog lookups for type info */
3285 astate->refattrlength = get_typlen(aref->refarraytype);
3286 get_typlenbyvalalign(aref->refelemtype,
3287 &astate->refelemlength,
3288 &astate->refelembyval,
3289 &astate->refelemalign);
3290 state = (ExprState *) astate;
3295 FuncExpr *funcexpr = (FuncExpr *) node;
3296 FuncExprState *fstate = makeNode(FuncExprState);
3298 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFunc;
3299 fstate->args = (List *)
3300 ExecInitExpr((Expr *) funcexpr->args, parent);
3301 fstate->func.fn_oid = InvalidOid; /* not initialized */
3302 state = (ExprState *) fstate;
3307 OpExpr *opexpr = (OpExpr *) node;
3308 FuncExprState *fstate = makeNode(FuncExprState);
3310 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOper;
3311 fstate->args = (List *)
3312 ExecInitExpr((Expr *) opexpr->args, parent);
3313 fstate->func.fn_oid = InvalidOid; /* not initialized */
3314 state = (ExprState *) fstate;
3317 case T_DistinctExpr:
3319 DistinctExpr *distinctexpr = (DistinctExpr *) node;
3320 FuncExprState *fstate = makeNode(FuncExprState);
3322 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalDistinct;
3323 fstate->args = (List *)
3324 ExecInitExpr((Expr *) distinctexpr->args, parent);
3325 fstate->func.fn_oid = InvalidOid; /* not initialized */
3326 state = (ExprState *) fstate;
3329 case T_ScalarArrayOpExpr:
3331 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
3332 ScalarArrayOpExprState *sstate = makeNode(ScalarArrayOpExprState);
3334 sstate->fxprstate.xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalScalarArrayOp;
3335 sstate->fxprstate.args = (List *)
3336 ExecInitExpr((Expr *) opexpr->args, parent);
3337 sstate->fxprstate.func.fn_oid = InvalidOid; /* not initialized */
3338 sstate->element_type = InvalidOid; /* ditto */
3339 state = (ExprState *) sstate;
3344 BoolExpr *boolexpr = (BoolExpr *) node;
3345 BoolExprState *bstate = makeNode(BoolExprState);
3347 switch (boolexpr->boolop)
3350 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAnd;
3353 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOr;
3356 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNot;
3359 elog(ERROR, "unrecognized boolop: %d",
3360 (int) boolexpr->boolop);
3363 bstate->args = (List *)
3364 ExecInitExpr((Expr *) boolexpr->args, parent);
3365 state = (ExprState *) bstate;
3370 /* Keep this in sync with ExecInitExprInitPlan, below */
3371 SubPlan *subplan = (SubPlan *) node;
3372 SubPlanState *sstate = makeNode(SubPlanState);
3374 sstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecSubPlan;
3377 elog(ERROR, "SubPlan found with no parent plan");
3380 * Here we just add the SubPlanState nodes to parent->subPlan.
3381 * The subplans will be initialized later.
3383 parent->subPlan = lcons(sstate, parent->subPlan);
3384 sstate->sub_estate = NULL;
3385 sstate->planstate = NULL;
3388 ExecInitExpr((Expr *) subplan->testexpr, parent);
3389 sstate->args = (List *)
3390 ExecInitExpr((Expr *) subplan->args, parent);
3392 state = (ExprState *) sstate;
3397 FieldSelect *fselect = (FieldSelect *) node;
3398 FieldSelectState *fstate = makeNode(FieldSelectState);
3400 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldSelect;
3401 fstate->arg = ExecInitExpr(fselect->arg, parent);
3402 fstate->argdesc = NULL;
3403 state = (ExprState *) fstate;
3408 FieldStore *fstore = (FieldStore *) node;
3409 FieldStoreState *fstate = makeNode(FieldStoreState);
3411 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldStore;
3412 fstate->arg = ExecInitExpr(fstore->arg, parent);
3413 fstate->newvals = (List *) ExecInitExpr((Expr *) fstore->newvals, parent);
3414 fstate->argdesc = NULL;
3415 state = (ExprState *) fstate;
3420 RelabelType *relabel = (RelabelType *) node;
3421 GenericExprState *gstate = makeNode(GenericExprState);
3423 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRelabelType;
3424 gstate->arg = ExecInitExpr(relabel->arg, parent);
3425 state = (ExprState *) gstate;
3428 case T_ConvertRowtypeExpr:
3430 ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) node;
3431 ConvertRowtypeExprState *cstate = makeNode(ConvertRowtypeExprState);
3433 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalConvertRowtype;
3434 cstate->arg = ExecInitExpr(convert->arg, parent);
3435 state = (ExprState *) cstate;
3440 CaseExpr *caseexpr = (CaseExpr *) node;
3441 CaseExprState *cstate = makeNode(CaseExprState);
3442 List *outlist = NIL;
3445 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCase;
3446 cstate->arg = ExecInitExpr(caseexpr->arg, parent);
3447 foreach(l, caseexpr->args)
3449 CaseWhen *when = (CaseWhen *) lfirst(l);
3450 CaseWhenState *wstate = makeNode(CaseWhenState);
3452 Assert(IsA(when, CaseWhen));
3453 wstate->xprstate.evalfunc = NULL; /* not used */
3454 wstate->xprstate.expr = (Expr *) when;
3455 wstate->expr = ExecInitExpr(when->expr, parent);
3456 wstate->result = ExecInitExpr(when->result, parent);
3457 outlist = lappend(outlist, wstate);
3459 cstate->args = outlist;
3460 cstate->defresult = ExecInitExpr(caseexpr->defresult, parent);
3461 state = (ExprState *) cstate;
3466 ArrayExpr *arrayexpr = (ArrayExpr *) node;
3467 ArrayExprState *astate = makeNode(ArrayExprState);
3468 List *outlist = NIL;
3471 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArray;
3472 foreach(l, arrayexpr->elements)
3474 Expr *e = (Expr *) lfirst(l);
3477 estate = ExecInitExpr(e, parent);
3478 outlist = lappend(outlist, estate);
3480 astate->elements = outlist;
3481 /* do one-time catalog lookup for type info */
3482 get_typlenbyvalalign(arrayexpr->element_typeid,
3483 &astate->elemlength,
3485 &astate->elemalign);
3486 state = (ExprState *) astate;
3491 RowExpr *rowexpr = (RowExpr *) node;
3492 RowExprState *rstate = makeNode(RowExprState);
3493 Form_pg_attribute *attrs;
3494 List *outlist = NIL;
3498 rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRow;
3499 /* Build tupdesc to describe result tuples */
3500 if (rowexpr->row_typeid == RECORDOID)
3502 /* generic record, use runtime type assignment */
3503 rstate->tupdesc = ExecTypeFromExprList(rowexpr->args);
3504 BlessTupleDesc(rstate->tupdesc);
3505 /* we won't need to redo this at runtime */
3509 /* it's been cast to a named type, use that */
3510 rstate->tupdesc = lookup_rowtype_tupdesc_copy(rowexpr->row_typeid, -1);
3512 /* Set up evaluation, skipping any deleted columns */
3513 Assert(list_length(rowexpr->args) <= rstate->tupdesc->natts);
3514 attrs = rstate->tupdesc->attrs;
3516 foreach(l, rowexpr->args)
3518 Expr *e = (Expr *) lfirst(l);
3521 if (!attrs[i]->attisdropped)
3524 * Guard against ALTER COLUMN TYPE on rowtype since
3525 * the RowExpr was created. XXX should we check
3526 * typmod too? Not sure we can be sure it'll be the
3529 if (exprType((Node *) e) != attrs[i]->atttypid)
3531 (errcode(ERRCODE_DATATYPE_MISMATCH),
3532 errmsg("ROW() column has type %s instead of type %s",
3533 format_type_be(exprType((Node *) e)),
3534 format_type_be(attrs[i]->atttypid))));
3539 * Ignore original expression and insert a NULL. We
3540 * don't really care what type of NULL it is, so
3541 * always make an int4 NULL.
3543 e = (Expr *) makeNullConst(INT4OID);
3545 estate = ExecInitExpr(e, parent);
3546 outlist = lappend(outlist, estate);
3549 rstate->args = outlist;
3550 state = (ExprState *) rstate;
3553 case T_RowCompareExpr:
3555 RowCompareExpr *rcexpr = (RowCompareExpr *) node;
3556 RowCompareExprState *rstate = makeNode(RowCompareExprState);
3557 int nopers = list_length(rcexpr->opnos);
3563 rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRowCompare;
3564 Assert(list_length(rcexpr->largs) == nopers);
3566 foreach(l, rcexpr->largs)
3568 Expr *e = (Expr *) lfirst(l);
3571 estate = ExecInitExpr(e, parent);
3572 outlist = lappend(outlist, estate);
3574 rstate->largs = outlist;
3575 Assert(list_length(rcexpr->rargs) == nopers);
3577 foreach(l, rcexpr->rargs)
3579 Expr *e = (Expr *) lfirst(l);
3582 estate = ExecInitExpr(e, parent);
3583 outlist = lappend(outlist, estate);
3585 rstate->rargs = outlist;
3586 Assert(list_length(rcexpr->opclasses) == nopers);
3587 rstate->funcs = (FmgrInfo *) palloc(nopers * sizeof(FmgrInfo));
3589 forboth(l, rcexpr->opnos, l2, rcexpr->opclasses)
3591 Oid opno = lfirst_oid(l);
3592 Oid opclass = lfirst_oid(l2);
3598 get_op_opclass_properties(opno, opclass,
3599 &strategy, &subtype, &recheck);
3600 proc = get_opclass_proc(opclass, subtype, BTORDER_PROC);
3603 * If we enforced permissions checks on index support
3604 * functions, we'd need to make a check here. But the
3605 * index support machinery doesn't do that, and neither
3608 fmgr_info(proc, &(rstate->funcs[i]));
3611 state = (ExprState *) rstate;
3614 case T_CoalesceExpr:
3616 CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
3617 CoalesceExprState *cstate = makeNode(CoalesceExprState);
3618 List *outlist = NIL;
3621 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoalesce;
3622 foreach(l, coalesceexpr->args)
3624 Expr *e = (Expr *) lfirst(l);
3627 estate = ExecInitExpr(e, parent);
3628 outlist = lappend(outlist, estate);
3630 cstate->args = outlist;
3631 state = (ExprState *) cstate;
3636 MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
3637 MinMaxExprState *mstate = makeNode(MinMaxExprState);
3638 List *outlist = NIL;
3640 TypeCacheEntry *typentry;
3642 mstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalMinMax;
3643 foreach(l, minmaxexpr->args)
3645 Expr *e = (Expr *) lfirst(l);
3648 estate = ExecInitExpr(e, parent);
3649 outlist = lappend(outlist, estate);
3651 mstate->args = outlist;
3652 /* Look up the btree comparison function for the datatype */
3653 typentry = lookup_type_cache(minmaxexpr->minmaxtype,
3654 TYPECACHE_CMP_PROC);
3655 if (!OidIsValid(typentry->cmp_proc))
3657 (errcode(ERRCODE_UNDEFINED_FUNCTION),
3658 errmsg("could not identify a comparison function for type %s",
3659 format_type_be(minmaxexpr->minmaxtype))));
3662 * If we enforced permissions checks on index support
3663 * functions, we'd need to make a check here. But the index
3664 * support machinery doesn't do that, and neither does this
3667 fmgr_info(typentry->cmp_proc, &(mstate->cfunc));
3668 state = (ExprState *) mstate;
3673 NullIfExpr *nullifexpr = (NullIfExpr *) node;
3674 FuncExprState *fstate = makeNode(FuncExprState);
3676 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullIf;
3677 fstate->args = (List *)
3678 ExecInitExpr((Expr *) nullifexpr->args, parent);
3679 fstate->func.fn_oid = InvalidOid; /* not initialized */
3680 state = (ExprState *) fstate;
3685 NullTest *ntest = (NullTest *) node;
3686 NullTestState *nstate = makeNode(NullTestState);
3688 nstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullTest;
3689 nstate->arg = ExecInitExpr(ntest->arg, parent);
3690 nstate->argisrow = type_is_rowtype(exprType((Node *) ntest->arg));
3691 nstate->argdesc = NULL;
3692 state = (ExprState *) nstate;
3697 BooleanTest *btest = (BooleanTest *) node;
3698 GenericExprState *gstate = makeNode(GenericExprState);
3700 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalBooleanTest;
3701 gstate->arg = ExecInitExpr(btest->arg, parent);
3702 state = (ExprState *) gstate;
3705 case T_CoerceToDomain:
3707 CoerceToDomain *ctest = (CoerceToDomain *) node;
3708 CoerceToDomainState *cstate = makeNode(CoerceToDomainState);
3710 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceToDomain;
3711 cstate->arg = ExecInitExpr(ctest->arg, parent);
3712 cstate->constraints = GetDomainConstraints(ctest->resulttype);
3713 state = (ExprState *) cstate;
3718 TargetEntry *tle = (TargetEntry *) node;
3719 GenericExprState *gstate = makeNode(GenericExprState);
3721 gstate->xprstate.evalfunc = NULL; /* not used */
3722 gstate->arg = ExecInitExpr(tle->expr, parent);
3723 state = (ExprState *) gstate;
3728 List *outlist = NIL;
3731 foreach(l, (List *) node)
3733 outlist = lappend(outlist,
3734 ExecInitExpr((Expr *) lfirst(l),
3737 /* Don't fall through to the "common" code below */
3738 return (ExprState *) outlist;
3741 elog(ERROR, "unrecognized node type: %d",
3742 (int) nodeTag(node));
3743 state = NULL; /* keep compiler quiet */
3747 /* Common code for all state-node types */
3754 * ExecInitExprInitPlan --- initialize a subplan expr that's being handled
3755 * as an InitPlan. This is identical to ExecInitExpr's handling of a regular
3756 * subplan expr, except we do NOT want to add the node to the parent's
3760 ExecInitExprInitPlan(SubPlan *node, PlanState *parent)
3762 SubPlanState *sstate = makeNode(SubPlanState);
3765 elog(ERROR, "SubPlan found with no parent plan");
3767 /* The subplan's state will be initialized later */
3768 sstate->sub_estate = NULL;
3769 sstate->planstate = NULL;
3771 sstate->testexpr = ExecInitExpr((Expr *) node->testexpr, parent);
3772 sstate->args = (List *) ExecInitExpr((Expr *) node->args, parent);
3774 sstate->xprstate.expr = (Expr *) node;
3780 * ExecPrepareExpr --- initialize for expression execution outside a normal
3781 * Plan tree context.
3783 * This differs from ExecInitExpr in that we don't assume the caller is
3784 * already running in the EState's per-query context. Also, we apply
3785 * fix_opfuncids() to the passed expression tree to be sure it is ready
3786 * to run. (In ordinary Plan trees the planner will have fixed opfuncids,
3787 * but callers outside the executor will not have done this.)
3790 ExecPrepareExpr(Expr *node, EState *estate)
3793 MemoryContext oldcontext;
3795 fix_opfuncids((Node *) node);
3797 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
3799 result = ExecInitExpr(node, NULL);
3801 MemoryContextSwitchTo(oldcontext);
3807 /* ----------------------------------------------------------------
3808 * ExecQual / ExecTargetList / ExecProject
3809 * ----------------------------------------------------------------
3812 /* ----------------------------------------------------------------
3815 * Evaluates a conjunctive boolean expression (qual list) and
3816 * returns true iff none of the subexpressions are false.
3817 * (We also return true if the list is empty.)
3819 * If some of the subexpressions yield NULL but none yield FALSE,
3820 * then the result of the conjunction is NULL (ie, unknown)
3821 * according to three-valued boolean logic. In this case,
3822 * we return the value specified by the "resultForNull" parameter.
3824 * Callers evaluating WHERE clauses should pass resultForNull=FALSE,
3825 * since SQL specifies that tuples with null WHERE results do not
3826 * get selected. On the other hand, callers evaluating constraint
3827 * conditions should pass resultForNull=TRUE, since SQL also specifies
3828 * that NULL constraint conditions are not failures.
3830 * NOTE: it would not be correct to use this routine to evaluate an
3831 * AND subclause of a boolean expression; for that purpose, a NULL
3832 * result must be returned as NULL so that it can be properly treated
3833 * in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
3834 * This routine is only used in contexts where a complete expression
3835 * is being evaluated and we know that NULL can be treated the same
3836 * as one boolean result or the other.
3838 * ----------------------------------------------------------------
3841 ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
3844 MemoryContext oldContext;
3850 EV_printf("ExecQual: qual is ");
3851 EV_nodeDisplay(qual);
3857 * Run in short-lived per-tuple context while computing expressions.
3859 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
3862 * Evaluate the qual conditions one at a time. If we find a FALSE result,
3863 * we can stop evaluating and return FALSE --- the AND result must be
3864 * FALSE. Also, if we find a NULL result when resultForNull is FALSE, we
3865 * can stop and return FALSE --- the AND result must be FALSE or NULL in
3866 * that case, and the caller doesn't care which.
3868 * If we get to the end of the list, we can return TRUE. This will happen
3869 * when the AND result is indeed TRUE, or when the AND result is NULL (one
3870 * or more NULL subresult, with all the rest TRUE) and the caller has
3871 * specified resultForNull = TRUE.
3877 ExprState *clause = (ExprState *) lfirst(l);
3881 expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
3885 if (resultForNull == false)
3887 result = false; /* treat NULL as FALSE */
3893 if (!DatumGetBool(expr_value))
3895 result = false; /* definitely FALSE */
3901 MemoryContextSwitchTo(oldContext);
3907 * Number of items in a tlist (including any resjunk items!)
3910 ExecTargetListLength(List *targetlist)
3912 /* This used to be more complex, but fjoins are dead */
3913 return list_length(targetlist);
3917 * Number of items in a tlist, not including any resjunk items
3920 ExecCleanTargetListLength(List *targetlist)
3925 foreach(tl, targetlist)
3927 TargetEntry *curTle = (TargetEntry *) lfirst(tl);
3929 Assert(IsA(curTle, TargetEntry));
3930 if (!curTle->resjunk)
3938 * Evaluates a targetlist with respect to the given
3939 * expression context. Returns TRUE if we were able to create
3940 * a result, FALSE if we have exhausted a set-valued expression.
3942 * Results are stored into the passed values and isnull arrays.
3943 * The caller must provide an itemIsDone array that persists across calls.
3945 * As with ExecEvalExpr, the caller should pass isDone = NULL if not
3946 * prepared to deal with sets of result tuples. Otherwise, a return
3947 * of *isDone = ExprMultipleResult signifies a set element, and a return
3948 * of *isDone = ExprEndResult signifies end of the set of tuple.
3951 ExecTargetList(List *targetlist,
3952 ExprContext *econtext,
3955 ExprDoneCond *itemIsDone,
3956 ExprDoneCond *isDone)
3958 MemoryContext oldContext;
3963 * Run in short-lived per-tuple context while computing expressions.
3965 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
3968 * evaluate all the expressions in the target list
3971 *isDone = ExprSingleResult; /* until proven otherwise */
3973 haveDoneSets = false; /* any exhausted set exprs in tlist? */
3975 foreach(tl, targetlist)
3977 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
3978 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
3979 AttrNumber resind = tle->resno - 1;
3981 values[resind] = ExecEvalExpr(gstate->arg,
3984 &itemIsDone[resind]);
3986 if (itemIsDone[resind] != ExprSingleResult)
3988 /* We have a set-valued expression in the tlist */
3991 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3992 errmsg("set-valued function called in context that cannot accept a set")));
3993 if (itemIsDone[resind] == ExprMultipleResult)
3995 /* we have undone sets in the tlist, set flag */
3996 *isDone = ExprMultipleResult;
4000 /* we have done sets in the tlist, set flag for that */
4001 haveDoneSets = true;
4009 * note: can't get here unless we verified isDone != NULL
4011 if (*isDone == ExprSingleResult)
4014 * all sets are done, so report that tlist expansion is complete.
4016 *isDone = ExprEndResult;
4017 MemoryContextSwitchTo(oldContext);
4023 * We have some done and some undone sets. Restart the done ones
4024 * so that we can deliver a tuple (if possible).
4026 foreach(tl, targetlist)
4028 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
4029 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
4030 AttrNumber resind = tle->resno - 1;
4032 if (itemIsDone[resind] == ExprEndResult)
4034 values[resind] = ExecEvalExpr(gstate->arg,
4037 &itemIsDone[resind]);
4039 if (itemIsDone[resind] == ExprEndResult)
4042 * Oh dear, this item is returning an empty set. Guess
4043 * we can't make a tuple after all.
4045 *isDone = ExprEndResult;
4052 * If we cannot make a tuple because some sets are empty, we still
4053 * have to cycle the nonempty sets to completion, else resources
4054 * will not be released from subplans etc.
4056 * XXX is that still necessary?
4058 if (*isDone == ExprEndResult)
4060 foreach(tl, targetlist)
4062 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
4063 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
4064 AttrNumber resind = tle->resno - 1;
4066 while (itemIsDone[resind] == ExprMultipleResult)
4068 values[resind] = ExecEvalExpr(gstate->arg,
4071 &itemIsDone[resind]);
4075 MemoryContextSwitchTo(oldContext);
4081 /* Report success */
4082 MemoryContextSwitchTo(oldContext);
4089 * Evaluates a simple-Variable-list projection.
4091 * Results are stored into the passed values and isnull arrays.
4094 ExecVariableList(ProjectionInfo *projInfo,
4098 ExprContext *econtext = projInfo->pi_exprContext;
4099 int *varSlotOffsets = projInfo->pi_varSlotOffsets;
4100 int *varNumbers = projInfo->pi_varNumbers;
4104 * Force extraction of all input values that we need.
4106 if (projInfo->pi_lastInnerVar > 0)
4107 slot_getsomeattrs(econtext->ecxt_innertuple,
4108 projInfo->pi_lastInnerVar);
4109 if (projInfo->pi_lastOuterVar > 0)
4110 slot_getsomeattrs(econtext->ecxt_outertuple,
4111 projInfo->pi_lastOuterVar);
4112 if (projInfo->pi_lastScanVar > 0)
4113 slot_getsomeattrs(econtext->ecxt_scantuple,
4114 projInfo->pi_lastScanVar);
4117 * Assign to result by direct extraction of fields from source slots ... a
4118 * mite ugly, but fast ...
4120 for (i = list_length(projInfo->pi_targetlist) - 1; i >= 0; i--)
4122 char *slotptr = ((char *) econtext) + varSlotOffsets[i];
4123 TupleTableSlot *varSlot = *((TupleTableSlot **) slotptr);
4124 int varNumber = varNumbers[i] - 1;
4126 values[i] = varSlot->tts_values[varNumber];
4127 isnull[i] = varSlot->tts_isnull[varNumber];
4134 * projects a tuple based on projection info and stores
4135 * it in the previously specified tuple table slot.
4137 * Note: the result is always a virtual tuple; therefore it
4138 * may reference the contents of the exprContext's scan tuples
4139 * and/or temporary results constructed in the exprContext.
4140 * If the caller wishes the result to be valid longer than that
4141 * data will be valid, he must call ExecMaterializeSlot on the
4145 ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
4147 TupleTableSlot *slot;
4152 Assert(projInfo != NULL);
4155 * get the projection info we want
4157 slot = projInfo->pi_slot;
4160 * Clear any former contents of the result slot. This makes it safe for
4161 * us to use the slot's Datum/isnull arrays as workspace. (Also, we can
4162 * return the slot as-is if we decide no rows can be projected.)
4164 ExecClearTuple(slot);
4167 * form a new result tuple (if possible); if successful, mark the result
4168 * slot as containing a valid virtual tuple
4170 if (projInfo->pi_isVarList)
4172 /* simple Var list: this always succeeds with one result row */
4174 *isDone = ExprSingleResult;
4175 ExecVariableList(projInfo,
4178 ExecStoreVirtualTuple(slot);
4182 if (ExecTargetList(projInfo->pi_targetlist,
4183 projInfo->pi_exprContext,
4186 projInfo->pi_itemIsDone,
4188 ExecStoreVirtualTuple(slot);