1 /*-------------------------------------------------------------------------
4 * Routines to evaluate qualification and targetlist expressions
6 * Portions Copyright (c) 1996-2007, 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.212 2007/02/03 14:06:53 petere Exp $
13 *-------------------------------------------------------------------------
17 * ExecEvalExpr - (now a macro) evaluate an expression, return a datum
18 * ExecEvalExprSwitchContext - same, but switch into eval memory context
19 * ExecQual - return true/false if qualification is satisfied
20 * ExecProject - form a new tuple by projecting the given tuple
23 * The more heavily used ExecEvalExpr routines, such as ExecEvalVar(),
24 * are hotspots. Making these faster will speed up the entire system.
26 * ExecProject() is used to make tuple projections. Rather then
27 * trying to speed it up, the execution plan should be pre-processed
28 * to facilitate attribute sharing between nodes wherever possible,
29 * instead of doing needless copying. -cim 5/31/91
31 * During expression evaluation, we check_stack_depth only in
32 * ExecMakeFunctionResult rather than at every single node. This
33 * is a compromise that trades off precision of the stack limit setting
39 #include "access/heapam.h"
40 #include "access/nbtree.h"
41 #include "catalog/pg_type.h"
42 #include "commands/typecmds.h"
43 #include "executor/execdebug.h"
44 #include "executor/nodeSubplan.h"
46 #include "miscadmin.h"
47 #include "nodes/makefuncs.h"
48 #include "optimizer/planmain.h"
49 #include "parser/parse_expr.h"
50 #include "utils/acl.h"
51 #include "utils/builtins.h"
52 #include "utils/lsyscache.h"
53 #include "utils/memutils.h"
54 #include "utils/typcache.h"
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 ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
66 bool *isNull, ExprDoneCond *isDone);
67 static Datum ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
68 bool *isNull, ExprDoneCond *isDone);
69 static Datum ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext,
70 bool *isNull, ExprDoneCond *isDone);
71 static Datum ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
72 bool *isNull, ExprDoneCond *isDone);
73 static Datum ExecEvalParam(ExprState *exprstate, ExprContext *econtext,
74 bool *isNull, ExprDoneCond *isDone);
75 static void ShutdownFuncExpr(Datum arg);
76 static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod,
77 TupleDesc *cache_field, ExprContext *econtext);
78 static void ShutdownTupleDescRef(Datum arg);
79 static ExprDoneCond ExecEvalFuncArgs(FunctionCallInfo fcinfo,
80 List *argList, ExprContext *econtext);
81 static Datum ExecMakeFunctionResultNoSets(FuncExprState *fcache,
82 ExprContext *econtext,
83 bool *isNull, ExprDoneCond *isDone);
84 static Datum ExecEvalFunc(FuncExprState *fcache, ExprContext *econtext,
85 bool *isNull, ExprDoneCond *isDone);
86 static Datum ExecEvalOper(FuncExprState *fcache, ExprContext *econtext,
87 bool *isNull, ExprDoneCond *isDone);
88 static Datum ExecEvalDistinct(FuncExprState *fcache, ExprContext *econtext,
89 bool *isNull, ExprDoneCond *isDone);
90 static Datum ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
91 ExprContext *econtext,
92 bool *isNull, ExprDoneCond *isDone);
93 static Datum ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
94 bool *isNull, ExprDoneCond *isDone);
95 static Datum ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
96 bool *isNull, ExprDoneCond *isDone);
97 static Datum ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
98 bool *isNull, ExprDoneCond *isDone);
99 static Datum ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
100 ExprContext *econtext,
101 bool *isNull, ExprDoneCond *isDone);
102 static Datum ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
103 bool *isNull, ExprDoneCond *isDone);
104 static Datum ExecEvalCaseTestExpr(ExprState *exprstate,
105 ExprContext *econtext,
106 bool *isNull, ExprDoneCond *isDone);
107 static Datum ExecEvalArray(ArrayExprState *astate,
108 ExprContext *econtext,
109 bool *isNull, ExprDoneCond *isDone);
110 static Datum ExecEvalRow(RowExprState *rstate,
111 ExprContext *econtext,
112 bool *isNull, ExprDoneCond *isDone);
113 static Datum ExecEvalRowCompare(RowCompareExprState *rstate,
114 ExprContext *econtext,
115 bool *isNull, ExprDoneCond *isDone);
116 static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr,
117 ExprContext *econtext,
118 bool *isNull, ExprDoneCond *isDone);
119 static Datum ExecEvalMinMax(MinMaxExprState *minmaxExpr,
120 ExprContext *econtext,
121 bool *isNull, ExprDoneCond *isDone);
122 static Datum ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
123 bool *isNull, ExprDoneCond *isDone);
124 static Datum ExecEvalNullIf(FuncExprState *nullIfExpr,
125 ExprContext *econtext,
126 bool *isNull, ExprDoneCond *isDone);
127 static Datum ExecEvalNullTest(NullTestState *nstate,
128 ExprContext *econtext,
129 bool *isNull, ExprDoneCond *isDone);
130 static Datum ExecEvalBooleanTest(GenericExprState *bstate,
131 ExprContext *econtext,
132 bool *isNull, ExprDoneCond *isDone);
133 static Datum ExecEvalCoerceToDomain(CoerceToDomainState *cstate,
134 ExprContext *econtext,
135 bool *isNull, ExprDoneCond *isDone);
136 static Datum ExecEvalCoerceToDomainValue(ExprState *exprstate,
137 ExprContext *econtext,
138 bool *isNull, ExprDoneCond *isDone);
139 static Datum ExecEvalFieldSelect(FieldSelectState *fstate,
140 ExprContext *econtext,
141 bool *isNull, ExprDoneCond *isDone);
142 static Datum ExecEvalFieldStore(FieldStoreState *fstate,
143 ExprContext *econtext,
144 bool *isNull, ExprDoneCond *isDone);
145 static Datum ExecEvalRelabelType(GenericExprState *exprstate,
146 ExprContext *econtext,
147 bool *isNull, ExprDoneCond *isDone);
150 /* ----------------------------------------------------------------
151 * ExecEvalExpr routines
153 * Recursively evaluate a targetlist or qualification expression.
155 * Each of the following routines having the signature
156 * Datum ExecEvalFoo(ExprState *expression,
157 * ExprContext *econtext,
159 * ExprDoneCond *isDone);
160 * is responsible for evaluating one type or subtype of ExprState node.
161 * They are normally called via the ExecEvalExpr macro, which makes use of
162 * the function pointer set up when the ExprState node was built by
163 * ExecInitExpr. (In some cases, we change this pointer later to avoid
164 * re-executing one-time overhead.)
166 * Note: for notational simplicity we declare these functions as taking the
167 * specific type of ExprState that they work on. This requires casting when
168 * assigning the function pointer in ExecInitExpr. Be careful that the
169 * function signature is declared correctly, because the cast suppresses
170 * automatic checking!
173 * All these functions share this calling convention:
176 * expression: the expression state tree to evaluate
177 * econtext: evaluation context information
180 * return value: Datum value of result
181 * *isNull: set to TRUE if result is NULL (actual return value is
182 * meaningless if so); set to FALSE if non-null result
183 * *isDone: set to indicator of set-result status
185 * A caller that can only accept a singleton (non-set) result should pass
186 * NULL for isDone; if the expression computes a set result then an error
187 * will be reported via ereport. If the caller does pass an isDone pointer
188 * then *isDone is set to one of these three states:
189 * ExprSingleResult singleton result (not a set)
190 * ExprMultipleResult return value is one element of a set
191 * ExprEndResult there are no more elements in the set
192 * When ExprMultipleResult is returned, the caller should invoke
193 * ExecEvalExpr() repeatedly until ExprEndResult is returned. ExprEndResult
194 * is returned after the last real set element. For convenience isNull will
195 * always be set TRUE when ExprEndResult is returned, but this should not be
196 * taken as indicating a NULL element of the set. Note that these return
197 * conventions allow us to distinguish among a singleton NULL, a NULL element
198 * of a set, and an empty set.
200 * The caller should already have switched into the temporary memory
201 * context econtext->ecxt_per_tuple_memory. The convenience entry point
202 * ExecEvalExprSwitchContext() is provided for callers who don't prefer to
203 * do the switch in an outer loop. We do not do the switch in these routines
204 * because it'd be a waste of cycles during nested expression evaluation.
205 * ----------------------------------------------------------------
212 * This function takes an ArrayRef and returns the extracted Datum
213 * if it's a simple reference, or the modified array value if it's
214 * an array assignment (i.e., array element or slice insertion).
216 * NOTE: if we get a NULL result from a subscript expression, we return NULL
217 * when it's an array reference, or raise an error when it's an assignment.
219 * NOTE: we deliberately refrain from applying DatumGetArrayTypeP() here,
220 * even though that might seem natural, because this code needs to support
221 * both varlena arrays and fixed-length array types. DatumGetArrayTypeP()
222 * only works for the varlena kind. The routines we call in arrayfuncs.c
223 * have to know the difference (that's what they need refattrlength for).
227 ExecEvalArrayRef(ArrayRefExprState *astate,
228 ExprContext *econtext,
230 ExprDoneCond *isDone)
232 ArrayRef *arrayRef = (ArrayRef *) astate->xprstate.expr;
233 ArrayType *array_source;
234 ArrayType *resultArray;
235 bool isAssignment = (arrayRef->refassgnexpr != NULL);
244 array_source = (ArrayType *)
245 DatumGetPointer(ExecEvalExpr(astate->refexpr,
251 * If refexpr yields NULL, and it's a fetch, then result is NULL. In the
252 * assignment case, we'll cons up something below.
256 if (isDone && *isDone == ExprEndResult)
257 return (Datum) NULL; /* end of set result */
262 foreach(l, astate->refupperindexpr)
264 ExprState *eltstate = (ExprState *) lfirst(l);
268 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
269 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
272 upper.indx[i++] = DatumGetInt32(ExecEvalExpr(eltstate,
276 /* If any index expr yields NULL, result is NULL or error */
281 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
282 errmsg("array subscript in assignment must not be null")));
288 if (astate->reflowerindexpr != NIL)
290 foreach(l, astate->reflowerindexpr)
292 ExprState *eltstate = (ExprState *) lfirst(l);
296 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
297 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
300 lower.indx[j++] = DatumGetInt32(ExecEvalExpr(eltstate,
304 /* If any index expr yields NULL, result is NULL or error */
309 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
310 errmsg("array subscript in assignment must not be null")));
315 /* this can't happen unless parser messed up */
317 elog(ERROR, "upper and lower index lists are not same length");
328 * Evaluate the value to be assigned into the array.
330 * XXX At some point we'll need to look into making the old value of
331 * the array element available via CaseTestExpr, as is done by
332 * ExecEvalFieldStore. This is not needed now but will be needed to
333 * support arrays of composite types; in an assignment to a field of
334 * an array member, the parser would generate a FieldStore that
335 * expects to fetch its input tuple via CaseTestExpr.
337 sourceData = ExecEvalExpr(astate->refassgnexpr,
343 * For an assignment to a fixed-length array type, both the original
344 * array and the value to be assigned into it must be non-NULL, else
345 * we punt and return the original array.
347 if (astate->refattrlength > 0) /* fixed-length array? */
348 if (eisnull || *isNull)
349 return PointerGetDatum(array_source);
352 * For assignment to varlena arrays, we handle a NULL original array
353 * by substituting an empty (zero-dimensional) array; insertion of the
354 * new element will result in a singleton array value. It does not
355 * matter whether the new element is NULL.
359 array_source = construct_empty_array(arrayRef->refelemtype);
364 resultArray = array_set(array_source, i,
368 astate->refattrlength,
369 astate->refelemlength,
370 astate->refelembyval,
371 astate->refelemalign);
373 resultArray = array_set_slice(array_source, i,
374 upper.indx, lower.indx,
375 (ArrayType *) DatumGetPointer(sourceData),
377 astate->refattrlength,
378 astate->refelemlength,
379 astate->refelembyval,
380 astate->refelemalign);
381 return PointerGetDatum(resultArray);
385 return array_ref(array_source, i, upper.indx,
386 astate->refattrlength,
387 astate->refelemlength,
388 astate->refelembyval,
389 astate->refelemalign,
393 resultArray = array_get_slice(array_source, i,
394 upper.indx, lower.indx,
395 astate->refattrlength,
396 astate->refelemlength,
397 astate->refelembyval,
398 astate->refelemalign);
399 return PointerGetDatum(resultArray);
404 /* ----------------------------------------------------------------
407 * Returns a Datum whose value is the value of the precomputed
408 * aggregate found in the given expression context.
409 * ----------------------------------------------------------------
412 ExecEvalAggref(AggrefExprState *aggref, ExprContext *econtext,
413 bool *isNull, ExprDoneCond *isDone)
416 *isDone = ExprSingleResult;
418 if (econtext->ecxt_aggvalues == NULL) /* safety check */
419 elog(ERROR, "no aggregates in this expression context");
421 *isNull = econtext->ecxt_aggnulls[aggref->aggno];
422 return econtext->ecxt_aggvalues[aggref->aggno];
425 /* ----------------------------------------------------------------
428 * Returns a Datum whose value is the value of a range
429 * variable with respect to given expression context.
431 * Note: ExecEvalVar is executed only the first time through in a given plan;
432 * it changes the ExprState's function pointer to pass control directly to
433 * ExecEvalScalarVar or ExecEvalWholeRowVar after making one-time checks.
434 * ----------------------------------------------------------------
437 ExecEvalVar(ExprState *exprstate, ExprContext *econtext,
438 bool *isNull, ExprDoneCond *isDone)
440 Var *variable = (Var *) exprstate->expr;
441 TupleTableSlot *slot;
445 *isDone = ExprSingleResult;
448 * Get the input slot and attribute number we want
450 * The asserts check that references to system attributes only appear at
451 * the level of a relation scan; at higher levels, system attributes must
452 * be treated as ordinary variables (since we no longer have access to the
455 attnum = variable->varattno;
457 switch (variable->varno)
459 case INNER: /* get the tuple from the inner node */
460 slot = econtext->ecxt_innertuple;
464 case OUTER: /* get the tuple from the outer node */
465 slot = econtext->ecxt_outertuple;
469 default: /* get the tuple from the relation being
471 slot = econtext->ecxt_scantuple;
475 if (attnum != InvalidAttrNumber)
478 * Scalar variable case.
480 * If it's a user attribute, check validity (bogus system attnums will
481 * be caught inside slot_getattr). What we have to check for here
482 * is the possibility of an attribute having been changed in type
483 * since the plan tree was created. Ideally the plan would get
484 * invalidated and not re-used, but until that day arrives, we need
485 * defenses. Fortunately it's sufficient to check once on the first
488 * Note: we allow a reference to a dropped attribute. slot_getattr
489 * will force a NULL result in such cases.
491 * Note: we check typmod, but allow the case that the Var has
492 * unspecified typmod while the column has a specific typmod.
496 TupleDesc slot_tupdesc = slot->tts_tupleDescriptor;
497 Form_pg_attribute attr;
499 if (attnum > slot_tupdesc->natts) /* should never happen */
500 elog(ERROR, "attribute number %d exceeds number of columns %d",
501 attnum, slot_tupdesc->natts);
503 attr = slot_tupdesc->attrs[attnum - 1];
505 /* can't check type if dropped, since atttypid is probably 0 */
506 if (!attr->attisdropped)
508 if (variable->vartype != attr->atttypid ||
509 (variable->vartypmod != attr->atttypmod &&
510 variable->vartypmod != -1))
512 (errmsg("attribute %d has wrong type", attnum),
513 errdetail("Table has type %s, but query expects %s.",
514 format_type_be(attr->atttypid),
515 format_type_be(variable->vartype))));
519 /* Skip the checking on future executions of node */
520 exprstate->evalfunc = ExecEvalScalarVar;
522 /* Fetch the value from the slot */
523 return slot_getattr(slot, attnum, isNull);
528 * Whole-row variable.
530 * If it's a RECORD Var, we'll use the slot's type ID info. It's
531 * likely that the slot's type is also RECORD; if so, make sure it's
532 * been "blessed", so that the Datum can be interpreted later.
534 * If the Var identifies a named composite type, we must check that
535 * the actual tuple type is compatible with it.
537 TupleDesc slot_tupdesc = slot->tts_tupleDescriptor;
539 if (variable->vartype == RECORDOID)
541 if (slot_tupdesc->tdtypeid == RECORDOID &&
542 slot_tupdesc->tdtypmod < 0)
543 assign_record_type_typmod(slot_tupdesc);
547 TupleDesc var_tupdesc;
551 * We really only care about number of attributes and data type.
552 * Also, we can ignore type mismatch on columns that are dropped
553 * in the destination type, so long as the physical storage
554 * matches. This is helpful in some cases involving out-of-date
557 var_tupdesc = lookup_rowtype_tupdesc(variable->vartype, -1);
559 if (var_tupdesc->natts != slot_tupdesc->natts)
561 (errcode(ERRCODE_DATATYPE_MISMATCH),
562 errmsg("table row type and query-specified row type do not match"),
563 errdetail("Table row contains %d attributes, but query expects %d.",
564 slot_tupdesc->natts, var_tupdesc->natts)));
566 for (i = 0; i < var_tupdesc->natts; i++)
568 Form_pg_attribute vattr = var_tupdesc->attrs[i];
569 Form_pg_attribute sattr = slot_tupdesc->attrs[i];
571 if (vattr->atttypid == sattr->atttypid)
572 continue; /* no worries */
573 if (!vattr->attisdropped)
575 (errcode(ERRCODE_DATATYPE_MISMATCH),
576 errmsg("table row type and query-specified row type do not match"),
577 errdetail("Table has type %s at ordinal position %d, but query expects %s.",
578 format_type_be(sattr->atttypid),
580 format_type_be(vattr->atttypid))));
582 if (vattr->attlen != sattr->attlen ||
583 vattr->attalign != sattr->attalign)
585 (errcode(ERRCODE_DATATYPE_MISMATCH),
586 errmsg("table row type and query-specified row type do not match"),
587 errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
591 ReleaseTupleDesc(var_tupdesc);
594 /* Skip the checking on future executions of node */
595 exprstate->evalfunc = ExecEvalWholeRowVar;
597 /* Fetch the value */
598 return ExecEvalWholeRowVar(exprstate, econtext, isNull, isDone);
602 /* ----------------------------------------------------------------
605 * Returns a Datum for a scalar variable.
606 * ----------------------------------------------------------------
609 ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext,
610 bool *isNull, ExprDoneCond *isDone)
612 Var *variable = (Var *) exprstate->expr;
613 TupleTableSlot *slot;
617 *isDone = ExprSingleResult;
619 /* Get the input slot and attribute number we want */
620 switch (variable->varno)
622 case INNER: /* get the tuple from the inner node */
623 slot = econtext->ecxt_innertuple;
626 case OUTER: /* get the tuple from the outer node */
627 slot = econtext->ecxt_outertuple;
630 default: /* get the tuple from the relation being
632 slot = econtext->ecxt_scantuple;
636 attnum = variable->varattno;
638 /* Fetch the value from the slot */
639 return slot_getattr(slot, attnum, isNull);
642 /* ----------------------------------------------------------------
643 * ExecEvalWholeRowVar
645 * Returns a Datum for a whole-row variable.
646 * ----------------------------------------------------------------
649 ExecEvalWholeRowVar(ExprState *exprstate, ExprContext *econtext,
650 bool *isNull, ExprDoneCond *isDone)
652 Var *variable = (Var *) exprstate->expr;
653 TupleTableSlot *slot = econtext->ecxt_scantuple;
656 HeapTupleHeader dtuple;
659 *isDone = ExprSingleResult;
662 tuple = ExecFetchSlotTuple(slot);
663 tupleDesc = slot->tts_tupleDescriptor;
666 * We have to make a copy of the tuple so we can safely insert the Datum
667 * overhead fields, which are not set in on-disk tuples.
669 dtuple = (HeapTupleHeader) palloc(tuple->t_len);
670 memcpy((char *) dtuple, (char *) tuple->t_data, tuple->t_len);
672 HeapTupleHeaderSetDatumLength(dtuple, tuple->t_len);
675 * If the Var identifies a named composite type, label the tuple with that
676 * type; otherwise use what is in the tupleDesc.
678 if (variable->vartype != RECORDOID)
680 HeapTupleHeaderSetTypeId(dtuple, variable->vartype);
681 HeapTupleHeaderSetTypMod(dtuple, variable->vartypmod);
685 HeapTupleHeaderSetTypeId(dtuple, tupleDesc->tdtypeid);
686 HeapTupleHeaderSetTypMod(dtuple, tupleDesc->tdtypmod);
689 return PointerGetDatum(dtuple);
692 /* ----------------------------------------------------------------
695 * Returns the value of a constant.
697 * Note that for pass-by-ref datatypes, we return a pointer to the
698 * actual constant node. This is one of the reasons why functions
699 * must treat their input arguments as read-only.
700 * ----------------------------------------------------------------
703 ExecEvalConst(ExprState *exprstate, ExprContext *econtext,
704 bool *isNull, ExprDoneCond *isDone)
706 Const *con = (Const *) exprstate->expr;
709 *isDone = ExprSingleResult;
711 *isNull = con->constisnull;
712 return con->constvalue;
715 /* ----------------------------------------------------------------
718 * Returns the value of a parameter. A param node contains
719 * something like ($.name) and the expression context contains
720 * the current parameter bindings (name = "sam") (age = 34)...
721 * so our job is to find and return the appropriate datum ("sam").
722 * ----------------------------------------------------------------
725 ExecEvalParam(ExprState *exprstate, ExprContext *econtext,
726 bool *isNull, ExprDoneCond *isDone)
728 Param *expression = (Param *) exprstate->expr;
729 int thisParamId = expression->paramid;
732 *isDone = ExprSingleResult;
734 if (expression->paramkind == PARAM_EXEC)
737 * PARAM_EXEC params (internal executor parameters) are stored in the
738 * ecxt_param_exec_vals array, and can be accessed by array index.
742 prm = &(econtext->ecxt_param_exec_vals[thisParamId]);
743 if (prm->execPlan != NULL)
745 /* Parameter not evaluated yet, so go do it */
746 ExecSetParamPlan(prm->execPlan, econtext);
747 /* ExecSetParamPlan should have processed this param... */
748 Assert(prm->execPlan == NULL);
750 *isNull = prm->isnull;
756 * PARAM_EXTERN parameters must be sought in ecxt_param_list_info.
758 ParamListInfo paramInfo = econtext->ecxt_param_list_info;
760 Assert(expression->paramkind == PARAM_EXTERN);
762 thisParamId > 0 && thisParamId <= paramInfo->numParams)
764 ParamExternData *prm = ¶mInfo->params[thisParamId - 1];
766 if (OidIsValid(prm->ptype))
768 Assert(prm->ptype == expression->paramtype);
769 *isNull = prm->isnull;
774 (errcode(ERRCODE_UNDEFINED_OBJECT),
775 errmsg("no value found for parameter %d", thisParamId)));
776 return (Datum) 0; /* keep compiler quiet */
781 /* ----------------------------------------------------------------
782 * ExecEvalOper / ExecEvalFunc support routines
783 * ----------------------------------------------------------------
790 * These functions return the value of the requested attribute
791 * out of the given tuple Datum.
792 * C functions which take a tuple as an argument are expected
793 * to use these. Ex: overpaid(EMP) might call GetAttributeByNum().
794 * Note: these are actually rather slow because they do a typcache
795 * lookup on each call.
798 GetAttributeByNum(HeapTupleHeader tuple,
806 HeapTupleData tmptup;
808 if (!AttributeNumberIsValid(attrno))
809 elog(ERROR, "invalid attribute number %d", attrno);
812 elog(ERROR, "a NULL isNull pointer was passed");
816 /* Kinda bogus but compatible with old behavior... */
821 tupType = HeapTupleHeaderGetTypeId(tuple);
822 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
823 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
826 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
827 * the fields in the struct just in case user tries to inspect system
830 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
831 ItemPointerSetInvalid(&(tmptup.t_self));
832 tmptup.t_tableOid = InvalidOid;
833 tmptup.t_data = tuple;
835 result = heap_getattr(&tmptup,
840 ReleaseTupleDesc(tupDesc);
846 GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
853 HeapTupleData tmptup;
857 elog(ERROR, "invalid attribute name");
860 elog(ERROR, "a NULL isNull pointer was passed");
864 /* Kinda bogus but compatible with old behavior... */
869 tupType = HeapTupleHeaderGetTypeId(tuple);
870 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
871 tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
873 attrno = InvalidAttrNumber;
874 for (i = 0; i < tupDesc->natts; i++)
876 if (namestrcmp(&(tupDesc->attrs[i]->attname), attname) == 0)
878 attrno = tupDesc->attrs[i]->attnum;
883 if (attrno == InvalidAttrNumber)
884 elog(ERROR, "attribute \"%s\" does not exist", attname);
887 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
888 * the fields in the struct just in case user tries to inspect system
891 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
892 ItemPointerSetInvalid(&(tmptup.t_self));
893 tmptup.t_tableOid = InvalidOid;
894 tmptup.t_data = tuple;
896 result = heap_getattr(&tmptup,
901 ReleaseTupleDesc(tupDesc);
907 * init_fcache - initialize a FuncExprState node during first use
910 init_fcache(Oid foid, FuncExprState *fcache, MemoryContext fcacheCxt)
914 /* Check permission to call function */
915 aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
916 if (aclresult != ACLCHECK_OK)
917 aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(foid));
920 * Safety check on nargs. Under normal circumstances this should never
921 * fail, as parser should check sooner. But possibly it might fail if
922 * server has been compiled with FUNC_MAX_ARGS smaller than some functions
923 * declared in pg_proc?
925 if (list_length(fcache->args) > FUNC_MAX_ARGS)
927 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
928 errmsg("cannot pass more than %d arguments to a function",
931 /* Set up the primary fmgr lookup information */
932 fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
934 /* Initialize additional info */
935 fcache->setArgsValid = false;
936 fcache->shutdown_reg = false;
937 fcache->func.fn_expr = (Node *) fcache->xprstate.expr;
941 * callback function in case a FuncExpr returning a set needs to be shut down
942 * before it has been run to completion
945 ShutdownFuncExpr(Datum arg)
947 FuncExprState *fcache = (FuncExprState *) DatumGetPointer(arg);
949 /* Clear any active set-argument state */
950 fcache->setArgsValid = false;
952 /* execUtils will deregister the callback... */
953 fcache->shutdown_reg = false;
957 * get_cached_rowtype: utility function to lookup a rowtype tupdesc
959 * type_id, typmod: identity of the rowtype
960 * cache_field: where to cache the TupleDesc pointer in expression state node
961 * (field must be initialized to NULL)
962 * econtext: expression context we are executing in
964 * NOTE: because the shutdown callback will be called during plan rescan,
965 * must be prepared to re-do this during any node execution; cannot call
966 * just once during expression initialization
969 get_cached_rowtype(Oid type_id, int32 typmod,
970 TupleDesc *cache_field, ExprContext *econtext)
972 TupleDesc tupDesc = *cache_field;
974 /* Do lookup if no cached value or if requested type changed */
975 if (tupDesc == NULL ||
976 type_id != tupDesc->tdtypeid ||
977 typmod != tupDesc->tdtypmod)
979 tupDesc = lookup_rowtype_tupdesc(type_id, typmod);
983 /* Release old tupdesc; but callback is already registered */
984 ReleaseTupleDesc(*cache_field);
988 /* Need to register shutdown callback to release tupdesc */
989 RegisterExprContextCallback(econtext,
990 ShutdownTupleDescRef,
991 PointerGetDatum(cache_field));
993 *cache_field = tupDesc;
999 * Callback function to release a tupdesc refcount at expression tree shutdown
1002 ShutdownTupleDescRef(Datum arg)
1004 TupleDesc *cache_field = (TupleDesc *) DatumGetPointer(arg);
1007 ReleaseTupleDesc(*cache_field);
1008 *cache_field = NULL;
1012 * Evaluate arguments for a function.
1015 ExecEvalFuncArgs(FunctionCallInfo fcinfo,
1017 ExprContext *econtext)
1019 ExprDoneCond argIsDone;
1023 argIsDone = ExprSingleResult; /* default assumption */
1026 foreach(arg, argList)
1028 ExprState *argstate = (ExprState *) lfirst(arg);
1029 ExprDoneCond thisArgIsDone;
1031 fcinfo->arg[i] = ExecEvalExpr(argstate,
1033 &fcinfo->argnull[i],
1036 if (thisArgIsDone != ExprSingleResult)
1039 * We allow only one argument to have a set value; we'd need much
1040 * more complexity to keep track of multiple set arguments (cf.
1041 * ExecTargetList) and it doesn't seem worth it.
1043 if (argIsDone != ExprSingleResult)
1045 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1046 errmsg("functions and operators can take at most one set argument")));
1047 argIsDone = thisArgIsDone;
1058 * ExecMakeFunctionResult
1060 * Evaluate the arguments to a function and then the function itself.
1063 ExecMakeFunctionResult(FuncExprState *fcache,
1064 ExprContext *econtext,
1066 ExprDoneCond *isDone)
1068 List *arguments = fcache->args;
1070 FunctionCallInfoData fcinfo;
1071 ReturnSetInfo rsinfo; /* for functions returning sets */
1072 ExprDoneCond argDone;
1076 /* Guard against stack overflow due to overly complex expressions */
1077 check_stack_depth();
1080 * arguments is a list of expressions to evaluate before passing to the
1081 * function manager. We skip the evaluation if it was already done in the
1082 * previous call (ie, we are continuing the evaluation of a set-valued
1083 * function). Otherwise, collect the current argument values into fcinfo.
1085 if (!fcache->setArgsValid)
1087 /* Need to prep callinfo structure */
1088 InitFunctionCallInfoData(fcinfo, &(fcache->func), 0, NULL, NULL);
1089 argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);
1090 if (argDone == ExprEndResult)
1092 /* input is an empty set, so return an empty set. */
1095 *isDone = ExprEndResult;
1098 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1099 errmsg("set-valued function called in context that cannot accept a set")));
1102 hasSetArg = (argDone != ExprSingleResult);
1106 /* Copy callinfo from previous evaluation */
1107 memcpy(&fcinfo, &fcache->setArgs, sizeof(fcinfo));
1108 hasSetArg = fcache->setHasSetArg;
1109 /* Reset flag (we may set it again below) */
1110 fcache->setArgsValid = false;
1114 * If function returns set, prepare a resultinfo node for communication
1116 if (fcache->func.fn_retset)
1118 fcinfo.resultinfo = (Node *) &rsinfo;
1119 rsinfo.type = T_ReturnSetInfo;
1120 rsinfo.econtext = econtext;
1121 rsinfo.expectedDesc = NULL;
1122 rsinfo.allowedModes = (int) SFRM_ValuePerCall;
1123 rsinfo.returnMode = SFRM_ValuePerCall;
1124 /* isDone is filled below */
1125 rsinfo.setResult = NULL;
1126 rsinfo.setDesc = NULL;
1130 * now return the value gotten by calling the function manager, passing
1131 * the function the evaluated parameter values.
1133 if (fcache->func.fn_retset || hasSetArg)
1136 * We need to return a set result. Complain if caller not ready to
1141 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1142 errmsg("set-valued function called in context that cannot accept a set")));
1145 * This loop handles the situation where we have both a set argument
1146 * and a set-valued function. Once we have exhausted the function's
1147 * value(s) for a particular argument value, we have to get the next
1148 * argument value and start the function over again. We might have to
1149 * do it more than once, if the function produces an empty result set
1150 * for a particular input value.
1155 * If function is strict, and there are any NULL arguments, skip
1156 * calling the function (at least for this set of args).
1160 if (fcache->func.fn_strict)
1162 for (i = 0; i < fcinfo.nargs; i++)
1164 if (fcinfo.argnull[i])
1174 fcinfo.isnull = false;
1175 rsinfo.isDone = ExprSingleResult;
1176 result = FunctionCallInvoke(&fcinfo);
1177 *isNull = fcinfo.isnull;
1178 *isDone = rsinfo.isDone;
1184 *isDone = ExprEndResult;
1187 if (*isDone != ExprEndResult)
1190 * Got a result from current argument. If function itself
1191 * returns set, save the current argument values to re-use on
1194 if (fcache->func.fn_retset && *isDone == ExprMultipleResult)
1196 memcpy(&fcache->setArgs, &fcinfo, sizeof(fcinfo));
1197 fcache->setHasSetArg = hasSetArg;
1198 fcache->setArgsValid = true;
1199 /* Register cleanup callback if we didn't already */
1200 if (!fcache->shutdown_reg)
1202 RegisterExprContextCallback(econtext,
1204 PointerGetDatum(fcache));
1205 fcache->shutdown_reg = true;
1210 * Make sure we say we are returning a set, even if the
1211 * function itself doesn't return sets.
1214 *isDone = ExprMultipleResult;
1218 /* Else, done with this argument */
1220 break; /* input not a set, so done */
1222 /* Re-eval args to get the next element of the input set */
1223 argDone = ExecEvalFuncArgs(&fcinfo, arguments, econtext);
1225 if (argDone != ExprMultipleResult)
1227 /* End of argument set, so we're done. */
1229 *isDone = ExprEndResult;
1235 * If we reach here, loop around to run the function on the new
1243 * Non-set case: much easier.
1245 * We change the ExprState function pointer to use the simpler
1246 * ExecMakeFunctionResultNoSets on subsequent calls. This amounts to
1247 * assuming that no argument can return a set if it didn't do so the
1250 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResultNoSets;
1253 *isDone = ExprSingleResult;
1256 * If function is strict, and there are any NULL arguments, skip
1257 * calling the function and return NULL.
1259 if (fcache->func.fn_strict)
1261 for (i = 0; i < fcinfo.nargs; i++)
1263 if (fcinfo.argnull[i])
1270 fcinfo.isnull = false;
1271 result = FunctionCallInvoke(&fcinfo);
1272 *isNull = fcinfo.isnull;
1279 * ExecMakeFunctionResultNoSets
1281 * Simplified version of ExecMakeFunctionResult that can only handle
1282 * non-set cases. Hand-tuned for speed.
1285 ExecMakeFunctionResultNoSets(FuncExprState *fcache,
1286 ExprContext *econtext,
1288 ExprDoneCond *isDone)
1292 FunctionCallInfoData fcinfo;
1295 /* Guard against stack overflow due to overly complex expressions */
1296 check_stack_depth();
1299 *isDone = ExprSingleResult;
1301 /* inlined, simplified version of ExecEvalFuncArgs */
1303 foreach(arg, fcache->args)
1305 ExprState *argstate = (ExprState *) lfirst(arg);
1307 fcinfo.arg[i] = ExecEvalExpr(argstate,
1314 InitFunctionCallInfoData(fcinfo, &(fcache->func), i, NULL, NULL);
1317 * If function is strict, and there are any NULL arguments, skip calling
1318 * the function and return NULL.
1320 if (fcache->func.fn_strict)
1324 if (fcinfo.argnull[i])
1331 /* fcinfo.isnull = false; */ /* handled by InitFunctionCallInfoData */
1332 result = FunctionCallInvoke(&fcinfo);
1333 *isNull = fcinfo.isnull;
1340 * ExecMakeTableFunctionResult
1342 * Evaluate a table function, producing a materialized result in a Tuplestore
1343 * object. *returnDesc is set to the tupledesc actually returned by the
1344 * function, or NULL if it didn't provide one.
1347 ExecMakeTableFunctionResult(ExprState *funcexpr,
1348 ExprContext *econtext,
1349 TupleDesc expectedDesc,
1350 TupleDesc *returnDesc)
1352 Tuplestorestate *tupstore = NULL;
1353 TupleDesc tupdesc = NULL;
1356 bool returnsSet = false;
1357 FunctionCallInfoData fcinfo;
1358 ReturnSetInfo rsinfo;
1359 HeapTupleData tmptup;
1360 MemoryContext callerContext;
1361 MemoryContext oldcontext;
1362 bool direct_function_call;
1363 bool first_time = true;
1365 callerContext = CurrentMemoryContext;
1367 funcrettype = exprType((Node *) funcexpr->expr);
1369 returnsTuple = type_is_rowtype(funcrettype);
1372 * Prepare a resultinfo node for communication. We always do this even if
1373 * not expecting a set result, so that we can pass expectedDesc. In the
1374 * generic-expression case, the expression doesn't actually get to see the
1375 * resultinfo, but set it up anyway because we use some of the fields as
1376 * our own state variables.
1378 InitFunctionCallInfoData(fcinfo, NULL, 0, NULL, (Node *) &rsinfo);
1379 rsinfo.type = T_ReturnSetInfo;
1380 rsinfo.econtext = econtext;
1381 rsinfo.expectedDesc = expectedDesc;
1382 rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize);
1383 rsinfo.returnMode = SFRM_ValuePerCall;
1384 /* isDone is filled below */
1385 rsinfo.setResult = NULL;
1386 rsinfo.setDesc = NULL;
1389 * Normally the passed expression tree will be a FuncExprState, since the
1390 * grammar only allows a function call at the top level of a table
1391 * function reference. However, if the function doesn't return set then
1392 * the planner might have replaced the function call via constant-folding
1393 * or inlining. So if we see any other kind of expression node, execute
1394 * it via the general ExecEvalExpr() code; the only difference is that we
1395 * don't get a chance to pass a special ReturnSetInfo to any functions
1396 * buried in the expression.
1398 if (funcexpr && IsA(funcexpr, FuncExprState) &&
1399 IsA(funcexpr->expr, FuncExpr))
1401 FuncExprState *fcache = (FuncExprState *) funcexpr;
1402 ExprDoneCond argDone;
1405 * This path is similar to ExecMakeFunctionResult.
1407 direct_function_call = true;
1410 * Initialize function cache if first time through
1412 if (fcache->func.fn_oid == InvalidOid)
1414 FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
1416 init_fcache(func->funcid, fcache, econtext->ecxt_per_query_memory);
1418 returnsSet = fcache->func.fn_retset;
1421 * Evaluate the function's argument list.
1423 * Note: ideally, we'd do this in the per-tuple context, but then the
1424 * argument values would disappear when we reset the context in the
1425 * inner loop. So do it in caller context. Perhaps we should make a
1426 * separate context just to hold the evaluated arguments?
1428 fcinfo.flinfo = &(fcache->func);
1429 argDone = ExecEvalFuncArgs(&fcinfo, fcache->args, econtext);
1430 /* We don't allow sets in the arguments of the table function */
1431 if (argDone != ExprSingleResult)
1433 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1434 errmsg("set-valued function called in context that cannot accept a set")));
1437 * If function is strict, and there are any NULL arguments, skip
1438 * calling the function and act like it returned NULL (or an empty
1439 * set, in the returns-set case).
1441 if (fcache->func.fn_strict)
1445 for (i = 0; i < fcinfo.nargs; i++)
1447 if (fcinfo.argnull[i])
1448 goto no_function_result;
1454 /* Treat funcexpr as a generic expression */
1455 direct_function_call = false;
1459 * Switch to short-lived context for calling the function or expression.
1461 MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1464 * Loop to handle the ValuePerCall protocol (which is also the same
1465 * behavior needed in the generic ExecEvalExpr path).
1472 CHECK_FOR_INTERRUPTS();
1475 * reset per-tuple memory context before each call of the function or
1476 * expression. This cleans up any local memory the function may leak
1479 ResetExprContext(econtext);
1481 /* Call the function or expression one time */
1482 if (direct_function_call)
1484 fcinfo.isnull = false;
1485 rsinfo.isDone = ExprSingleResult;
1486 result = FunctionCallInvoke(&fcinfo);
1490 result = ExecEvalExpr(funcexpr, econtext,
1491 &fcinfo.isnull, &rsinfo.isDone);
1494 /* Which protocol does function want to use? */
1495 if (rsinfo.returnMode == SFRM_ValuePerCall)
1498 * Check for end of result set.
1500 if (rsinfo.isDone == ExprEndResult)
1504 * Can't do anything very useful with NULL rowtype values. For a
1505 * function returning set, we consider this a protocol violation
1506 * (but another alternative would be to just ignore the result and
1507 * "continue" to get another row). For a function not returning
1508 * set, we fall out of the loop; we'll cons up an all-nulls result
1511 if (returnsTuple && fcinfo.isnull)
1516 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1517 errmsg("function returning set of rows cannot return null value")));
1521 * If first time through, build tupdesc and tuplestore for result
1525 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1529 * Use the type info embedded in the rowtype Datum to look
1530 * up the needed tupdesc. Make a copy for the query.
1534 td = DatumGetHeapTupleHeader(result);
1535 tupdesc = lookup_rowtype_tupdesc_copy(HeapTupleHeaderGetTypeId(td),
1536 HeapTupleHeaderGetTypMod(td));
1541 * Scalar type, so make a single-column descriptor
1543 tupdesc = CreateTemplateTupleDesc(1, false);
1544 TupleDescInitEntry(tupdesc,
1551 tupstore = tuplestore_begin_heap(true, false, work_mem);
1552 MemoryContextSwitchTo(oldcontext);
1553 rsinfo.setResult = tupstore;
1554 rsinfo.setDesc = tupdesc;
1558 * Store current resultset item.
1564 td = DatumGetHeapTupleHeader(result);
1567 * tuplestore_puttuple needs a HeapTuple not a bare
1568 * HeapTupleHeader, but it doesn't need all the fields.
1570 tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
1576 tuple = heap_form_tuple(tupdesc, &result, &fcinfo.isnull);
1579 oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1580 tuplestore_puttuple(tupstore, tuple);
1581 MemoryContextSwitchTo(oldcontext);
1586 if (rsinfo.isDone != ExprMultipleResult)
1589 else if (rsinfo.returnMode == SFRM_Materialize)
1591 /* check we're on the same page as the function author */
1592 if (!first_time || rsinfo.isDone != ExprSingleResult)
1594 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1595 errmsg("table-function protocol for materialize mode was not followed")));
1596 /* Done evaluating the set result */
1601 (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
1602 errmsg("unrecognized table-function returnMode: %d",
1603 (int) rsinfo.returnMode)));
1611 * If we got nothing from the function (ie, an empty-set or NULL result),
1612 * we have to create the tuplestore to return, and if it's a
1613 * non-set-returning function then insert a single all-nulls row.
1615 if (rsinfo.setResult == NULL)
1617 MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1618 tupstore = tuplestore_begin_heap(true, false, work_mem);
1619 rsinfo.setResult = tupstore;
1622 int natts = expectedDesc->natts;
1627 MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1628 nulldatums = (Datum *) palloc0(natts * sizeof(Datum));
1629 nullflags = (bool *) palloc(natts * sizeof(bool));
1630 memset(nullflags, true, natts * sizeof(bool));
1631 tuple = heap_form_tuple(expectedDesc, nulldatums, nullflags);
1632 MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
1633 tuplestore_puttuple(tupstore, tuple);
1637 MemoryContextSwitchTo(callerContext);
1639 /* The returned pointers are those in rsinfo */
1640 *returnDesc = rsinfo.setDesc;
1641 return rsinfo.setResult;
1645 /* ----------------------------------------------------------------
1649 * Evaluate the functional result of a list of arguments by calling the
1651 * ----------------------------------------------------------------
1654 /* ----------------------------------------------------------------
1656 * ----------------------------------------------------------------
1659 ExecEvalFunc(FuncExprState *fcache,
1660 ExprContext *econtext,
1662 ExprDoneCond *isDone)
1664 /* This is called only the first time through */
1665 FuncExpr *func = (FuncExpr *) fcache->xprstate.expr;
1667 /* Initialize function lookup info */
1668 init_fcache(func->funcid, fcache, econtext->ecxt_per_query_memory);
1670 /* Go directly to ExecMakeFunctionResult on subsequent uses */
1671 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
1673 return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
1676 /* ----------------------------------------------------------------
1678 * ----------------------------------------------------------------
1681 ExecEvalOper(FuncExprState *fcache,
1682 ExprContext *econtext,
1684 ExprDoneCond *isDone)
1686 /* This is called only the first time through */
1687 OpExpr *op = (OpExpr *) fcache->xprstate.expr;
1689 /* Initialize function lookup info */
1690 init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory);
1692 /* Go directly to ExecMakeFunctionResult on subsequent uses */
1693 fcache->xprstate.evalfunc = (ExprStateEvalFunc) ExecMakeFunctionResult;
1695 return ExecMakeFunctionResult(fcache, econtext, isNull, isDone);
1698 /* ----------------------------------------------------------------
1701 * IS DISTINCT FROM must evaluate arguments to determine whether
1702 * they are NULL; if either is NULL then the result is already
1703 * known. If neither is NULL, then proceed to evaluate the
1704 * function. Note that this is *always* derived from the equals
1705 * operator, but since we need special processing of the arguments
1706 * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
1707 * ----------------------------------------------------------------
1710 ExecEvalDistinct(FuncExprState *fcache,
1711 ExprContext *econtext,
1713 ExprDoneCond *isDone)
1716 FunctionCallInfoData fcinfo;
1717 ExprDoneCond argDone;
1720 /* Set default values for result flags: non-null, not a set result */
1723 *isDone = ExprSingleResult;
1726 * Initialize function cache if first time through
1728 if (fcache->func.fn_oid == InvalidOid)
1730 DistinctExpr *op = (DistinctExpr *) fcache->xprstate.expr;
1732 init_fcache(op->opfuncid, fcache, econtext->ecxt_per_query_memory);
1733 Assert(!fcache->func.fn_retset);
1737 * extract info from fcache
1739 argList = fcache->args;
1741 /* Need to prep callinfo structure */
1742 InitFunctionCallInfoData(fcinfo, &(fcache->func), 0, NULL, NULL);
1743 argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
1744 if (argDone != ExprSingleResult)
1746 (errcode(ERRCODE_DATATYPE_MISMATCH),
1747 errmsg("IS DISTINCT FROM does not support set arguments")));
1748 Assert(fcinfo.nargs == 2);
1750 if (fcinfo.argnull[0] && fcinfo.argnull[1])
1752 /* Both NULL? Then is not distinct... */
1753 result = BoolGetDatum(FALSE);
1755 else if (fcinfo.argnull[0] || fcinfo.argnull[1])
1757 /* Only one is NULL? Then is distinct... */
1758 result = BoolGetDatum(TRUE);
1762 fcinfo.isnull = false;
1763 result = FunctionCallInvoke(&fcinfo);
1764 *isNull = fcinfo.isnull;
1765 /* Must invert result of "=" */
1766 result = BoolGetDatum(!DatumGetBool(result));
1773 * ExecEvalScalarArrayOp
1775 * Evaluate "scalar op ANY/ALL (array)". The operator always yields boolean,
1776 * and we combine the results across all array elements using OR and AND
1777 * (for ANY and ALL respectively). Of course we short-circuit as soon as
1778 * the result is known.
1781 ExecEvalScalarArrayOp(ScalarArrayOpExprState *sstate,
1782 ExprContext *econtext,
1783 bool *isNull, ExprDoneCond *isDone)
1785 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) sstate->fxprstate.xprstate.expr;
1786 bool useOr = opexpr->useOr;
1791 FunctionCallInfoData fcinfo;
1792 ExprDoneCond argDone;
1801 /* Set default values for result flags: non-null, not a set result */
1804 *isDone = ExprSingleResult;
1807 * Initialize function cache if first time through
1809 if (sstate->fxprstate.func.fn_oid == InvalidOid)
1811 init_fcache(opexpr->opfuncid, &sstate->fxprstate,
1812 econtext->ecxt_per_query_memory);
1813 Assert(!sstate->fxprstate.func.fn_retset);
1816 /* Need to prep callinfo structure */
1817 InitFunctionCallInfoData(fcinfo, &(sstate->fxprstate.func), 0, NULL, NULL);
1818 argDone = ExecEvalFuncArgs(&fcinfo, sstate->fxprstate.args, econtext);
1819 if (argDone != ExprSingleResult)
1821 (errcode(ERRCODE_DATATYPE_MISMATCH),
1822 errmsg("op ANY/ALL (array) does not support set arguments")));
1823 Assert(fcinfo.nargs == 2);
1826 * If the array is NULL then we return NULL --- it's not very meaningful
1827 * to do anything else, even if the operator isn't strict.
1829 if (fcinfo.argnull[1])
1834 /* Else okay to fetch and detoast the array */
1835 arr = DatumGetArrayTypeP(fcinfo.arg[1]);
1838 * If the array is empty, we return either FALSE or TRUE per the useOr
1839 * flag. This is correct even if the scalar is NULL; since we would
1840 * evaluate the operator zero times, it matters not whether it would want
1843 nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
1845 return BoolGetDatum(!useOr);
1848 * If the scalar is NULL, and the function is strict, return NULL; no
1849 * point in iterating the loop.
1851 if (fcinfo.argnull[0] && sstate->fxprstate.func.fn_strict)
1858 * We arrange to look up info about the element type only once per series
1859 * of calls, assuming the element type doesn't change underneath us.
1861 if (sstate->element_type != ARR_ELEMTYPE(arr))
1863 get_typlenbyvalalign(ARR_ELEMTYPE(arr),
1867 sstate->element_type = ARR_ELEMTYPE(arr);
1869 typlen = sstate->typlen;
1870 typbyval = sstate->typbyval;
1871 typalign = sstate->typalign;
1873 result = BoolGetDatum(!useOr);
1876 /* Loop over the array elements */
1877 s = (char *) ARR_DATA_PTR(arr);
1878 bitmap = ARR_NULLBITMAP(arr);
1881 for (i = 0; i < nitems; i++)
1886 /* Get array element, checking for NULL */
1887 if (bitmap && (*bitmap & bitmask) == 0)
1889 fcinfo.arg[1] = (Datum) 0;
1890 fcinfo.argnull[1] = true;
1894 elt = fetch_att(s, typbyval, typlen);
1895 s = att_addlength(s, typlen, PointerGetDatum(s));
1896 s = (char *) att_align(s, typalign);
1897 fcinfo.arg[1] = elt;
1898 fcinfo.argnull[1] = false;
1901 /* Call comparison function */
1902 if (fcinfo.argnull[1] && sstate->fxprstate.func.fn_strict)
1904 fcinfo.isnull = true;
1905 thisresult = (Datum) 0;
1909 fcinfo.isnull = false;
1910 thisresult = FunctionCallInvoke(&fcinfo);
1913 /* Combine results per OR or AND semantics */
1918 if (DatumGetBool(thisresult))
1920 result = BoolGetDatum(true);
1922 break; /* needn't look at any more elements */
1927 if (!DatumGetBool(thisresult))
1929 result = BoolGetDatum(false);
1931 break; /* needn't look at any more elements */
1935 /* advance bitmap pointer if any */
1939 if (bitmask == 0x100)
1947 *isNull = resultnull;
1951 /* ----------------------------------------------------------------
1956 * Evaluate boolean expressions, with appropriate short-circuiting.
1958 * The query planner reformulates clause expressions in the
1959 * qualification to conjunctive normal form. If we ever get
1960 * an AND to evaluate, we can be sure that it's not a top-level
1961 * clause in the qualification, but appears lower (as a function
1962 * argument, for example), or in the target list. Not that you
1963 * need to know this, mind you...
1964 * ----------------------------------------------------------------
1967 ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
1968 bool *isNull, ExprDoneCond *isDone)
1970 ExprState *clause = linitial(notclause->args);
1974 *isDone = ExprSingleResult;
1976 expr_value = ExecEvalExpr(clause, econtext, isNull, NULL);
1979 * if the expression evaluates to null, then we just cascade the null back
1980 * to whoever called us.
1986 * evaluation of 'not' is simple.. expr is false, then return 'true' and
1989 return BoolGetDatum(!DatumGetBool(expr_value));
1992 /* ----------------------------------------------------------------
1994 * ----------------------------------------------------------------
1997 ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
1998 bool *isNull, ExprDoneCond *isDone)
2000 List *clauses = orExpr->args;
2005 *isDone = ExprSingleResult;
2010 * If any of the clauses is TRUE, the OR result is TRUE regardless of the
2011 * states of the rest of the clauses, so we can stop evaluating and return
2012 * TRUE immediately. If none are TRUE and one or more is NULL, we return
2013 * NULL; otherwise we return FALSE. This makes sense when you interpret
2014 * NULL as "don't know": if we have a TRUE then the OR is TRUE even if we
2015 * aren't sure about some of the other inputs. If all the known inputs are
2016 * FALSE, but we have one or more "don't knows", then we have to report
2017 * that we "don't know" what the OR's result should be --- perhaps one of
2018 * the "don't knows" would have been TRUE if we'd known its value. Only
2019 * when all the inputs are known to be FALSE can we state confidently that
2020 * the OR's result is FALSE.
2022 foreach(clause, clauses)
2024 ExprState *clausestate = (ExprState *) lfirst(clause);
2027 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
2030 * if we have a non-null true result, then return it.
2033 AnyNull = true; /* remember we got a null */
2034 else if (DatumGetBool(clause_value))
2035 return clause_value;
2038 /* AnyNull is true if at least one clause evaluated to NULL */
2040 return BoolGetDatum(false);
2043 /* ----------------------------------------------------------------
2045 * ----------------------------------------------------------------
2048 ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
2049 bool *isNull, ExprDoneCond *isDone)
2051 List *clauses = andExpr->args;
2056 *isDone = ExprSingleResult;
2061 * If any of the clauses is FALSE, the AND result is FALSE regardless of
2062 * the states of the rest of the clauses, so we can stop evaluating and
2063 * return FALSE immediately. If none are FALSE and one or more is NULL,
2064 * we return NULL; otherwise we return TRUE. This makes sense when you
2065 * interpret NULL as "don't know", using the same sort of reasoning as for
2069 foreach(clause, clauses)
2071 ExprState *clausestate = (ExprState *) lfirst(clause);
2074 clause_value = ExecEvalExpr(clausestate, econtext, isNull, NULL);
2077 * if we have a non-null false result, then return it.
2080 AnyNull = true; /* remember we got a null */
2081 else if (!DatumGetBool(clause_value))
2082 return clause_value;
2085 /* AnyNull is true if at least one clause evaluated to NULL */
2087 return BoolGetDatum(!AnyNull);
2090 /* ----------------------------------------------------------------
2091 * ExecEvalConvertRowtype
2093 * Evaluate a rowtype coercion operation. This may require
2094 * rearranging field positions.
2095 * ----------------------------------------------------------------
2098 ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
2099 ExprContext *econtext,
2100 bool *isNull, ExprDoneCond *isDone)
2102 ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) cstate->xprstate.expr;
2105 HeapTupleHeader tuple;
2106 HeapTupleData tmptup;
2107 AttrNumber *attrMap;
2115 tupDatum = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
2117 /* this test covers the isDone exception too: */
2121 tuple = DatumGetHeapTupleHeader(tupDatum);
2123 /* Lookup tupdescs if first time through or after rescan */
2124 if (cstate->indesc == NULL)
2125 get_cached_rowtype(exprType((Node *) convert->arg), -1,
2126 &cstate->indesc, econtext);
2127 if (cstate->outdesc == NULL)
2128 get_cached_rowtype(convert->resulttype, -1,
2129 &cstate->outdesc, econtext);
2131 Assert(HeapTupleHeaderGetTypeId(tuple) == cstate->indesc->tdtypeid);
2132 Assert(HeapTupleHeaderGetTypMod(tuple) == cstate->indesc->tdtypmod);
2134 /* if first time through, initialize */
2135 if (cstate->attrMap == NULL)
2137 MemoryContext old_cxt;
2140 /* allocate state in long-lived memory context */
2141 old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
2143 /* prepare map from old to new attribute numbers */
2144 n = cstate->outdesc->natts;
2145 cstate->attrMap = (AttrNumber *) palloc0(n * sizeof(AttrNumber));
2146 for (i = 0; i < n; i++)
2148 Form_pg_attribute att = cstate->outdesc->attrs[i];
2154 if (att->attisdropped)
2155 continue; /* attrMap[i] is already 0 */
2156 attname = NameStr(att->attname);
2157 atttypid = att->atttypid;
2158 atttypmod = att->atttypmod;
2159 for (j = 0; j < cstate->indesc->natts; j++)
2161 att = cstate->indesc->attrs[j];
2162 if (att->attisdropped)
2164 if (strcmp(attname, NameStr(att->attname)) == 0)
2166 /* Found it, check type */
2167 if (atttypid != att->atttypid || atttypmod != att->atttypmod)
2168 elog(ERROR, "attribute \"%s\" of type %s does not match corresponding attribute of type %s",
2170 format_type_be(cstate->indesc->tdtypeid),
2171 format_type_be(cstate->outdesc->tdtypeid));
2172 cstate->attrMap[i] = (AttrNumber) (j + 1);
2176 if (cstate->attrMap[i] == 0)
2177 elog(ERROR, "attribute \"%s\" of type %s does not exist",
2179 format_type_be(cstate->indesc->tdtypeid));
2181 /* preallocate workspace for Datum arrays */
2182 n = cstate->indesc->natts + 1; /* +1 for NULL */
2183 cstate->invalues = (Datum *) palloc(n * sizeof(Datum));
2184 cstate->inisnull = (bool *) palloc(n * sizeof(bool));
2185 n = cstate->outdesc->natts;
2186 cstate->outvalues = (Datum *) palloc(n * sizeof(Datum));
2187 cstate->outisnull = (bool *) palloc(n * sizeof(bool));
2189 MemoryContextSwitchTo(old_cxt);
2192 attrMap = cstate->attrMap;
2193 invalues = cstate->invalues;
2194 inisnull = cstate->inisnull;
2195 outvalues = cstate->outvalues;
2196 outisnull = cstate->outisnull;
2197 outnatts = cstate->outdesc->natts;
2200 * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader.
2202 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
2203 tmptup.t_data = tuple;
2206 * Extract all the values of the old tuple, offsetting the arrays so that
2207 * invalues[0] is NULL and invalues[1] is the first source attribute; this
2208 * exactly matches the numbering convention in attrMap.
2210 heap_deform_tuple(&tmptup, cstate->indesc, invalues + 1, inisnull + 1);
2211 invalues[0] = (Datum) 0;
2215 * Transpose into proper fields of the new tuple.
2217 for (i = 0; i < outnatts; i++)
2221 outvalues[i] = invalues[j];
2222 outisnull[i] = inisnull[j];
2226 * Now form the new tuple.
2228 result = heap_form_tuple(cstate->outdesc, outvalues, outisnull);
2230 return HeapTupleGetDatum(result);
2233 /* ----------------------------------------------------------------
2236 * Evaluate a CASE clause. Will have boolean expressions
2237 * inside the WHEN clauses, and will have expressions
2239 * - thomas 1998-11-09
2240 * ----------------------------------------------------------------
2243 ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
2244 bool *isNull, ExprDoneCond *isDone)
2246 List *clauses = caseExpr->args;
2252 *isDone = ExprSingleResult;
2255 * If there's a test expression, we have to evaluate it and save the value
2256 * where the CaseTestExpr placeholders can find it. We must save and
2257 * restore prior setting of econtext's caseValue fields, in case this node
2258 * is itself within a larger CASE.
2260 save_datum = econtext->caseValue_datum;
2261 save_isNull = econtext->caseValue_isNull;
2265 econtext->caseValue_datum = ExecEvalExpr(caseExpr->arg,
2267 &econtext->caseValue_isNull,
2272 * we evaluate each of the WHEN clauses in turn, as soon as one is true we
2273 * return the corresponding result. If none are true then we return the
2274 * value of the default clause, or NULL if there is none.
2276 foreach(clause, clauses)
2278 CaseWhenState *wclause = lfirst(clause);
2281 clause_value = ExecEvalExpr(wclause->expr,
2287 * if we have a true test, then we return the result, since the case
2288 * statement is satisfied. A NULL result from the test is not
2291 if (DatumGetBool(clause_value) && !*isNull)
2293 econtext->caseValue_datum = save_datum;
2294 econtext->caseValue_isNull = save_isNull;
2295 return ExecEvalExpr(wclause->result,
2302 econtext->caseValue_datum = save_datum;
2303 econtext->caseValue_isNull = save_isNull;
2305 if (caseExpr->defresult)
2307 return ExecEvalExpr(caseExpr->defresult,
2318 * ExecEvalCaseTestExpr
2320 * Return the value stored by CASE.
2323 ExecEvalCaseTestExpr(ExprState *exprstate,
2324 ExprContext *econtext,
2325 bool *isNull, ExprDoneCond *isDone)
2328 *isDone = ExprSingleResult;
2329 *isNull = econtext->caseValue_isNull;
2330 return econtext->caseValue_datum;
2333 /* ----------------------------------------------------------------
2334 * ExecEvalArray - ARRAY[] expressions
2335 * ----------------------------------------------------------------
2338 ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
2339 bool *isNull, ExprDoneCond *isDone)
2341 ArrayExpr *arrayExpr = (ArrayExpr *) astate->xprstate.expr;
2344 Oid element_type = arrayExpr->element_typeid;
2349 /* Set default values for result flags: non-null, not a set result */
2352 *isDone = ExprSingleResult;
2354 if (!arrayExpr->multidims)
2356 /* Elements are presumably of scalar type */
2363 nelems = list_length(astate->elements);
2365 /* Shouldn't happen here, but if length is 0, return empty array */
2367 return PointerGetDatum(construct_empty_array(element_type));
2369 dvalues = (Datum *) palloc(nelems * sizeof(Datum));
2370 dnulls = (bool *) palloc(nelems * sizeof(bool));
2372 /* loop through and build array of datums */
2373 foreach(element, astate->elements)
2375 ExprState *e = (ExprState *) lfirst(element);
2377 dvalues[i] = ExecEvalExpr(e, econtext, &dnulls[i], NULL);
2381 /* setup for 1-D array of the given length */
2385 result = construct_md_array(dvalues, dnulls, ndims, dims, lbs,
2393 /* Must be nested array expressions */
2396 int outer_nelems = 0;
2398 int *elem_dims = NULL;
2399 int *elem_lbs = NULL;
2400 bool firstone = true;
2401 bool havenulls = false;
2402 bool haveempty = false;
2412 i = list_length(astate->elements);
2413 subdata = (char **) palloc(i * sizeof(char *));
2414 subbitmaps = (bits8 **) palloc(i * sizeof(bits8 *));
2415 subbytes = (int *) palloc(i * sizeof(int));
2416 subnitems = (int *) palloc(i * sizeof(int));
2418 /* loop through and get data area from each element */
2419 foreach(element, astate->elements)
2421 ExprState *e = (ExprState *) lfirst(element);
2427 arraydatum = ExecEvalExpr(e, econtext, &eisnull, NULL);
2428 /* temporarily ignore null subarrays */
2435 array = DatumGetArrayTypeP(arraydatum);
2437 /* run-time double-check on element type */
2438 if (element_type != ARR_ELEMTYPE(array))
2440 (errcode(ERRCODE_DATATYPE_MISMATCH),
2441 errmsg("cannot merge incompatible arrays"),
2442 errdetail("Array with element type %s cannot be "
2443 "included in ARRAY construct with element type %s.",
2444 format_type_be(ARR_ELEMTYPE(array)),
2445 format_type_be(element_type))));
2447 this_ndims = ARR_NDIM(array);
2448 /* temporarily ignore zero-dimensional subarrays */
2449 if (this_ndims <= 0)
2457 /* Get sub-array details from first member */
2458 elem_ndims = this_ndims;
2459 ndims = elem_ndims + 1;
2460 if (ndims <= 0 || ndims > MAXDIM)
2462 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2463 errmsg("number of array dimensions (%d) exceeds " \
2464 "the maximum allowed (%d)", ndims, MAXDIM)));
2466 elem_dims = (int *) palloc(elem_ndims * sizeof(int));
2467 memcpy(elem_dims, ARR_DIMS(array), elem_ndims * sizeof(int));
2468 elem_lbs = (int *) palloc(elem_ndims * sizeof(int));
2469 memcpy(elem_lbs, ARR_LBOUND(array), elem_ndims * sizeof(int));
2475 /* Check other sub-arrays are compatible */
2476 if (elem_ndims != this_ndims ||
2477 memcmp(elem_dims, ARR_DIMS(array),
2478 elem_ndims * sizeof(int)) != 0 ||
2479 memcmp(elem_lbs, ARR_LBOUND(array),
2480 elem_ndims * sizeof(int)) != 0)
2482 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2483 errmsg("multidimensional arrays must have array "
2484 "expressions with matching dimensions")));
2487 subdata[outer_nelems] = ARR_DATA_PTR(array);
2488 subbitmaps[outer_nelems] = ARR_NULLBITMAP(array);
2489 subbytes[outer_nelems] = ARR_SIZE(array) - ARR_DATA_OFFSET(array);
2490 nbytes += subbytes[outer_nelems];
2491 subnitems[outer_nelems] = ArrayGetNItems(this_ndims,
2493 nitems += subnitems[outer_nelems];
2494 havenulls |= ARR_HASNULL(array);
2499 * If all items were null or empty arrays, return an empty array;
2500 * otherwise, if some were and some weren't, raise error. (Note:
2501 * we must special-case this somehow to avoid trying to generate
2502 * a 1-D array formed from empty arrays. It's not ideal...)
2506 if (ndims == 0) /* didn't find any nonempty array */
2507 return PointerGetDatum(construct_empty_array(element_type));
2509 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2510 errmsg("multidimensional arrays must have array "
2511 "expressions with matching dimensions")));
2514 /* setup for multi-D array */
2515 dims[0] = outer_nelems;
2517 for (i = 1; i < ndims; i++)
2519 dims[i] = elem_dims[i - 1];
2520 lbs[i] = elem_lbs[i - 1];
2525 dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nitems);
2526 nbytes += dataoffset;
2530 dataoffset = 0; /* marker for no null bitmap */
2531 nbytes += ARR_OVERHEAD_NONULLS(ndims);
2534 result = (ArrayType *) palloc(nbytes);
2535 result->size = nbytes;
2536 result->ndim = ndims;
2537 result->dataoffset = dataoffset;
2538 result->elemtype = element_type;
2539 memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
2540 memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
2542 dat = ARR_DATA_PTR(result);
2544 for (i = 0; i < outer_nelems; i++)
2546 memcpy(dat, subdata[i], subbytes[i]);
2549 array_bitmap_copy(ARR_NULLBITMAP(result), iitem,
2552 iitem += subnitems[i];
2556 return PointerGetDatum(result);
2559 /* ----------------------------------------------------------------
2560 * ExecEvalRow - ROW() expressions
2561 * ----------------------------------------------------------------
2564 ExecEvalRow(RowExprState *rstate,
2565 ExprContext *econtext,
2566 bool *isNull, ExprDoneCond *isDone)
2575 /* Set default values for result flags: non-null, not a set result */
2578 *isDone = ExprSingleResult;
2580 /* Allocate workspace */
2581 natts = rstate->tupdesc->natts;
2582 values = (Datum *) palloc0(natts * sizeof(Datum));
2583 isnull = (bool *) palloc(natts * sizeof(bool));
2585 /* preset to nulls in case rowtype has some later-added columns */
2586 memset(isnull, true, natts * sizeof(bool));
2588 /* Evaluate field values */
2590 foreach(arg, rstate->args)
2592 ExprState *e = (ExprState *) lfirst(arg);
2594 values[i] = ExecEvalExpr(e, econtext, &isnull[i], NULL);
2598 tuple = heap_form_tuple(rstate->tupdesc, values, isnull);
2603 return HeapTupleGetDatum(tuple);
2606 /* ----------------------------------------------------------------
2607 * ExecEvalRowCompare - ROW() comparison-op ROW()
2608 * ----------------------------------------------------------------
2611 ExecEvalRowCompare(RowCompareExprState *rstate,
2612 ExprContext *econtext,
2613 bool *isNull, ExprDoneCond *isDone)
2616 RowCompareType rctype = ((RowCompareExpr *) rstate->xprstate.expr)->rctype;
2617 int32 cmpresult = 0;
2623 *isDone = ExprSingleResult;
2624 *isNull = true; /* until we get a result */
2627 forboth(l, rstate->largs, r, rstate->rargs)
2629 ExprState *le = (ExprState *) lfirst(l);
2630 ExprState *re = (ExprState *) lfirst(r);
2631 FunctionCallInfoData locfcinfo;
2633 InitFunctionCallInfoData(locfcinfo, &(rstate->funcs[i]), 2,
2635 locfcinfo.arg[0] = ExecEvalExpr(le, econtext,
2636 &locfcinfo.argnull[0], NULL);
2637 locfcinfo.arg[1] = ExecEvalExpr(re, econtext,
2638 &locfcinfo.argnull[1], NULL);
2639 if (rstate->funcs[i].fn_strict &&
2640 (locfcinfo.argnull[0] || locfcinfo.argnull[1]))
2641 return (Datum) 0; /* force NULL result */
2642 locfcinfo.isnull = false;
2643 cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
2644 if (locfcinfo.isnull)
2645 return (Datum) 0; /* force NULL result */
2647 break; /* no need to compare remaining columns */
2653 /* EQ and NE cases aren't allowed here */
2655 result = (cmpresult < 0);
2658 result = (cmpresult <= 0);
2661 result = (cmpresult >= 0);
2664 result = (cmpresult > 0);
2667 elog(ERROR, "unrecognized RowCompareType: %d", (int) rctype);
2668 result = 0; /* keep compiler quiet */
2673 return BoolGetDatum(result);
2676 /* ----------------------------------------------------------------
2678 * ----------------------------------------------------------------
2681 ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
2682 bool *isNull, ExprDoneCond *isDone)
2687 *isDone = ExprSingleResult;
2689 /* Simply loop through until something NOT NULL is found */
2690 foreach(arg, coalesceExpr->args)
2692 ExprState *e = (ExprState *) lfirst(arg);
2695 value = ExecEvalExpr(e, econtext, isNull, NULL);
2700 /* Else return NULL */
2705 /* ----------------------------------------------------------------
2707 * ----------------------------------------------------------------
2710 ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
2711 bool *isNull, ExprDoneCond *isDone)
2713 Datum result = (Datum) 0;
2714 MinMaxOp op = ((MinMaxExpr *) minmaxExpr->xprstate.expr)->op;
2715 FunctionCallInfoData locfcinfo;
2719 *isDone = ExprSingleResult;
2720 *isNull = true; /* until we get a result */
2722 InitFunctionCallInfoData(locfcinfo, &minmaxExpr->cfunc, 2, NULL, NULL);
2723 locfcinfo.argnull[0] = false;
2724 locfcinfo.argnull[1] = false;
2726 foreach(arg, minmaxExpr->args)
2728 ExprState *e = (ExprState *) lfirst(arg);
2733 value = ExecEvalExpr(e, econtext, &valueIsNull, NULL);
2735 continue; /* ignore NULL inputs */
2739 /* first nonnull input, adopt value */
2745 /* apply comparison function */
2746 locfcinfo.arg[0] = result;
2747 locfcinfo.arg[1] = value;
2748 locfcinfo.isnull = false;
2749 cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo));
2750 if (locfcinfo.isnull) /* probably should not happen */
2752 if (cmpresult > 0 && op == IS_LEAST)
2754 else if (cmpresult < 0 && op == IS_GREATEST)
2762 /* ----------------------------------------------------------------
2764 * ----------------------------------------------------------------
2767 ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
2768 bool *isNull, ExprDoneCond *isDone)
2770 XmlExpr *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
2780 *isDone = ExprSingleResult;
2781 *isNull = true; /* until we get a result */
2789 foreach(arg, xmlExpr->args)
2791 ExprState *e = (ExprState *) lfirst(arg);
2793 value = ExecEvalExpr(e, econtext, &isnull, NULL);
2795 values = lappend(values, DatumGetPointer(value));
2798 if (list_length(values) > 0)
2801 return PointerGetDatum(xmlconcat(values));
2807 initStringInfo(&buf);
2809 forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
2811 ExprState *e = (ExprState *) lfirst(arg);
2812 char *argname = strVal(lfirst(narg));
2814 value = ExecEvalExpr(e, econtext, &isnull, NULL);
2817 appendStringInfo(&buf, "<%s>%s</%s>",
2819 map_sql_value_to_xml_value(value, exprType((Node *) e->expr)),
2827 /* The remaining cases don't need to set up buf */
2830 return PointerGetDatum(xmlelement(xmlExpr, econtext));
2837 bool preserve_whitespace;
2839 /* arguments are known to be text, bool */
2840 Assert(list_length(xmlExpr->args) == 2);
2842 e = (ExprState *) linitial(xmlExpr->args);
2843 value = ExecEvalExpr(e, econtext, &isnull, NULL);
2846 data = DatumGetTextP(value);
2848 e = (ExprState *) lsecond(xmlExpr->args);
2849 value = ExecEvalExpr(e, econtext, &isnull, NULL);
2850 if (isnull) /* probably can't happen */
2852 preserve_whitespace = DatumGetBool(value);
2856 return PointerGetDatum(xmlparse(data,
2858 preserve_whitespace));
2867 /* optional argument is known to be text */
2868 Assert(list_length(xmlExpr->args) <= 1);
2872 e = (ExprState *) linitial(xmlExpr->args);
2873 value = ExecEvalExpr(e, econtext, &isnull, NULL);
2877 arg = DatumGetTextP(value);
2885 return PointerGetDatum(xmlpi(xexpr->name, arg, isnull, isNull));
2896 /* arguments are known to be xml, text, int */
2897 Assert(list_length(xmlExpr->args) == 3);
2899 e = (ExprState *) linitial(xmlExpr->args);
2900 value = ExecEvalExpr(e, econtext, &isnull, NULL);
2903 data = DatumGetXmlP(value);
2905 e = (ExprState *) lsecond(xmlExpr->args);
2906 value = ExecEvalExpr(e, econtext, &isnull, NULL);
2910 version = DatumGetTextP(value);
2912 e = (ExprState *) lthird(xmlExpr->args);
2913 value = ExecEvalExpr(e, econtext, &isnull, NULL);
2914 standalone = DatumGetInt32(value);
2918 return PointerGetDatum(xmlroot(data,
2924 case IS_XMLSERIALIZE:
2928 /* argument type is known to be xml */
2929 Assert(list_length(xmlExpr->args) == 1);
2931 e = (ExprState *) linitial(xmlExpr->args);
2932 value = ExecEvalExpr(e, econtext, &isnull, NULL);
2938 return PointerGetDatum(xmltotext_with_xmloption(DatumGetXmlP(value), xexpr->xmloption));
2946 /* optional argument is known to be xml */
2947 Assert(list_length(xmlExpr->args) == 1);
2949 e = (ExprState *) linitial(xmlExpr->args);
2950 value = ExecEvalExpr(e, econtext, &isnull, NULL);
2956 return BoolGetDatum(xml_is_document(DatumGetXmlP(value)));
2966 int len = buf.len + VARHDRSZ;
2968 result = palloc(len);
2969 VARATT_SIZEP(result) = len;
2970 memcpy(VARDATA(result), buf.data, buf.len);
2974 return PointerGetDatum(result);
2977 /* ----------------------------------------------------------------
2980 * Note that this is *always* derived from the equals operator,
2981 * but since we need special processing of the arguments
2982 * we can not simply reuse ExecEvalOper() or ExecEvalFunc().
2983 * ----------------------------------------------------------------
2986 ExecEvalNullIf(FuncExprState *nullIfExpr,
2987 ExprContext *econtext,
2988 bool *isNull, ExprDoneCond *isDone)
2991 FunctionCallInfoData fcinfo;
2992 ExprDoneCond argDone;
2996 *isDone = ExprSingleResult;
2999 * Initialize function cache if first time through
3001 if (nullIfExpr->func.fn_oid == InvalidOid)
3003 NullIfExpr *op = (NullIfExpr *) nullIfExpr->xprstate.expr;
3005 init_fcache(op->opfuncid, nullIfExpr, econtext->ecxt_per_query_memory);
3006 Assert(!nullIfExpr->func.fn_retset);
3010 * extract info from nullIfExpr
3012 argList = nullIfExpr->args;
3014 /* Need to prep callinfo structure */
3015 InitFunctionCallInfoData(fcinfo, &(nullIfExpr->func), 0, NULL, NULL);
3016 argDone = ExecEvalFuncArgs(&fcinfo, argList, econtext);
3017 if (argDone != ExprSingleResult)
3019 (errcode(ERRCODE_DATATYPE_MISMATCH),
3020 errmsg("NULLIF does not support set arguments")));
3021 Assert(fcinfo.nargs == 2);
3023 /* if either argument is NULL they can't be equal */
3024 if (!fcinfo.argnull[0] && !fcinfo.argnull[1])
3026 fcinfo.isnull = false;
3027 result = FunctionCallInvoke(&fcinfo);
3028 /* if the arguments are equal return null */
3029 if (!fcinfo.isnull && DatumGetBool(result))
3036 /* else return first argument */
3037 *isNull = fcinfo.argnull[0];
3038 return fcinfo.arg[0];
3041 /* ----------------------------------------------------------------
3044 * Evaluate a NullTest node.
3045 * ----------------------------------------------------------------
3048 ExecEvalNullTest(NullTestState *nstate,
3049 ExprContext *econtext,
3051 ExprDoneCond *isDone)
3053 NullTest *ntest = (NullTest *) nstate->xprstate.expr;
3056 result = ExecEvalExpr(nstate->arg, econtext, isNull, isDone);
3058 if (isDone && *isDone == ExprEndResult)
3059 return result; /* nothing to check */
3061 if (nstate->argisrow && !(*isNull))
3063 HeapTupleHeader tuple;
3067 HeapTupleData tmptup;
3070 tuple = DatumGetHeapTupleHeader(result);
3072 tupType = HeapTupleHeaderGetTypeId(tuple);
3073 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3075 /* Lookup tupdesc if first time through or if type changes */
3076 tupDesc = get_cached_rowtype(tupType, tupTypmod,
3077 &nstate->argdesc, econtext);
3080 * heap_attisnull needs a HeapTuple not a bare HeapTupleHeader.
3082 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3083 tmptup.t_data = tuple;
3085 for (att = 1; att <= tupDesc->natts; att++)
3087 /* ignore dropped columns */
3088 if (tupDesc->attrs[att - 1]->attisdropped)
3090 if (heap_attisnull(&tmptup, att))
3092 /* null field disproves IS NOT NULL */
3093 if (ntest->nulltesttype == IS_NOT_NULL)
3094 return BoolGetDatum(false);
3098 /* non-null field disproves IS NULL */
3099 if (ntest->nulltesttype == IS_NULL)
3100 return BoolGetDatum(false);
3104 return BoolGetDatum(true);
3108 /* Simple scalar-argument case, or a null rowtype datum */
3109 switch (ntest->nulltesttype)
3115 return BoolGetDatum(true);
3118 return BoolGetDatum(false);
3123 return BoolGetDatum(false);
3126 return BoolGetDatum(true);
3128 elog(ERROR, "unrecognized nulltesttype: %d",
3129 (int) ntest->nulltesttype);
3130 return (Datum) 0; /* keep compiler quiet */
3135 /* ----------------------------------------------------------------
3136 * ExecEvalBooleanTest
3138 * Evaluate a BooleanTest node.
3139 * ----------------------------------------------------------------
3142 ExecEvalBooleanTest(GenericExprState *bstate,
3143 ExprContext *econtext,
3145 ExprDoneCond *isDone)
3147 BooleanTest *btest = (BooleanTest *) bstate->xprstate.expr;
3150 result = ExecEvalExpr(bstate->arg, econtext, isNull, isDone);
3152 if (isDone && *isDone == ExprEndResult)
3153 return result; /* nothing to check */
3155 switch (btest->booltesttype)
3161 return BoolGetDatum(false);
3163 else if (DatumGetBool(result))
3164 return BoolGetDatum(true);
3166 return BoolGetDatum(false);
3171 return BoolGetDatum(true);
3173 else if (DatumGetBool(result))
3174 return BoolGetDatum(false);
3176 return BoolGetDatum(true);
3181 return BoolGetDatum(false);
3183 else if (DatumGetBool(result))
3184 return BoolGetDatum(false);
3186 return BoolGetDatum(true);
3191 return BoolGetDatum(true);
3193 else if (DatumGetBool(result))
3194 return BoolGetDatum(true);
3196 return BoolGetDatum(false);
3201 return BoolGetDatum(true);
3204 return BoolGetDatum(false);
3205 case IS_NOT_UNKNOWN:
3209 return BoolGetDatum(false);
3212 return BoolGetDatum(true);
3214 elog(ERROR, "unrecognized booltesttype: %d",
3215 (int) btest->booltesttype);
3216 return (Datum) 0; /* keep compiler quiet */
3221 * ExecEvalCoerceToDomain
3223 * Test the provided data against the domain constraint(s). If the data
3224 * passes the constraint specifications, pass it through (return the
3225 * datum) otherwise throw an error.
3228 ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
3229 bool *isNull, ExprDoneCond *isDone)
3231 CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
3235 result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
3237 if (isDone && *isDone == ExprEndResult)
3238 return result; /* nothing to check */
3240 foreach(l, cstate->constraints)
3242 DomainConstraintState *con = (DomainConstraintState *) lfirst(l);
3244 switch (con->constrainttype)
3246 case DOM_CONSTRAINT_NOTNULL:
3249 (errcode(ERRCODE_NOT_NULL_VIOLATION),
3250 errmsg("domain %s does not allow null values",
3251 format_type_be(ctest->resulttype))));
3253 case DOM_CONSTRAINT_CHECK:
3261 * Set up value to be returned by CoerceToDomainValue
3262 * nodes. We must save and restore prior setting of
3263 * econtext's domainValue fields, in case this node is
3264 * itself within a check expression for another domain.
3266 save_datum = econtext->domainValue_datum;
3267 save_isNull = econtext->domainValue_isNull;
3269 econtext->domainValue_datum = result;
3270 econtext->domainValue_isNull = *isNull;
3272 conResult = ExecEvalExpr(con->check_expr,
3273 econtext, &conIsNull, NULL);
3276 !DatumGetBool(conResult))
3278 (errcode(ERRCODE_CHECK_VIOLATION),
3279 errmsg("value for domain %s violates check constraint \"%s\"",
3280 format_type_be(ctest->resulttype),
3282 econtext->domainValue_datum = save_datum;
3283 econtext->domainValue_isNull = save_isNull;
3288 elog(ERROR, "unrecognized constraint type: %d",
3289 (int) con->constrainttype);
3294 /* If all has gone well (constraints did not fail) return the datum */
3299 * ExecEvalCoerceToDomainValue
3301 * Return the value stored by CoerceToDomain.
3304 ExecEvalCoerceToDomainValue(ExprState *exprstate,
3305 ExprContext *econtext,
3306 bool *isNull, ExprDoneCond *isDone)
3309 *isDone = ExprSingleResult;
3310 *isNull = econtext->domainValue_isNull;
3311 return econtext->domainValue_datum;
3314 /* ----------------------------------------------------------------
3315 * ExecEvalFieldSelect
3317 * Evaluate a FieldSelect node.
3318 * ----------------------------------------------------------------
3321 ExecEvalFieldSelect(FieldSelectState *fstate,
3322 ExprContext *econtext,
3324 ExprDoneCond *isDone)
3326 FieldSelect *fselect = (FieldSelect *) fstate->xprstate.expr;
3327 AttrNumber fieldnum = fselect->fieldnum;
3330 HeapTupleHeader tuple;
3334 Form_pg_attribute attr;
3335 HeapTupleData tmptup;
3337 tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
3339 /* this test covers the isDone exception too: */
3343 tuple = DatumGetHeapTupleHeader(tupDatum);
3345 tupType = HeapTupleHeaderGetTypeId(tuple);
3346 tupTypmod = HeapTupleHeaderGetTypMod(tuple);
3348 /* Lookup tupdesc if first time through or if type changes */
3349 tupDesc = get_cached_rowtype(tupType, tupTypmod,
3350 &fstate->argdesc, econtext);
3352 /* Check for dropped column, and force a NULL result if so */
3353 if (fieldnum <= 0 ||
3354 fieldnum > tupDesc->natts) /* should never happen */
3355 elog(ERROR, "attribute number %d exceeds number of columns %d",
3356 fieldnum, tupDesc->natts);
3357 attr = tupDesc->attrs[fieldnum - 1];
3358 if (attr->attisdropped)
3364 /* Check for type mismatch --- possible after ALTER COLUMN TYPE? */
3365 if (fselect->resulttype != attr->atttypid ||
3366 (fselect->resulttypmod != attr->atttypmod &&
3367 fselect->resulttypmod != -1))
3369 (errmsg("attribute %d has wrong type", fieldnum),
3370 errdetail("Table has type %s, but query expects %s.",
3371 format_type_be(attr->atttypid),
3372 format_type_be(fselect->resulttype))));
3375 * heap_getattr needs a HeapTuple not a bare HeapTupleHeader. We set all
3376 * the fields in the struct just in case user tries to inspect system
3379 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple);
3380 ItemPointerSetInvalid(&(tmptup.t_self));
3381 tmptup.t_tableOid = InvalidOid;
3382 tmptup.t_data = tuple;
3384 result = heap_getattr(&tmptup,
3391 /* ----------------------------------------------------------------
3392 * ExecEvalFieldStore
3394 * Evaluate a FieldStore node.
3395 * ----------------------------------------------------------------
3398 ExecEvalFieldStore(FieldStoreState *fstate,
3399 ExprContext *econtext,
3401 ExprDoneCond *isDone)
3403 FieldStore *fstore = (FieldStore *) fstate->xprstate.expr;
3414 tupDatum = ExecEvalExpr(fstate->arg, econtext, isNull, isDone);
3416 if (isDone && *isDone == ExprEndResult)
3419 /* Lookup tupdesc if first time through or after rescan */
3420 tupDesc = get_cached_rowtype(fstore->resulttype, -1,
3421 &fstate->argdesc, econtext);
3423 /* Allocate workspace */
3424 values = (Datum *) palloc(tupDesc->natts * sizeof(Datum));
3425 isnull = (bool *) palloc(tupDesc->natts * sizeof(bool));
3430 * heap_deform_tuple needs a HeapTuple not a bare HeapTupleHeader. We
3431 * set all the fields in the struct just in case.
3433 HeapTupleHeader tuphdr;
3434 HeapTupleData tmptup;
3436 tuphdr = DatumGetHeapTupleHeader(tupDatum);
3437 tmptup.t_len = HeapTupleHeaderGetDatumLength(tuphdr);
3438 ItemPointerSetInvalid(&(tmptup.t_self));
3439 tmptup.t_tableOid = InvalidOid;
3440 tmptup.t_data = tuphdr;
3442 heap_deform_tuple(&tmptup, tupDesc, values, isnull);
3446 /* Convert null input tuple into an all-nulls row */
3447 memset(isnull, true, tupDesc->natts * sizeof(bool));
3450 /* Result is never null */
3453 save_datum = econtext->caseValue_datum;
3454 save_isNull = econtext->caseValue_isNull;
3456 forboth(l1, fstate->newvals, l2, fstore->fieldnums)
3458 ExprState *newval = (ExprState *) lfirst(l1);
3459 AttrNumber fieldnum = lfirst_int(l2);
3461 Assert(fieldnum > 0 && fieldnum <= tupDesc->natts);
3464 * Use the CaseTestExpr mechanism to pass down the old value of the
3465 * field being replaced; this is useful in case we have a nested field
3466 * update situation. It's safe to reuse the CASE mechanism because
3467 * there cannot be a CASE between here and where the value would be
3470 econtext->caseValue_datum = values[fieldnum - 1];
3471 econtext->caseValue_isNull = isnull[fieldnum - 1];
3473 values[fieldnum - 1] = ExecEvalExpr(newval,
3475 &isnull[fieldnum - 1],
3479 econtext->caseValue_datum = save_datum;
3480 econtext->caseValue_isNull = save_isNull;
3482 tuple = heap_form_tuple(tupDesc, values, isnull);
3487 return HeapTupleGetDatum(tuple);
3490 /* ----------------------------------------------------------------
3491 * ExecEvalRelabelType
3493 * Evaluate a RelabelType node.
3494 * ----------------------------------------------------------------
3497 ExecEvalRelabelType(GenericExprState *exprstate,
3498 ExprContext *econtext,
3499 bool *isNull, ExprDoneCond *isDone)
3501 return ExecEvalExpr(exprstate->arg, econtext, isNull, isDone);
3506 * ExecEvalExprSwitchContext
3508 * Same as ExecEvalExpr, but get into the right allocation context explicitly.
3511 ExecEvalExprSwitchContext(ExprState *expression,
3512 ExprContext *econtext,
3514 ExprDoneCond *isDone)
3517 MemoryContext oldContext;
3519 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
3520 retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
3521 MemoryContextSwitchTo(oldContext);
3527 * ExecInitExpr: prepare an expression tree for execution
3529 * This function builds and returns an ExprState tree paralleling the given
3530 * Expr node tree. The ExprState tree can then be handed to ExecEvalExpr
3531 * for execution. Because the Expr tree itself is read-only as far as
3532 * ExecInitExpr and ExecEvalExpr are concerned, several different executions
3533 * of the same plan tree can occur concurrently.
3535 * This must be called in a memory context that will last as long as repeated
3536 * executions of the expression are needed. Typically the context will be
3537 * the same as the per-query context of the associated ExprContext.
3539 * Any Aggref and SubPlan nodes found in the tree are added to the lists
3540 * of such nodes held by the parent PlanState. Otherwise, we do very little
3541 * initialization here other than building the state-node tree. Any nontrivial
3542 * work associated with initializing runtime info for a node should happen
3543 * during the first actual evaluation of that node. (This policy lets us
3544 * avoid work if the node is never actually evaluated.)
3546 * Note: there is no ExecEndExpr function; we assume that any resource
3547 * cleanup needed will be handled by just releasing the memory context
3548 * in which the state tree is built. Functions that require additional
3549 * cleanup work can register a shutdown callback in the ExprContext.
3551 * 'node' is the root of the expression tree to examine
3552 * 'parent' is the PlanState node that owns the expression.
3554 * 'parent' may be NULL if we are preparing an expression that is not
3555 * associated with a plan tree. (If so, it can't have aggs or subplans.)
3556 * This case should usually come through ExecPrepareExpr, not directly here.
3559 ExecInitExpr(Expr *node, PlanState *parent)
3566 /* Guard against stack overflow due to overly complex expressions */
3567 check_stack_depth();
3569 switch (nodeTag(node))
3572 state = (ExprState *) makeNode(ExprState);
3573 state->evalfunc = ExecEvalVar;
3576 state = (ExprState *) makeNode(ExprState);
3577 state->evalfunc = ExecEvalConst;
3580 state = (ExprState *) makeNode(ExprState);
3581 state->evalfunc = ExecEvalParam;
3583 case T_CoerceToDomainValue:
3584 state = (ExprState *) makeNode(ExprState);
3585 state->evalfunc = ExecEvalCoerceToDomainValue;
3587 case T_CaseTestExpr:
3588 state = (ExprState *) makeNode(ExprState);
3589 state->evalfunc = ExecEvalCaseTestExpr;
3593 Aggref *aggref = (Aggref *) node;
3594 AggrefExprState *astate = makeNode(AggrefExprState);
3596 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAggref;
3597 if (parent && IsA(parent, AggState))
3599 AggState *aggstate = (AggState *) parent;
3602 aggstate->aggs = lcons(astate, aggstate->aggs);
3603 naggs = ++aggstate->numaggs;
3605 astate->args = (List *) ExecInitExpr((Expr *) aggref->args,
3609 * Complain if the aggregate's arguments contain any
3610 * aggregates; nested agg functions are semantically
3611 * nonsensical. (This should have been caught earlier,
3612 * but we defend against it here anyway.)
3614 if (naggs != aggstate->numaggs)
3616 (errcode(ERRCODE_GROUPING_ERROR),
3617 errmsg("aggregate function calls cannot be nested")));
3621 /* planner messed up */
3622 elog(ERROR, "aggref found in non-Agg plan node");
3624 state = (ExprState *) astate;
3629 ArrayRef *aref = (ArrayRef *) node;
3630 ArrayRefExprState *astate = makeNode(ArrayRefExprState);
3632 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArrayRef;
3633 astate->refupperindexpr = (List *)
3634 ExecInitExpr((Expr *) aref->refupperindexpr, parent);
3635 astate->reflowerindexpr = (List *)
3636 ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
3637 astate->refexpr = ExecInitExpr(aref->refexpr, parent);
3638 astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
3640 /* do one-time catalog lookups for type info */
3641 astate->refattrlength = get_typlen(aref->refarraytype);
3642 get_typlenbyvalalign(aref->refelemtype,
3643 &astate->refelemlength,
3644 &astate->refelembyval,
3645 &astate->refelemalign);
3646 state = (ExprState *) astate;
3651 FuncExpr *funcexpr = (FuncExpr *) node;
3652 FuncExprState *fstate = makeNode(FuncExprState);
3654 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFunc;
3655 fstate->args = (List *)
3656 ExecInitExpr((Expr *) funcexpr->args, parent);
3657 fstate->func.fn_oid = InvalidOid; /* not initialized */
3658 state = (ExprState *) fstate;
3663 OpExpr *opexpr = (OpExpr *) node;
3664 FuncExprState *fstate = makeNode(FuncExprState);
3666 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOper;
3667 fstate->args = (List *)
3668 ExecInitExpr((Expr *) opexpr->args, parent);
3669 fstate->func.fn_oid = InvalidOid; /* not initialized */
3670 state = (ExprState *) fstate;
3673 case T_DistinctExpr:
3675 DistinctExpr *distinctexpr = (DistinctExpr *) node;
3676 FuncExprState *fstate = makeNode(FuncExprState);
3678 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalDistinct;
3679 fstate->args = (List *)
3680 ExecInitExpr((Expr *) distinctexpr->args, parent);
3681 fstate->func.fn_oid = InvalidOid; /* not initialized */
3682 state = (ExprState *) fstate;
3685 case T_ScalarArrayOpExpr:
3687 ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
3688 ScalarArrayOpExprState *sstate = makeNode(ScalarArrayOpExprState);
3690 sstate->fxprstate.xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalScalarArrayOp;
3691 sstate->fxprstate.args = (List *)
3692 ExecInitExpr((Expr *) opexpr->args, parent);
3693 sstate->fxprstate.func.fn_oid = InvalidOid; /* not initialized */
3694 sstate->element_type = InvalidOid; /* ditto */
3695 state = (ExprState *) sstate;
3700 BoolExpr *boolexpr = (BoolExpr *) node;
3701 BoolExprState *bstate = makeNode(BoolExprState);
3703 switch (boolexpr->boolop)
3706 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAnd;
3709 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalOr;
3712 bstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNot;
3715 elog(ERROR, "unrecognized boolop: %d",
3716 (int) boolexpr->boolop);
3719 bstate->args = (List *)
3720 ExecInitExpr((Expr *) boolexpr->args, parent);
3721 state = (ExprState *) bstate;
3726 /* Keep this in sync with ExecInitExprInitPlan, below */
3727 SubPlan *subplan = (SubPlan *) node;
3728 SubPlanState *sstate = makeNode(SubPlanState);
3730 sstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecSubPlan;
3733 elog(ERROR, "SubPlan found with no parent plan");
3736 * Here we just add the SubPlanState nodes to parent->subPlan.
3737 * The subplans will be initialized later.
3739 parent->subPlan = lcons(sstate, parent->subPlan);
3740 sstate->sub_estate = NULL;
3741 sstate->planstate = NULL;
3744 ExecInitExpr((Expr *) subplan->testexpr, parent);
3745 sstate->args = (List *)
3746 ExecInitExpr((Expr *) subplan->args, parent);
3748 state = (ExprState *) sstate;
3753 FieldSelect *fselect = (FieldSelect *) node;
3754 FieldSelectState *fstate = makeNode(FieldSelectState);
3756 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldSelect;
3757 fstate->arg = ExecInitExpr(fselect->arg, parent);
3758 fstate->argdesc = NULL;
3759 state = (ExprState *) fstate;
3764 FieldStore *fstore = (FieldStore *) node;
3765 FieldStoreState *fstate = makeNode(FieldStoreState);
3767 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalFieldStore;
3768 fstate->arg = ExecInitExpr(fstore->arg, parent);
3769 fstate->newvals = (List *) ExecInitExpr((Expr *) fstore->newvals, parent);
3770 fstate->argdesc = NULL;
3771 state = (ExprState *) fstate;
3776 RelabelType *relabel = (RelabelType *) node;
3777 GenericExprState *gstate = makeNode(GenericExprState);
3779 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRelabelType;
3780 gstate->arg = ExecInitExpr(relabel->arg, parent);
3781 state = (ExprState *) gstate;
3784 case T_ConvertRowtypeExpr:
3786 ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) node;
3787 ConvertRowtypeExprState *cstate = makeNode(ConvertRowtypeExprState);
3789 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalConvertRowtype;
3790 cstate->arg = ExecInitExpr(convert->arg, parent);
3791 state = (ExprState *) cstate;
3796 CaseExpr *caseexpr = (CaseExpr *) node;
3797 CaseExprState *cstate = makeNode(CaseExprState);
3798 List *outlist = NIL;
3801 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCase;
3802 cstate->arg = ExecInitExpr(caseexpr->arg, parent);
3803 foreach(l, caseexpr->args)
3805 CaseWhen *when = (CaseWhen *) lfirst(l);
3806 CaseWhenState *wstate = makeNode(CaseWhenState);
3808 Assert(IsA(when, CaseWhen));
3809 wstate->xprstate.evalfunc = NULL; /* not used */
3810 wstate->xprstate.expr = (Expr *) when;
3811 wstate->expr = ExecInitExpr(when->expr, parent);
3812 wstate->result = ExecInitExpr(when->result, parent);
3813 outlist = lappend(outlist, wstate);
3815 cstate->args = outlist;
3816 cstate->defresult = ExecInitExpr(caseexpr->defresult, parent);
3817 state = (ExprState *) cstate;
3822 ArrayExpr *arrayexpr = (ArrayExpr *) node;
3823 ArrayExprState *astate = makeNode(ArrayExprState);
3824 List *outlist = NIL;
3827 astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArray;
3828 foreach(l, arrayexpr->elements)
3830 Expr *e = (Expr *) lfirst(l);
3833 estate = ExecInitExpr(e, parent);
3834 outlist = lappend(outlist, estate);
3836 astate->elements = outlist;
3837 /* do one-time catalog lookup for type info */
3838 get_typlenbyvalalign(arrayexpr->element_typeid,
3839 &astate->elemlength,
3841 &astate->elemalign);
3842 state = (ExprState *) astate;
3847 RowExpr *rowexpr = (RowExpr *) node;
3848 RowExprState *rstate = makeNode(RowExprState);
3849 Form_pg_attribute *attrs;
3850 List *outlist = NIL;
3854 rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRow;
3855 /* Build tupdesc to describe result tuples */
3856 if (rowexpr->row_typeid == RECORDOID)
3858 /* generic record, use runtime type assignment */
3859 rstate->tupdesc = ExecTypeFromExprList(rowexpr->args);
3860 BlessTupleDesc(rstate->tupdesc);
3861 /* we won't need to redo this at runtime */
3865 /* it's been cast to a named type, use that */
3866 rstate->tupdesc = lookup_rowtype_tupdesc_copy(rowexpr->row_typeid, -1);
3868 /* Set up evaluation, skipping any deleted columns */
3869 Assert(list_length(rowexpr->args) <= rstate->tupdesc->natts);
3870 attrs = rstate->tupdesc->attrs;
3872 foreach(l, rowexpr->args)
3874 Expr *e = (Expr *) lfirst(l);
3877 if (!attrs[i]->attisdropped)
3880 * Guard against ALTER COLUMN TYPE on rowtype since
3881 * the RowExpr was created. XXX should we check
3882 * typmod too? Not sure we can be sure it'll be the
3885 if (exprType((Node *) e) != attrs[i]->atttypid)
3887 (errcode(ERRCODE_DATATYPE_MISMATCH),
3888 errmsg("ROW() column has type %s instead of type %s",
3889 format_type_be(exprType((Node *) e)),
3890 format_type_be(attrs[i]->atttypid))));
3895 * Ignore original expression and insert a NULL. We
3896 * don't really care what type of NULL it is, so
3897 * always make an int4 NULL.
3899 e = (Expr *) makeNullConst(INT4OID);
3901 estate = ExecInitExpr(e, parent);
3902 outlist = lappend(outlist, estate);
3905 rstate->args = outlist;
3906 state = (ExprState *) rstate;
3909 case T_RowCompareExpr:
3911 RowCompareExpr *rcexpr = (RowCompareExpr *) node;
3912 RowCompareExprState *rstate = makeNode(RowCompareExprState);
3913 int nopers = list_length(rcexpr->opnos);
3919 rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRowCompare;
3920 Assert(list_length(rcexpr->largs) == nopers);
3922 foreach(l, rcexpr->largs)
3924 Expr *e = (Expr *) lfirst(l);
3927 estate = ExecInitExpr(e, parent);
3928 outlist = lappend(outlist, estate);
3930 rstate->largs = outlist;
3931 Assert(list_length(rcexpr->rargs) == nopers);
3933 foreach(l, rcexpr->rargs)
3935 Expr *e = (Expr *) lfirst(l);
3938 estate = ExecInitExpr(e, parent);
3939 outlist = lappend(outlist, estate);
3941 rstate->rargs = outlist;
3942 Assert(list_length(rcexpr->opfamilies) == nopers);
3943 rstate->funcs = (FmgrInfo *) palloc(nopers * sizeof(FmgrInfo));
3945 forboth(l, rcexpr->opnos, l2, rcexpr->opfamilies)
3947 Oid opno = lfirst_oid(l);
3948 Oid opfamily = lfirst_oid(l2);
3955 get_op_opfamily_properties(opno, opfamily,
3960 proc = get_opfamily_proc(opfamily,
3966 * If we enforced permissions checks on index support
3967 * functions, we'd need to make a check here. But the
3968 * index support machinery doesn't do that, and neither
3971 fmgr_info(proc, &(rstate->funcs[i]));
3974 state = (ExprState *) rstate;
3977 case T_CoalesceExpr:
3979 CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
3980 CoalesceExprState *cstate = makeNode(CoalesceExprState);
3981 List *outlist = NIL;
3984 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoalesce;
3985 foreach(l, coalesceexpr->args)
3987 Expr *e = (Expr *) lfirst(l);
3990 estate = ExecInitExpr(e, parent);
3991 outlist = lappend(outlist, estate);
3993 cstate->args = outlist;
3994 state = (ExprState *) cstate;
3999 MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
4000 MinMaxExprState *mstate = makeNode(MinMaxExprState);
4001 List *outlist = NIL;
4003 TypeCacheEntry *typentry;
4005 mstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalMinMax;
4006 foreach(l, minmaxexpr->args)
4008 Expr *e = (Expr *) lfirst(l);
4011 estate = ExecInitExpr(e, parent);
4012 outlist = lappend(outlist, estate);
4014 mstate->args = outlist;
4015 /* Look up the btree comparison function for the datatype */
4016 typentry = lookup_type_cache(minmaxexpr->minmaxtype,
4017 TYPECACHE_CMP_PROC);
4018 if (!OidIsValid(typentry->cmp_proc))
4020 (errcode(ERRCODE_UNDEFINED_FUNCTION),
4021 errmsg("could not identify a comparison function for type %s",
4022 format_type_be(minmaxexpr->minmaxtype))));
4025 * If we enforced permissions checks on index support
4026 * functions, we'd need to make a check here. But the index
4027 * support machinery doesn't do that, and neither does this
4030 fmgr_info(typentry->cmp_proc, &(mstate->cfunc));
4031 state = (ExprState *) mstate;
4036 XmlExpr *xexpr = (XmlExpr *) node;
4037 XmlExprState *xstate = makeNode(XmlExprState);
4042 xstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalXml;
4043 xstate->named_outfuncs = (FmgrInfo *)
4044 palloc0(list_length(xexpr->named_args) * sizeof(FmgrInfo));
4047 foreach(arg, xexpr->named_args)
4049 Expr *e = (Expr *) lfirst(arg);
4054 estate = ExecInitExpr(e, parent);
4055 outlist = lappend(outlist, estate);
4057 getTypeOutputInfo(exprType((Node *) e),
4058 &typOutFunc, &typIsVarlena);
4059 fmgr_info(typOutFunc, &xstate->named_outfuncs[i]);
4062 xstate->named_args = outlist;
4065 foreach(arg, xexpr->args)
4067 Expr *e = (Expr *) lfirst(arg);
4070 estate = ExecInitExpr(e, parent);
4071 outlist = lappend(outlist, estate);
4073 xstate->args = outlist;
4075 state = (ExprState *) xstate;
4080 NullIfExpr *nullifexpr = (NullIfExpr *) node;
4081 FuncExprState *fstate = makeNode(FuncExprState);
4083 fstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullIf;
4084 fstate->args = (List *)
4085 ExecInitExpr((Expr *) nullifexpr->args, parent);
4086 fstate->func.fn_oid = InvalidOid; /* not initialized */
4087 state = (ExprState *) fstate;
4092 NullTest *ntest = (NullTest *) node;
4093 NullTestState *nstate = makeNode(NullTestState);
4095 nstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullTest;
4096 nstate->arg = ExecInitExpr(ntest->arg, parent);
4097 nstate->argisrow = type_is_rowtype(exprType((Node *) ntest->arg));
4098 nstate->argdesc = NULL;
4099 state = (ExprState *) nstate;
4104 BooleanTest *btest = (BooleanTest *) node;
4105 GenericExprState *gstate = makeNode(GenericExprState);
4107 gstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalBooleanTest;
4108 gstate->arg = ExecInitExpr(btest->arg, parent);
4109 state = (ExprState *) gstate;
4112 case T_CoerceToDomain:
4114 CoerceToDomain *ctest = (CoerceToDomain *) node;
4115 CoerceToDomainState *cstate = makeNode(CoerceToDomainState);
4117 cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoerceToDomain;
4118 cstate->arg = ExecInitExpr(ctest->arg, parent);
4119 cstate->constraints = GetDomainConstraints(ctest->resulttype);
4120 state = (ExprState *) cstate;
4125 TargetEntry *tle = (TargetEntry *) node;
4126 GenericExprState *gstate = makeNode(GenericExprState);
4128 gstate->xprstate.evalfunc = NULL; /* not used */
4129 gstate->arg = ExecInitExpr(tle->expr, parent);
4130 state = (ExprState *) gstate;
4135 List *outlist = NIL;
4138 foreach(l, (List *) node)
4140 outlist = lappend(outlist,
4141 ExecInitExpr((Expr *) lfirst(l),
4144 /* Don't fall through to the "common" code below */
4145 return (ExprState *) outlist;
4148 elog(ERROR, "unrecognized node type: %d",
4149 (int) nodeTag(node));
4150 state = NULL; /* keep compiler quiet */
4154 /* Common code for all state-node types */
4161 * ExecInitExprInitPlan --- initialize a subplan expr that's being handled
4162 * as an InitPlan. This is identical to ExecInitExpr's handling of a regular
4163 * subplan expr, except we do NOT want to add the node to the parent's
4167 ExecInitExprInitPlan(SubPlan *node, PlanState *parent)
4169 SubPlanState *sstate = makeNode(SubPlanState);
4172 elog(ERROR, "SubPlan found with no parent plan");
4174 /* The subplan's state will be initialized later */
4175 sstate->sub_estate = NULL;
4176 sstate->planstate = NULL;
4178 sstate->testexpr = ExecInitExpr((Expr *) node->testexpr, parent);
4179 sstate->args = (List *) ExecInitExpr((Expr *) node->args, parent);
4181 sstate->xprstate.expr = (Expr *) node;
4187 * ExecPrepareExpr --- initialize for expression execution outside a normal
4188 * Plan tree context.
4190 * This differs from ExecInitExpr in that we don't assume the caller is
4191 * already running in the EState's per-query context. Also, we apply
4192 * fix_opfuncids() to the passed expression tree to be sure it is ready
4193 * to run. (In ordinary Plan trees the planner will have fixed opfuncids,
4194 * but callers outside the executor will not have done this.)
4197 ExecPrepareExpr(Expr *node, EState *estate)
4200 MemoryContext oldcontext;
4202 fix_opfuncids((Node *) node);
4204 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
4206 result = ExecInitExpr(node, NULL);
4208 MemoryContextSwitchTo(oldcontext);
4214 /* ----------------------------------------------------------------
4215 * ExecQual / ExecTargetList / ExecProject
4216 * ----------------------------------------------------------------
4219 /* ----------------------------------------------------------------
4222 * Evaluates a conjunctive boolean expression (qual list) and
4223 * returns true iff none of the subexpressions are false.
4224 * (We also return true if the list is empty.)
4226 * If some of the subexpressions yield NULL but none yield FALSE,
4227 * then the result of the conjunction is NULL (ie, unknown)
4228 * according to three-valued boolean logic. In this case,
4229 * we return the value specified by the "resultForNull" parameter.
4231 * Callers evaluating WHERE clauses should pass resultForNull=FALSE,
4232 * since SQL specifies that tuples with null WHERE results do not
4233 * get selected. On the other hand, callers evaluating constraint
4234 * conditions should pass resultForNull=TRUE, since SQL also specifies
4235 * that NULL constraint conditions are not failures.
4237 * NOTE: it would not be correct to use this routine to evaluate an
4238 * AND subclause of a boolean expression; for that purpose, a NULL
4239 * result must be returned as NULL so that it can be properly treated
4240 * in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
4241 * This routine is only used in contexts where a complete expression
4242 * is being evaluated and we know that NULL can be treated the same
4243 * as one boolean result or the other.
4245 * ----------------------------------------------------------------
4248 ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
4251 MemoryContext oldContext;
4257 EV_printf("ExecQual: qual is ");
4258 EV_nodeDisplay(qual);
4264 * Run in short-lived per-tuple context while computing expressions.
4266 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
4269 * Evaluate the qual conditions one at a time. If we find a FALSE result,
4270 * we can stop evaluating and return FALSE --- the AND result must be
4271 * FALSE. Also, if we find a NULL result when resultForNull is FALSE, we
4272 * can stop and return FALSE --- the AND result must be FALSE or NULL in
4273 * that case, and the caller doesn't care which.
4275 * If we get to the end of the list, we can return TRUE. This will happen
4276 * when the AND result is indeed TRUE, or when the AND result is NULL (one
4277 * or more NULL subresult, with all the rest TRUE) and the caller has
4278 * specified resultForNull = TRUE.
4284 ExprState *clause = (ExprState *) lfirst(l);
4288 expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
4292 if (resultForNull == false)
4294 result = false; /* treat NULL as FALSE */
4300 if (!DatumGetBool(expr_value))
4302 result = false; /* definitely FALSE */
4308 MemoryContextSwitchTo(oldContext);
4314 * Number of items in a tlist (including any resjunk items!)
4317 ExecTargetListLength(List *targetlist)
4319 /* This used to be more complex, but fjoins are dead */
4320 return list_length(targetlist);
4324 * Number of items in a tlist, not including any resjunk items
4327 ExecCleanTargetListLength(List *targetlist)
4332 foreach(tl, targetlist)
4334 TargetEntry *curTle = (TargetEntry *) lfirst(tl);
4336 Assert(IsA(curTle, TargetEntry));
4337 if (!curTle->resjunk)
4345 * Evaluates a targetlist with respect to the given
4346 * expression context. Returns TRUE if we were able to create
4347 * a result, FALSE if we have exhausted a set-valued expression.
4349 * Results are stored into the passed values and isnull arrays.
4350 * The caller must provide an itemIsDone array that persists across calls.
4352 * As with ExecEvalExpr, the caller should pass isDone = NULL if not
4353 * prepared to deal with sets of result tuples. Otherwise, a return
4354 * of *isDone = ExprMultipleResult signifies a set element, and a return
4355 * of *isDone = ExprEndResult signifies end of the set of tuple.
4358 ExecTargetList(List *targetlist,
4359 ExprContext *econtext,
4362 ExprDoneCond *itemIsDone,
4363 ExprDoneCond *isDone)
4365 MemoryContext oldContext;
4370 * Run in short-lived per-tuple context while computing expressions.
4372 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
4375 * evaluate all the expressions in the target list
4378 *isDone = ExprSingleResult; /* until proven otherwise */
4380 haveDoneSets = false; /* any exhausted set exprs in tlist? */
4382 foreach(tl, targetlist)
4384 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
4385 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
4386 AttrNumber resind = tle->resno - 1;
4388 values[resind] = ExecEvalExpr(gstate->arg,
4391 &itemIsDone[resind]);
4393 if (itemIsDone[resind] != ExprSingleResult)
4395 /* We have a set-valued expression in the tlist */
4398 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4399 errmsg("set-valued function called in context that cannot accept a set")));
4400 if (itemIsDone[resind] == ExprMultipleResult)
4402 /* we have undone sets in the tlist, set flag */
4403 *isDone = ExprMultipleResult;
4407 /* we have done sets in the tlist, set flag for that */
4408 haveDoneSets = true;
4416 * note: can't get here unless we verified isDone != NULL
4418 if (*isDone == ExprSingleResult)
4421 * all sets are done, so report that tlist expansion is complete.
4423 *isDone = ExprEndResult;
4424 MemoryContextSwitchTo(oldContext);
4430 * We have some done and some undone sets. Restart the done ones
4431 * so that we can deliver a tuple (if possible).
4433 foreach(tl, targetlist)
4435 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
4436 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
4437 AttrNumber resind = tle->resno - 1;
4439 if (itemIsDone[resind] == ExprEndResult)
4441 values[resind] = ExecEvalExpr(gstate->arg,
4444 &itemIsDone[resind]);
4446 if (itemIsDone[resind] == ExprEndResult)
4449 * Oh dear, this item is returning an empty set. Guess
4450 * we can't make a tuple after all.
4452 *isDone = ExprEndResult;
4459 * If we cannot make a tuple because some sets are empty, we still
4460 * have to cycle the nonempty sets to completion, else resources
4461 * will not be released from subplans etc.
4463 * XXX is that still necessary?
4465 if (*isDone == ExprEndResult)
4467 foreach(tl, targetlist)
4469 GenericExprState *gstate = (GenericExprState *) lfirst(tl);
4470 TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
4471 AttrNumber resind = tle->resno - 1;
4473 while (itemIsDone[resind] == ExprMultipleResult)
4475 values[resind] = ExecEvalExpr(gstate->arg,
4478 &itemIsDone[resind]);
4482 MemoryContextSwitchTo(oldContext);
4488 /* Report success */
4489 MemoryContextSwitchTo(oldContext);
4496 * Evaluates a simple-Variable-list projection.
4498 * Results are stored into the passed values and isnull arrays.
4501 ExecVariableList(ProjectionInfo *projInfo,
4505 ExprContext *econtext = projInfo->pi_exprContext;
4506 int *varSlotOffsets = projInfo->pi_varSlotOffsets;
4507 int *varNumbers = projInfo->pi_varNumbers;
4511 * Force extraction of all input values that we need.
4513 if (projInfo->pi_lastInnerVar > 0)
4514 slot_getsomeattrs(econtext->ecxt_innertuple,
4515 projInfo->pi_lastInnerVar);
4516 if (projInfo->pi_lastOuterVar > 0)
4517 slot_getsomeattrs(econtext->ecxt_outertuple,
4518 projInfo->pi_lastOuterVar);
4519 if (projInfo->pi_lastScanVar > 0)
4520 slot_getsomeattrs(econtext->ecxt_scantuple,
4521 projInfo->pi_lastScanVar);
4524 * Assign to result by direct extraction of fields from source slots ... a
4525 * mite ugly, but fast ...
4527 for (i = list_length(projInfo->pi_targetlist) - 1; i >= 0; i--)
4529 char *slotptr = ((char *) econtext) + varSlotOffsets[i];
4530 TupleTableSlot *varSlot = *((TupleTableSlot **) slotptr);
4531 int varNumber = varNumbers[i] - 1;
4533 values[i] = varSlot->tts_values[varNumber];
4534 isnull[i] = varSlot->tts_isnull[varNumber];
4541 * projects a tuple based on projection info and stores
4542 * it in the previously specified tuple table slot.
4544 * Note: the result is always a virtual tuple; therefore it
4545 * may reference the contents of the exprContext's scan tuples
4546 * and/or temporary results constructed in the exprContext.
4547 * If the caller wishes the result to be valid longer than that
4548 * data will be valid, he must call ExecMaterializeSlot on the
4552 ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
4554 TupleTableSlot *slot;
4559 Assert(projInfo != NULL);
4562 * get the projection info we want
4564 slot = projInfo->pi_slot;
4567 * Clear any former contents of the result slot. This makes it safe for
4568 * us to use the slot's Datum/isnull arrays as workspace. (Also, we can
4569 * return the slot as-is if we decide no rows can be projected.)
4571 ExecClearTuple(slot);
4574 * form a new result tuple (if possible); if successful, mark the result
4575 * slot as containing a valid virtual tuple
4577 if (projInfo->pi_isVarList)
4579 /* simple Var list: this always succeeds with one result row */
4581 *isDone = ExprSingleResult;
4582 ExecVariableList(projInfo,
4585 ExecStoreVirtualTuple(slot);
4589 if (ExecTargetList(projInfo->pi_targetlist,
4590 projInfo->pi_exprContext,
4593 projInfo->pi_itemIsDone,
4595 ExecStoreVirtualTuple(slot);