1 /*-------------------------------------------------------------------------
4 * Routines to evaluate qualification and targetlist expressions
6 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.85 2001/03/23 04:49:53 momjian Exp $
13 *-------------------------------------------------------------------------
17 * ExecEvalExpr - evaluate an expression and 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 * ExecEvalExpr() and ExecEvalVar() are hotspots. making these faster
24 * will speed up the entire system. Unfortunately they are currently
25 * implemented recursively. Eliminating the recursion is bound to
26 * improve the speed of the executor.
28 * ExecProject() is used to make tuple projections. Rather then
29 * trying to speed it up, the execution plan should be pre-processed
30 * to facilitate attribute sharing between nodes wherever possible,
31 * instead of doing needless copying. -cim 5/31/91
37 #include "access/heapam.h"
38 #include "executor/execFlatten.h"
39 #include "executor/execdebug.h"
40 #include "executor/functions.h"
41 #include "executor/nodeSubplan.h"
42 #include "utils/array.h"
43 #include "utils/builtins.h"
44 #include "utils/fcache.h"
47 /* static function decls */
48 static Datum ExecEvalAggref(Aggref *aggref, ExprContext *econtext,
50 static Datum ExecEvalArrayRef(ArrayRef *arrayRef, ExprContext *econtext,
51 bool *isNull, ExprDoneCond *isDone);
52 static Datum ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull);
53 static Datum ExecEvalOper(Expr *opClause, ExprContext *econtext,
54 bool *isNull, ExprDoneCond *isDone);
55 static Datum ExecEvalFunc(Expr *funcClause, ExprContext *econtext,
56 bool *isNull, ExprDoneCond *isDone);
57 static ExprDoneCond ExecEvalFuncArgs(FunctionCachePtr fcache,
59 ExprContext *econtext);
60 static Datum ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull);
61 static Datum ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull);
62 static Datum ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull);
63 static Datum ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext,
64 bool *isNull, ExprDoneCond *isDone);
70 * This function takes an ArrayRef and returns the extracted Datum
71 * if it's a simple reference, or the modified array value if it's
72 * an array assignment (i.e., array element or slice insertion).
74 * NOTE: if we get a NULL result from a subexpression, we return NULL when
75 * it's an array reference, or the unmodified source array when it's an
76 * array assignment. This may seem peculiar, but if we return NULL (as was
77 * done in versions up through 7.0) then an assignment like
78 * UPDATE table SET arrayfield[4] = NULL
79 * will result in setting the whole array to NULL, which is certainly not
80 * very desirable. By returning the source array we make the assignment
81 * into a no-op, instead. (Eventually we need to redesign arrays so that
82 * individual elements can be NULL, but for now, let's try to protect users
83 * from shooting themselves in the foot.)
85 * NOTE: we deliberately refrain from applying DatumGetArrayTypeP() here,
86 * even though that might seem natural, because this code needs to support
87 * both varlena arrays and fixed-length array types. DatumGetArrayTypeP()
88 * only works for the varlena kind. The routines we call in arrayfuncs.c
89 * have to know the difference (that's what they need refattrlength for).
93 ExecEvalArrayRef(ArrayRef *arrayRef,
94 ExprContext *econtext,
98 ArrayType *array_source;
99 ArrayType *resultArray;
100 bool isAssignment = (arrayRef->refassgnexpr != NULL);
108 if (arrayRef->refexpr != NULL)
110 array_source = (ArrayType *)
111 DatumGetPointer(ExecEvalExpr(arrayRef->refexpr,
117 * If refexpr yields NULL, result is always NULL, for now anyway.
118 * (This means you cannot assign to an element or slice of an
119 * array that's NULL; it'll just stay NULL.)
128 * Empty refexpr indicates we are doing an INSERT into an array
129 * column. For now, we just take the refassgnexpr (which the
130 * parser will have ensured is an array value) and return it
131 * as-is, ignoring any subscripts that may have been supplied in
132 * the INSERT column list. This is a kluge, but it's not real
133 * clear what the semantics ought to be...
138 foreach(elt, arrayRef->refupperindexpr)
141 elog(ERROR, "ExecEvalArrayRef: can only handle %d dimensions",
144 upper.indx[i++] = DatumGetInt32(ExecEvalExpr((Node *) lfirst(elt),
148 /* If any index expr yields NULL, result is NULL or source array */
151 if (!isAssignment || array_source == NULL)
154 return PointerGetDatum(array_source);
158 if (arrayRef->reflowerindexpr != NIL)
160 foreach(elt, arrayRef->reflowerindexpr)
163 elog(ERROR, "ExecEvalArrayRef: can only handle %d dimensions",
166 lower.indx[j++] = DatumGetInt32(ExecEvalExpr((Node *) lfirst(elt),
172 * If any index expr yields NULL, result is NULL or source
177 if (!isAssignment || array_source == NULL)
180 return PointerGetDatum(array_source);
185 "ExecEvalArrayRef: upper and lower indices mismatch");
193 Datum sourceData = ExecEvalExpr(arrayRef->refassgnexpr,
199 * For now, can't cope with inserting NULL into an array, so make
200 * it a no-op per discussion above...
204 if (array_source == NULL)
207 return PointerGetDatum(array_source);
210 if (array_source == NULL)
211 return sourceData; /* XXX do something else? */
214 resultArray = array_set(array_source, i,
217 arrayRef->refelembyval,
218 arrayRef->refelemlength,
219 arrayRef->refattrlength,
222 resultArray = array_set_slice(array_source, i,
223 upper.indx, lower.indx,
224 (ArrayType *) DatumGetPointer(sourceData),
225 arrayRef->refelembyval,
226 arrayRef->refelemlength,
227 arrayRef->refattrlength,
229 return PointerGetDatum(resultArray);
233 return array_ref(array_source, i,
235 arrayRef->refelembyval,
236 arrayRef->refelemlength,
237 arrayRef->refattrlength,
241 resultArray = array_get_slice(array_source, i,
242 upper.indx, lower.indx,
243 arrayRef->refelembyval,
244 arrayRef->refelemlength,
245 arrayRef->refattrlength,
247 return PointerGetDatum(resultArray);
252 /* ----------------------------------------------------------------
255 * Returns a Datum whose value is the value of the precomputed
256 * aggregate found in the given expression context.
257 * ----------------------------------------------------------------
260 ExecEvalAggref(Aggref *aggref, ExprContext *econtext, bool *isNull)
262 if (econtext->ecxt_aggvalues == NULL) /* safety check */
263 elog(ERROR, "ExecEvalAggref: no aggregates in this expression context");
265 *isNull = econtext->ecxt_aggnulls[aggref->aggno];
266 return econtext->ecxt_aggvalues[aggref->aggno];
269 /* ----------------------------------------------------------------
272 * Returns a Datum whose value is the value of a range
273 * variable with respect to given expression context.
276 * As an entry condition, we expect that the datatype the
277 * plan expects to get (as told by our "variable" argument) is in
278 * fact the datatype of the attribute the plan says to fetch (as
279 * seen in the current context, identified by our "econtext"
282 * If we fetch a Type A attribute and Caller treats it as if it
283 * were Type B, there will be undefined results (e.g. crash).
284 * One way these might mismatch now is that we're accessing a
285 * catalog class and the type information in the pg_attribute
286 * class does not match the hardcoded pg_attribute information
287 * (in pg_attribute.h) for the class in question.
289 * We have an Assert to make sure this entry condition is met.
291 * ---------------------------------------------------------------- */
293 ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
296 TupleTableSlot *slot;
299 TupleDesc tuple_type;
302 * get the slot we want
304 switch (variable->varno)
306 case INNER: /* get the tuple from the inner node */
307 slot = econtext->ecxt_innertuple;
310 case OUTER: /* get the tuple from the outer node */
311 slot = econtext->ecxt_outertuple;
314 default: /* get the tuple from the relation being
316 slot = econtext->ecxt_scantuple;
321 * extract tuple information from the slot
323 heapTuple = slot->val;
324 tuple_type = slot->ttc_tupleDescriptor;
326 attnum = variable->varattno;
328 /* (See prolog for explanation of this Assert) */
329 Assert(attnum <= 0 ||
330 (attnum - 1 <= tuple_type->natts - 1 &&
331 tuple_type->attrs[attnum - 1] != NULL &&
332 variable->vartype == tuple_type->attrs[attnum - 1]->atttypid));
335 * If the attribute number is invalid, then we are supposed to return
336 * the entire tuple, we give back a whole slot so that callers know
337 * what the tuple looks like. XXX why copy? Couldn't we just give
338 * back the existing slot?
340 if (attnum == InvalidAttrNumber)
342 TupleTableSlot *tempSlot = MakeTupleTableSlot();
346 tup = heap_copytuple(heapTuple);
347 td = CreateTupleDescCopy(tuple_type);
349 ExecSetSlotDescriptor(tempSlot, td, true);
350 ExecStoreTuple(tup, tempSlot, InvalidBuffer, true);
351 return PointerGetDatum(tempSlot);
354 result = heap_getattr(heapTuple, /* tuple containing attribute */
355 attnum, /* attribute number of desired
357 tuple_type, /* tuple descriptor of tuple */
358 isNull); /* return: is attribute null? */
363 /* ----------------------------------------------------------------
366 * Returns the value of a parameter. A param node contains
367 * something like ($.name) and the expression context contains
368 * the current parameter bindings (name = "sam") (age = 34)...
369 * so our job is to replace the param node with the datum
370 * containing the appropriate information ("sam").
372 * Q: if we have a parameter ($.foo) without a binding, i.e.
373 * there is no (foo = xxx) in the parameter list info,
374 * is this a fatal error or should this be a "not available"
375 * (in which case we shoud return a Const node with the
376 * isnull flag) ? -cim 10/13/89
378 * Minor modification: Param nodes now have an extra field,
379 * `paramkind' which specifies the type of parameter
380 * (see params.h). So while searching the paramList for
381 * a paramname/value pair, we have also to check for `kind'.
383 * NOTE: The last entry in `paramList' is always an
384 * entry with kind == PARAM_INVALID.
385 * ----------------------------------------------------------------
388 ExecEvalParam(Param *expression, ExprContext *econtext, bool *isNull)
390 char *thisParameterName;
391 int thisParameterKind = expression->paramkind;
392 AttrNumber thisParameterId = expression->paramid;
394 ParamListInfo paramList;
396 if (thisParameterKind == PARAM_EXEC)
400 prm = &(econtext->ecxt_param_exec_vals[thisParameterId]);
401 if (prm->execPlan != NULL)
403 ExecSetParamPlan(prm->execPlan, econtext);
404 /* ExecSetParamPlan should have processed this param... */
405 Assert(prm->execPlan == NULL);
407 *isNull = prm->isnull;
411 thisParameterName = expression->paramname;
412 paramList = econtext->ecxt_param_list_info;
417 * search the list with the parameter info to find a matching name. An
418 * entry with an InvalidName denotes the last element in the array.
421 if (paramList != NULL)
425 * search for an entry in 'paramList' that matches the
428 while (paramList->kind != PARAM_INVALID && !matchFound)
430 switch (thisParameterKind)
433 if (thisParameterKind == paramList->kind &&
434 strcmp(paramList->name, thisParameterName) == 0)
438 if (thisParameterKind == paramList->kind &&
439 paramList->id == thisParameterId)
444 if (thisParameterKind == paramList->kind &&
445 paramList->id == thisParameterId)
452 if (strcmp(paramList->name, thisParameterName) != 0)
455 "ExecEvalParam: new/old params with same id & diff names");
462 * oops! this is not supposed to happen!
464 elog(ERROR, "ExecEvalParam: invalid paramkind %d",
476 * ooops! we couldn't find this parameter in the parameter list.
479 elog(ERROR, "ExecEvalParam: Unknown value for parameter %s",
486 *isNull = paramList->isnull;
487 return paramList->value;
491 /* ----------------------------------------------------------------
492 * ExecEvalOper / ExecEvalFunc support routines
493 * ----------------------------------------------------------------
500 * These are functions which return the value of the
501 * named attribute out of the tuple from the arg slot. User defined
502 * C functions which take a tuple as an argument are expected
503 * to use this. Ex: overpaid(EMP) might call GetAttributeByNum().
506 GetAttributeByNum(TupleTableSlot *slot,
512 if (!AttributeNumberIsValid(attrno))
513 elog(ERROR, "GetAttributeByNum: Invalid attribute number");
515 if (!AttrNumberIsForUserDefinedAttr(attrno))
516 elog(ERROR, "GetAttributeByNum: cannot access system attributes here");
518 if (isNull == (bool *) NULL)
519 elog(ERROR, "GetAttributeByNum: a NULL isNull flag was passed");
527 retval = heap_getattr(slot->val,
529 slot->ttc_tupleDescriptor,
538 GetAttributeByName(TupleTableSlot *slot, char *attname, bool *isNull)
547 elog(ERROR, "GetAttributeByName: Invalid attribute name");
549 if (isNull == (bool *) NULL)
550 elog(ERROR, "GetAttributeByName: a NULL isNull flag was passed");
558 tupdesc = slot->ttc_tupleDescriptor;
559 natts = slot->val->t_data->t_natts;
561 attrno = InvalidAttrNumber;
562 for (i = 0; i < tupdesc->natts; i++)
564 if (namestrcmp(&(tupdesc->attrs[i]->attname), attname) == 0)
566 attrno = tupdesc->attrs[i]->attnum;
571 if (attrno == InvalidAttrNumber)
572 elog(ERROR, "GetAttributeByName: attribute %s not found", attname);
574 retval = heap_getattr(slot->val,
585 * Evaluate arguments for a function.
588 ExecEvalFuncArgs(FunctionCachePtr fcache,
590 ExprContext *econtext)
592 ExprDoneCond argIsDone;
596 argIsDone = ExprSingleResult; /* default assumption */
599 foreach(arg, argList)
601 ExprDoneCond thisArgIsDone;
603 fcache->fcinfo.arg[i] = ExecEvalExpr((Node *) lfirst(arg),
605 &fcache->fcinfo.argnull[i],
608 if (thisArgIsDone != ExprSingleResult)
612 * We allow only one argument to have a set value; we'd need
613 * much more complexity to keep track of multiple set
614 * arguments (cf. ExecTargetList) and it doesn't seem worth
617 if (argIsDone != ExprSingleResult)
618 elog(ERROR, "Functions and operators can take only one set argument");
619 fcache->hasSetArg = true;
620 argIsDone = thisArgIsDone;
629 * ExecMakeFunctionResult
631 * Evaluate the arguments to a function and then the function itself.
633 * NOTE: econtext is used only for evaluating the argument expressions;
634 * it is not passed to the function itself.
637 ExecMakeFunctionResult(FunctionCachePtr fcache,
639 ExprContext *econtext,
641 ExprDoneCond *isDone)
644 ExprDoneCond argDone;
648 * arguments is a list of expressions to evaluate before passing to
649 * the function manager. We skip the evaluation if it was already
650 * done in the previous call (ie, we are continuing the evaluation of
651 * a set-valued function). Otherwise, collect the current argument
652 * values into fcache->fcinfo.
654 if (fcache->fcinfo.nargs > 0 && !fcache->argsValid)
656 argDone = ExecEvalFuncArgs(fcache, arguments, econtext);
657 if (argDone == ExprEndResult)
659 /* input is an empty set, so return an empty set. */
662 *isDone = ExprEndResult;
664 elog(ERROR, "Set-valued function called in context that cannot accept a set");
670 * now return the value gotten by calling the function manager,
671 * passing the function the evaluated parameter values.
673 if (fcache->func.fn_retset || fcache->hasSetArg)
677 * We need to return a set result. Complain if caller not ready
681 elog(ERROR, "Set-valued function called in context that cannot accept a set");
684 * This loop handles the situation where we have both a set
685 * argument and a set-valued function. Once we have exhausted the
686 * function's value(s) for a particular argument value, we have to
687 * get the next argument value and start the function over again.
688 * We might have to do it more than once, if the function produces
689 * an empty result set for a particular input value.
695 * If function is strict, and there are any NULL arguments,
696 * skip calling the function (at least for this set of args).
700 if (fcache->func.fn_strict)
702 for (i = 0; i < fcache->fcinfo.nargs; i++)
704 if (fcache->fcinfo.argnull[i])
714 fcache->fcinfo.isnull = false;
715 fcache->rsinfo.isDone = ExprSingleResult;
716 result = FunctionCallInvoke(&fcache->fcinfo);
717 *isNull = fcache->fcinfo.isnull;
718 *isDone = fcache->rsinfo.isDone;
724 *isDone = ExprEndResult;
727 if (*isDone != ExprEndResult)
731 * Got a result from current argument. If function itself
732 * returns set, flag that we want to reuse current
733 * argument values on next call.
735 if (fcache->func.fn_retset)
736 fcache->argsValid = true;
739 * Make sure we say we are returning a set, even if the
740 * function itself doesn't return sets.
742 *isDone = ExprMultipleResult;
746 /* Else, done with this argument */
747 fcache->argsValid = false;
749 if (!fcache->hasSetArg)
750 break; /* input not a set, so done */
752 /* Re-eval args to get the next element of the input set */
753 argDone = ExecEvalFuncArgs(fcache, arguments, econtext);
755 if (argDone != ExprMultipleResult)
759 * End of arguments, so reset the hasSetArg flag and say
762 fcache->hasSetArg = false;
764 *isDone = ExprEndResult;
770 * If we reach here, loop around to run the function on the
779 * Non-set case: much easier.
781 * If function is strict, and there are any NULL arguments, skip
782 * calling the function and return NULL.
784 if (fcache->func.fn_strict)
786 for (i = 0; i < fcache->fcinfo.nargs; i++)
788 if (fcache->fcinfo.argnull[i])
795 fcache->fcinfo.isnull = false;
796 result = FunctionCallInvoke(&fcache->fcinfo);
797 *isNull = fcache->fcinfo.isnull;
804 /* ----------------------------------------------------------------
808 * Evaluate the functional result of a list of arguments by calling the
810 * ----------------------------------------------------------------
813 /* ----------------------------------------------------------------
815 * ----------------------------------------------------------------
818 ExecEvalOper(Expr *opClause,
819 ExprContext *econtext,
821 ExprDoneCond *isDone)
825 FunctionCachePtr fcache;
828 * we extract the oid of the function associated with the op and then
829 * pass the work onto ExecMakeFunctionResult which evaluates the
830 * arguments and returns the result of calling the function on the
831 * evaluated arguments.
833 op = (Oper *) opClause->oper;
834 argList = opClause->args;
837 * get the fcache from the Oper node. If it is NULL, then initialize
840 fcache = op->op_fcache;
843 fcache = init_fcache(op->opid, length(argList),
844 econtext->ecxt_per_query_memory);
845 op->op_fcache = fcache;
848 return ExecMakeFunctionResult(fcache, argList, econtext,
852 /* ----------------------------------------------------------------
854 * ----------------------------------------------------------------
858 ExecEvalFunc(Expr *funcClause,
859 ExprContext *econtext,
861 ExprDoneCond *isDone)
865 FunctionCachePtr fcache;
868 * we extract the oid of the function associated with the func node
869 * and then pass the work onto ExecMakeFunctionResult which evaluates
870 * the arguments and returns the result of calling the function on the
871 * evaluated arguments.
873 * this is nearly identical to the ExecEvalOper code.
875 func = (Func *) funcClause->oper;
876 argList = funcClause->args;
879 * get the fcache from the Func node. If it is NULL, then initialize
882 fcache = func->func_fcache;
885 fcache = init_fcache(func->funcid, length(argList),
886 econtext->ecxt_per_query_memory);
887 func->func_fcache = fcache;
890 return ExecMakeFunctionResult(fcache, argList, econtext,
894 /* ----------------------------------------------------------------
899 * Evaluate boolean expressions. Evaluation of 'or' is
900 * short-circuited when the first true (or null) value is found.
902 * The query planner reformulates clause expressions in the
903 * qualification to conjunctive normal form. If we ever get
904 * an AND to evaluate, we can be sure that it's not a top-level
905 * clause in the qualification, but appears lower (as a function
906 * argument, for example), or in the target list. Not that you
907 * need to know this, mind you...
908 * ----------------------------------------------------------------
911 ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull)
916 clause = lfirst(notclause->args);
918 expr_value = ExecEvalExpr(clause, econtext, isNull, NULL);
921 * if the expression evaluates to null, then we just cascade the null
922 * back to whoever called us.
928 * evaluation of 'not' is simple.. expr is false, then return 'true'
931 return BoolGetDatum(!DatumGetBool(expr_value));
934 /* ----------------------------------------------------------------
936 * ----------------------------------------------------------------
939 ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
946 clauses = orExpr->args;
950 * If any of the clauses is TRUE, the OR result is TRUE regardless of
951 * the states of the rest of the clauses, so we can stop evaluating
952 * and return TRUE immediately. If none are TRUE and one or more is
953 * NULL, we return NULL; otherwise we return FALSE. This makes sense
954 * when you interpret NULL as "don't know": if we have a TRUE then the
955 * OR is TRUE even if we aren't sure about some of the other inputs.
956 * If all the known inputs are FALSE, but we have one or more "don't
957 * knows", then we have to report that we "don't know" what the OR's
958 * result should be --- perhaps one of the "don't knows" would have
959 * been TRUE if we'd known its value. Only when all the inputs are
960 * known to be FALSE can we state confidently that the OR's result is
963 foreach(clause, clauses)
965 clause_value = ExecEvalExpr((Node *) lfirst(clause),
966 econtext, isNull, NULL);
969 * if we have a non-null true result, then return it.
972 AnyNull = true; /* remember we got a null */
973 else if (DatumGetBool(clause_value))
977 /* AnyNull is true if at least one clause evaluated to NULL */
979 return BoolGetDatum(false);
982 /* ----------------------------------------------------------------
984 * ----------------------------------------------------------------
987 ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull)
994 clauses = andExpr->args;
998 * If any of the clauses is FALSE, the AND result is FALSE regardless
999 * of the states of the rest of the clauses, so we can stop evaluating
1000 * and return FALSE immediately. If none are FALSE and one or more is
1001 * NULL, we return NULL; otherwise we return TRUE. This makes sense
1002 * when you interpret NULL as "don't know", using the same sort of
1003 * reasoning as for OR, above.
1005 foreach(clause, clauses)
1007 clause_value = ExecEvalExpr((Node *) lfirst(clause),
1008 econtext, isNull, NULL);
1011 * if we have a non-null false result, then return it.
1014 AnyNull = true; /* remember we got a null */
1015 else if (!DatumGetBool(clause_value))
1016 return clause_value;
1019 /* AnyNull is true if at least one clause evaluated to NULL */
1021 return BoolGetDatum(!AnyNull);
1024 /* ----------------------------------------------------------------
1027 * Evaluate a CASE clause. Will have boolean expressions
1028 * inside the WHEN clauses, and will have expressions
1030 * - thomas 1998-11-09
1031 * ----------------------------------------------------------------
1034 ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext,
1035 bool *isNull, ExprDoneCond *isDone)
1041 clauses = caseExpr->args;
1044 * we evaluate each of the WHEN clauses in turn, as soon as one is
1045 * true we return the corresponding result. If none are true then we
1046 * return the value of the default clause, or NULL if there is none.
1048 foreach(clause, clauses)
1050 CaseWhen *wclause = lfirst(clause);
1052 clause_value = ExecEvalExpr(wclause->expr,
1058 * if we have a true test, then we return the result, since the
1059 * case statement is satisfied. A NULL result from the test is
1060 * not considered true.
1062 if (DatumGetBool(clause_value) && !*isNull)
1064 return ExecEvalExpr(wclause->result,
1071 if (caseExpr->defresult)
1073 return ExecEvalExpr(caseExpr->defresult,
1083 /* ----------------------------------------------------------------
1084 * ExecEvalFieldSelect
1086 * Evaluate a FieldSelect node.
1087 * ----------------------------------------------------------------
1090 ExecEvalFieldSelect(FieldSelect *fselect,
1091 ExprContext *econtext,
1093 ExprDoneCond *isDone)
1096 TupleTableSlot *resSlot;
1098 result = ExecEvalExpr(fselect->arg, econtext, isNull, isDone);
1101 resSlot = (TupleTableSlot *) DatumGetPointer(result);
1102 Assert(resSlot != NULL && IsA(resSlot, TupleTableSlot));
1103 result = heap_getattr(resSlot->val,
1105 resSlot->ttc_tupleDescriptor,
1110 /* ----------------------------------------------------------------
1113 * Recursively evaluate a targetlist or qualification expression.
1116 * expression: the expression tree to evaluate
1117 * econtext: evaluation context information
1120 * return value: Datum value of result
1121 * *isNull: set to TRUE if result is NULL (actual return value is
1122 * meaningless if so); set to FALSE if non-null result
1123 * *isDone: set to indicator of set-result status
1125 * A caller that can only accept a singleton (non-set) result should pass
1126 * NULL for isDone; if the expression computes a set result then an elog()
1127 * error will be reported. If the caller does pass an isDone pointer then
1128 * *isDone is set to one of these three states:
1129 * ExprSingleResult singleton result (not a set)
1130 * ExprMultipleResult return value is one element of a set
1131 * ExprEndResult there are no more elements in the set
1132 * When ExprMultipleResult is returned, the caller should invoke
1133 * ExecEvalExpr() repeatedly until ExprEndResult is returned. ExprEndResult
1134 * is returned after the last real set element. For convenience isNull will
1135 * always be set TRUE when ExprEndResult is returned, but this should not be
1136 * taken as indicating a NULL element of the set. Note that these return
1137 * conventions allow us to distinguish among a singleton NULL, a NULL element
1138 * of a set, and an empty set.
1140 * The caller should already have switched into the temporary memory
1141 * context econtext->ecxt_per_tuple_memory. The convenience entry point
1142 * ExecEvalExprSwitchContext() is provided for callers who don't prefer to
1143 * do the switch in an outer loop. We do not do the switch here because
1144 * it'd be a waste of cycles during recursive entries to ExecEvalExpr().
1146 * This routine is an inner loop routine and must be as fast as possible.
1147 * ----------------------------------------------------------------
1150 ExecEvalExpr(Node *expression,
1151 ExprContext *econtext,
1153 ExprDoneCond *isDone)
1157 /* Set default values for result flags: non-null, not a set result */
1160 *isDone = ExprSingleResult;
1162 /* Is this still necessary? Doubtful... */
1163 if (expression == NULL)
1170 * here we dispatch the work to the appropriate type of function given
1171 * the type of our expression.
1173 switch (nodeTag(expression))
1176 retDatum = ExecEvalVar((Var *) expression, econtext, isNull);
1180 Const *con = (Const *) expression;
1182 retDatum = con->constvalue;
1183 *isNull = con->constisnull;
1187 retDatum = ExecEvalParam((Param *) expression, econtext, isNull);
1190 retDatum = ExecEvalIter((Iter *) expression,
1196 retDatum = ExecEvalAggref((Aggref *) expression, econtext, isNull);
1199 retDatum = ExecEvalArrayRef((ArrayRef *) expression,
1206 Expr *expr = (Expr *) expression;
1208 switch (expr->opType)
1211 retDatum = ExecEvalOper(expr, econtext,
1215 retDatum = ExecEvalFunc(expr, econtext,
1219 retDatum = ExecEvalOr(expr, econtext, isNull);
1222 retDatum = ExecEvalAnd(expr, econtext, isNull);
1225 retDatum = ExecEvalNot(expr, econtext, isNull);
1228 retDatum = ExecSubPlan((SubPlan *) expr->oper,
1229 expr->args, econtext,
1233 elog(ERROR, "ExecEvalExpr: unknown expression type %d",
1235 retDatum = 0; /* keep compiler quiet */
1241 retDatum = ExecEvalFieldSelect((FieldSelect *) expression,
1247 retDatum = ExecEvalExpr(((RelabelType *) expression)->arg,
1253 retDatum = ExecEvalCase((CaseExpr *) expression,
1260 elog(ERROR, "ExecEvalExpr: unknown expression type %d",
1261 nodeTag(expression));
1262 retDatum = 0; /* keep compiler quiet */
1267 } /* ExecEvalExpr() */
1271 * Same as above, but get into the right allocation context explicitly.
1274 ExecEvalExprSwitchContext(Node *expression,
1275 ExprContext *econtext,
1277 ExprDoneCond *isDone)
1280 MemoryContext oldContext;
1282 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1283 retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
1284 MemoryContextSwitchTo(oldContext);
1289 /* ----------------------------------------------------------------
1290 * ExecQual / ExecTargetList / ExecProject
1291 * ----------------------------------------------------------------
1294 /* ----------------------------------------------------------------
1297 * Evaluates a conjunctive boolean expression (qual list) and
1298 * returns true iff none of the subexpressions are false.
1299 * (We also return true if the list is empty.)
1301 * If some of the subexpressions yield NULL but none yield FALSE,
1302 * then the result of the conjunction is NULL (ie, unknown)
1303 * according to three-valued boolean logic. In this case,
1304 * we return the value specified by the "resultForNull" parameter.
1306 * Callers evaluating WHERE clauses should pass resultForNull=FALSE,
1307 * since SQL specifies that tuples with null WHERE results do not
1308 * get selected. On the other hand, callers evaluating constraint
1309 * conditions should pass resultForNull=TRUE, since SQL also specifies
1310 * that NULL constraint conditions are not failures.
1312 * NOTE: it would not be correct to use this routine to evaluate an
1313 * AND subclause of a boolean expression; for that purpose, a NULL
1314 * result must be returned as NULL so that it can be properly treated
1315 * in the next higher operator (cf. ExecEvalAnd and ExecEvalOr).
1316 * This routine is only used in contexts where a complete expression
1317 * is being evaluated and we know that NULL can be treated the same
1318 * as one boolean result or the other.
1320 * ----------------------------------------------------------------
1323 ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
1326 MemoryContext oldContext;
1332 EV_printf("ExecQual: qual is ");
1333 EV_nodeDisplay(qual);
1339 * Run in short-lived per-tuple context while computing expressions.
1341 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1344 * Evaluate the qual conditions one at a time. If we find a FALSE
1345 * result, we can stop evaluating and return FALSE --- the AND result
1346 * must be FALSE. Also, if we find a NULL result when resultForNull
1347 * is FALSE, we can stop and return FALSE --- the AND result must be
1348 * FALSE or NULL in that case, and the caller doesn't care which.
1350 * If we get to the end of the list, we can return TRUE. This will
1351 * happen when the AND result is indeed TRUE, or when the AND result
1352 * is NULL (one or more NULL subresult, with all the rest TRUE) and
1353 * the caller has specified resultForNull = TRUE.
1357 foreach(qlist, qual)
1359 Node *clause = (Node *) lfirst(qlist);
1363 expr_value = ExecEvalExpr(clause, econtext, &isNull, NULL);
1367 if (resultForNull == false)
1369 result = false; /* treat NULL as FALSE */
1375 if (!DatumGetBool(expr_value))
1377 result = false; /* definitely FALSE */
1383 MemoryContextSwitchTo(oldContext);
1389 * Number of items in a tlist (including any resjunk items!)
1392 ExecTargetListLength(List *targetlist)
1397 foreach(tl, targetlist)
1399 TargetEntry *curTle = (TargetEntry *) lfirst(tl);
1401 if (curTle->resdom != NULL)
1404 len += curTle->fjoin->fj_nNodes;
1410 * Number of items in a tlist, not including any resjunk items
1413 ExecCleanTargetListLength(List *targetlist)
1418 foreach(tl, targetlist)
1420 TargetEntry *curTle = (TargetEntry *) lfirst(tl);
1422 if (curTle->resdom != NULL)
1424 if (!curTle->resdom->resjunk)
1428 len += curTle->fjoin->fj_nNodes;
1433 /* ----------------------------------------------------------------
1436 * Evaluates a targetlist with respect to the current
1437 * expression context and return a tuple.
1439 * As with ExecEvalExpr, the caller should pass isDone = NULL if not
1440 * prepared to deal with sets of result tuples. Otherwise, a return
1441 * of *isDone = ExprMultipleResult signifies a set element, and a return
1442 * of *isDone = ExprEndResult signifies end of the set of tuple.
1443 * ----------------------------------------------------------------
1446 ExecTargetList(List *targetlist,
1448 TupleDesc targettype,
1450 ExprContext *econtext,
1451 ExprDoneCond *isDone)
1453 MemoryContext oldContext;
1455 #define NPREALLOCDOMAINS 64
1456 char nullsArray[NPREALLOCDOMAINS];
1457 bool fjIsNullArray[NPREALLOCDOMAINS];
1458 ExprDoneCond itemIsDoneArray[NPREALLOCDOMAINS];
1461 ExprDoneCond *itemIsDone;
1468 static struct tupleDesc NullTupleDesc; /* we assume this inits to
1474 EV_printf("ExecTargetList: tl is ");
1475 EV_nodeDisplay(targetlist);
1479 * Run in short-lived per-tuple context while computing expressions.
1481 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1484 * There used to be some klugy and demonstrably broken code here that
1485 * special-cased the situation where targetlist == NIL. Now we just
1486 * fall through and return an empty-but-valid tuple. We do, however,
1487 * have to cope with the possibility that targettype is NULL ---
1488 * heap_formtuple won't like that, so pass a dummy descriptor with
1489 * natts = 0 to deal with it.
1491 if (targettype == NULL)
1492 targettype = &NullTupleDesc;
1495 * allocate an array of char's to hold the "null" information only if
1496 * we have a really large targetlist. otherwise we use the stack.
1498 * We also allocate a bool array that is used to hold fjoin result state,
1499 * and another array that holds the isDone status for each targetlist
1500 * item. The isDone status is needed so that we can iterate,
1501 * generating multiple tuples, when one or more tlist items return
1502 * sets. (We expect the caller to call us again if we return:
1504 * isDone = ExprMultipleResult.)
1506 if (nodomains > NPREALLOCDOMAINS)
1508 nulls = (char *) palloc(nodomains * sizeof(char));
1509 fjIsNull = (bool *) palloc(nodomains * sizeof(bool));
1510 itemIsDone = (ExprDoneCond *) palloc(nodomains * sizeof(ExprDoneCond));
1515 fjIsNull = fjIsNullArray;
1516 itemIsDone = itemIsDoneArray;
1520 * evaluate all the expressions in the target list
1524 *isDone = ExprSingleResult; /* until proven otherwise */
1526 haveDoneSets = false; /* any exhausted set exprs in tlist? */
1528 foreach(tl, targetlist)
1532 if (tle->resdom != NULL)
1534 resind = tle->resdom->resno - 1;
1536 values[resind] = ExecEvalExpr(tle->expr,
1539 &itemIsDone[resind]);
1540 nulls[resind] = isNull ? 'n' : ' ';
1542 if (itemIsDone[resind] != ExprSingleResult)
1544 /* We have a set-valued expression in the tlist */
1546 elog(ERROR, "Set-valued function called in context that cannot accept a set");
1547 if (itemIsDone[resind] == ExprMultipleResult)
1549 /* we have undone sets in the tlist, set flag */
1550 *isDone = ExprMultipleResult;
1554 /* we have done sets in the tlist, set flag for that */
1555 haveDoneSets = true;
1564 List *fjTlist = (List *) tle->expr;
1565 Fjoin *fjNode = tle->fjoin;
1566 int nNodes = fjNode->fj_nNodes;
1567 DatumPtr results = fjNode->fj_results;
1569 ExecEvalFjoin(tle, econtext, fjIsNull, isDone);
1572 * XXX this is wrong, but since fjoin code is completely
1573 * broken anyway, I'm not going to worry about it now --- tgl
1576 if (isDone && *isDone == ExprEndResult)
1578 MemoryContextSwitchTo(oldContext);
1584 * get the result from the inner node
1586 fjRes = (Resdom *) fjNode->fj_innerNode;
1587 resind = fjRes->resno - 1;
1588 values[resind] = results[0];
1589 nulls[resind] = fjIsNull[0] ? 'n' : ' ';
1592 * Get results from all of the outer nodes
1596 curNode++, fjTlist = lnext(fjTlist))
1598 Node *outernode = lfirst(fjTlist);
1600 fjRes = (Resdom *) outernode->iterexpr;
1601 resind = fjRes->resno - 1;
1602 values[resind] = results[curNode];
1603 nulls[resind] = fjIsNull[curNode] ? 'n' : ' ';
1606 elog(ERROR, "ExecTargetList: fjoin nodes not currently supported");
1615 * note: can't get here unless we verified isDone != NULL
1617 if (*isDone == ExprSingleResult)
1621 * all sets are done, so report that tlist expansion is
1624 *isDone = ExprEndResult;
1625 MemoryContextSwitchTo(oldContext);
1633 * We have some done and some undone sets. Restart the done
1634 * ones so that we can deliver a tuple (if possible).
1636 foreach(tl, targetlist)
1640 if (tle->resdom != NULL)
1642 resind = tle->resdom->resno - 1;
1644 if (itemIsDone[resind] == ExprEndResult)
1646 values[resind] = ExecEvalExpr(tle->expr,
1649 &itemIsDone[resind]);
1650 nulls[resind] = isNull ? 'n' : ' ';
1652 if (itemIsDone[resind] == ExprEndResult)
1656 * Oh dear, this item is returning an empty
1657 * set. Guess we can't make a tuple after all.
1659 *isDone = ExprEndResult;
1667 * If we cannot make a tuple because some sets are empty, we
1668 * still have to cycle the nonempty sets to completion, else
1669 * resources will not be released from subplans etc.
1671 if (*isDone == ExprEndResult)
1673 foreach(tl, targetlist)
1677 if (tle->resdom != NULL)
1679 resind = tle->resdom->resno - 1;
1681 while (itemIsDone[resind] == ExprMultipleResult)
1683 (void) ExecEvalExpr(tle->expr,
1686 &itemIsDone[resind]);
1691 MemoryContextSwitchTo(oldContext);
1699 * form the new result tuple (in the caller's memory context!)
1701 MemoryContextSwitchTo(oldContext);
1703 newTuple = (HeapTuple) heap_formtuple(targettype, values, nulls);
1708 * free the status arrays if we palloc'd them
1710 if (nodomains > NPREALLOCDOMAINS)
1720 /* ----------------------------------------------------------------
1723 * projects a tuple based on projection info and stores
1724 * it in the specified tuple table slot.
1726 * Note: someday soon the executor can be extended to eliminate
1727 * redundant projections by storing pointers to datums
1728 * in the tuple table and then passing these around when
1729 * possible. this should make things much quicker.
1731 * ----------------------------------------------------------------
1734 ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
1736 TupleTableSlot *slot;
1741 ExprContext *econtext;
1747 if (projInfo == NULL)
1748 return (TupleTableSlot *) NULL;
1751 * get the projection info we want
1753 slot = projInfo->pi_slot;
1754 targetlist = projInfo->pi_targetlist;
1755 len = projInfo->pi_len;
1756 tupType = slot->ttc_tupleDescriptor;
1758 tupValue = projInfo->pi_tupValue;
1759 econtext = projInfo->pi_exprContext;
1762 * form a new result tuple (if possible --- result can be NULL)
1764 newTuple = ExecTargetList(targetlist,
1772 * store the tuple in the projection slot and return the slot.
1774 return ExecStoreTuple(newTuple, /* tuple to store */
1775 slot, /* slot to store in */
1776 InvalidBuffer, /* tuple has no buffer */