1 /*-------------------------------------------------------------------------
4 * Routines to evaluate qualification and targetlist expressions
6 * Portions Copyright (c) 1996-2009, 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.246 2009/04/08 21:51:38 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 (and substitute routines) rather than at every
33 * single node. This is a compromise that trades off precision of the
34 * stack limit setting to gain speed.
39 #include "access/nbtree.h"
40 #include "catalog/pg_type.h"
41 #include "commands/typecmds.h"
42 #include "executor/execdebug.h"
43 #include "executor/nodeSubplan.h"
45 #include "miscadmin.h"
46 #include "nodes/makefuncs.h"
47 #include "nodes/nodeFuncs.h"
48 #include "optimizer/planner.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"
55 #include "utils/xml.h"
58 /* static function decls */
59 static Datum ExecEvalArrayRef(ArrayRefExprState *astate,
60 ExprContext *econtext,
61 bool *isNull, ExprDoneCond *isDone);
62 static Datum ExecEvalAggref(AggrefExprState *aggref,
63 ExprContext *econtext,
64 bool *isNull, ExprDoneCond *isDone);
65 static Datum ExecEvalWindowFunc(WindowFuncExprState *wfunc,
66 ExprContext *econtext,
67 bool *isNull, ExprDoneCond *isDone);
68 static Datum ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
69 bool *isNull, ExprDoneCond *isDone);
70 static Datum ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
71 bool *isNull, ExprDoneCond *isDone);
72 static Datum ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext,
73 bool *isNull, ExprDoneCond *isDone);
74 static Datum ExecEvalWholeRowSlow(ExprState *exprstate, ExprContext *econtext,
75 bool *isNull, ExprDoneCond *isDone);
76 static Datum ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
77 bool *isNull, ExprDoneCond *isDone);
78 static Datum ExecEvalParam(ExprState *exprstate, ExprContext *econtext,
79 bool *isNull, ExprDoneCond *isDone);
80 static void init_fcache(Oid foid, FuncExprState *fcache,
81 MemoryContext fcacheCxt, bool needDescForSets);
82 static void ShutdownFuncExpr(Datum arg);
83 static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod,
84 TupleDesc *cache_field, ExprContext *econtext);
85 static void ShutdownTupleDescRef(Datum arg);
86 static ExprDoneCond ExecEvalFuncArgs(FunctionCallInfo fcinfo,
87 List *argList, ExprContext *econtext);
88 static void ExecPrepareTuplestoreResult(FuncExprState *fcache,
89 ExprContext *econtext,
90 Tuplestorestate *resultStore,
91 TupleDesc resultDesc);
92 static void tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc);
93 static Datum ExecMakeFunctionResult(FuncExprState *fcache,
94 ExprContext *econtext,
96 ExprDoneCond *isDone);
97 static Datum ExecMakeFunctionResultNoSets(FuncExprState *fcache,
98 ExprContext *econtext,
99 bool *isNull, ExprDoneCond *isDone);
100 static Datum ExecEvalFunc(FuncExprState *fcache, ExprContext *econtext,
101 bool *isNull, ExprDoneCond *isDone);
102 static Datum ExecEvalOper(FuncExprState *fcache, ExprContext *econtext,
103 bool *isNull, ExprDoneCond *isDone);
104 static Datum ExecEvalDistinct(FuncExprState *fcache, ExprContext *econtext,
105 bool *isNull, ExprDoneCond *isDone);
106 static Datum ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
107 ExprContext *econtext,
108 bool *isNull, ExprDoneCond *isDone);
109 static Datum ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
110 bool *isNull, ExprDoneCond *isDone);
111 static Datum ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
112 bool *isNull, ExprDoneCond *isDone);
113 static Datum ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
114 bool *isNull, ExprDoneCond *isDone);
115 static Datum ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
116 ExprContext *econtext,
117 bool *isNull, ExprDoneCond *isDone);
118 static Datum ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
119 bool *isNull, ExprDoneCond *isDone);
120 static Datum ExecEvalCaseTestExpr(ExprState *exprstate,
121 ExprContext *econtext,
122 bool *isNull, ExprDoneCond *isDone);
123 static Datum ExecEvalArray(ArrayExprState *astate,
124 ExprContext *econtext,
125 bool *isNull, ExprDoneCond *isDone);
126 static Datum ExecEvalRow(RowExprState *rstate,
127 ExprContext *econtext,
128 bool *isNull, ExprDoneCond *isDone);
129 static Datum ExecEvalRowCompare(RowCompareExprState *rstate,
130 ExprContext *econtext,
131 bool *isNull, ExprDoneCond *isDone);
132 static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr,
133 ExprContext *econtext,
134 bool *isNull, ExprDoneCond *isDone);
135 static Datum ExecEvalMinMax(MinMaxExprState *minmaxExpr,
136 ExprContext *econtext,
137 bool *isNull, ExprDoneCond *isDone);
138 static Datum ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
139 bool *isNull, ExprDoneCond *isDone);
140 static Datum ExecEvalNullIf(FuncExprState *nullIfExpr,
141 ExprContext *econtext,
142 bool *isNull, ExprDoneCond *isDone);
143 static Datum ExecEvalNullTest(NullTestState *nstate,
144 ExprContext *econtext,
145 bool *isNull, ExprDoneCond *isDone);
146 static Datum ExecEvalBooleanTest(GenericExprState *bstate,
147 ExprContext *econtext,
148 bool *isNull, ExprDoneCond *isDone);
149 static Datum ExecEvalCoerceToDomain(CoerceToDomainState *cstate,
150 ExprContext *econtext,
151 bool *isNull, ExprDoneCond *isDone);
152 static Datum ExecEvalCoerceToDomainValue(ExprState *exprstate,
153 ExprContext *econtext,
154 bool *isNull, ExprDoneCond *isDone);
155 static Datum ExecEvalFieldSelect(FieldSelectState *fstate,
156 ExprContext *econtext,
157 bool *isNull, ExprDoneCond *isDone);
158 static Datum ExecEvalFieldStore(FieldStoreState *fstate,
159 ExprContext *econtext,
160 bool *isNull, ExprDoneCond *isDone);
161 static Datum ExecEvalRelabelType(GenericExprState *exprstate,
162 ExprContext *econtext,
163 bool *isNull, ExprDoneCond *isDone);
164 static Datum ExecEvalCoerceViaIO(CoerceViaIOState *iostate,
165 ExprContext *econtext,
166 bool *isNull, ExprDoneCond *isDone);
167 static Datum ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
168 ExprContext *econtext,
169 bool *isNull, ExprDoneCond *isDone);
170 static Datum ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
171 bool *isNull, ExprDoneCond *isDone);
174 /* ----------------------------------------------------------------
175 * ExecEvalExpr routines
177 * Recursively evaluate a targetlist or qualification expression.
179 * Each of the following routines having the signature
180 * Datum ExecEvalFoo(ExprState *expression,
181 * ExprContext *econtext,
183 * ExprDoneCond *isDone);
184 * is responsible for evaluating one type or subtype of ExprState node.
185 * They are normally called via the ExecEvalExpr macro, which makes use of
186 * the function pointer set up when the ExprState node was built by
187 * ExecInitExpr. (In some cases, we change this pointer later to avoid
188 * re-executing one-time overhead.)
190 * Note: for notational simplicity we declare these functions as taking the
191 * specific type of ExprState that they work on. This requires casting when
192 * assigning the function pointer in ExecInitExpr. Be careful that the
193 * function signature is declared correctly, because the cast suppresses
194 * automatic checking!
197 * All these functions share this calling convention:
200 * expression: the expression state tree to evaluate
201 * econtext: evaluation context information
204 * return value: Datum value of result
205 * *isNull: set to TRUE if result is NULL (actual return value is
206 * meaningless if so); set to FALSE if non-null result
207 * *isDone: set to indicator of set-result status
209 * A caller that can only accept a singleton (non-set) result should pass
210 * NULL for isDone; if the expression computes a set result then an error
211 * will be reported via ereport. If the caller does pass an isDone pointer
212 * then *isDone is set to one of these three states:
213 * ExprSingleResult singleton result (not a set)
214 * ExprMultipleResult return value is one element of a set
215 * ExprEndResult there are no more elements in the set
216 * When ExprMultipleResult is returned, the caller should invoke
217 * ExecEvalExpr() repeatedly until ExprEndResult is returned. ExprEndResult
218 * is returned after the last real set element. For convenience isNull will
219 * always be set TRUE when ExprEndResult is returned, but this should not be
220 * taken as indicating a NULL element of the set. Note that these return
221 * conventions allow us to distinguish among a singleton NULL, a NULL element
222 * of a set, and an empty set.
224 * The caller should already have switched into the temporary memory
225 * context econtext->ecxt_per_tuple_memory. The convenience entry point
226 * ExecEvalExprSwitchContext() is provided for callers who don't prefer to
227 * do the switch in an outer loop. We do not do the switch in these routines
228 * because it'd be a waste of cycles during nested expression evaluation.
229 * ----------------------------------------------------------------
236 * This function takes an ArrayRef and returns the extracted Datum
237 * if it's a simple reference, or the modified array value if it's
238 * an array assignment (i.e., array element or slice insertion).
240 * NOTE: if we get a NULL result from a subscript expression, we return NULL
241 * when it's an array reference, or raise an error when it's an assignment.
243 * NOTE: we deliberately refrain from applying DatumGetArrayTypeP() here,
244 * even though that might seem natural, because this code needs to support
245 * both varlena arrays and fixed-length array types. DatumGetArrayTypeP()
246 * only works for the varlena kind. The routines we call in arrayfuncs.c
247 * have to know the difference (that's what they need refattrlength for).
251 ExecEvalArrayRef(ArrayRefExprState *astate,
252 ExprContext *econtext,
254 ExprDoneCond *isDone)
256 ArrayRef *arrayRef = (ArrayRef *) astate->xprstate.expr;
257 ArrayType *array_source;
258 ArrayType *resultArray;
259 bool isAssignment = (arrayRef->refassgnexpr != NULL);
268 array_source = (ArrayType *)
269 DatumGetPointer(ExecEvalExpr(astate->refexpr,
275 * If refexpr yields NULL, and it's a fetch, then result is NULL. In the
276 * assignment case, we'll cons up something below.
280 if (isDone && *isDone == ExprEndResult)
281 return (Datum) NULL; /* end of set result */
286 foreach(l, astate->refupperindexpr)
288 ExprState *eltstate = (ExprState *) lfirst(l);
292 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
293 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
296 upper.indx[i++] = DatumGetInt32(ExecEvalExpr(eltstate,
300 /* If any index expr yields NULL, result is NULL or error */
305 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
306 errmsg("array subscript in assignment must not be null")));
312 if (astate->reflowerindexpr != NIL)
314 foreach(l, astate->reflowerindexpr)
316 ExprState *eltstate = (ExprState *) lfirst(l);
320 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
321 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
324 lower.indx[j++] = DatumGetInt32(ExecEvalExpr(eltstate,
328 /* If any index expr yields NULL, result is NULL or error */
333 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
334 errmsg("array subscript in assignment must not be null")));
339 /* this can't happen unless parser messed up */
341 elog(ERROR, "upper and lower index lists are not same length");
352 * Evaluate the value to be assigned into the array.
354 * XXX At some point we'll need to look into making the old value of
355 * the array element available via CaseTestExpr, as is done by
356 * ExecEvalFieldStore. This is not needed now but will be needed to
357 * support arrays of composite types; in an assignment to a field of
358 * an array member, the parser would generate a FieldStore that
359 * expects to fetch its input tuple via CaseTestExpr.
361 sourceData = ExecEvalExpr(astate->refassgnexpr,
367 * For an assignment to a fixed-length array type, both the original
368 * array and the value to be assigned into it must be non-NULL, else
369 * we punt and return the original array.
371 if (astate->refattrlength > 0) /* fixed-length array? */
372 if (eisnull || *isNull)
373 return PointerGetDatum(array_source);
376 * For assignment to varlena arrays, we handle a NULL original array
377 * by substituting an empty (zero-dimensional) array; insertion of the
378 * new element will result in a singleton array value. It does not
379 * matter whether the new element is NULL.
383 array_source = construct_empty_array(arrayRef->refelemtype);
388 resultArray = array_set(array_source, i,
392 astate->refattrlength,
393 astate->refelemlength,
394 astate->refelembyval,
395 astate->refelemalign);
397 resultArray = array_set_slice(array_source, i,
398 upper.indx, lower.indx,
399 (ArrayType *) DatumGetPointer(sourceData),
401 astate->refattrlength,
402 astate->refelemlength,
403 astate->refelembyval,
404 astate->refelemalign);
405 return PointerGetDatum(resultArray);
409 return array_ref(array_source, i, upper.indx,
410 astate->refattrlength,
411 astate->refelemlength,
412 astate->refelembyval,
413 astate->refelemalign,
417 resultArray = array_get_slice(array_source, i,
418 upper.indx, lower.indx,
419 astate->refattrlength,
420 astate->refelemlength,
421 astate->refelembyval,
422 astate->refelemalign);
423 return PointerGetDatum(resultArray);
428 /* ----------------------------------------------------------------
431 * Returns a Datum whose value is the value of the precomputed
432 * aggregate found in the given expression context.
433 * ----------------------------------------------------------------
436 ExecEvalAggref(AggrefExprState *aggref, ExprContext *econtext,
437 bool *isNull, ExprDoneCond *isDone)
440 *isDone = ExprSingleResult;
442 if (econtext->ecxt_aggvalues == NULL) /* safety check */
443 elog(ERROR, "no aggregates in this expression context");
445 *isNull = econtext->ecxt_aggnulls[aggref->aggno];
446 return econtext->ecxt_aggvalues[aggref->aggno];
449 /* ----------------------------------------------------------------
452 * Returns a Datum whose value is the value of the precomputed
453 * window function found in the given expression context.
454 * ----------------------------------------------------------------
457 ExecEvalWindowFunc(WindowFuncExprState *wfunc, ExprContext *econtext,
458 bool *isNull, ExprDoneCond *isDone)
461 *isDone = ExprSingleResult;
463 if (econtext->ecxt_aggvalues == NULL) /* safety check */
464 elog(ERROR, "no window functions in this expression context");
466 *isNull = econtext->ecxt_aggnulls[wfunc->wfuncno];
467 return econtext->ecxt_aggvalues[wfunc->wfuncno];
470 /* ----------------------------------------------------------------
473 * Returns a Datum whose value is the value of a range
474 * variable with respect to given expression context.
476 * Note: ExecEvalVar is executed only the first time through in a given plan;
477 * it changes the ExprState's function pointer to pass control directly to
478 * ExecEvalScalarVar, ExecEvalWholeRowVar, or ExecEvalWholeRowSlow after
479 * making one-time checks.
480 * ----------------------------------------------------------------
483 ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
484 bool *isNull, ExprDoneCond *isDone)
486 Var *variable = (Var *) exprstate->expr;
487 TupleTableSlot *slot;
491 *isDone = ExprSingleResult;
494 * Get the input slot and attribute number we want
496 * The asserts check that references to system attributes only appear at
497 * the level of a relation scan; at higher levels, system attributes must
498 * be treated as ordinary variables (since we no longer have access to the
501 attnum = variable->varattno;
503 switch (variable->varno)
505 case INNER: /* get the tuple from the inner node */
506 slot = econtext->ecxt_innertuple;
510 case OUTER: /* get the tuple from the outer node */
511 slot = econtext->ecxt_outertuple;
515 default: /* get the tuple from the relation being
517 slot = econtext->ecxt_scantuple;
521 if (attnum != InvalidAttrNumber)
524 * Scalar variable case.
526 * If it's a user attribute, check validity (bogus system attnums will
527 * be caught inside slot_getattr). What we have to check for here is
528 * the possibility of an attribute having been changed in type since
529 * the plan tree was created. Ideally the plan would get invalidated
530 * and not re-used, but until that day arrives, we need defenses.
531 * Fortunately it's sufficient to check once on the first time
534 * Note: we allow a reference to a dropped attribute. slot_getattr
535 * will force a NULL result in such cases.
537 * Note: ideally we'd check typmod as well as typid, but that seems
538 * impractical at the moment: in many cases the tupdesc will have been
539 * generated by ExecTypeFromTL(), and that can't guarantee to generate
540 * an accurate typmod in all cases, because some expression node types
541 * don't carry typmod.
545 TupleDesc slot_tupdesc = slot->tts_tupleDescriptor;
546 Form_pg_attribute attr;
548 if (attnum > slot_tupdesc->natts) /* should never happen */
549 elog(ERROR, "attribute number %d exceeds number of columns %d",
550 attnum, slot_tupdesc->natts);
552 attr = slot_tupdesc->attrs[attnum - 1];
554 /* can't check type if dropped, since atttypid is probably 0 */
555 if (!attr->attisdropped)
557 if (variable->vartype != attr->atttypid)
559 (errmsg("attribute %d has wrong type", attnum),
560 errdetail("Table has type %s, but query expects %s.",
561 format_type_be(attr->atttypid),
562 format_type_be(variable->vartype))));
566 /* Skip the checking on future executions of node */
567 exprstate->evalfunc = ExecEvalScalarVar;
569 /* Fetch the value from the slot */
570 return slot_getattr(slot, attnum, isNull);
575 * Whole-row variable.
577 * If it's a RECORD Var, we'll use the slot's type ID info. It's
578 * likely that the slot's type is also RECORD; if so, make sure it's
579 * been "blessed", so that the Datum can be interpreted later.
581 * If the Var identifies a named composite type, we must check that
582 * the actual tuple type is compatible with it.
584 TupleDesc slot_tupdesc = slot->tts_tupleDescriptor;
585 bool needslow = false;
587 if (variable->vartype == RECORDOID)
589 if (slot_tupdesc->tdtypeid == RECORDOID &&
590 slot_tupdesc->tdtypmod < 0)
591 assign_record_type_typmod(slot_tupdesc);
595 TupleDesc var_tupdesc;
599 * We really only care about number of attributes and data type.
600 * Also, we can ignore type mismatch on columns that are dropped
601 * in the destination type, so long as the physical storage
602 * matches. This is helpful in some cases involving out-of-date
603 * cached plans. Also, we have to allow the case that the slot
604 * has more columns than the Var's type, because we might be
605 * looking at the output of a subplan that includes resjunk
606 * columns. (XXX it would be nice to verify that the extra
607 * columns are all marked resjunk, but we haven't got access to
608 * the subplan targetlist here...) Resjunk columns should always
609 * be at the end of a targetlist, so it's sufficient to ignore
610 * them here; but we need to use ExecEvalWholeRowSlow to get rid
611 * of them in the eventual output tuples.
613 var_tupdesc = lookup_rowtype_tupdesc(variable->vartype, -1);
615 if (var_tupdesc->natts > slot_tupdesc->natts)
617 (errcode(ERRCODE_DATATYPE_MISMATCH),
618 errmsg("table row type and query-specified row type do not match"),
619 errdetail(ngettext("Table row contains %d attribute, but query expects %d.",
620 "Table row contains %d attributes, but query expects %d.",
621 slot_tupdesc->natts),
622 slot_tupdesc->natts, var_tupdesc->natts)));
623 else if (var_tupdesc->natts < slot_tupdesc->natts)
626 for (i = 0; i < var_tupdesc->natts; i++)
628 Form_pg_attribute vattr = var_tupdesc->attrs[i];
629 Form_pg_attribute sattr = slot_tupdesc->attrs[i];
631 if (vattr->atttypid == sattr->atttypid)
632 continue; /* no worries */
633 if (!vattr->attisdropped)
635 (errcode(ERRCODE_DATATYPE_MISMATCH),
636 errmsg("table row type and query-specified row type do not match"),
637 errdetail("Table has type %s at ordinal position %d, but query expects %s.",
638 format_type_be(sattr->atttypid),
640 format_type_be(vattr->atttypid))));
642 if (vattr->attlen != sattr->attlen ||
643 vattr->attalign != sattr->attalign)
645 (errcode(ERRCODE_DATATYPE_MISMATCH),
646 errmsg("table row type and query-specified row type do not match"),
647 errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
651 ReleaseTupleDesc(var_tupdesc);
654 /* Skip the checking on future executions of node */
656 exprstate->evalfunc = ExecEvalWholeRowSlow;
658 exprstate->evalfunc = ExecEvalWholeRowVar;
660 /* Fetch the value */
661 return ExecEvalWholeRowVar(exprstate, econtext, isNull, isDone);
665 /* ----------------------------------------------------------------
668 * Returns a Datum for a scalar variable.
669 * ----------------------------------------------------------------
672 ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
673 bool *isNull, ExprDoneCond *isDone)
675 Var *variable = (Var *) exprstate->expr;
676 TupleTableSlot *slot;
680 *isDone = ExprSingleResult;
682 /* Get the input slot and attribute number we want */
683 switch (variable->varno)
685 case INNER: /* get the tuple from the inner node */
686 slot = econtext->ecxt_innertuple;
689 case OUTER: /* get the tuple from the outer node */
690 slot = econtext->ecxt_outertuple;
693 default: /* get the tuple from the relation being
695 slot = econtext->ecxt_scantuple;
699 attnum = variable->varattno;
701 /* Fetch the value from the slot */
702 return slot_getattr(slot, attnum, isNull);
705 /* ----------------------------------------------------------------
706 * ExecEvalWholeRowVar
708 * Returns a Datum for a whole-row variable.
709 * ----------------------------------------------------------------
712 ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext,
713 bool *isNull, ExprDoneCond *isDone)
715 Var *variable = (Var *) exprstate->expr;
716 TupleTableSlot *slot = econtext->ecxt_scantuple;
719 HeapTupleHeader dtuple;
722 *isDone = ExprSingleResult;
725 tuple = ExecFetchSlotTuple(slot);
726 tupleDesc = slot->tts_tupleDescriptor;
729 * We have to make a copy of the tuple so we can safely insert the Datum
730 * overhead fields, which are not set in on-disk tuples.
732 dtuple = (HeapTupleHeader) palloc(tuple->t_len);
733 memcpy((char *) dtuple, (char *) tuple->t_data, tuple->t_len);
735 HeapTupleHeaderSetDatumLength(dtuple, tuple->t_len);
738 * If the Var identifies a named composite type, label the tuple with that
739 * type; otherwise use what is in the tupleDesc.
741 if (variable->vartype != RECORDOID)
743 HeapTupleHeaderSetTypeId(dtuple, variable->vartype);
744 HeapTupleHeaderSetTypMod(dtuple, variable->vartypmod);
748 HeapTupleHeaderSetTypeId(dtuple, tupleDesc->tdtypeid);
749 HeapTupleHeaderSetTypMod(dtuple, tupleDesc->tdtypmod);
752 return PointerGetDatum(dtuple);
755 /* ----------------------------------------------------------------
756 * ExecEvalWholeRowSlow
758 * Returns a Datum for a whole-row variable, in the "slow" case where
759 * we can't just copy the subplan's output.
760 * ----------------------------------------------------------------
763 ExecEvalWholeRowSlow(ExprState *exprstate, ExprContext *econtext,
764 bool *isNull, ExprDoneCond *isDone)
766 Var *variable = (Var *) exprstate->expr;
767 TupleTableSlot *slot = econtext->ecxt_scantuple;
769 TupleDesc var_tupdesc;
770 HeapTupleHeader dtuple;
773 *isDone = ExprSingleResult;
777 * Currently, the only case handled here is stripping of trailing resjunk
778 * fields, which we do in a slightly chintzy way by just adjusting the
779 * tuple's natts header field. Possibly there will someday be a need for
780 * more-extensive rearrangements, in which case it'd be worth
781 * disassembling and reassembling the tuple (perhaps use a JunkFilter for
784 Assert(variable->vartype != RECORDOID);
785 var_tupdesc = lookup_rowtype_tupdesc(variable->vartype, -1);
787 tuple = ExecFetchSlotTuple(slot);
790 * We have to make a copy of the tuple so we can safely insert the Datum
791 * overhead fields, which are not set in on-disk tuples; not to mention
792 * fooling with its natts field.
794 dtuple = (HeapTupleHeader) palloc(tuple->t_len);
795 memcpy((char *) dtuple, (char *) tuple->t_data, tuple->t_len);
797 HeapTupleHeaderSetDatumLength(dtuple, tuple->t_len);
798 HeapTupleHeaderSetTypeId(dtuple, variable->vartype);
799 HeapTupleHeaderSetTypMod(dtuple, variable->vartypmod);
801 Assert(HeapTupleHeaderGetNatts(dtuple) >= var_tupdesc->natts);
802 HeapTupleHeaderSetNatts(dtuple, var_tupdesc->natts);
804 ReleaseTupleDesc(var_tupdesc);
806 return PointerGetDatum(dtuple);
809 /* ----------------------------------------------------------------
812 * Returns the value of a constant.
814 * Note that for pass-by-ref datatypes, we return a pointer to the
815 * actual constant node. This is one of the reasons why functions
816 * must treat their input arguments as read-only.
817 * ----------------------------------------------------------------
820 ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
821 bool *isNull, ExprDoneCond *isDone)
823 Const *con = (Const *) exprstate->expr;
826 *isDone = ExprSingleResult;
828 *isNull = con->constisnull;
829 return con->constvalue;
832 /* ----------------------------------------------------------------
835 * Returns the value of a parameter. A param node contains
836 * something like ($.name) and the expression context contains
837 * the current parameter bindings (name = "sam") (age = 34)...
838 * so our job is to find and return the appropriate datum ("sam").
839 * ----------------------------------------------------------------
842 ExecEvalParam(ExprState *exprstate, ExprContext *econtext,
843 bool *isNull, ExprDoneCond *isDone)
845 Param *expression = (Param *) exprstate->expr;
846 int thisParamId = expression->paramid;
849 *isDone = ExprSingleResult;
851 if (expression->paramkind == PARAM_EXEC)
854 * PARAM_EXEC params (internal executor parameters) are stored in the
855 * ecxt_param_exec_vals array, and can be accessed by array index.
859 prm = &(econtext->ecxt_param_exec_vals[thisParamId]);
860 if (prm->execPlan != NULL)
862 /* Parameter not evaluated yet, so go do it */
863 ExecSetParamPlan(prm->execPlan, econtext);
864 /* ExecSetParamPlan should have processed this param... */
865 Assert(prm->execPlan == NULL);
867 *isNull = prm->isnull;
873 * PARAM_EXTERN parameters must be sought in ecxt_param_list_info.
875 ParamListInfo paramInfo = econtext->ecxt_param_list_info;
877 Assert(expression->paramkind == PARAM_EXTERN);
879 thisParamId > 0 && thisParamId <= paramInfo->numParams)
881 ParamExternData *prm = ¶mInfo->params[thisParamId - 1];
883 if (OidIsValid(prm->ptype))
885 Assert(prm->ptype == expression->paramtype);
886 *isNull = prm->isnull;
891 (errcode(ERRCODE_UNDEFINED_OBJECT),
892 errmsg("no value found for parameter %d", thisParamId)));
893 return (Datum) 0; /* keep compiler quiet */
898 /* ----------------------------------------------------------------
899 * ExecEvalOper / ExecEvalFunc support routines
900 * ----------------------------------------------------------------
907 * These functions return the value of the requested attribute
908 * out of the given tuple Datum.
909 * C functions which take a tuple as an argument are expected
910 * to use these. Ex: overpaid(EMP) might call GetAttributeByNum().
911 * Note: these are actually rather slow because they do a typcache
912 * lookup on each call.
915 GetAttributeByNum(HeapTupleHeader tuple,
923 HeapTupleData tmptup;
925 if (!AttributeNumberIsValid(attrno))
926 elog(ERROR, "invalid attribute number %d", attrno);
929 elog(ERROR, "a NULL isNull pointer was passed");
933 /* Kinda bogus but compatible with old behavior... */
938 tupType = HeapTupleHeaderGetTypeId(tuple);
939 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
940 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
943 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
944 * the fields in the struct just in case user tries to inspect system
947 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
948 ItemPointerSetInvalid(&(tmptup.t_self));
949 tmptup.t_tableOid = InvalidOid;
950 tmptup.t_data = tuple;
952 result = heap_getattr(&tmptup,
957 ReleaseTupleDesc(tupDesc);
963 GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
970 HeapTupleData tmptup;
974 elog(ERROR, "invalid attribute name");
977 elog(ERROR, "a NULL isNull pointer was passed");
981 /* Kinda bogus but compatible with old behavior... */
986 tupType = HeapTupleHeaderGetTypeId(tuple);
987 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
988 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
990 attrno = InvalidAttrNumber;
991 for (i = 0; i < tupDesc->natts; i++)
993 if (namestrcmp(&(tupDesc->attrs[i]->attname), attname) == 0)
995 attrno = tupDesc->attrs[i]->attnum;
1000 if (attrno == InvalidAttrNumber)
1001 elog(ERROR, "attribute \"%s\" does not exist", attname);
1004 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
1005 * the fields in the struct just in case user tries to inspect system
1008 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
1009 ItemPointerSetInvalid(&(tmptup.t_self));
1010 tmptup.t_tableOid = InvalidOid;
1011 tmptup.t_data = tuple;
1013 result = heap_getattr(&tmptup,
1018 ReleaseTupleDesc(tupDesc);
1024 * init_fcache - initialize a FuncExprState node during first use
1027 init_fcache(Oid foid, FuncExprState *fcache,
1028 MemoryContext fcacheCxt, bool needDescForSets)
1030 AclResult aclresult;
1032 /* Check permission to call function */
1033 aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
1034 if (aclresult != ACLCHECK_OK)
1035 aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(foid));
1038 * Safety check on nargs. Under normal circumstances this should never
1039 * fail, as parser should check sooner. But possibly it might fail if
1040 * server has been compiled with FUNC_MAX_ARGS smaller than some functions
1041 * declared in pg_proc?
1043 if (list_length(fcache->args) > FUNC_MAX_ARGS)
1045 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
1046 errmsg(ngettext("cannot pass more than %d argument to a function",
1047 "cannot pass more than %d arguments to a function",
1051 /* Set up the primary fmgr lookup information */
1052 fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
1053 fcache->func.fn_expr = (Node *) fcache->xprstate.expr;
1055 /* If function returns set, prepare expected tuple descriptor */
1056 if (fcache->func.fn_retset && needDescForSets)
1058 TypeFuncClass functypclass;
1061 MemoryContext oldcontext;
1063 functypclass = get_expr_result_type(fcache->func.fn_expr,
1067 /* Must save tupdesc in fcache's context */
1068 oldcontext = MemoryContextSwitchTo(fcacheCxt);
1070 if (functypclass == TYPEFUNC_COMPOSITE)
1072 /* Composite data type, e.g. a table's row type */
1074 /* Must copy it out of typcache for safety */
1075 fcache->funcResultDesc = CreateTupleDescCopy(tupdesc);
1076 fcache->funcReturnsTuple = true;
1078 else if (functypclass == TYPEFUNC_SCALAR)
1080 /* Base data type, i.e. scalar */
1081 tupdesc = CreateTemplateTupleDesc(1, false);
1082 TupleDescInitEntry(tupdesc,
1088 fcache->funcResultDesc = tupdesc;
1089 fcache->funcReturnsTuple = false;
1093 /* Else, we will complain if function wants materialize mode */
1094 fcache->funcResultDesc = NULL;
1097 MemoryContextSwitchTo(oldcontext);
1100 fcache->funcResultDesc = NULL;
1102 /* Initialize additional state */
1103 fcache->funcResultStore = NULL;
1104 fcache->funcResultSlot = NULL;
1105 fcache->setArgsValid = false;
1106 fcache->shutdown_reg = false;
1110 * callback function in case a FuncExpr returning a set needs to be shut down
1111 * before it has been run to completion
1114 ShutdownFuncExpr(Datum arg)
1116 FuncExprState *fcache = (FuncExprState *) DatumGetPointer(arg);
1118 /* If we have a slot, make sure it's let go of any tuplestore pointer */
1119 if (fcache->funcResultSlot)
1120 ExecClearTuple(fcache->funcResultSlot);
1122 /* Release any open tuplestore */
1123 if (fcache->funcResultStore)
1124 tuplestore_end(fcache->funcResultStore);
1125 fcache->funcResultStore = NULL;
1127 /* Clear any active set-argument state */
1128 fcache->setArgsValid = false;
1130 /* execUtils will deregister the callback... */
1131 fcache->shutdown_reg = false;
1135 * get_cached_rowtype: utility function to lookup a rowtype tupdesc
1137 * type_id, typmod: identity of the rowtype
1138 * cache_field: where to cache the TupleDesc pointer in expression state node
1139 * (field must be initialized to NULL)
1140 * econtext: expression context we are executing in
1142 * NOTE: because the shutdown callback will be called during plan rescan,
1143 * must be prepared to re-do this during any node execution; cannot call
1144 * just once during expression initialization
1147 get_cached_rowtype(Oid type_id, int32 typmod,
1148 TupleDesc *cache_field, ExprContext *econtext)
1150 TupleDesc tupDesc = *cache_field;
1152 /* Do lookup if no cached value or if requested type changed */
1153 if (tupDesc == NULL ||
1154 type_id != tupDesc->tdtypeid ||
1155 typmod != tupDesc->tdtypmod)
1157 tupDesc = lookup_rowtype_tupdesc(type_id, typmod);
1161 /* Release old tupdesc; but callback is already registered */
1162 ReleaseTupleDesc(*cache_field);
1166 /* Need to register shutdown callback to release tupdesc */
1167 RegisterExprContextCallback(econtext,
1168 ShutdownTupleDescRef,
1169 PointerGetDatum(cache_field));
1171 *cache_field = tupDesc;
1177 * Callback function to release a tupdesc refcount at expression tree shutdown
1180 ShutdownTupleDescRef(Datum arg)
1182 TupleDesc *cache_field = (TupleDesc *) DatumGetPointer(arg);
1185 ReleaseTupleDesc(*cache_field);
1186 *cache_field = NULL;
1190 * Evaluate arguments for a function.
1193 ExecEvalFuncArgs(FunctionCallInfo fcinfo,
1195 ExprContext *econtext)
1197 ExprDoneCond argIsDone;
1201 argIsDone = ExprSingleResult; /* default assumption */
1204 foreach(arg, argList)
1206 ExprState *argstate = (ExprState *) lfirst(arg);
1207 ExprDoneCond thisArgIsDone;
1209 fcinfo->arg[i] = ExecEvalExpr(argstate,
1211 &fcinfo->argnull[i],
1214 if (thisArgIsDone != ExprSingleResult)
1217 * We allow only one argument to have a set value; we'd need much
1218 * more complexity to keep track of multiple set arguments (cf.
1219 * ExecTargetList) and it doesn't seem worth it.
1221 if (argIsDone != ExprSingleResult)
1223 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1224 errmsg("functions and operators can take at most one set argument")));
1225 argIsDone = thisArgIsDone;
1236 * ExecPrepareTuplestoreResult
1238 * Subroutine for ExecMakeFunctionResult: prepare to extract rows from a
1239 * tuplestore function result. We must set up a funcResultSlot (unless
1240 * already done in a previous call cycle) and verify that the function
1241 * returned the expected tuple descriptor.
1244 ExecPrepareTuplestoreResult(FuncExprState *fcache,
1245 ExprContext *econtext,
1246 Tuplestorestate *resultStore,
1247 TupleDesc resultDesc)
1249 fcache->funcResultStore = resultStore;
1251 if (fcache->funcResultSlot == NULL)
1253 /* Create a slot so we can read data out of the tuplestore */
1254 MemoryContext oldcontext;
1256 /* We must have been able to determine the result rowtype */
1257 if (fcache->funcResultDesc == NULL)
1259 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1260 errmsg("function returning setof record called in "
1261 "context that cannot accept type record")));
1263 oldcontext = MemoryContextSwitchTo(fcache->func.fn_mcxt);
1264 fcache->funcResultSlot =
1265 MakeSingleTupleTableSlot(fcache->funcResultDesc);
1266 MemoryContextSwitchTo(oldcontext);
1270 * If function provided a tupdesc, cross-check it. We only really
1271 * need to do this for functions returning RECORD, but might as well
1276 if (fcache->funcResultDesc)
1277 tupledesc_match(fcache->funcResultDesc, resultDesc);
1280 * If it is a dynamically-allocated TupleDesc, free it: it is
1281 * typically allocated in a per-query context, so we must avoid
1282 * leaking it across multiple usages.
1284 if (resultDesc->tdrefcount == -1)
1285 FreeTupleDesc(resultDesc);
1288 /* Register cleanup callback if we didn't already */
1289 if (!fcache->shutdown_reg)
1291 RegisterExprContextCallback(econtext,
1293 PointerGetDatum(fcache));
1294 fcache->shutdown_reg = true;
1299 * Check that function result tuple type (src_tupdesc) matches or can
1300 * be considered to match what the query expects (dst_tupdesc). If
1301 * they don't match, ereport.
1303 * We really only care about number of attributes and data type.
1304 * Also, we can ignore type mismatch on columns that are dropped in the
1305 * destination type, so long as the physical storage matches. This is
1306 * helpful in some cases involving out-of-date cached plans.
1309 tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc)
1313 if (dst_tupdesc->natts != src_tupdesc->natts)
1315 (errcode(ERRCODE_DATATYPE_MISMATCH),
1316 errmsg("function return row and query-specified return row do not match"),
1317 errdetail(ngettext("Returned row contains %d attribute, but query expects %d.",
1318 "Returned row contains %d attributes, but query expects %d.",
1319 src_tupdesc->natts),
1320 src_tupdesc->natts, dst_tupdesc->natts)));
1322 for (i = 0; i < dst_tupdesc->natts; i++)
1324 Form_pg_attribute dattr = dst_tupdesc->attrs[i];
1325 Form_pg_attribute sattr = src_tupdesc->attrs[i];
1327 if (dattr->atttypid == sattr->atttypid)
1328 continue; /* no worries */
1329 if (!dattr->attisdropped)
1331 (errcode(ERRCODE_DATATYPE_MISMATCH),
1332 errmsg("function return row and query-specified return row do not match"),
1333 errdetail("Returned type %s at ordinal position %d, but query expects %s.",
1334 format_type_be(sattr->atttypid),
1336 format_type_be(dattr->atttypid))));
1338 if (dattr->attlen != sattr->attlen ||
1339 dattr->attalign != sattr->attalign)
1341 (errcode(ERRCODE_DATATYPE_MISMATCH),
1342 errmsg("function return row and query-specified return row do not match"),
1343 errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
1349 * ExecMakeFunctionResult
1351 * Evaluate the arguments to a function and then the function itself.
1352 * init_fcache is presumed already run on the FuncExprState.
1354 * This function handles the most general case, wherein the function or
1355 * one of its arguments might (or might not) return a set. If we find
1356 * no sets involved, we will change the FuncExprState's function pointer
1357 * to use a simpler method on subsequent calls.
1360 ExecMakeFunctionResult(FuncExprState *fcache,
1361 ExprContext *econtext,
1363 ExprDoneCond *isDone)
1367 FunctionCallInfoData fcinfo_data;
1368 FunctionCallInfo fcinfo;
1369 PgStat_FunctionCallUsage fcusage;
1370 ReturnSetInfo rsinfo; /* for functions returning sets */
1371 ExprDoneCond argDone;
1377 /* Guard against stack overflow due to overly complex expressions */
1378 check_stack_depth();
1381 * If a previous call of the function returned a set result in the form
1382 * of a tuplestore, continue reading rows from the tuplestore until it's
1385 if (fcache->funcResultStore)
1387 Assert(isDone); /* it was provided before ... */
1388 if (tuplestore_gettupleslot(fcache->funcResultStore, true, false,
1389 fcache->funcResultSlot))
1391 *isDone = ExprMultipleResult;
1392 if (fcache->funcReturnsTuple)
1394 /* We must return the whole tuple as a Datum. */
1396 return ExecFetchSlotTupleDatum(fcache->funcResultSlot);
1400 /* Extract the first column and return it as a scalar. */
1401 return slot_getattr(fcache->funcResultSlot, 1, isNull);
1404 /* Exhausted the tuplestore, so clean up */
1405 tuplestore_end(fcache->funcResultStore);
1406 fcache->funcResultStore = NULL;
1407 /* We are done unless there was a set-valued argument */
1408 if (!fcache->setHasSetArg)
1410 *isDone = ExprEndResult;
1414 /* If there was, continue evaluating the argument values */
1415 Assert(!fcache->setArgsValid);
1419 * For non-set-returning functions, we just use a local-variable
1420 * FunctionCallInfoData. For set-returning functions we keep the callinfo
1421 * record in fcache->setArgs so that it can survive across multiple
1422 * value-per-call invocations. (The reason we don't just do the latter
1423 * all the time is that plpgsql expects to be able to use simple expression
1424 * trees re-entrantly. Which might not be a good idea, but the penalty
1425 * for not doing so is high.)
1427 if (fcache->func.fn_retset)
1428 fcinfo = &fcache->setArgs;
1430 fcinfo = &fcinfo_data;
1433 * arguments is a list of expressions to evaluate before passing to the
1434 * function manager. We skip the evaluation if it was already done in the
1435 * previous call (ie, we are continuing the evaluation of a set-valued
1436 * function). Otherwise, collect the current argument values into fcinfo.
1438 arguments = fcache->args;
1439 if (!fcache->setArgsValid)
1441 /* Need to prep callinfo structure */
1442 InitFunctionCallInfoData(*fcinfo, &(fcache->func), 0, NULL, NULL);
1443 argDone = ExecEvalFuncArgs(fcinfo, arguments, econtext);
1444 if (argDone == ExprEndResult)
1446 /* input is an empty set, so return an empty set. */
1449 *isDone = ExprEndResult;
1452 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1453 errmsg("set-valued function called in context that cannot accept a set")));
1456 hasSetArg = (argDone != ExprSingleResult);
1460 /* Re-use callinfo from previous evaluation */
1461 hasSetArg = fcache->setHasSetArg;
1462 /* Reset flag (we may set it again below) */
1463 fcache->setArgsValid = false;
1467 * Now call the function, passing the evaluated parameter values.
1469 if (fcache->func.fn_retset || hasSetArg)
1472 * We need to return a set result. Complain if caller not ready to
1477 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1478 errmsg("set-valued function called in context that cannot accept a set")));
1481 * Prepare a resultinfo node for communication. If the function
1482 * doesn't itself return set, we don't pass the resultinfo to the
1483 * function, but we need to fill it in anyway for internal use.
1485 if (fcache->func.fn_retset)
1486 fcinfo->resultinfo = (Node *) &rsinfo;
1487 rsinfo.type = T_ReturnSetInfo;
1488 rsinfo.econtext = econtext;
1489 rsinfo.expectedDesc = fcache->funcResultDesc;
1490 rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
1491 /* note we do not set SFRM_Materialize_Random or _Preferred */
1492 rsinfo.returnMode = SFRM_ValuePerCall;
1493 /* isDone is filled below */
1494 rsinfo.setResult = NULL;
1495 rsinfo.setDesc = NULL;
1498 * This loop handles the situation where we have both a set argument
1499 * and a set-valued function. Once we have exhausted the function's
1500 * value(s) for a particular argument value, we have to get the next
1501 * argument value and start the function over again. We might have to
1502 * do it more than once, if the function produces an empty result set
1503 * for a particular input value.
1508 * If function is strict, and there are any NULL arguments, skip
1509 * calling the function (at least for this set of args).
1513 if (fcache->func.fn_strict)
1515 for (i = 0; i < fcinfo->nargs; i++)
1517 if (fcinfo->argnull[i])
1527 pgstat_init_function_usage(fcinfo, &fcusage);
1529 fcinfo->isnull = false;
1530 rsinfo.isDone = ExprSingleResult;
1531 result = FunctionCallInvoke(fcinfo);
1532 *isNull = fcinfo->isnull;
1533 *isDone = rsinfo.isDone;
1535 pgstat_end_function_usage(&fcusage,
1536 rsinfo.isDone != ExprMultipleResult);
1542 *isDone = ExprEndResult;
1545 /* Which protocol does function want to use? */
1546 if (rsinfo.returnMode == SFRM_ValuePerCall)
1548 if (*isDone != ExprEndResult)
1551 * Got a result from current argument. If function itself
1552 * returns set, save the current argument values to re-use
1555 if (fcache->func.fn_retset &&
1556 *isDone == ExprMultipleResult)
1558 Assert(fcinfo == &fcache->setArgs);
1559 fcache->setHasSetArg = hasSetArg;
1560 fcache->setArgsValid = true;
1561 /* Register cleanup callback if we didn't already */
1562 if (!fcache->shutdown_reg)
1564 RegisterExprContextCallback(econtext,
1566 PointerGetDatum(fcache));
1567 fcache->shutdown_reg = true;
1572 * Make sure we say we are returning a set, even if the
1573 * function itself doesn't return sets.
1576 *isDone = ExprMultipleResult;
1580 else if (rsinfo.returnMode == SFRM_Materialize)
1582 /* check we're on the same page as the function author */
1583 if (rsinfo.isDone != ExprSingleResult)
1585 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1586 errmsg("table-function protocol for materialize mode was not followed")));
1587 if (rsinfo.setResult != NULL)
1589 /* prepare to return values from the tuplestore */
1590 ExecPrepareTuplestoreResult(fcache, econtext,
1593 /* remember whether we had set arguments */
1594 fcache->setHasSetArg = hasSetArg;
1595 /* loop back to top to start returning from tuplestore */
1598 /* if setResult was left null, treat it as empty set */
1599 *isDone = ExprEndResult;
1605 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1606 errmsg("unrecognized table-function returnMode: %d",
1607 (int) rsinfo.returnMode)));
1609 /* Else, done with this argument */
1611 break; /* input not a set, so done */
1613 /* Re-eval args to get the next element of the input set */
1614 argDone = ExecEvalFuncArgs(fcinfo, arguments, econtext);
1616 if (argDone != ExprMultipleResult)
1618 /* End of argument set, so we're done. */
1620 *isDone = ExprEndResult;
1626 * If we reach here, loop around to run the function on the new
1634 * Non-set case: much easier.
1636 * We change the ExprState function pointer to use the simpler
1637 * ExecMakeFunctionResultNoSets on subsequent calls. This amounts to
1638 * assuming that no argument can return a set if it didn't do so the
1641 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResultNoSets;
1644 *isDone = ExprSingleResult;
1647 * If function is strict, and there are any NULL arguments, skip
1648 * calling the function and return NULL.
1650 if (fcache->func.fn_strict)
1652 for (i = 0; i < fcinfo->nargs; i++)
1654 if (fcinfo->argnull[i])
1662 pgstat_init_function_usage(fcinfo, &fcusage);
1664 fcinfo->isnull = false;
1665 result = FunctionCallInvoke(fcinfo);
1666 *isNull = fcinfo->isnull;
1668 pgstat_end_function_usage(&fcusage, true);
1675 * ExecMakeFunctionResultNoSets
1677 * Simplified version of ExecMakeFunctionResult that can only handle
1678 * non-set cases. Hand-tuned for speed.
1681 ExecMakeFunctionResultNoSets(FuncExprState *fcache,
1682 ExprContext *econtext,
1684 ExprDoneCond *isDone)
1688 FunctionCallInfoData fcinfo;
1689 PgStat_FunctionCallUsage fcusage;
1692 /* Guard against stack overflow due to overly complex expressions */
1693 check_stack_depth();
1696 *isDone = ExprSingleResult;
1698 /* inlined, simplified version of ExecEvalFuncArgs */
1700 foreach(arg, fcache->args)
1702 ExprState *argstate = (ExprState *) lfirst(arg);
1704 fcinfo.arg[i] = ExecEvalExpr(argstate,
1711 InitFunctionCallInfoData(fcinfo, &(fcache->func), i, NULL, NULL);
1714 * If function is strict, and there are any NULL arguments, skip calling
1715 * the function and return NULL.
1717 if (fcache->func.fn_strict)
1721 if (fcinfo.argnull[i])
1729 pgstat_init_function_usage(&fcinfo, &fcusage);
1731 /* fcinfo.isnull = false; */ /* handled by InitFunctionCallInfoData */
1732 result = FunctionCallInvoke(&fcinfo);
1733 *isNull = fcinfo.isnull;
1735 pgstat_end_function_usage(&fcusage, true);
1742 * ExecMakeTableFunctionResult
1744 * Evaluate a table function, producing a materialized result in a Tuplestore
1748 ExecMakeTableFunctionResult(ExprState *funcexpr,
1749 ExprContext *econtext,
1750 TupleDesc expectedDesc,
1753 Tuplestorestate *tupstore = NULL;
1754 TupleDesc tupdesc = NULL;
1757 bool returnsSet = false;
1758 FunctionCallInfoData fcinfo;
1759 PgStat_FunctionCallUsage fcusage;
1760 ReturnSetInfo rsinfo;
1761 HeapTupleData tmptup;
1762 MemoryContext callerContext;
1763 MemoryContext oldcontext;
1764 bool direct_function_call;
1765 bool first_time = true;
1767 callerContext = CurrentMemoryContext;
1769 funcrettype = exprType((Node *) funcexpr->expr);
1771 returnsTuple = type_is_rowtype(funcrettype);
1774 * Prepare a resultinfo node for communication. We always do this even if
1775 * not expecting a set result, so that we can pass expectedDesc. In the
1776 * generic-expression case, the expression doesn't actually get to see the
1777 * resultinfo, but set it up anyway because we use some of the fields as
1778 * our own state variables.
1780 InitFunctionCallInfoData(fcinfo, NULL, 0, NULL, (Node *) &rsinfo);
1781 rsinfo.type = T_ReturnSetInfo;
1782 rsinfo.econtext = econtext;
1783 rsinfo.expectedDesc = expectedDesc;
1784 rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize | SFRM_Materialize_Preferred);
1786 rsinfo.allowedModes |= (int) SFRM_Materialize_Random;
1787 rsinfo.returnMode = SFRM_ValuePerCall;
1788 /* isDone is filled below */
1789 rsinfo.setResult = NULL;
1790 rsinfo.setDesc = NULL;
1793 * Normally the passed expression tree will be a FuncExprState, since the
1794 * grammar only allows a function call at the top level of a table
1795 * function reference. However, if the function doesn't return set then
1796 * the planner might have replaced the function call via constant-folding
1797 * or inlining. So if we see any other kind of expression node, execute
1798 * it via the general ExecEvalExpr() code; the only difference is that we
1799 * don't get a chance to pass a special ReturnSetInfo to any functions
1800 * buried in the expression.
1802 if (funcexpr && IsA(funcexpr, FuncExprState) &&
1803 IsA(funcexpr->expr, FuncExpr))
1805 FuncExprState *fcache = (FuncExprState *) funcexpr;
1806 ExprDoneCond argDone;
1809 * This path is similar to ExecMakeFunctionResult.
1811 direct_function_call = true;
1814 * Initialize function cache if first time through
1816 if (fcache->func.fn_oid == InvalidOid)
1818 FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
1820 init_fcache(func->funcid, fcache,
1821 econtext->ecxt_per_query_memory, false);
1823 returnsSet = fcache->func.fn_retset;
1826 * Evaluate the function's argument list.
1828 * Note: ideally, we'd do this in the per-tuple context, but then the
1829 * argument values would disappear when we reset the context in the
1830 * inner loop. So do it in caller context. Perhaps we should make a
1831 * separate context just to hold the evaluated arguments?
1833 fcinfo.flinfo = &(fcache->func);
1834 argDone = ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
1835 /* We don't allow sets in the arguments of the table function */
1836 if (argDone != ExprSingleResult)
1838 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1839 errmsg("set-valued function called in context that cannot accept a set")));
1842 * If function is strict, and there are any NULL arguments, skip
1843 * calling the function and act like it returned NULL (or an empty
1844 * set, in the returns-set case).
1846 if (fcache->func.fn_strict)
1850 for (i = 0; i < fcinfo.nargs; i++)
1852 if (fcinfo.argnull[i])
1853 goto no_function_result;
1859 /* Treat funcexpr as a generic expression */
1860 direct_function_call = false;
1864 * Switch to short-lived context for calling the function or expression.
1866 MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1869 * Loop to handle the ValuePerCall protocol (which is also the same
1870 * behavior needed in the generic ExecEvalExpr path).
1876 CHECK_FOR_INTERRUPTS();
1879 * reset per-tuple memory context before each call of the function or
1880 * expression. This cleans up any local memory the function may leak
1883 ResetExprContext(econtext);
1885 /* Call the function or expression one time */
1886 if (direct_function_call)
1888 pgstat_init_function_usage(&fcinfo, &fcusage);
1890 fcinfo.isnull = false;
1891 rsinfo.isDone = ExprSingleResult;
1892 result = FunctionCallInvoke(&fcinfo);
1894 pgstat_end_function_usage(&fcusage,
1895 rsinfo.isDone != ExprMultipleResult);
1899 result = ExecEvalExpr(funcexpr, econtext,
1900 &fcinfo.isnull, &rsinfo.isDone);
1903 /* Which protocol does function want to use? */
1904 if (rsinfo.returnMode == SFRM_ValuePerCall)
1907 * Check for end of result set.
1909 if (rsinfo.isDone == ExprEndResult)
1913 * Can't do anything very useful with NULL rowtype values. For a
1914 * function returning set, we consider this a protocol violation
1915 * (but another alternative would be to just ignore the result and
1916 * "continue" to get another row). For a function not returning
1917 * set, we fall out of the loop; we'll cons up an all-nulls result
1920 if (returnsTuple && fcinfo.isnull)
1925 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1926 errmsg("function returning set of rows cannot return null value")));
1930 * If first time through, build tupdesc and tuplestore for result
1934 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1938 * Use the type info embedded in the rowtype Datum to look
1939 * up the needed tupdesc. Make a copy for the query.
1943 td = DatumGetHeapTupleHeader(result);
1944 tupdesc = lookup_rowtype_tupdesc_copy(HeapTupleHeaderGetTypeId(td),
1945 HeapTupleHeaderGetTypMod(td));
1950 * Scalar type, so make a single-column descriptor
1952 tupdesc = CreateTemplateTupleDesc(1, false);
1953 TupleDescInitEntry(tupdesc,
1960 tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
1961 MemoryContextSwitchTo(oldcontext);
1962 rsinfo.setResult = tupstore;
1963 rsinfo.setDesc = tupdesc;
1967 * Store current resultset item.
1973 td = DatumGetHeapTupleHeader(result);
1976 * tuplestore_puttuple needs a HeapTuple not a bare
1977 * HeapTupleHeader, but it doesn't need all the fields.
1979 tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
1982 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1983 tuplestore_puttuple(tupstore, &tmptup);
1987 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1988 tuplestore_putvalues(tupstore, tupdesc, &result, &fcinfo.isnull);
1990 MemoryContextSwitchTo(oldcontext);
1995 if (rsinfo.isDone != ExprMultipleResult)
1998 else if (rsinfo.returnMode == SFRM_Materialize)
2000 /* check we're on the same page as the function author */
2001 if (!first_time || rsinfo.isDone != ExprSingleResult)
2003 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
2004 errmsg("table-function protocol for materialize mode was not followed")));
2005 /* Done evaluating the set result */
2010 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
2011 errmsg("unrecognized table-function returnMode: %d",
2012 (int) rsinfo.returnMode)));
2020 * If we got nothing from the function (ie, an empty-set or NULL result),
2021 * we have to create the tuplestore to return, and if it's a
2022 * non-set-returning function then insert a single all-nulls row.
2024 if (rsinfo.setResult == NULL)
2026 MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2027 tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
2028 rsinfo.setResult = tupstore;
2031 int natts = expectedDesc->natts;
2035 MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
2036 nulldatums = (Datum *) palloc0(natts * sizeof(Datum));
2037 nullflags = (bool *) palloc(natts * sizeof(bool));
2038 memset(nullflags, true, natts * sizeof(bool));
2039 MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2040 tuplestore_putvalues(tupstore, expectedDesc, nulldatums, nullflags);
2045 * If function provided a tupdesc, cross-check it. We only really
2046 * need to do this for functions returning RECORD, but might as well
2051 tupledesc_match(expectedDesc, rsinfo.setDesc);
2054 * If it is a dynamically-allocated TupleDesc, free it: it is
2055 * typically allocated in a per-query context, so we must avoid
2056 * leaking it across multiple usages.
2058 if (rsinfo.setDesc->tdrefcount == -1)
2059 FreeTupleDesc(rsinfo.setDesc);
2062 MemoryContextSwitchTo(callerContext);
2064 /* All done, pass back the tuplestore */
2065 return rsinfo.setResult;
2069 /* ----------------------------------------------------------------
2073 * Evaluate the functional result of a list of arguments by calling the
2075 * ----------------------------------------------------------------
2078 /* ----------------------------------------------------------------
2080 * ----------------------------------------------------------------
2083 ExecEvalFunc(FuncExprState *fcache,
2084 ExprContext *econtext,
2086 ExprDoneCond *isDone)
2088 /* This is called only the first time through */
2089 FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
2091 /* Initialize function lookup info */
2092 init_fcache(func->funcid, fcache, econtext->ecxt_per_query_memory, true);
2094 /* Go directly to ExecMakeFunctionResult on subsequent uses */
2095 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
2097 return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
2100 /* ----------------------------------------------------------------
2102 * ----------------------------------------------------------------
2105 ExecEvalOper(FuncExprState *fcache,
2106 ExprContext *econtext,
2108 ExprDoneCond *isDone)
2110 /* This is called only the first time through */
2111 OpExpr *op = (OpExpr *) fcache->xprstate.expr;
2113 /* Initialize function lookup info */
2114 init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory, true);
2116 /* Go directly to ExecMakeFunctionResult on subsequent uses */
2117 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
2119 return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
2122 /* ----------------------------------------------------------------
2125 * IS DISTINCT FROM must evaluate arguments to determine whether
2126 * they are NULL; if either is NULL then the result is already
2127 * known. If neither is NULL, then proceed to evaluate the
2128 * function. Note that this is *always* derived from the equals
2129 * operator, but since we need special processing of the arguments
2130 * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
2131 * ----------------------------------------------------------------
2134 ExecEvalDistinct(FuncExprState *fcache,
2135 ExprContext *econtext,
2137 ExprDoneCond *isDone)
2140 FunctionCallInfoData fcinfo;
2141 ExprDoneCond argDone;
2144 /* Set default values for result flags: non-null, not a set result */
2147 *isDone = ExprSingleResult;
2150 * Initialize function cache if first time through
2152 if (fcache->func.fn_oid == InvalidOid)
2154 DistinctExpr *op = (DistinctExpr *) fcache->xprstate.expr;
2156 init_fcache(op->opfuncid, fcache,
2157 econtext->ecxt_per_query_memory, true);
2158 Assert(!fcache->func.fn_retset);
2162 * extract info from fcache
2164 argList = fcache->args;
2166 /* Need to prep callinfo structure */
2167 InitFunctionCallInfoData(fcinfo, &(fcache->func), 0, NULL, NULL);
2168 argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
2169 if (argDone != ExprSingleResult)
2171 (errcode(ERRCODE_DATATYPE_MISMATCH),
2172 errmsg("IS DISTINCT FROM does not support set arguments")));
2173 Assert(fcinfo.nargs == 2);
2175 if (fcinfo.argnull[0] && fcinfo.argnull[1])
2177 /* Both NULL? Then is not distinct... */
2178 result = BoolGetDatum(FALSE);
2180 else if (fcinfo.argnull[0] || fcinfo.argnull[1])
2182 /* Only one is NULL? Then is distinct... */
2183 result = BoolGetDatum(TRUE);
2187 fcinfo.isnull = false;
2188 result = FunctionCallInvoke(&fcinfo);
2189 *isNull = fcinfo.isnull;
2190 /* Must invert result of "=" */
2191 result = BoolGetDatum(!DatumGetBool(result));
2198 * ExecEvalScalarArrayOp
2200 * Evaluate "scalar op ANY/ALL (array)". The operator always yields boolean,
2201 * and we combine the results across all array elements using OR and AND
2202 * (for ANY and ALL respectively). Of course we short-circuit as soon as
2203 * the result is known.
2206 ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
2207 ExprContext *econtext,
2208 bool *isNull, ExprDoneCond *isDone)
2210 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) sstate->fxprstate.xprstate.expr;
2211 bool useOr = opexpr->useOr;
2216 FunctionCallInfoData fcinfo;
2217 ExprDoneCond argDone;
2226 /* Set default values for result flags: non-null, not a set result */
2229 *isDone = ExprSingleResult;
2232 * Initialize function cache if first time through
2234 if (sstate->fxprstate.func.fn_oid == InvalidOid)
2236 init_fcache(opexpr->opfuncid, &sstate->fxprstate,
2237 econtext->ecxt_per_query_memory, true);
2238 Assert(!sstate->fxprstate.func.fn_retset);
2241 /* Need to prep callinfo structure */
2242 InitFunctionCallInfoData(fcinfo, &(sstate->fxprstate.func), 0, NULL, NULL);
2243 argDone = ExecEvalFuncArgs(&fcinfo, sstate->fxprstate.args, econtext);
2244 if (argDone != ExprSingleResult)
2246 (errcode(ERRCODE_DATATYPE_MISMATCH),
2247 errmsg("op ANY/ALL (array) does not support set arguments")));
2248 Assert(fcinfo.nargs == 2);
2251 * If the array is NULL then we return NULL --- it's not very meaningful
2252 * to do anything else, even if the operator isn't strict.
2254 if (fcinfo.argnull[1])
2259 /* Else okay to fetch and detoast the array */
2260 arr = DatumGetArrayTypeP(fcinfo.arg[1]);
2263 * If the array is empty, we return either FALSE or TRUE per the useOr
2264 * flag. This is correct even if the scalar is NULL; since we would
2265 * evaluate the operator zero times, it matters not whether it would want
2268 nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
2270 return BoolGetDatum(!useOr);
2273 * If the scalar is NULL, and the function is strict, return NULL; no
2274 * point in iterating the loop.
2276 if (fcinfo.argnull[0] && sstate->fxprstate.func.fn_strict)
2283 * We arrange to look up info about the element type only once per series
2284 * of calls, assuming the element type doesn't change underneath us.
2286 if (sstate->element_type != ARR_ELEMTYPE(arr))
2288 get_typlenbyvalalign(ARR_ELEMTYPE(arr),
2292 sstate->element_type = ARR_ELEMTYPE(arr);
2294 typlen = sstate->typlen;
2295 typbyval = sstate->typbyval;
2296 typalign = sstate->typalign;
2298 result = BoolGetDatum(!useOr);
2301 /* Loop over the array elements */
2302 s = (char *) ARR_DATA_PTR(arr);
2303 bitmap = ARR_NULLBITMAP(arr);
2306 for (i = 0; i < nitems; i++)
2311 /* Get array element, checking for NULL */
2312 if (bitmap && (*bitmap & bitmask) == 0)
2314 fcinfo.arg[1] = (Datum) 0;
2315 fcinfo.argnull[1] = true;
2319 elt = fetch_att(s, typbyval, typlen);
2320 s = att_addlength_pointer(s, typlen, s);
2321 s = (char *) att_align_nominal(s, typalign);
2322 fcinfo.arg[1] = elt;
2323 fcinfo.argnull[1] = false;
2326 /* Call comparison function */
2327 if (fcinfo.argnull[1] && sstate->fxprstate.func.fn_strict)
2329 fcinfo.isnull = true;
2330 thisresult = (Datum) 0;
2334 fcinfo.isnull = false;
2335 thisresult = FunctionCallInvoke(&fcinfo);
2338 /* Combine results per OR or AND semantics */
2343 if (DatumGetBool(thisresult))
2345 result = BoolGetDatum(true);
2347 break; /* needn't look at any more elements */
2352 if (!DatumGetBool(thisresult))
2354 result = BoolGetDatum(false);
2356 break; /* needn't look at any more elements */
2360 /* advance bitmap pointer if any */
2364 if (bitmask == 0x100)
2372 *isNull = resultnull;
2376 /* ----------------------------------------------------------------
2381 * Evaluate boolean expressions, with appropriate short-circuiting.
2383 * The query planner reformulates clause expressions in the
2384 * qualification to conjunctive normal form. If we ever get
2385 * an AND to evaluate, we can be sure that it's not a top-level
2386 * clause in the qualification, but appears lower (as a function
2387 * argument, for example), or in the target list. Not that you
2388 * need to know this, mind you...
2389 * ----------------------------------------------------------------
2392 ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
2393 bool *isNull, ExprDoneCond *isDone)
2395 ExprState *clause = linitial(notclause->args);
2399 *isDone = ExprSingleResult;
2401 expr_value = ExecEvalExpr(clause, econtext, isNull, NULL);
2404 * if the expression evaluates to null, then we just cascade the null back
2405 * to whoever called us.
2411 * evaluation of 'not' is simple.. expr is false, then return 'true' and
2414 return BoolGetDatum(!DatumGetBool(expr_value));
2417 /* ----------------------------------------------------------------
2419 * ----------------------------------------------------------------
2422 ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
2423 bool *isNull, ExprDoneCond *isDone)
2425 List *clauses = orExpr->args;
2430 *isDone = ExprSingleResult;
2435 * If any of the clauses is TRUE, the OR result is TRUE regardless of the
2436 * states of the rest of the clauses, so we can stop evaluating and return
2437 * TRUE immediately. If none are TRUE and one or more is NULL, we return
2438 * NULL; otherwise we return FALSE. This makes sense when you interpret
2439 * NULL as "don't know": if we have a TRUE then the OR is TRUE even if we
2440 * aren't sure about some of the other inputs. If all the known inputs are
2441 * FALSE, but we have one or more "don't knows", then we have to report
2442 * that we "don't know" what the OR's result should be --- perhaps one of
2443 * the "don't knows" would have been TRUE if we'd known its value. Only
2444 * when all the inputs are known to be FALSE can we state confidently that
2445 * the OR's result is FALSE.
2447 foreach(clause, clauses)
2449 ExprState *clausestate = (ExprState *) lfirst(clause);
2452 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
2455 * if we have a non-null true result, then return it.
2458 AnyNull = true; /* remember we got a null */
2459 else if (DatumGetBool(clause_value))
2460 return clause_value;
2463 /* AnyNull is true if at least one clause evaluated to NULL */
2465 return BoolGetDatum(false);
2468 /* ----------------------------------------------------------------
2470 * ----------------------------------------------------------------
2473 ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
2474 bool *isNull, ExprDoneCond *isDone)
2476 List *clauses = andExpr->args;
2481 *isDone = ExprSingleResult;
2486 * If any of the clauses is FALSE, the AND result is FALSE regardless of
2487 * the states of the rest of the clauses, so we can stop evaluating and
2488 * return FALSE immediately. If none are FALSE and one or more is NULL,
2489 * we return NULL; otherwise we return TRUE. This makes sense when you
2490 * interpret NULL as "don't know", using the same sort of reasoning as for
2494 foreach(clause, clauses)
2496 ExprState *clausestate = (ExprState *) lfirst(clause);
2499 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
2502 * if we have a non-null false result, then return it.
2505 AnyNull = true; /* remember we got a null */
2506 else if (!DatumGetBool(clause_value))
2507 return clause_value;
2510 /* AnyNull is true if at least one clause evaluated to NULL */
2512 return BoolGetDatum(!AnyNull);
2515 /* ----------------------------------------------------------------
2516 * ExecEvalConvertRowtype
2518 * Evaluate a rowtype coercion operation. This may require
2519 * rearranging field positions.
2520 * ----------------------------------------------------------------
2523 ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
2524 ExprContext *econtext,
2525 bool *isNull, ExprDoneCond *isDone)
2527 ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) cstate->xprstate.expr;
2530 HeapTupleHeader tuple;
2531 HeapTupleData tmptup;
2532 AttrNumber *attrMap;
2540 tupDatum = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
2542 /* this test covers the isDone exception too: */
2546 tuple = DatumGetHeapTupleHeader(tupDatum);
2548 /* Lookup tupdescs if first time through or after rescan */
2549 if (cstate->indesc == NULL)
2550 get_cached_rowtype(exprType((Node *) convert->arg), -1,
2551 &cstate->indesc, econtext);
2552 if (cstate->outdesc == NULL)
2553 get_cached_rowtype(convert->resulttype, -1,
2554 &cstate->outdesc, econtext);
2556 Assert(HeapTupleHeaderGetTypeId(tuple) == cstate->indesc->tdtypeid);
2557 Assert(HeapTupleHeaderGetTypMod(tuple) == cstate->indesc->tdtypmod);
2559 /* if first time through, initialize */
2560 if (cstate->attrMap == NULL)
2562 MemoryContext old_cxt;
2565 /* allocate state in long-lived memory context */
2566 old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2568 /* prepare map from old to new attribute numbers */
2569 n = cstate->outdesc->natts;
2570 cstate->attrMap = (AttrNumber *) palloc0(n * sizeof(AttrNumber));
2571 for (i = 0; i < n; i++)
2573 Form_pg_attribute att = cstate->outdesc->attrs[i];
2579 if (att->attisdropped)
2580 continue; /* attrMap[i] is already 0 */
2581 attname = NameStr(att->attname);
2582 atttypid = att->atttypid;
2583 atttypmod = att->atttypmod;
2584 for (j = 0; j < cstate->indesc->natts; j++)
2586 att = cstate->indesc->attrs[j];
2587 if (att->attisdropped)
2589 if (strcmp(attname, NameStr(att->attname)) == 0)
2591 /* Found it, check type */
2592 if (atttypid != att->atttypid || atttypmod != att->atttypmod)
2593 elog(ERROR, "attribute \"%s\" of type %s does not match corresponding attribute of type %s",
2595 format_type_be(cstate->indesc->tdtypeid),
2596 format_type_be(cstate->outdesc->tdtypeid));
2597 cstate->attrMap[i] = (AttrNumber) (j + 1);
2601 if (cstate->attrMap[i] == 0)
2602 elog(ERROR, "attribute \"%s\" of type %s does not exist",
2604 format_type_be(cstate->indesc->tdtypeid));
2606 /* preallocate workspace for Datum arrays */
2607 n = cstate->indesc->natts + 1; /* +1 for NULL */
2608 cstate->invalues = (Datum *) palloc(n * sizeof(Datum));
2609 cstate->inisnull = (bool *) palloc(n * sizeof(bool));
2610 n = cstate->outdesc->natts;
2611 cstate->outvalues = (Datum *) palloc(n * sizeof(Datum));
2612 cstate->outisnull = (bool *) palloc(n * sizeof(bool));
2614 MemoryContextSwitchTo(old_cxt);
2617 attrMap = cstate->attrMap;
2618 invalues = cstate->invalues;
2619 inisnull = cstate->inisnull;
2620 outvalues = cstate->outvalues;
2621 outisnull = cstate->outisnull;
2622 outnatts = cstate->outdesc->natts;
2625 * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader.
2627 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2628 tmptup.t_data = tuple;
2631 * Extract all the values of the old tuple, offsetting the arrays so that
2632 * invalues[0] is NULL and invalues[1] is the first source attribute; this
2633 * exactly matches the numbering convention in attrMap.
2635 heap_deform_tuple(&tmptup, cstate->indesc, invalues + 1, inisnull + 1);
2636 invalues[0] = (Datum) 0;
2640 * Transpose into proper fields of the new tuple.
2642 for (i = 0; i < outnatts; i++)
2646 outvalues[i] = invalues[j];
2647 outisnull[i] = inisnull[j];
2651 * Now form the new tuple.
2653 result = heap_form_tuple(cstate->outdesc, outvalues, outisnull);
2655 return HeapTupleGetDatum(result);
2658 /* ----------------------------------------------------------------
2661 * Evaluate a CASE clause. Will have boolean expressions
2662 * inside the WHEN clauses, and will have expressions
2664 * - thomas 1998-11-09
2665 * ----------------------------------------------------------------
2668 ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
2669 bool *isNull, ExprDoneCond *isDone)
2671 List *clauses = caseExpr->args;
2677 *isDone = ExprSingleResult;
2680 * If there's a test expression, we have to evaluate it and save the value
2681 * where the CaseTestExpr placeholders can find it. We must save and
2682 * restore prior setting of econtext's caseValue fields, in case this node
2683 * is itself within a larger CASE.
2685 save_datum = econtext->caseValue_datum;
2686 save_isNull = econtext->caseValue_isNull;
2690 econtext->caseValue_datum = ExecEvalExpr(caseExpr->arg,
2692 &econtext->caseValue_isNull,
2697 * we evaluate each of the WHEN clauses in turn, as soon as one is true we
2698 * return the corresponding result. If none are true then we return the
2699 * value of the default clause, or NULL if there is none.
2701 foreach(clause, clauses)
2703 CaseWhenState *wclause = lfirst(clause);
2706 clause_value = ExecEvalExpr(wclause->expr,
2712 * if we have a true test, then we return the result, since the case
2713 * statement is satisfied. A NULL result from the test is not
2716 if (DatumGetBool(clause_value) && !*isNull)
2718 econtext->caseValue_datum = save_datum;
2719 econtext->caseValue_isNull = save_isNull;
2720 return ExecEvalExpr(wclause->result,
2727 econtext->caseValue_datum = save_datum;
2728 econtext->caseValue_isNull = save_isNull;
2730 if (caseExpr->defresult)
2732 return ExecEvalExpr(caseExpr->defresult,
2743 * ExecEvalCaseTestExpr
2745 * Return the value stored by CASE.
2748 ExecEvalCaseTestExpr(ExprState *exprstate,
2749 ExprContext *econtext,
2750 bool *isNull, ExprDoneCond *isDone)
2753 *isDone = ExprSingleResult;
2754 *isNull = econtext->caseValue_isNull;
2755 return econtext->caseValue_datum;
2758 /* ----------------------------------------------------------------
2759 * ExecEvalArray - ARRAY[] expressions
2760 * ----------------------------------------------------------------
2763 ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
2764 bool *isNull, ExprDoneCond *isDone)
2766 ArrayExpr *arrayExpr = (ArrayExpr *) astate->xprstate.expr;
2769 Oid element_type = arrayExpr->element_typeid;
2774 /* Set default values for result flags: non-null, not a set result */
2777 *isDone = ExprSingleResult;
2779 if (!arrayExpr->multidims)
2781 /* Elements are presumably of scalar type */
2788 nelems = list_length(astate->elements);
2790 /* Shouldn't happen here, but if length is 0, return empty array */
2792 return PointerGetDatum(construct_empty_array(element_type));
2794 dvalues = (Datum *) palloc(nelems * sizeof(Datum));
2795 dnulls = (bool *) palloc(nelems * sizeof(bool));
2797 /* loop through and build array of datums */
2798 foreach(element, astate->elements)
2800 ExprState *e = (ExprState *) lfirst(element);
2802 dvalues[i] = ExecEvalExpr(e, econtext, &dnulls[i], NULL);
2806 /* setup for 1-D array of the given length */
2810 result = construct_md_array(dvalues, dnulls, ndims, dims, lbs,
2818 /* Must be nested array expressions */
2821 int outer_nelems = 0;
2823 int *elem_dims = NULL;
2824 int *elem_lbs = NULL;
2825 bool firstone = true;
2826 bool havenulls = false;
2827 bool haveempty = false;
2837 i = list_length(astate->elements);
2838 subdata = (char **) palloc(i * sizeof(char *));
2839 subbitmaps = (bits8 **) palloc(i * sizeof(bits8 *));
2840 subbytes = (int *) palloc(i * sizeof(int));
2841 subnitems = (int *) palloc(i * sizeof(int));
2843 /* loop through and get data area from each element */
2844 foreach(element, astate->elements)
2846 ExprState *e = (ExprState *) lfirst(element);
2852 arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
2853 /* temporarily ignore null subarrays */
2860 array = DatumGetArrayTypeP(arraydatum);
2862 /* run-time double-check on element type */
2863 if (element_type != ARR_ELEMTYPE(array))
2865 (errcode(ERRCODE_DATATYPE_MISMATCH),
2866 errmsg("cannot merge incompatible arrays"),
2867 errdetail("Array with element type %s cannot be "
2868 "included in ARRAY construct with element type %s.",
2869 format_type_be(ARR_ELEMTYPE(array)),
2870 format_type_be(element_type))));
2872 this_ndims = ARR_NDIM(array);
2873 /* temporarily ignore zero-dimensional subarrays */
2874 if (this_ndims <= 0)
2882 /* Get sub-array details from first member */
2883 elem_ndims = this_ndims;
2884 ndims = elem_ndims + 1;
2885 if (ndims <= 0 || ndims > MAXDIM)
2887 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2888 errmsg("number of array dimensions (%d) exceeds " \
2889 "the maximum allowed (%d)", ndims, MAXDIM)));
2891 elem_dims = (int *) palloc(elem_ndims * sizeof(int));
2892 memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
2893 elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
2894 memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
2900 /* Check other sub-arrays are compatible */
2901 if (elem_ndims != this_ndims ||
2902 memcmp(elem_dims, ARR_DIMS(array),
2903 elem_ndims * sizeof(int)) != 0 ||
2904 memcmp(elem_lbs, ARR_LBOUND(array),
2905 elem_ndims * sizeof(int)) != 0)
2907 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2908 errmsg("multidimensional arrays must have array "
2909 "expressions with matching dimensions")));
2912 subdata[outer_nelems] = ARR_DATA_PTR(array);
2913 subbitmaps[outer_nelems] = ARR_NULLBITMAP(array);
2914 subbytes[outer_nelems] = ARR_SIZE(array) - ARR_DATA_OFFSET(array);
2915 nbytes += subbytes[outer_nelems];
2916 subnitems[outer_nelems] = ArrayGetNItems(this_ndims,
2918 nitems += subnitems[outer_nelems];
2919 havenulls |= ARR_HASNULL(array);
2924 * If all items were null or empty arrays, return an empty array;
2925 * otherwise, if some were and some weren't, raise error. (Note: we
2926 * must special-case this somehow to avoid trying to generate a 1-D
2927 * array formed from empty arrays. It's not ideal...)
2931 if (ndims == 0) /* didn't find any nonempty array */
2932 return PointerGetDatum(construct_empty_array(element_type));
2934 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2935 errmsg("multidimensional arrays must have array "
2936 "expressions with matching dimensions")));
2939 /* setup for multi-D array */
2940 dims[0] = outer_nelems;
2942 for (i = 1; i < ndims; i++)
2944 dims[i] = elem_dims[i - 1];
2945 lbs[i] = elem_lbs[i - 1];
2950 dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nitems);
2951 nbytes += dataoffset;
2955 dataoffset = 0; /* marker for no null bitmap */
2956 nbytes += ARR_OVERHEAD_NONULLS(ndims);
2959 result = (ArrayType *) palloc(nbytes);
2960 SET_VARSIZE(result, nbytes);
2961 result->ndim = ndims;
2962 result->dataoffset = dataoffset;
2963 result->elemtype = element_type;
2964 memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
2965 memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
2967 dat = ARR_DATA_PTR(result);
2969 for (i = 0; i < outer_nelems; i++)
2971 memcpy(dat, subdata[i], subbytes[i]);
2974 array_bitmap_copy(ARR_NULLBITMAP(result), iitem,
2977 iitem += subnitems[i];
2981 return PointerGetDatum(result);
2984 /* ----------------------------------------------------------------
2985 * ExecEvalRow - ROW() expressions
2986 * ----------------------------------------------------------------
2989 ExecEvalRow(RowExprState *rstate,
2990 ExprContext *econtext,
2991 bool *isNull, ExprDoneCond *isDone)
3000 /* Set default values for result flags: non-null, not a set result */
3003 *isDone = ExprSingleResult;
3005 /* Allocate workspace */
3006 natts = rstate->tupdesc->natts;
3007 values = (Datum *) palloc0(natts * sizeof(Datum));
3008 isnull = (bool *) palloc(natts * sizeof(bool));
3010 /* preset to nulls in case rowtype has some later-added columns */
3011 memset(isnull, true, natts * sizeof(bool));
3013 /* Evaluate field values */
3015 foreach(arg, rstate->args)
3017 ExprState *e = (ExprState *) lfirst(arg);
3019 values[i] = ExecEvalExpr(e, econtext, &isnull[i], NULL);
3023 tuple = heap_form_tuple(rstate->tupdesc, values, isnull);
3028 return HeapTupleGetDatum(tuple);
3031 /* ----------------------------------------------------------------
3032 * ExecEvalRowCompare - ROW() comparison-op ROW()
3033 * ----------------------------------------------------------------
3036 ExecEvalRowCompare(RowCompareExprState *rstate,
3037 ExprContext *econtext,
3038 bool *isNull, ExprDoneCond *isDone)
3041 RowCompareType rctype = ((RowCompareExpr *) rstate->xprstate.expr)->rctype;
3042 int32 cmpresult = 0;
3048 *isDone = ExprSingleResult;
3049 *isNull = true; /* until we get a result */
3052 forboth(l, rstate->largs, r, rstate->rargs)
3054 ExprState *le = (ExprState *) lfirst(l);
3055 ExprState *re = (ExprState *) lfirst(r);
3056 FunctionCallInfoData locfcinfo;
3058 InitFunctionCallInfoData(locfcinfo, &(rstate->funcs[i]), 2,
3060 locfcinfo.arg[0] = ExecEvalExpr(le, econtext,
3061 &locfcinfo.argnull[0], NULL);
3062 locfcinfo.arg[1] = ExecEvalExpr(re, econtext,
3063 &locfcinfo.argnull[1], NULL);
3064 if (rstate->funcs[i].fn_strict &&
3065 (locfcinfo.argnull[0] || locfcinfo.argnull[1]))
3066 return (Datum) 0; /* force NULL result */
3067 locfcinfo.isnull = false;
3068 cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
3069 if (locfcinfo.isnull)
3070 return (Datum) 0; /* force NULL result */
3072 break; /* no need to compare remaining columns */
3078 /* EQ and NE cases aren't allowed here */
3080 result = (cmpresult < 0);
3083 result = (cmpresult <= 0);
3086 result = (cmpresult >= 0);
3089 result = (cmpresult > 0);
3092 elog(ERROR, "unrecognized RowCompareType: %d", (int) rctype);
3093 result = 0; /* keep compiler quiet */
3098 return BoolGetDatum(result);
3101 /* ----------------------------------------------------------------
3103 * ----------------------------------------------------------------
3106 ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
3107 bool *isNull, ExprDoneCond *isDone)
3112 *isDone = ExprSingleResult;
3114 /* Simply loop through until something NOT NULL is found */
3115 foreach(arg, coalesceExpr->args)
3117 ExprState *e = (ExprState *) lfirst(arg);
3120 value = ExecEvalExpr(e, econtext, isNull, NULL);
3125 /* Else return NULL */
3130 /* ----------------------------------------------------------------
3132 * ----------------------------------------------------------------
3135 ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
3136 bool *isNull, ExprDoneCond *isDone)
3138 Datum result = (Datum) 0;
3139 MinMaxOp op = ((MinMaxExpr *) minmaxExpr->xprstate.expr)->op;
3140 FunctionCallInfoData locfcinfo;
3144 *isDone = ExprSingleResult;
3145 *isNull = true; /* until we get a result */
3147 InitFunctionCallInfoData(locfcinfo, &minmaxExpr->cfunc, 2, NULL, NULL);
3148 locfcinfo.argnull[0] = false;
3149 locfcinfo.argnull[1] = false;
3151 foreach(arg, minmaxExpr->args)
3153 ExprState *e = (ExprState *) lfirst(arg);
3158 value = ExecEvalExpr(e, econtext, &valueIsNull, NULL);
3160 continue; /* ignore NULL inputs */
3164 /* first nonnull input, adopt value */
3170 /* apply comparison function */
3171 locfcinfo.arg[0] = result;
3172 locfcinfo.arg[1] = value;
3173 locfcinfo.isnull = false;
3174 cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
3175 if (locfcinfo.isnull) /* probably should not happen */
3177 if (cmpresult > 0 && op == IS_LEAST)
3179 else if (cmpresult < 0 && op == IS_GREATEST)
3187 /* ----------------------------------------------------------------
3189 * ----------------------------------------------------------------
3192 ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
3193 bool *isNull, ExprDoneCond *isDone)
3195 XmlExpr *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
3202 *isDone = ExprSingleResult;
3203 *isNull = true; /* until we get a result */
3211 foreach(arg, xmlExpr->args)
3213 ExprState *e = (ExprState *) lfirst(arg);
3215 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3217 values = lappend(values, DatumGetPointer(value));
3220 if (list_length(values) > 0)
3223 return PointerGetDatum(xmlconcat(values));
3234 initStringInfo(&buf);
3235 forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
3237 ExprState *e = (ExprState *) lfirst(arg);
3238 char *argname = strVal(lfirst(narg));
3240 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3243 appendStringInfo(&buf, "<%s>%s</%s>",
3245 map_sql_value_to_xml_value(value, exprType((Node *) e->expr)),
3260 result = cstring_to_text_with_len(buf.data, buf.len);
3263 return PointerGetDatum(result);
3270 return PointerGetDatum(xmlelement(xmlExpr, econtext));
3277 bool preserve_whitespace;
3279 /* arguments are known to be text, bool */
3280 Assert(list_length(xmlExpr->args) == 2);
3282 e = (ExprState *) linitial(xmlExpr->args);
3283 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3286 data = DatumGetTextP(value);
3288 e = (ExprState *) lsecond(xmlExpr->args);
3289 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3290 if (isnull) /* probably can't happen */
3292 preserve_whitespace = DatumGetBool(value);
3296 return PointerGetDatum(xmlparse(data,
3298 preserve_whitespace));
3307 /* optional argument is known to be text */
3308 Assert(list_length(xmlExpr->args) <= 1);
3312 e = (ExprState *) linitial(xmlExpr->args);
3313 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3317 arg = DatumGetTextP(value);
3325 return PointerGetDatum(xmlpi(xexpr->name, arg, isnull, isNull));
3336 /* arguments are known to be xml, text, int */
3337 Assert(list_length(xmlExpr->args) == 3);
3339 e = (ExprState *) linitial(xmlExpr->args);
3340 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3343 data = DatumGetXmlP(value);
3345 e = (ExprState *) lsecond(xmlExpr->args);
3346 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3350 version = DatumGetTextP(value);
3352 e = (ExprState *) lthird(xmlExpr->args);
3353 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3354 standalone = DatumGetInt32(value);
3358 return PointerGetDatum(xmlroot(data,
3364 case IS_XMLSERIALIZE:
3368 /* argument type is known to be xml */
3369 Assert(list_length(xmlExpr->args) == 1);
3371 e = (ExprState *) linitial(xmlExpr->args);
3372 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3378 return PointerGetDatum(xmltotext_with_xmloption(DatumGetXmlP(value), xexpr->xmloption));
3386 /* optional argument is known to be xml */
3387 Assert(list_length(xmlExpr->args) == 1);
3389 e = (ExprState *) linitial(xmlExpr->args);
3390 value = ExecEvalExpr(e, econtext, &isnull, NULL);
3396 return BoolGetDatum(xml_is_document(DatumGetXmlP(value)));
3402 elog(ERROR, "unrecognized XML operation");
3406 /* ----------------------------------------------------------------
3409 * Note that this is *always* derived from the equals operator,
3410 * but since we need special processing of the arguments
3411 * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
3412 * ----------------------------------------------------------------
3415 ExecEvalNullIf(FuncExprState *nullIfExpr,
3416 ExprContext *econtext,
3417 bool *isNull, ExprDoneCond *isDone)
3420 FunctionCallInfoData fcinfo;
3421 ExprDoneCond argDone;
3425 *isDone = ExprSingleResult;
3428 * Initialize function cache if first time through
3430 if (nullIfExpr->func.fn_oid == InvalidOid)
3432 NullIfExpr *op = (NullIfExpr *) nullIfExpr->xprstate.expr;
3434 init_fcache(op->opfuncid, nullIfExpr,
3435 econtext->ecxt_per_query_memory, true);
3436 Assert(!nullIfExpr->func.fn_retset);
3440 * extract info from nullIfExpr
3442 argList = nullIfExpr->args;
3444 /* Need to prep callinfo structure */
3445 InitFunctionCallInfoData(fcinfo, &(nullIfExpr->func), 0, NULL, NULL);
3446 argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
3447 if (argDone != ExprSingleResult)
3449 (errcode(ERRCODE_DATATYPE_MISMATCH),
3450 errmsg("NULLIF does not support set arguments")));
3451 Assert(fcinfo.nargs == 2);
3453 /* if either argument is NULL they can't be equal */
3454 if (!fcinfo.argnull[0] && !fcinfo.argnull[1])
3456 fcinfo.isnull = false;
3457 result = FunctionCallInvoke(&fcinfo);
3458 /* if the arguments are equal return null */
3459 if (!fcinfo.isnull && DatumGetBool(result))
3466 /* else return first argument */
3467 *isNull = fcinfo.argnull[0];
3468 return fcinfo.arg[0];
3471 /* ----------------------------------------------------------------
3474 * Evaluate a NullTest node.
3475 * ----------------------------------------------------------------
3478 ExecEvalNullTest(NullTestState *nstate,
3479 ExprContext *econtext,
3481 ExprDoneCond *isDone)
3483 NullTest *ntest = (NullTest *) nstate->xprstate.expr;
3486 result = ExecEvalExpr(nstate->arg, econtext, isNull, isDone);
3488 if (isDone && *isDone == ExprEndResult)
3489 return result; /* nothing to check */
3491 if (nstate->argisrow && !(*isNull))
3493 HeapTupleHeader tuple;
3497 HeapTupleData tmptup;
3500 tuple = DatumGetHeapTupleHeader(result);
3502 tupType = HeapTupleHeaderGetTypeId(tuple);
3503 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3505 /* Lookup tupdesc if first time through or if type changes */
3506 tupDesc = get_cached_rowtype(tupType, tupTypmod,
3507 &nstate->argdesc, econtext);
3510 * heap_attisnull needs a HeapTuple not a bare HeapTupleHeader.
3512 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3513 tmptup.t_data = tuple;
3515 for (att = 1; att <= tupDesc->natts; att++)
3517 /* ignore dropped columns */
3518 if (tupDesc->attrs[att - 1]->attisdropped)
3520 if (heap_attisnull(&tmptup, att))
3522 /* null field disproves IS NOT NULL */
3523 if (ntest->nulltesttype == IS_NOT_NULL)
3524 return BoolGetDatum(false);
3528 /* non-null field disproves IS NULL */
3529 if (ntest->nulltesttype == IS_NULL)
3530 return BoolGetDatum(false);
3534 return BoolGetDatum(true);
3538 /* Simple scalar-argument case, or a null rowtype datum */
3539 switch (ntest->nulltesttype)
3545 return BoolGetDatum(true);
3548 return BoolGetDatum(false);
3553 return BoolGetDatum(false);
3556 return BoolGetDatum(true);
3558 elog(ERROR, "unrecognized nulltesttype: %d",
3559 (int) ntest->nulltesttype);
3560 return (Datum) 0; /* keep compiler quiet */
3565 /* ----------------------------------------------------------------
3566 * ExecEvalBooleanTest
3568 * Evaluate a BooleanTest node.
3569 * ----------------------------------------------------------------
3572 ExecEvalBooleanTest(GenericExprState *bstate,
3573 ExprContext *econtext,
3575 ExprDoneCond *isDone)
3577 BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;
3580 result = ExecEvalExpr(bstate->arg, econtext, isNull, isDone);
3582 if (isDone && *isDone == ExprEndResult)
3583 return result; /* nothing to check */
3585 switch (btest->booltesttype)
3591 return BoolGetDatum(false);
3593 else if (DatumGetBool(result))
3594 return BoolGetDatum(true);
3596 return BoolGetDatum(false);
3601 return BoolGetDatum(true);
3603 else if (DatumGetBool(result))
3604 return BoolGetDatum(false);
3606 return BoolGetDatum(true);
3611 return BoolGetDatum(false);
3613 else if (DatumGetBool(result))
3614 return BoolGetDatum(false);
3616 return BoolGetDatum(true);
3621 return BoolGetDatum(true);
3623 else if (DatumGetBool(result))
3624 return BoolGetDatum(true);
3626 return BoolGetDatum(false);
3631 return BoolGetDatum(true);
3634 return BoolGetDatum(false);
3635 case IS_NOT_UNKNOWN:
3639 return BoolGetDatum(false);
3642 return BoolGetDatum(true);
3644 elog(ERROR, "unrecognized booltesttype: %d",
3645 (int) btest->booltesttype);
3646 return (Datum) 0; /* keep compiler quiet */
3651 * ExecEvalCoerceToDomain
3653 * Test the provided data against the domain constraint(s). If the data
3654 * passes the constraint specifications, pass it through (return the
3655 * datum) otherwise throw an error.
3658 ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
3659 bool *isNull, ExprDoneCond *isDone)
3661 CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
3665 result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
3667 if (isDone && *isDone == ExprEndResult)
3668 return result; /* nothing to check */
3670 foreach(l, cstate->constraints)
3672 DomainConstraintState *con = (DomainConstraintState *) lfirst(l);
3674 switch (con->constrainttype)
3676 case DOM_CONSTRAINT_NOTNULL:
3679 (errcode(ERRCODE_NOT_NULL_VIOLATION),
3680 errmsg("domain %s does not allow null values",
3681 format_type_be(ctest->resulttype))));
3683 case DOM_CONSTRAINT_CHECK:
3691 * Set up value to be returned by CoerceToDomainValue
3692 * nodes. We must save and restore prior setting of
3693 * econtext's domainValue fields, in case this node is
3694 * itself within a check expression for another domain.
3696 save_datum = econtext->domainValue_datum;
3697 save_isNull = econtext->domainValue_isNull;
3699 econtext->domainValue_datum = result;
3700 econtext->domainValue_isNull = *isNull;
3702 conResult = ExecEvalExpr(con->check_expr,
3703 econtext, &conIsNull, NULL);
3706 !DatumGetBool(conResult))
3708 (errcode(ERRCODE_CHECK_VIOLATION),
3709 errmsg("value for domain %s violates check constraint \"%s\"",
3710 format_type_be(ctest->resulttype),
3712 econtext->domainValue_datum = save_datum;
3713 econtext->domainValue_isNull = save_isNull;
3718 elog(ERROR, "unrecognized constraint type: %d",
3719 (int) con->constrainttype);
3724 /* If all has gone well (constraints did not fail) return the datum */
3729 * ExecEvalCoerceToDomainValue
3731 * Return the value stored by CoerceToDomain.
3734 ExecEvalCoerceToDomainValue(ExprState *exprstate,
3735 ExprContext *econtext,
3736 bool *isNull, ExprDoneCond *isDone)
3739 *isDone = ExprSingleResult;
3740 *isNull = econtext->domainValue_isNull;
3741 return econtext->domainValue_datum;
3744 /* ----------------------------------------------------------------
3745 * ExecEvalFieldSelect
3747 * Evaluate a FieldSelect node.
3748 * ----------------------------------------------------------------
3751 ExecEvalFieldSelect(FieldSelectState *fstate,
3752 ExprContext *econtext,
3754 ExprDoneCond *isDone)
3756 FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
3757 AttrNumber fieldnum = fselect->fieldnum;
3760 HeapTupleHeader tuple;
3764 Form_pg_attribute attr;
3765 HeapTupleData tmptup;
3767 tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
3769 /* this test covers the isDone exception too: */
3773 tuple = DatumGetHeapTupleHeader(tupDatum);
3775 tupType = HeapTupleHeaderGetTypeId(tuple);
3776 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3778 /* Lookup tupdesc if first time through or if type changes */
3779 tupDesc = get_cached_rowtype(tupType, tupTypmod,
3780 &fstate->argdesc, econtext);
3782 /* Check for dropped column, and force a NULL result if so */
3783 if (fieldnum <= 0 ||
3784 fieldnum > tupDesc->natts) /* should never happen */
3785 elog(ERROR, "attribute number %d exceeds number of columns %d",
3786 fieldnum, tupDesc->natts);
3787 attr = tupDesc->attrs[fieldnum - 1];
3788 if (attr->attisdropped)
3794 /* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
3795 /* As in ExecEvalVar, we should but can't check typmod */
3796 if (fselect->resulttype != attr->atttypid)
3798 (errmsg("attribute %d has wrong type", fieldnum),
3799 errdetail("Table has type %s, but query expects %s.",
3800 format_type_be(attr->atttypid),
3801 format_type_be(fselect->resulttype))));
3804 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
3805 * the fields in the struct just in case user tries to inspect system
3808 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3809 ItemPointerSetInvalid(&(tmptup.t_self));
3810 tmptup.t_tableOid = InvalidOid;
3811 tmptup.t_data = tuple;
3813 result = heap_getattr(&tmptup,
3820 /* ----------------------------------------------------------------
3821 * ExecEvalFieldStore
3823 * Evaluate a FieldStore node.
3824 * ----------------------------------------------------------------
3827 ExecEvalFieldStore(FieldStoreState *fstate,
3828 ExprContext *econtext,
3830 ExprDoneCond *isDone)
3832 FieldStore *fstore = (FieldStore *) fstate->xprstate.expr;
3843 tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
3845 if (isDone && *isDone == ExprEndResult)
3848 /* Lookup tupdesc if first time through or after rescan */
3849 tupDesc = get_cached_rowtype(fstore->resulttype, -1,
3850 &fstate->argdesc, econtext);
3852 /* Allocate workspace */
3853 values = (Datum *) palloc(tupDesc->natts * sizeof(Datum));
3854 isnull = (bool *) palloc(tupDesc->natts * sizeof(bool));
3859 * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader. We
3860 * set all the fields in the struct just in case.
3862 HeapTupleHeader tuphdr;
3863 HeapTupleData tmptup;
3865 tuphdr = DatumGetHeapTupleHeader(tupDatum);
3866 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuphdr);
3867 ItemPointerSetInvalid(&(tmptup.t_self));
3868 tmptup.t_tableOid = InvalidOid;
3869 tmptup.t_data = tuphdr;
3871 heap_deform_tuple(&tmptup, tupDesc, values, isnull);
3875 /* Convert null input tuple into an all-nulls row */
3876 memset(isnull, true, tupDesc->natts * sizeof(bool));
3879 /* Result is never null */
3882 save_datum = econtext->caseValue_datum;
3883 save_isNull = econtext->caseValue_isNull;
3885 forboth(l1, fstate->newvals, l2, fstore->fieldnums)
3887 ExprState *newval = (ExprState *) lfirst(l1);
3888 AttrNumber fieldnum = lfirst_int(l2);
3890 Assert(fieldnum > 0 && fieldnum <= tupDesc->natts);
3893 * Use the CaseTestExpr mechanism to pass down the old value of the
3894 * field being replaced; this is useful in case we have a nested field
3895 * update situation. It's safe to reuse the CASE mechanism because
3896 * there cannot be a CASE between here and where the value would be
3899 econtext->caseValue_datum = values[fieldnum - 1];
3900 econtext->caseValue_isNull = isnull[fieldnum - 1];
3902 values[fieldnum - 1] = ExecEvalExpr(newval,
3904 &isnull[fieldnum - 1],
3908 econtext->caseValue_datum = save_datum;
3909 econtext->caseValue_isNull = save_isNull;
3911 tuple = heap_form_tuple(tupDesc, values, isnull);
3916 return HeapTupleGetDatum(tuple);
3919 /* ----------------------------------------------------------------
3920 * ExecEvalRelabelType
3922 * Evaluate a RelabelType node.
3923 * ----------------------------------------------------------------
3926 ExecEvalRelabelType(GenericExprState *exprstate,
3927 ExprContext *econtext,
3928 bool *isNull, ExprDoneCond *isDone)
3930 return ExecEvalExpr(exprstate->arg, econtext, isNull, isDone);
3933 /* ----------------------------------------------------------------
3934 * ExecEvalCoerceViaIO
3936 * Evaluate a CoerceViaIO node.
3937 * ----------------------------------------------------------------
3940 ExecEvalCoerceViaIO(CoerceViaIOState *iostate,
3941 ExprContext *econtext,
3942 bool *isNull, ExprDoneCond *isDone)
3948 inputval = ExecEvalExpr(iostate->arg, econtext, isNull, isDone);
3950 if (isDone && *isDone == ExprEndResult)
3951 return inputval; /* nothing to do */
3954 string = NULL; /* output functions are not called on nulls */
3956 string = OutputFunctionCall(&iostate->outfunc, inputval);
3958 result = InputFunctionCall(&iostate->infunc,
3960 iostate->intypioparam,
3963 /* The input function cannot change the null/not-null status */
3967 /* ----------------------------------------------------------------
3968 * ExecEvalArrayCoerceExpr
3970 * Evaluate an ArrayCoerceExpr node.
3971 * ----------------------------------------------------------------
3974 ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
3975 ExprContext *econtext,
3976 bool *isNull, ExprDoneCond *isDone)
3978 ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) astate->xprstate.expr;
3981 FunctionCallInfoData locfcinfo;
3983 result = ExecEvalExpr(astate->arg, econtext, isNull, isDone);
3985 if (isDone && *isDone == ExprEndResult)
3986 return result; /* nothing to do */
3988 return result; /* nothing to do */
3991 * If it's binary-compatible, modify the element type in the array header,
3992 * but otherwise leave the array as we received it.
3994 if (!OidIsValid(acoerce->elemfuncid))
3996 /* Detoast input array if necessary, and copy in any case */
3997 array = DatumGetArrayTypePCopy(result);
3998 ARR_ELEMTYPE(array) = astate->resultelemtype;
3999 PG_RETURN_ARRAYTYPE_P(array);
4002 /* Detoast input array if necessary, but don't make a useless copy */
4003 array = DatumGetArrayTypeP(result);
4005 /* Initialize function cache if first time through */
4006 if (astate->elemfunc.fn_oid == InvalidOid)
4008 AclResult aclresult;
4010 /* Check permission to call function */
4011 aclresult = pg_proc_aclcheck(acoerce->elemfuncid, GetUserId(),
4013 if (aclresult != ACLCHECK_OK)
4014 aclcheck_error(aclresult, ACL_KIND_PROC,
4015 get_func_name(acoerce->elemfuncid));
4017 /* Set up the primary fmgr lookup information */
4018 fmgr_info_cxt(acoerce->elemfuncid, &(astate->elemfunc),
4019 econtext->ecxt_per_query_memory);
4021 /* Initialize additional info */
4022 astate->elemfunc.fn_expr = (Node *) acoerce;
4026 * Use array_map to apply the function to each array element.
4028 * We pass on the desttypmod and isExplicit flags whether or not the
4029 * function wants them.
4031 InitFunctionCallInfoData(locfcinfo, &(astate->elemfunc), 3,
4033 locfcinfo.arg[0] = PointerGetDatum(array);
4034 locfcinfo.arg[1] = Int32GetDatum(acoerce->resulttypmod);
4035 locfcinfo.arg[2] = BoolGetDatum(acoerce->isExplicit);
4036 locfcinfo.argnull[0] = false;
4037 locfcinfo.argnull[1] = false;
4038 locfcinfo.argnull[2] = false;
4040 return array_map(&locfcinfo, ARR_ELEMTYPE(array), astate->resultelemtype,
4044 /* ----------------------------------------------------------------
4045 * ExecEvalCurrentOfExpr
4047 * The planner must convert CURRENT OF into a TidScan qualification.
4048 * So, we have to be able to do ExecInitExpr on a CurrentOfExpr,
4049 * but we shouldn't ever actually execute it.
4050 * ----------------------------------------------------------------
4053 ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
4054 bool *isNull, ExprDoneCond *isDone)
4056 elog(ERROR, "CURRENT OF cannot be executed");
4057 return 0; /* keep compiler quiet */
4062 * ExecEvalExprSwitchContext
4064 * Same as ExecEvalExpr, but get into the right allocation context explicitly.
4067 ExecEvalExprSwitchContext(ExprState *expression,
4068 ExprContext *econtext,
4070 ExprDoneCond *isDone)
4073 MemoryContext oldContext;
4075 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
4076 retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
4077 MemoryContextSwitchTo(oldContext);
4083 * ExecInitExpr: prepare an expression tree for execution
4085 * This function builds and returns an ExprState tree paralleling the given
4086 * Expr node tree. The ExprState tree can then be handed to ExecEvalExpr
4087 * for execution. Because the Expr tree itself is read-only as far as
4088 * ExecInitExpr and ExecEvalExpr are concerned, several different executions
4089 * of the same plan tree can occur concurrently.
4091 * This must be called in a memory context that will last as long as repeated
4092 * executions of the expression are needed. Typically the context will be
4093 * the same as the per-query context of the associated ExprContext.
4095 * Any Aggref, WindowFunc, or SubPlan nodes found in the tree are added to the
4096 * lists of such nodes held by the parent PlanState. Otherwise, we do very
4097 * little initialization here other than building the state-node tree. Any
4098 * nontrivial work associated with initializing runtime info for a node should
4099 * happen during the first actual evaluation of that node. (This policy lets
4100 * us avoid work if the node is never actually evaluated.)
4102 * Note: there is no ExecEndExpr function; we assume that any resource
4103 * cleanup needed will be handled by just releasing the memory context
4104 * in which the state tree is built. Functions that require additional
4105 * cleanup work can register a shutdown callback in the ExprContext.
4107 * 'node' is the root of the expression tree to examine
4108 * 'parent' is the PlanState node that owns the expression.
4110 * 'parent' may be NULL if we are preparing an expression that is not
4111 * associated with a plan tree. (If so, it can't have aggs or subplans.)
4112 * This case should usually come through ExecPrepareExpr, not directly here.
4115 ExecInitExpr(Expr *node, PlanState *parent)
4122 /* Guard against stack overflow due to overly complex expressions */
4123 check_stack_depth();
4125 switch (nodeTag(node))
4128 state = (ExprState *) makeNode(ExprState);
4129 state->evalfunc = ExecEvalVar;
4132 state = (ExprState *) makeNode(ExprState);
4133 state->evalfunc = ExecEvalConst;
4136 state = (ExprState *) makeNode(ExprState);
4137 state->evalfunc = ExecEvalParam;
4139 case T_CoerceToDomainValue:
4140 state = (ExprState *) makeNode(ExprState);
4141 state->evalfunc = ExecEvalCoerceToDomainValue;
4143 case T_CaseTestExpr:
4144 state = (ExprState *) makeNode(ExprState);
4145 state->evalfunc = ExecEvalCaseTestExpr;
4149 Aggref *aggref = (Aggref *) node;
4150 AggrefExprState *astate = makeNode(AggrefExprState);
4152 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAggref;
4153 if (parent && IsA(parent, AggState))
4155 AggState *aggstate = (AggState *) parent;
4158 aggstate->aggs = lcons(astate, aggstate->aggs);
4159 naggs = ++aggstate->numaggs;
4161 astate->args = (List *) ExecInitExpr((Expr *) aggref->args,
4165 * Complain if the aggregate's arguments contain any
4166 * aggregates; nested agg functions are semantically
4167 * nonsensical. (This should have been caught earlier,
4168 * but we defend against it here anyway.)
4170 if (naggs != aggstate->numaggs)
4172 (errcode(ERRCODE_GROUPING_ERROR),
4173 errmsg("aggregate function calls cannot be nested")));
4177 /* planner messed up */
4178 elog(ERROR, "Aggref found in non-Agg plan node");
4180 state = (ExprState *) astate;
4185 WindowFunc *wfunc = (WindowFunc *) node;
4186 WindowFuncExprState *wfstate = makeNode(WindowFuncExprState);
4188 wfstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalWindowFunc;
4189 if (parent && IsA(parent, WindowAggState))
4191 WindowAggState *winstate = (WindowAggState *) parent;
4194 winstate->funcs = lcons(wfstate, winstate->funcs);
4195 nfuncs = ++winstate->numfuncs;
4197 winstate->numaggs++;
4199 wfstate->args = (List *) ExecInitExpr((Expr *) wfunc->args,
4203 * Complain if the windowfunc's arguments contain any
4204 * windowfuncs; nested window functions are semantically
4205 * nonsensical. (This should have been caught earlier,
4206 * but we defend against it here anyway.)
4208 if (nfuncs != winstate->numfuncs)
4210 (errcode(ERRCODE_WINDOWING_ERROR),
4211 errmsg("window function calls cannot be nested")));
4215 /* planner messed up */
4216 elog(ERROR, "WindowFunc found in non-WindowAgg plan node");
4218 state = (ExprState *) wfstate;
4223 ArrayRef *aref = (ArrayRef *) node;
4224 ArrayRefExprState *astate = makeNode(ArrayRefExprState);
4226 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayRef;
4227 astate->refupperindexpr = (List *)
4228 ExecInitExpr((Expr *) aref->refupperindexpr, parent);
4229 astate->reflowerindexpr = (List *)
4230 ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
4231 astate->refexpr = ExecInitExpr(aref->refexpr, parent);
4232 astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
4234 /* do one-time catalog lookups for type info */
4235 astate->refattrlength = get_typlen(aref->refarraytype);
4236 get_typlenbyvalalign(aref->refelemtype,
4237 &astate->refelemlength,
4238 &astate->refelembyval,
4239 &astate->refelemalign);
4240 state = (ExprState *) astate;
4245 FuncExpr *funcexpr = (FuncExpr *) node;
4246 FuncExprState *fstate = makeNode(FuncExprState);
4248 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFunc;
4249 fstate->args = (List *)
4250 ExecInitExpr((Expr *) funcexpr->args, parent);
4251 fstate->func.fn_oid = InvalidOid; /* not initialized */
4252 state = (ExprState *) fstate;
4257 OpExpr *opexpr = (OpExpr *) node;
4258 FuncExprState *fstate = makeNode(FuncExprState);
4260 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOper;
4261 fstate->args = (List *)
4262 ExecInitExpr((Expr *) opexpr->args, parent);
4263 fstate->func.fn_oid = InvalidOid; /* not initialized */
4264 state = (ExprState *) fstate;
4267 case T_DistinctExpr:
4269 DistinctExpr *distinctexpr = (DistinctExpr *) node;
4270 FuncExprState *fstate = makeNode(FuncExprState);
4272 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalDistinct;
4273 fstate->args = (List *)
4274 ExecInitExpr((Expr *) distinctexpr->args, parent);
4275 fstate->func.fn_oid = InvalidOid; /* not initialized */
4276 state = (ExprState *) fstate;
4279 case T_ScalarArrayOpExpr:
4281 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
4282 ScalarArrayOpExprState *sstate = makeNode(ScalarArrayOpExprState);
4284 sstate->fxprstate.xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalScalarArrayOp;
4285 sstate->fxprstate.args = (List *)
4286 ExecInitExpr((Expr *) opexpr->args, parent);
4287 sstate->fxprstate.func.fn_oid = InvalidOid; /* not initialized */
4288 sstate->element_type = InvalidOid; /* ditto */
4289 state = (ExprState *) sstate;
4294 BoolExpr *boolexpr = (BoolExpr *) node;
4295 BoolExprState *bstate = makeNode(BoolExprState);
4297 switch (boolexpr->boolop)
4300 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAnd;
4303 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOr;
4306 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNot;
4309 elog(ERROR, "unrecognized boolop: %d",
4310 (int) boolexpr->boolop);
4313 bstate->args = (List *)
4314 ExecInitExpr((Expr *) boolexpr->args, parent);
4315 state = (ExprState *) bstate;
4320 SubPlan *subplan = (SubPlan *) node;
4321 SubPlanState *sstate;
4324 elog(ERROR, "SubPlan found with no parent plan");
4326 sstate = ExecInitSubPlan(subplan, parent);
4328 /* Add SubPlanState nodes to parent->subPlan */
4329 parent->subPlan = lappend(parent->subPlan, sstate);
4331 state = (ExprState *) sstate;
4334 case T_AlternativeSubPlan:
4336 AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
4337 AlternativeSubPlanState *asstate;
4340 elog(ERROR, "AlternativeSubPlan found with no parent plan");
4342 asstate = ExecInitAlternativeSubPlan(asplan, parent);
4344 state = (ExprState *) asstate;
4349 FieldSelect *fselect = (FieldSelect *) node;
4350 FieldSelectState *fstate = makeNode(FieldSelectState);
4352 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldSelect;
4353 fstate->arg = ExecInitExpr(fselect->arg, parent);
4354 fstate->argdesc = NULL;
4355 state = (ExprState *) fstate;
4360 FieldStore *fstore = (FieldStore *) node;
4361 FieldStoreState *fstate = makeNode(FieldStoreState);
4363 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldStore;
4364 fstate->arg = ExecInitExpr(fstore->arg, parent);
4365 fstate->newvals = (List *) ExecInitExpr((Expr *) fstore->newvals, parent);
4366 fstate->argdesc = NULL;
4367 state = (ExprState *) fstate;
4372 RelabelType *relabel = (RelabelType *) node;
4373 GenericExprState *gstate = makeNode(GenericExprState);
4375 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRelabelType;
4376 gstate->arg = ExecInitExpr(relabel->arg, parent);
4377 state = (ExprState *) gstate;
4382 CoerceViaIO *iocoerce = (CoerceViaIO *) node;
4383 CoerceViaIOState *iostate = makeNode(CoerceViaIOState);
4387 iostate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceViaIO;
4388 iostate->arg = ExecInitExpr(iocoerce->arg, parent);
4389 /* lookup the result type's input function */
4390 getTypeInputInfo(iocoerce->resulttype, &iofunc,
4391 &iostate->intypioparam);
4392 fmgr_info(iofunc, &iostate->infunc);
4393 /* lookup the input type's output function */
4394 getTypeOutputInfo(exprType((Node *) iocoerce->arg),
4395 &iofunc, &typisvarlena);
4396 fmgr_info(iofunc, &iostate->outfunc);
4397 state = (ExprState *) iostate;
4400 case T_ArrayCoerceExpr:
4402 ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
4403 ArrayCoerceExprState *astate = makeNode(ArrayCoerceExprState);
4405 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayCoerceExpr;
4406 astate->arg = ExecInitExpr(acoerce->arg, parent);
4407 astate->resultelemtype = get_element_type(acoerce->resulttype);
4408 if (astate->resultelemtype == InvalidOid)
4410 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4411 errmsg("target type is not an array")));
4412 /* Arrays over domains aren't supported yet */
4413 Assert(getBaseType(astate->resultelemtype) ==
4414 astate->resultelemtype);
4415 astate->elemfunc.fn_oid = InvalidOid; /* not initialized */
4416 astate->amstate = (ArrayMapState *) palloc0(sizeof(ArrayMapState));
4417 state = (ExprState *) astate;
4420 case T_ConvertRowtypeExpr:
4422 ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) node;
4423 ConvertRowtypeExprState *cstate = makeNode(ConvertRowtypeExprState);
4425 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalConvertRowtype;
4426 cstate->arg = ExecInitExpr(convert->arg, parent);
4427 state = (ExprState *) cstate;
4432 CaseExpr *caseexpr = (CaseExpr *) node;
4433 CaseExprState *cstate = makeNode(CaseExprState);
4434 List *outlist = NIL;
4437 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCase;
4438 cstate->arg = ExecInitExpr(caseexpr->arg, parent);
4439 foreach(l, caseexpr->args)
4441 CaseWhen *when = (CaseWhen *) lfirst(l);
4442 CaseWhenState *wstate = makeNode(CaseWhenState);
4444 Assert(IsA(when, CaseWhen));
4445 wstate->xprstate.evalfunc = NULL; /* not used */
4446 wstate->xprstate.expr = (Expr *) when;
4447 wstate->expr = ExecInitExpr(when->expr, parent);
4448 wstate->result = ExecInitExpr(when->result, parent);
4449 outlist = lappend(outlist, wstate);
4451 cstate->args = outlist;
4452 cstate->defresult = ExecInitExpr(caseexpr->defresult, parent);
4453 state = (ExprState *) cstate;
4458 ArrayExpr *arrayexpr = (ArrayExpr *) node;
4459 ArrayExprState *astate = makeNode(ArrayExprState);
4460 List *outlist = NIL;
4463 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArray;
4464 foreach(l, arrayexpr->elements)
4466 Expr *e = (Expr *) lfirst(l);
4469 estate = ExecInitExpr(e, parent);
4470 outlist = lappend(outlist, estate);
4472 astate->elements = outlist;
4473 /* do one-time catalog lookup for type info */
4474 get_typlenbyvalalign(arrayexpr->element_typeid,
4475 &astate->elemlength,
4477 &astate->elemalign);
4478 state = (ExprState *) astate;
4483 RowExpr *rowexpr = (RowExpr *) node;
4484 RowExprState *rstate = makeNode(RowExprState);
4485 Form_pg_attribute *attrs;
4486 List *outlist = NIL;
4490 rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRow;
4491 /* Build tupdesc to describe result tuples */
4492 if (rowexpr->row_typeid == RECORDOID)
4494 /* generic record, use runtime type assignment */
4495 rstate->tupdesc = ExecTypeFromExprList(rowexpr->args);
4496 BlessTupleDesc(rstate->tupdesc);
4497 /* we won't need to redo this at runtime */
4501 /* it's been cast to a named type, use that */
4502 rstate->tupdesc = lookup_rowtype_tupdesc_copy(rowexpr->row_typeid, -1);
4504 /* Set up evaluation, skipping any deleted columns */
4505 Assert(list_length(rowexpr->args) <= rstate->tupdesc->natts);
4506 attrs = rstate->tupdesc->attrs;
4508 foreach(l, rowexpr->args)
4510 Expr *e = (Expr *) lfirst(l);
4513 if (!attrs[i]->attisdropped)
4516 * Guard against ALTER COLUMN TYPE on rowtype since
4517 * the RowExpr was created. XXX should we check
4518 * typmod too? Not sure we can be sure it'll be the
4521 if (exprType((Node *) e) != attrs[i]->atttypid)
4523 (errcode(ERRCODE_DATATYPE_MISMATCH),
4524 errmsg("ROW() column has type %s instead of type %s",
4525 format_type_be(exprType((Node *) e)),
4526 format_type_be(attrs[i]->atttypid))));
4531 * Ignore original expression and insert a NULL. We
4532 * don't really care what type of NULL it is, so
4533 * always make an int4 NULL.
4535 e = (Expr *) makeNullConst(INT4OID, -1);
4537 estate = ExecInitExpr(e, parent);
4538 outlist = lappend(outlist, estate);
4541 rstate->args = outlist;
4542 state = (ExprState *) rstate;
4545 case T_RowCompareExpr:
4547 RowCompareExpr *rcexpr = (RowCompareExpr *) node;
4548 RowCompareExprState *rstate = makeNode(RowCompareExprState);
4549 int nopers = list_length(rcexpr->opnos);
4555 rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRowCompare;
4556 Assert(list_length(rcexpr->largs) == nopers);
4558 foreach(l, rcexpr->largs)
4560 Expr *e = (Expr *) lfirst(l);
4563 estate = ExecInitExpr(e, parent);
4564 outlist = lappend(outlist, estate);
4566 rstate->largs = outlist;
4567 Assert(list_length(rcexpr->rargs) == nopers);
4569 foreach(l, rcexpr->rargs)
4571 Expr *e = (Expr *) lfirst(l);
4574 estate = ExecInitExpr(e, parent);
4575 outlist = lappend(outlist, estate);
4577 rstate->rargs = outlist;
4578 Assert(list_length(rcexpr->opfamilies) == nopers);
4579 rstate->funcs = (FmgrInfo *) palloc(nopers * sizeof(FmgrInfo));
4581 forboth(l, rcexpr->opnos, l2, rcexpr->opfamilies)
4583 Oid opno = lfirst_oid(l);
4584 Oid opfamily = lfirst_oid(l2);
4590 get_op_opfamily_properties(opno, opfamily,
4594 proc = get_opfamily_proc(opfamily,
4600 * If we enforced permissions checks on index support
4601 * functions, we'd need to make a check here. But the
4602 * index support machinery doesn't do that, and neither
4605 fmgr_info(proc, &(rstate->funcs[i]));
4608 state = (ExprState *) rstate;
4611 case T_CoalesceExpr:
4613 CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
4614 CoalesceExprState *cstate = makeNode(CoalesceExprState);
4615 List *outlist = NIL;
4618 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoalesce;
4619 foreach(l, coalesceexpr->args)
4621 Expr *e = (Expr *) lfirst(l);
4624 estate = ExecInitExpr(e, parent);
4625 outlist = lappend(outlist, estate);
4627 cstate->args = outlist;
4628 state = (ExprState *) cstate;
4633 MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
4634 MinMaxExprState *mstate = makeNode(MinMaxExprState);
4635 List *outlist = NIL;
4637 TypeCacheEntry *typentry;
4639 mstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalMinMax;
4640 foreach(l, minmaxexpr->args)
4642 Expr *e = (Expr *) lfirst(l);
4645 estate = ExecInitExpr(e, parent);
4646 outlist = lappend(outlist, estate);
4648 mstate->args = outlist;
4649 /* Look up the btree comparison function for the datatype */
4650 typentry = lookup_type_cache(minmaxexpr->minmaxtype,
4651 TYPECACHE_CMP_PROC);
4652 if (!OidIsValid(typentry->cmp_proc))
4654 (errcode(ERRCODE_UNDEFINED_FUNCTION),
4655 errmsg("could not identify a comparison function for type %s",
4656 format_type_be(minmaxexpr->minmaxtype))));
4659 * If we enforced permissions checks on index support
4660 * functions, we'd need to make a check here. But the index
4661 * support machinery doesn't do that, and neither does this
4664 fmgr_info(typentry->cmp_proc, &(mstate->cfunc));
4665 state = (ExprState *) mstate;
4670 XmlExpr *xexpr = (XmlExpr *) node;
4671 XmlExprState *xstate = makeNode(XmlExprState);
4675 xstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalXml;
4677 foreach(arg, xexpr->named_args)
4679 Expr *e = (Expr *) lfirst(arg);
4682 estate = ExecInitExpr(e, parent);
4683 outlist = lappend(outlist, estate);
4685 xstate->named_args = outlist;
4688 foreach(arg, xexpr->args)
4690 Expr *e = (Expr *) lfirst(arg);
4693 estate = ExecInitExpr(e, parent);
4694 outlist = lappend(outlist, estate);
4696 xstate->args = outlist;
4698 state = (ExprState *) xstate;
4703 NullIfExpr *nullifexpr = (NullIfExpr *) node;
4704 FuncExprState *fstate = makeNode(FuncExprState);
4706 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullIf;
4707 fstate->args = (List *)
4708 ExecInitExpr((Expr *) nullifexpr->args, parent);
4709 fstate->func.fn_oid = InvalidOid; /* not initialized */
4710 state = (ExprState *) fstate;
4715 NullTest *ntest = (NullTest *) node;
4716 NullTestState *nstate = makeNode(NullTestState);
4718 nstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullTest;
4719 nstate->arg = ExecInitExpr(ntest->arg, parent);
4720 nstate->argisrow = type_is_rowtype(exprType((Node *) ntest->arg));
4721 nstate->argdesc = NULL;
4722 state = (ExprState *) nstate;
4727 BooleanTest *btest = (BooleanTest *) node;
4728 GenericExprState *gstate = makeNode(GenericExprState);
4730 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalBooleanTest;
4731 gstate->arg = ExecInitExpr(btest->arg, parent);
4732 state = (ExprState *) gstate;
4735 case T_CoerceToDomain:
4737 CoerceToDomain *ctest = (CoerceToDomain *) node;
4738 CoerceToDomainState *cstate = makeNode(CoerceToDomainState);
4740 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceToDomain;
4741 cstate->arg = ExecInitExpr(ctest->arg, parent);
4742 cstate->constraints = GetDomainConstraints(ctest->resulttype);
4743 state = (ExprState *) cstate;
4746 case T_CurrentOfExpr:
4747 state = (ExprState *) makeNode(ExprState);
4748 state->evalfunc = ExecEvalCurrentOfExpr;
4752 TargetEntry *tle = (TargetEntry *) node;
4753 GenericExprState *gstate = makeNode(GenericExprState);
4755 gstate->xprstate.evalfunc = NULL; /* not used */
4756 gstate->arg = ExecInitExpr(tle->expr, parent);
4757 state = (ExprState *) gstate;
4762 List *outlist = NIL;
4765 foreach(l, (List *) node)
4767 outlist = lappend(outlist,
4768 ExecInitExpr((Expr *) lfirst(l),
4771 /* Don't fall through to the "common" code below */
4772 return (ExprState *) outlist;
4775 elog(ERROR, "unrecognized node type: %d",
4776 (int) nodeTag(node));
4777 state = NULL; /* keep compiler quiet */
4781 /* Common code for all state-node types */
4788 * ExecPrepareExpr --- initialize for expression execution outside a normal
4789 * Plan tree context.
4791 * This differs from ExecInitExpr in that we don't assume the caller is
4792 * already running in the EState's per-query context. Also, we run the
4793 * passed expression tree through expression_planner() to prepare it for
4794 * execution. (In ordinary Plan trees the regular planning process will have
4795 * made the appropriate transformations on expressions, but for standalone
4796 * expressions this won't have happened.)
4799 ExecPrepareExpr(Expr *node, EState *estate)
4802 MemoryContext oldcontext;
4804 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
4806 node = expression_planner(node);
4808 result = ExecInitExpr(node, NULL);
4810 MemoryContextSwitchTo(oldcontext);
4816 /* ----------------------------------------------------------------
4817 * ExecQual / ExecTargetList / ExecProject
4818 * ----------------------------------------------------------------
4821 /* ----------------------------------------------------------------
4824 * Evaluates a conjunctive boolean expression (qual list) and
4825 * returns true iff none of the subexpressions are false.
4826 * (We also return true if the list is empty.)
4828 * If some of the subexpressions yield NULL but none yield FALSE,
4829 * then the result of the conjunction is NULL (ie, unknown)
4830 * according to three-valued boolean logic. In this case,
4831 * we return the value specified by the "resultForNull" parameter.
4833 * Callers evaluating WHERE clauses should pass resultForNull=FALSE,
4834 * since SQL specifies that tuples with null WHERE results do not
4835 * get selected. On the other hand, callers evaluating constraint
4836 * conditions should pass resultForNull=TRUE, since SQL also specifies
4837 * that NULL constraint conditions are not failures.
4839 * NOTE: it would not be correct to use this routine to evaluate an
4840 * AND subclause of a boolean expression; for that purpose, a NULL
4841 * result must be returned as NULL so that it can be properly treated
4842 * in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
4843 * This routine is only used in contexts where a complete expression
4844 * is being evaluated and we know that NULL can be treated the same
4845 * as one boolean result or the other.
4847 * ----------------------------------------------------------------
4850 ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
4853 MemoryContext oldContext;
4859 EV_printf("ExecQual: qual is ");
4860 EV_nodeDisplay(qual);
4866 * Run in short-lived per-tuple context while computing expressions.
4868 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
4871 * Evaluate the qual conditions one at a time. If we find a FALSE result,
4872 * we can stop evaluating and return FALSE --- the AND result must be
4873 * FALSE. Also, if we find a NULL result when resultForNull is FALSE, we
4874 * can stop and return FALSE --- the AND result must be FALSE or NULL in
4875 * that case, and the caller doesn't care which.
4877 * If we get to the end of the list, we can return TRUE. This will happen
4878 * when the AND result is indeed TRUE, or when the AND result is NULL (one
4879 * or more NULL subresult, with all the rest TRUE) and the caller has
4880 * specified resultForNull = TRUE.
4886 ExprState *clause = (ExprState *) lfirst(l);
4890 expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
4894 if (resultForNull == false)
4896 result = false; /* treat NULL as FALSE */
4902 if (!DatumGetBool(expr_value))
4904 result = false; /* definitely FALSE */
4910 MemoryContextSwitchTo(oldContext);
4916 * Number of items in a tlist (including any resjunk items!)
4919 ExecTargetListLength(List *targetlist)
4921 /* This used to be more complex, but fjoins are dead */
4922 return list_length(targetlist);
4926 * Number of items in a tlist, not including any resjunk items
4929 ExecCleanTargetListLength(List *targetlist)
4934 foreach(tl, targetlist)
4936 TargetEntry *curTle = (TargetEntry *) lfirst(tl);
4938 Assert(IsA(curTle, TargetEntry));
4939 if (!curTle->resjunk)
4947 * Evaluates a targetlist with respect to the given
4948 * expression context. Returns TRUE if we were able to create
4949 * a result, FALSE if we have exhausted a set-valued expression.
4951 * Results are stored into the passed values and isnull arrays.
4952 * The caller must provide an itemIsDone array that persists across calls.
4954 * As with ExecEvalExpr, the caller should pass isDone = NULL if not
4955 * prepared to deal with sets of result tuples. Otherwise, a return
4956 * of *isDone = ExprMultipleResult signifies a set element, and a return
4957 * of *isDone = ExprEndResult signifies end of the set of tuple.
4958 * We assume that *isDone has been initialized to ExprSingleResult by caller.
4961 ExecTargetList(List *targetlist,
4962 ExprContext *econtext,
4965 ExprDoneCond *itemIsDone,
4966 ExprDoneCond *isDone)
4968 MemoryContext oldContext;
4973 * Run in short-lived per-tuple context while computing expressions.
4975 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
4978 * evaluate all the expressions in the target list
4980 haveDoneSets = false; /* any exhausted set exprs in tlist? */
4982 foreach(tl, targetlist)
4984 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
4985 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
4986 AttrNumber resind = tle->resno - 1;
4988 values[resind] = ExecEvalExpr(gstate->arg,
4991 &itemIsDone[resind]);
4993 if (itemIsDone[resind] != ExprSingleResult)
4995 /* We have a set-valued expression in the tlist */
4998 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4999 errmsg("set-valued function called in context that cannot accept a set")));
5000 if (itemIsDone[resind] == ExprMultipleResult)
5002 /* we have undone sets in the tlist, set flag */
5003 *isDone = ExprMultipleResult;
5007 /* we have done sets in the tlist, set flag for that */
5008 haveDoneSets = true;
5016 * note: can't get here unless we verified isDone != NULL
5018 if (*isDone == ExprSingleResult)
5021 * all sets are done, so report that tlist expansion is complete.
5023 *isDone = ExprEndResult;
5024 MemoryContextSwitchTo(oldContext);
5030 * We have some done and some undone sets. Restart the done ones
5031 * so that we can deliver a tuple (if possible).
5033 foreach(tl, targetlist)
5035 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
5036 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
5037 AttrNumber resind = tle->resno - 1;
5039 if (itemIsDone[resind] == ExprEndResult)
5041 values[resind] = ExecEvalExpr(gstate->arg,
5044 &itemIsDone[resind]);
5046 if (itemIsDone[resind] == ExprEndResult)
5049 * Oh dear, this item is returning an empty set. Guess
5050 * we can't make a tuple after all.
5052 *isDone = ExprEndResult;
5059 * If we cannot make a tuple because some sets are empty, we still
5060 * have to cycle the nonempty sets to completion, else resources
5061 * will not be released from subplans etc.
5063 * XXX is that still necessary?
5065 if (*isDone == ExprEndResult)
5067 foreach(tl, targetlist)
5069 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
5070 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
5071 AttrNumber resind = tle->resno - 1;
5073 while (itemIsDone[resind] == ExprMultipleResult)
5075 values[resind] = ExecEvalExpr(gstate->arg,
5078 &itemIsDone[resind]);
5082 MemoryContextSwitchTo(oldContext);
5088 /* Report success */
5089 MemoryContextSwitchTo(oldContext);
5097 * projects a tuple based on projection info and stores
5098 * it in the previously specified tuple table slot.
5100 * Note: the result is always a virtual tuple; therefore it
5101 * may reference the contents of the exprContext's scan tuples
5102 * and/or temporary results constructed in the exprContext.
5103 * If the caller wishes the result to be valid longer than that
5104 * data will be valid, he must call ExecMaterializeSlot on the
5108 ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
5110 TupleTableSlot *slot;
5111 ExprContext *econtext;
5117 Assert(projInfo != NULL);
5120 * get the projection info we want
5122 slot = projInfo->pi_slot;
5123 econtext = projInfo->pi_exprContext;
5125 /* Assume single result row until proven otherwise */
5127 *isDone = ExprSingleResult;
5130 * Clear any former contents of the result slot. This makes it safe for
5131 * us to use the slot's Datum/isnull arrays as workspace. (Also, we can
5132 * return the slot as-is if we decide no rows can be projected.)
5134 ExecClearTuple(slot);
5137 * Force extraction of all input values that we'll need. The
5138 * Var-extraction loops below depend on this, and we are also prefetching
5139 * all attributes that will be referenced in the generic expressions.
5141 if (projInfo->pi_lastInnerVar > 0)
5142 slot_getsomeattrs(econtext->ecxt_innertuple,
5143 projInfo->pi_lastInnerVar);
5144 if (projInfo->pi_lastOuterVar > 0)
5145 slot_getsomeattrs(econtext->ecxt_outertuple,
5146 projInfo->pi_lastOuterVar);
5147 if (projInfo->pi_lastScanVar > 0)
5148 slot_getsomeattrs(econtext->ecxt_scantuple,
5149 projInfo->pi_lastScanVar);
5152 * Assign simple Vars to result by direct extraction of fields from source
5153 * slots ... a mite ugly, but fast ...
5155 numSimpleVars = projInfo->pi_numSimpleVars;
5156 if (numSimpleVars > 0)
5158 Datum *values = slot->tts_values;
5159 bool *isnull = slot->tts_isnull;
5160 int *varSlotOffsets = projInfo->pi_varSlotOffsets;
5161 int *varNumbers = projInfo->pi_varNumbers;
5164 if (projInfo->pi_directMap)
5166 /* especially simple case where vars go to output in order */
5167 for (i = 0; i < numSimpleVars; i++)
5169 char *slotptr = ((char *) econtext) + varSlotOffsets[i];
5170 TupleTableSlot *varSlot = *((TupleTableSlot **) slotptr);
5171 int varNumber = varNumbers[i] - 1;
5173 values[i] = varSlot->tts_values[varNumber];
5174 isnull[i] = varSlot->tts_isnull[varNumber];
5179 /* we have to pay attention to varOutputCols[] */
5180 int *varOutputCols = projInfo->pi_varOutputCols;
5182 for (i = 0; i < numSimpleVars; i++)
5184 char *slotptr = ((char *) econtext) + varSlotOffsets[i];
5185 TupleTableSlot *varSlot = *((TupleTableSlot **) slotptr);
5186 int varNumber = varNumbers[i] - 1;
5187 int varOutputCol = varOutputCols[i] - 1;
5189 values[varOutputCol] = varSlot->tts_values[varNumber];
5190 isnull[varOutputCol] = varSlot->tts_isnull[varNumber];
5196 * If there are any generic expressions, evaluate them. It's possible
5197 * that there are set-returning functions in such expressions; if so
5198 * and we have reached the end of the set, we return the result slot,
5199 * which we already marked empty.
5201 if (projInfo->pi_targetlist)
5203 if (!ExecTargetList(projInfo->pi_targetlist,
5207 projInfo->pi_itemIsDone,
5209 return slot; /* no more result rows, return empty slot */
5213 * Successfully formed a result row. Mark the result slot as containing a
5214 * valid virtual tuple.
5216 return ExecStoreVirtualTuple(slot);