1 /*-------------------------------------------------------------------------
4 * Routines to evaluate qualification and targetlist expressions
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.39 1998/12/04 15:33:19 thomas Exp $
12 *-------------------------------------------------------------------------
16 * ExecEvalExpr - evaluate an expression and return a datum
17 * ExecQual - return true/false if qualification is satisified
18 * ExecTargetList - form a new tuple by projecting the given tuple
21 * ExecEvalExpr() and ExecEvalVar() are hotspots. making these faster
22 * will speed up the entire system. Unfortunately they are currently
23 * implemented recursively. Eliminating the recursion is bound to
24 * improve the speed of the executor.
26 * ExecTargetList() 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
36 #include "access/heapam.h"
37 #include "catalog/pg_language.h"
38 #include "executor/execdebug.h"
39 #include "executor/executor.h"
40 #include "executor/execFlatten.h"
41 #include "executor/functions.h"
42 #include "executor/nodeSubplan.h"
44 #include "nodes/memnodes.h"
45 #include "nodes/primnodes.h"
46 #include "nodes/relation.h"
47 #include "optimizer/clauses.h"
48 #include "utils/array.h"
49 #include "utils/builtins.h"
50 #include "utils/fcache.h"
51 #include "utils/fcache2.h"
52 #include "utils/mcxt.h"
53 #include "utils/memutils.h"
57 * externs and constants
62 * XXX Used so we can get rid of use of Const nodes in the executor.
63 * Currently only used by ExecHashGetBucket and set only by ExecMakeVarConst
64 * and by ExecEvalArrayRef.
69 /* static functions decls */
70 static Datum ExecEvalAggreg(Aggreg *agg, ExprContext *econtext, bool *isNull);
71 static Datum ExecEvalArrayRef(ArrayRef *arrayRef, ExprContext *econtext,
72 bool *isNull, bool *isDone);
73 static Datum ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull);
74 static Datum ExecEvalFunc(Expr *funcClause, ExprContext *econtext,
75 bool *isNull, bool *isDone);
76 static void ExecEvalFuncArgs(FunctionCachePtr fcache, ExprContext *econtext,
77 List *argList, Datum argV[], bool *argIsDone);
78 static Datum ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull);
79 static Datum ExecEvalOper(Expr *opClause, ExprContext *econtext,
81 static Datum ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull);
82 static Datum ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull);
83 static Datum ExecMakeFunctionResult(Node *node, List *arguments,
84 ExprContext *econtext, bool *isNull, bool *isDone);
85 static bool ExecQualClause(Node *clause, ExprContext *econtext);
90 * This function takes an ArrayRef and returns a Const Node if it
91 * is an array reference or returns the changed Array Node if it is
92 * an array assignment.
96 ExecEvalArrayRef(ArrayRef *arrayRef,
97 ExprContext *econtext,
104 ArrayType *array_scanner;
115 array_scanner = (ArrayType *) ExecEvalExpr(arrayRef->refexpr,
122 upperIndexpr = arrayRef->refupperindexpr;
124 foreach(elt, upperIndexpr)
126 upper.indx[i++] = (int32) ExecEvalExpr((Node *) lfirst(elt),
134 lowerIndexpr = arrayRef->reflowerindexpr;
136 if (lowerIndexpr != NIL)
138 foreach(elt, lowerIndexpr)
140 lower.indx[j++] = (int32) ExecEvalExpr((Node *) lfirst(elt),
149 "ExecEvalArrayRef: upper and lower indices mismatch");
153 assgnexpr = arrayRef->refassgnexpr;
154 if (assgnexpr != NULL)
156 dataPtr = (char *) ExecEvalExpr((Node *)
161 execConstByVal = arrayRef->refelembyval;
162 execConstLen = arrayRef->refelemlength;
164 return (Datum) array_set(array_scanner, i, upper.indx, dataPtr,
165 arrayRef->refelembyval,
166 arrayRef->refelemlength,
167 arrayRef->refattrlength, isNull);
168 return (Datum) array_assgn(array_scanner, i, upper.indx,
170 (ArrayType *) dataPtr,
171 arrayRef->refelembyval,
172 arrayRef->refelemlength, isNull);
174 execConstByVal = arrayRef->refelembyval;
175 execConstLen = arrayRef->refelemlength;
177 return (Datum) array_ref(array_scanner, i, upper.indx,
178 arrayRef->refelembyval,
179 arrayRef->refelemlength,
180 arrayRef->refattrlength, isNull);
181 return (Datum) array_clip(array_scanner, i, upper.indx, lower.indx,
182 arrayRef->refelembyval,
183 arrayRef->refelemlength, isNull);
187 /* ----------------------------------------------------------------
190 * Returns a Datum whose value is the value of the precomputed
191 * aggregate found in the given expression context.
192 * ----------------------------------------------------------------
195 ExecEvalAggreg(Aggreg *agg, ExprContext *econtext, bool *isNull)
197 *isNull = econtext->ecxt_nulls[agg->aggno];
198 return econtext->ecxt_values[agg->aggno];
201 /* ----------------------------------------------------------------
204 * Returns a Datum whose value is the value of a range
205 * variable with respect to given expression context.
208 * As an entry condition, we expect that the datatype the
209 * plan expects to get (as told by our "variable" argument) is in
210 * fact the datatype of the attribute the plan says to fetch (as
211 * seen in the current context, identified by our "econtext"
214 * If we fetch a Type A attribute and Caller treats it as if it
215 * were Type B, there will be undefined results (e.g. crash).
216 * One way these might mismatch now is that we're accessing a
217 * catalog class and the type information in the pg_attribute
218 * class does not match the hardcoded pg_attribute information
219 * (in pg_attribute.h) for the class in question.
221 * We have an Assert to make sure this entry condition is met.
223 * ---------------------------------------------------------------- */
225 ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
228 TupleTableSlot *slot;
231 TupleDesc tuple_type;
237 * get the slot we want
240 switch (variable->varno)
242 case INNER: /* get the tuple from the inner node */
243 slot = econtext->ecxt_innertuple;
246 case OUTER: /* get the tuple from the outer node */
247 slot = econtext->ecxt_outertuple;
250 default: /* get the tuple from the relation being
252 slot = econtext->ecxt_scantuple;
257 * extract tuple information from the slot
260 heapTuple = slot->val;
261 tuple_type = slot->ttc_tupleDescriptor;
262 buffer = slot->ttc_buffer;
264 attnum = variable->varattno;
266 /* (See prolog for explanation of this Assert) */
267 Assert(attnum <= 0 ||
268 (attnum - 1 <= tuple_type->natts - 1 &&
269 tuple_type->attrs[attnum - 1] != NULL &&
270 variable->vartype == tuple_type->attrs[attnum - 1]->atttypid))
273 * If the attribute number is invalid, then we are supposed to return
274 * the entire tuple, we give back a whole slot so that callers know
275 * what the tuple looks like.
277 if (attnum == InvalidAttrNumber)
279 TupleTableSlot *tempSlot;
283 tempSlot = makeNode(TupleTableSlot);
284 tempSlot->ttc_shouldFree = false;
285 tempSlot->ttc_descIsNew = true;
286 tempSlot->ttc_tupleDescriptor = (TupleDesc) NULL,
287 tempSlot->ttc_buffer = InvalidBuffer;
288 tempSlot->ttc_whichplan = -1;
290 tup = heap_copytuple(heapTuple);
291 td = CreateTupleDescCopy(slot->ttc_tupleDescriptor);
293 ExecSetSlotDescriptor(tempSlot, td);
295 ExecStoreTuple(tup, tempSlot, InvalidBuffer, true);
296 return (Datum) tempSlot;
299 result = heap_getattr(heapTuple, /* tuple containing attribute */
300 attnum, /* attribute number of desired
302 tuple_type, /* tuple descriptor of tuple */
303 isNull); /* return: is attribute null? */
306 * return null if att is null
313 * get length and type information..
314 * ??? what should we do about variable length attributes
315 * - variable length attributes have their length stored
316 * in the first 4 bytes of the memory pointed to by the
317 * returned value.. If we can determine that the type
318 * is a variable length type, we can do the right thing.
325 * If this is a pseudo-att, we get the type and fake the length.
326 * There ought to be a routine to return the real lengths, so
327 * we'll mark this one ... XXX -mao
330 len = heap_sysattrlen(attnum); /* XXX see -mao above */
331 byval = heap_sysattrbyval(attnum); /* XXX see -mao above */
335 len = tuple_type->attrs[attnum - 1]->attlen;
336 byval = tuple_type->attrs[attnum - 1]->attbyval ? true : false;
339 execConstByVal = byval;
345 /* ----------------------------------------------------------------
348 * Returns the value of a parameter. A param node contains
349 * something like ($.name) and the expression context contains
350 * the current parameter bindings (name = "sam") (age = 34)...
351 * so our job is to replace the param node with the datum
352 * containing the appropriate information ("sam").
354 * Q: if we have a parameter ($.foo) without a binding, i.e.
355 * there is no (foo = xxx) in the parameter list info,
356 * is this a fatal error or should this be a "not available"
357 * (in which case we shoud return a Const node with the
358 * isnull flag) ? -cim 10/13/89
360 * Minor modification: Param nodes now have an extra field,
361 * `paramkind' which specifies the type of parameter
362 * (see params.h). So while searching the paramList for
363 * a paramname/value pair, we have also to check for `kind'.
365 * NOTE: The last entry in `paramList' is always an
366 * entry with kind == PARAM_INVALID.
367 * ----------------------------------------------------------------
370 ExecEvalParam(Param *expression, ExprContext *econtext, bool *isNull)
373 char *thisParameterName;
374 int thisParameterKind = expression->paramkind;
375 AttrNumber thisParameterId = expression->paramid;
377 ParamListInfo paramList;
379 if (thisParameterKind == PARAM_EXEC)
381 ParamExecData *prm = &(econtext->ecxt_param_exec_vals[thisParameterId]);
383 if (prm->execPlan != NULL)
384 ExecSetParamPlan(prm->execPlan);
385 Assert(prm->execPlan == NULL);
386 *isNull = prm->isnull;
390 thisParameterName = expression->paramname;
391 paramList = econtext->ecxt_param_list_info;
396 * search the list with the parameter info to find a matching name. An
397 * entry with an InvalidName denotes the last element in the array.
400 if (paramList != NULL)
404 * search for an entry in 'paramList' that matches the
407 while (paramList->kind != PARAM_INVALID && !matchFound)
409 switch (thisParameterKind)
412 if (thisParameterKind == paramList->kind &&
413 strcmp(paramList->name, thisParameterName) == 0)
417 if (thisParameterKind == paramList->kind &&
418 paramList->id == thisParameterId)
423 if (thisParameterKind == paramList->kind &&
424 paramList->id == thisParameterId)
431 if (strcmp(paramList->name, thisParameterName) != 0)
434 "ExecEvalParam: new/old params with same id & diff names");
441 * oops! this is not supposed to happen!
443 elog(ERROR, "ExecEvalParam: invalid paramkind %d",
455 * ooops! we couldn't find this parameter in the parameter list.
458 elog(ERROR, "ExecEvalParam: Unknown value for parameter %s",
465 if (paramList->isnull)
471 if (expression->param_tlist != NIL)
475 List *tlist = expression->param_tlist;
476 TargetEntry *tle = (TargetEntry *) lfirst(tlist);
477 TupleTableSlot *slot = (TupleTableSlot *) paramList->value;
480 value = ProjectAttribute(slot->ttc_tupleDescriptor,
484 return paramList->value;
488 /* ----------------------------------------------------------------
489 * ExecEvalOper / ExecEvalFunc support routines
490 * ----------------------------------------------------------------
497 * These are functions which return the value of the
498 * named attribute out of the tuple from the arg slot. User defined
499 * C functions which take a tuple as an argument are expected
500 * to use this. Ex: overpaid(EMP) might call GetAttributeByNum().
503 /* static but gets called from external functions */
505 GetAttributeByNum(TupleTableSlot *slot,
511 if (!AttributeNumberIsValid(attrno))
512 elog(ERROR, "GetAttributeByNum: Invalid attribute number");
514 if (!AttrNumberIsForUserDefinedAttr(attrno))
515 elog(ERROR, "GetAttributeByNum: cannot access system attributes here");
517 if (isNull == (bool *) NULL)
518 elog(ERROR, "GetAttributeByNum: a NULL isNull flag was passed");
523 return (char *) NULL;
526 retval = heap_getattr(slot->val,
528 slot->ttc_tupleDescriptor,
531 return (char *) NULL;
532 return (char *) retval;
535 /* XXX name for catalogs */
538 att_by_num(TupleTableSlot *slot,
542 return GetAttributeByNum(slot, attrno, isNull);
548 GetAttributeByName(TupleTableSlot *slot, char *attname, bool *isNull)
557 elog(ERROR, "GetAttributeByName: Invalid attribute name");
559 if (isNull == (bool *) NULL)
560 elog(ERROR, "GetAttributeByName: a NULL isNull flag was passed");
565 return (char *) NULL;
568 tupdesc = slot->ttc_tupleDescriptor;
569 natts = slot->val->t_data->t_natts;
571 attrno = InvalidAttrNumber;
572 for (i = 0; i < tupdesc->natts; i++)
574 if (namestrcmp(&(tupdesc->attrs[i]->attname), attname) == 0)
576 attrno = tupdesc->attrs[i]->attnum;
581 if (attrno == InvalidAttrNumber)
582 elog(ERROR, "GetAttributeByName: attribute %s not found", attname);
584 retval = heap_getattr(slot->val,
589 return (char *) NULL;
590 return (char *) retval;
593 /* XXX name for catalogs */
596 att_by_name(TupleTableSlot *slot, char *attname, bool *isNull)
598 return GetAttributeByName(slot, attname, isNull);
604 ExecEvalFuncArgs(FunctionCachePtr fcache,
605 ExprContext *econtext,
615 nullVect = fcache->nullVect;
618 foreach(arg, argList)
621 * evaluate the expression, in general functions cannot take
622 * sets as arguments but we make an exception in the case of
623 * nested dot expressions. We have to watch out for this case
628 ExecEvalExpr((Node *) lfirst(arg),
637 fcache->setArg = (char *) argV[0];
638 fcache->hasSetArg = true;
649 * ExecMakeFunctionResult
653 ExecMakeFunctionResult(Node *node,
655 ExprContext *econtext,
659 Datum argV[MAXFMGRARGS];
660 FunctionCachePtr fcache;
661 Func *funcNode = NULL;
662 Oper *operNode = NULL;
663 bool funcisset = false;
666 * This is kind of ugly, Func nodes now have targetlists so that we
667 * know when and what to project out from postquel function results.
668 * This means we have to pass the func node all the way down instead
669 * of using only the fcache struct as before. ExecMakeFunctionResult
670 * becomes a little bit more of a dual personality as a result.
674 funcNode = (Func *) node;
675 fcache = funcNode->func_fcache;
679 operNode = (Oper *) node;
680 fcache = operNode->op_fcache;
684 * arguments is a list of expressions to evaluate
685 * before passing to the function manager.
686 * We collect the results of evaluating the expressions
687 * into a datum array (argV) and pass this array to arrayFmgr()
690 if (fcache->nargs != 0)
694 if (fcache->nargs > MAXFMGRARGS)
695 elog(ERROR, "ExecMakeFunctionResult: too many arguments");
698 * If the setArg in the fcache is set we have an argument
699 * returning a set of tuples (i.e. a nested dot expression). We
700 * don't want to evaluate the arguments again until the function
701 * is done. hasSetArg will always be false until we eval the args
702 * for the first time. We should set this in the parser.
704 if ((fcache->hasSetArg) && fcache->setArg != NULL)
706 argV[0] = (Datum) fcache->setArg;
710 ExecEvalFuncArgs(fcache, econtext, arguments, argV, &argDone);
712 if ((fcache->hasSetArg) && (argDone))
721 * If this function is really a set, we have to diddle with things. If
722 * the function has already been called at least once, then the setArg
723 * field of the fcache holds the OID of this set in pg_proc. (This is
724 * not quite legit, since the setArg field is really for functions
725 * which take sets of tuples as input - set functions take no inputs
726 * at all. But it's a nice place to stash this value, for now.)
728 * If this is the first call of the set's function, then the call to
729 * ExecEvalFuncArgs above just returned the OID of the pg_proc tuple
730 * which defines this set. So replace the existing funcid in the
731 * funcnode with the set's OID. Also, we want a new fcache which
732 * points to the right function, so get that, now that we have the
733 * right OID. Also zero out the argV, since the real set doesn't take
736 if (((Func *) node)->funcid == F_SETEVAL)
743 ((Func *) node)->funcid = (Oid) PointerGetDatum(fcache->setArg);
748 ((Func *) node)->funcid = (Oid) argV[0];
749 setFcache(node, argV[0], NIL, econtext);
750 fcache = ((Func *) node)->func_fcache;
751 fcache->setArg = (char *) argV[0];
757 * now return the value gotten by calling the function manager,
758 * passing the function the evaluated parameter values.
761 if (fcache->language == SQLlanguageId)
766 result = postquel_function(funcNode, (char **) argV, isNull, isDone);
769 * finagle the situation where we are iterating through all
770 * results in a nested dot function (whose argument function
771 * returns a set of tuples) and the current function finally
772 * finishes. We need to get the next argument in the set and run
773 * the function all over again. This is getting unclean.
775 if ((*isDone) && (fcache->hasSetArg))
779 ExecEvalFuncArgs(fcache, econtext, arguments, argV, &argDone);
783 fcache->setArg = (char *) NULL;
785 result = (Datum) NULL;
788 result = postquel_function(funcNode,
797 * reset the funcid so that next call to this routine will
798 * still recognize this func as a set. Note that for now we
799 * assume that the set function in pg_proc must be a Postquel
800 * function - the funcid is not reset below for C functions.
802 ((Func *) node)->funcid = F_SETEVAL;
805 * If we're done with the results of this function, get rid of
809 ((Func *) node)->func_fcache = NULL;
819 for (i = 0; i < fcache->nargs; i++)
820 if (fcache->nullVect[i] == true)
823 return (Datum) fmgr_c(&fcache->func, (FmgrValues *) argV, isNull);
828 /* ----------------------------------------------------------------
832 * Evaluate the functional result of a list of arguments by calling the
833 * function manager. Note that in the case of operator expressions, the
834 * optimizer had better have already replaced the operator OID with the
835 * appropriate function OID or we're hosed.
838 * Presumably the function manager will not take null arguments, so we
839 * check for null arguments before sending the arguments to (fmgr).
841 * Returns the value of the functional expression.
842 * ----------------------------------------------------------------
845 /* ----------------------------------------------------------------
847 * ----------------------------------------------------------------
850 ExecEvalOper(Expr *opClause, ExprContext *econtext, bool *isNull)
854 FunctionCachePtr fcache;
858 * an opclause is a list (op args). (I think)
860 * we extract the oid of the function associated with
861 * the op and then pass the work onto ExecMakeFunctionResult
862 * which evaluates the arguments and returns the result of
863 * calling the function on the evaluated arguments.
866 op = (Oper *) opClause->oper;
867 argList = opClause->args;
870 * get the fcache from the Oper node. If it is NULL, then initialize
873 fcache = op->op_fcache;
876 setFcache((Node *) op, op->opid, argList, econtext);
877 fcache = op->op_fcache;
881 * call ExecMakeFunctionResult() with a dummy isDone that we ignore.
882 * We don't have operator whose arguments are sets.
886 ExecMakeFunctionResult((Node *) op, argList, econtext, isNull, &isDone);
889 /* ----------------------------------------------------------------
891 * ----------------------------------------------------------------
895 ExecEvalFunc(Expr *funcClause,
896 ExprContext *econtext,
902 FunctionCachePtr fcache;
905 * an funcclause is a list (func args). (I think)
907 * we extract the oid of the function associated with
908 * the func node and then pass the work onto ExecMakeFunctionResult
909 * which evaluates the arguments and returns the result of
910 * calling the function on the evaluated arguments.
912 * this is nearly identical to the ExecEvalOper code.
915 func = (Func *) funcClause->oper;
916 argList = funcClause->args;
919 * get the fcache from the Func node. If it is NULL, then initialize
922 fcache = func->func_fcache;
925 setFcache((Node *) func, func->funcid, argList, econtext);
926 fcache = func->func_fcache;
930 ExecMakeFunctionResult((Node *) func, argList, econtext, isNull, isDone);
933 /* ----------------------------------------------------------------
938 * Evaluate boolean expressions. Evaluation of 'or' is
939 * short-circuited when the first true (or null) value is found.
941 * The query planner reformulates clause expressions in the
942 * qualification to conjunctive normal form. If we ever get
943 * an AND to evaluate, we can be sure that it's not a top-level
944 * clause in the qualification, but appears lower (as a function
945 * argument, for example), or in the target list. Not that you
946 * need to know this, mind you...
947 * ----------------------------------------------------------------
950 ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull)
956 clause = lfirst(notclause->args);
959 * We don't iterate over sets in the quals, so pass in an isDone
960 * flag, but ignore it.
963 expr_value = ExecEvalExpr(clause, econtext, isNull, &isDone);
966 * if the expression evaluates to null, then we just
967 * cascade the null back to whoever called us.
974 * evaluation of 'not' is simple.. expr is false, then
975 * return 'true' and vice versa.
978 if (DatumGetInt32(expr_value) == 0)
981 return (Datum) false;
984 /* ----------------------------------------------------------------
986 * ----------------------------------------------------------------
989 ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
995 Datum const_value = 0;
998 clauses = orExpr->args;
1001 * we use three valued logic functions here...
1002 * we evaluate each of the clauses in turn,
1003 * as soon as one is true we return that
1004 * value. If none is true and none of the
1005 * clauses evaluate to NULL we return
1006 * the value of the last clause evaluated (which
1007 * should be false) with *isNull set to false else
1008 * if none is true and at least one clause evaluated
1009 * to NULL we set *isNull flag to true -
1012 foreach(clause, clauses)
1016 * We don't iterate over sets in the quals, so pass in an isDone
1017 * flag, but ignore it.
1020 const_value = ExecEvalExpr((Node *) lfirst(clause),
1026 * if the expression evaluates to null, then we
1027 * remember it in the local IsNull flag, if none of the
1028 * clauses are true then we need to set *isNull
1037 * Many functions don't (or can't!) check if an argument is NULL
1038 * or NOT_NULL and may return TRUE (1) with *isNull TRUE
1039 * (an_int4_column <> 1: int4ne returns TRUE for NULLs).
1040 * Not having time to fix the function manager I want to fix OR:
1041 * if we had 'x <> 1 OR x isnull' then when x is NULL
1042 * TRUE was returned by the 'x <> 1' clause ...
1043 * but ExecQualClause says that the qualification should *fail*
1044 * if isnull is TRUE for any value returned by ExecEvalExpr.
1045 * So, force this rule here:
1046 * if isnull is TRUE then the clause failed.
1047 * Note: nullvalue() & nonnullvalue() always sets isnull to FALSE for NULLs.
1054 * if we have a true result, then we return it.
1057 if (DatumGetInt32(const_value) != 0)
1061 /* IsNull is true if at least one clause evaluated to NULL */
1066 /* ----------------------------------------------------------------
1068 * ----------------------------------------------------------------
1071 ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull)
1075 Datum const_value = 0;
1081 clauses = andExpr->args;
1084 * we evaluate each of the clauses in turn,
1085 * as soon as one is false we return that
1086 * value. If none are false or NULL then we return
1087 * the value of the last clause evaluated, which
1091 foreach(clause, clauses)
1095 * We don't iterate over sets in the quals, so pass in an isDone
1096 * flag, but ignore it.
1099 const_value = ExecEvalExpr((Node *) lfirst(clause),
1105 * if the expression evaluates to null, then we
1106 * remember it in IsNull, if none of the clauses after
1107 * this evaluates to false we will have to set *isNull
1115 * if we have a false result, then we return it, since the
1116 * conjunction must be false.
1119 if (DatumGetInt32(const_value) == 0)
1127 /* ----------------------------------------------------------------
1130 * Evaluate a CASE clause. Will have boolean expressions
1131 * inside the WHEN clauses, and will have constants
1133 * - thomas 1998-11-09
1134 * ----------------------------------------------------------------
1137 ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull)
1142 Datum const_value = 0;
1145 clauses = caseExpr->args;
1148 * we evaluate each of the WHEN clauses in turn,
1149 * as soon as one is true we return the corresponding
1150 * result. If none are true then we return the value
1151 * of the default clause, or NULL.
1154 foreach(clause, clauses)
1158 * We don't iterate over sets in the quals, so pass in an isDone
1159 * flag, but ignore it.
1163 wclause = lfirst(clause);
1164 const_value = ExecEvalExpr((Node *) wclause->expr,
1170 * if we have a true test, then we return the result,
1171 * since the case statement is satisfied.
1174 if (DatumGetInt32(const_value) != 0)
1176 const_value = ExecEvalExpr((Node *) wclause->result,
1180 return (Datum) const_value;
1185 if (caseExpr->defresult)
1187 const_value = ExecEvalExpr((Node *) caseExpr->defresult,
1200 /* ----------------------------------------------------------------
1203 * Recursively evaluate a targetlist or qualification expression.
1205 * This routine is an inner loop routine and should be as fast
1208 * Node comparison functions were replaced by macros for speed and to plug
1209 * memory leaks incurred by using the planner's Lispy stuff for
1210 * comparisons. Order of evaluation of node comparisons IS IMPORTANT;
1211 * the macros do no checks. Order of evaluation:
1213 * o an isnull check, largely to avoid coredumps since greg doubts this
1214 * routine is called with a null ptr anyway in proper operation, but is
1215 * not completely sure...
1216 * o ExactNodeType checks.
1217 * o clause checks or other checks where we look at the lfirst of something.
1218 * ----------------------------------------------------------------
1221 ExecEvalExpr(Node *expression,
1222 ExprContext *econtext,
1231 * Some callers don't care about is done and only want 1 result. They
1232 * indicate this by passing NULL
1238 * here we dispatch the work to the appropriate type
1239 * of function given the type of our expression.
1242 if (expression == NULL)
1245 return (Datum) true;
1248 switch (nodeTag(expression))
1251 retDatum = (Datum) ExecEvalVar((Var *) expression, econtext, isNull);
1255 Const *con = (Const *) expression;
1257 if (con->constisnull)
1259 retDatum = con->constvalue;
1263 retDatum = (Datum) ExecEvalParam((Param *) expression, econtext, isNull);
1266 retDatum = (Datum) ExecEvalIter((Iter *) expression,
1272 retDatum = (Datum) ExecEvalAggreg((Aggreg *) expression,
1277 retDatum = (Datum) ExecEvalArrayRef((ArrayRef *) expression,
1284 Expr *expr = (Expr *) expression;
1286 switch (expr->opType)
1289 retDatum = (Datum) ExecEvalOper(expr, econtext, isNull);
1292 retDatum = (Datum) ExecEvalFunc(expr, econtext, isNull, isDone);
1295 retDatum = (Datum) ExecEvalOr(expr, econtext, isNull);
1298 retDatum = (Datum) ExecEvalAnd(expr, econtext, isNull);
1301 retDatum = (Datum) ExecEvalNot(expr, econtext, isNull);
1304 retDatum = (Datum) ExecSubPlan((SubPlan *) expr->oper, expr->args, econtext);
1307 elog(ERROR, "ExecEvalExpr: unknown expression type %d", expr->opType);
1313 retDatum = (Datum) ExecEvalCase((CaseExpr *) expression, econtext, isNull);
1317 elog(ERROR, "ExecEvalExpr: unknown expression type %d", nodeTag(expression));
1322 } /* ExecEvalExpr() */
1325 /* ----------------------------------------------------------------
1326 * ExecQual / ExecTargetList
1327 * ----------------------------------------------------------------
1330 /* ----------------------------------------------------------------
1333 * this is a workhorse for ExecQual. ExecQual has to deal
1334 * with a list of qualifications, so it passes each qualification
1335 * in the list to this function one at a time. ExecQualClause
1336 * returns true when the qualification *fails* and false if
1337 * the qualification succeeded (meaning we have to test the
1338 * rest of the qualification)
1339 * ----------------------------------------------------------------
1342 ExecQualClause(Node *clause, ExprContext *econtext)
1348 /* when there is a null clause, consider the qualification to be true */
1353 * pass isDone, but ignore it. We don't iterate over multiple returns
1354 * in the qualifications.
1356 expr_value = (Datum)
1357 ExecEvalExpr(clause, econtext, &isNull, &isDone);
1360 * this is interesting behaviour here. When a clause evaluates
1361 * to null, then we consider this as passing the qualification.
1362 * it seems kind of like, if the qual is NULL, then there's no
1370 * remember, we return true when the qualification fails..
1373 if (DatumGetInt32(expr_value) == 0)
1379 /* ----------------------------------------------------------------
1382 * Evaluates a conjunctive boolean expression and returns t
1383 * iff none of the subexpressions are false (or null).
1384 * ----------------------------------------------------------------
1387 ExecQual(List *qual, ExprContext *econtext)
1396 EV_printf("ExecQual: qual is ");
1397 EV_nodeDisplay(qual);
1403 * return true immediately if no qual
1410 * a "qual" is a list of clauses. To evaluate the
1411 * qual, we evaluate each of the clauses in the list.
1413 * ExecQualClause returns true when we know the qualification
1414 * *failed* so we just pass each clause in qual to it until
1415 * we know the qual failed or there are no more clauses.
1420 foreach(clause, qual)
1422 result = ExecQualClause((Node *) lfirst(clause), econtext);
1428 * if result is true, then it means a clause failed so we
1429 * return false. if result is false then it means no clause
1430 * failed so we return true.
1440 ExecTargetListLength(List *targetlist)
1444 TargetEntry *curTle;
1447 foreach(tl, targetlist)
1449 curTle = lfirst(tl);
1451 if (curTle->resdom != NULL)
1454 len += curTle->fjoin->fj_nNodes;
1459 /* ----------------------------------------------------------------
1462 * Evaluates a targetlist with respect to the current
1463 * expression context and return a tuple.
1464 * ----------------------------------------------------------------
1467 ExecTargetList(List *targetlist,
1469 TupleDesc targettype,
1471 ExprContext *econtext,
1474 char nulls_array[64];
1475 bool fjNullArray[64];
1491 EV_printf("ExecTargetList: tl is ");
1492 EV_nodeDisplay(targetlist);
1496 * Return a dummy tuple if the targetlist is empty .
1497 * the dummy tuple is necessary to differentiate
1498 * between passing and failing the qualification.
1501 if (targetlist == NIL)
1504 * I now think that the only time this makes
1505 * any sence is when we run a delete query. Then
1506 * we need to return something other than nil
1507 * so we know to delete the tuple associated
1508 * with the saved tupleid.. see what ExecutePlan
1509 * does with the returned tuple.. -cim 9/21/89
1511 * It could also happen in queries like:
1512 * retrieve (foo.all) where bar.a = 3
1514 * is this a new phenomenon? it might cause bogus behavior
1515 * if we try to free this tuple later!! I put a hook in
1516 * ExecProject to watch out for this case -mer 24 Aug 1992
1519 CXT1_printf("ExecTargetList: context is %d\n", CurrentMemoryContext);
1521 return (HeapTuple) true;
1525 * allocate an array of char's to hold the "null" information
1526 * only if we have a really large targetlist. otherwise we use
1532 null_head = (char *) palloc(nodomains + 1);
1533 fjIsNull = (bool *) palloc(nodomains + 1);
1537 null_head = &nulls_array[0];
1538 fjIsNull = &fjNullArray[0];
1542 * evaluate all the expressions in the target list
1545 EV_printf("ExecTargetList: setting target list values\n");
1548 foreach(tl, targetlist)
1551 * remember, a target list is a list of lists:
1553 * ((<resdom | fjoin> expr) (<resdom | fjoin> expr) ...)
1555 * tl is a pointer to successive cdr's of the targetlist
1556 * tle is a pointer to the target list entry in tl
1561 if (tle->resdom != NULL)
1564 resdom = tle->resdom;
1565 resind = resdom->resno - 1;
1566 constvalue = (Datum) ExecEvalExpr(expr,
1571 if ((IsA(expr, Iter)) && (*isDone))
1572 return (HeapTuple) NULL;
1574 values[resind] = constvalue;
1577 null_head[resind] = ' ';
1579 null_head[resind] = 'n';
1585 List *fjTlist = (List *) tle->expr;
1586 Fjoin *fjNode = tle->fjoin;
1587 int nNodes = fjNode->fj_nNodes;
1588 DatumPtr results = fjNode->fj_results;
1590 ExecEvalFjoin(tle, econtext, fjIsNull, isDone);
1592 return (HeapTuple) NULL;
1595 * get the result from the inner node
1597 fjRes = (Resdom *) fjNode->fj_innerNode;
1598 resind = fjRes->resno - 1;
1600 null_head[resind] = 'n';
1603 null_head[resind] = ' ';
1604 values[resind] = results[0];
1608 * Get results from all of the outer nodes
1612 curNode++, fjTlist = lnext(fjTlist))
1614 #if 0 /* what is this?? */
1615 Node *outernode = lfirst(fjTlist);
1617 fjRes = (Resdom *) outernode->iterexpr;
1619 resind = fjRes->resno - 1;
1620 if (fjIsNull[curNode])
1621 null_head[resind] = 'n';
1624 null_head[resind] = ' ';
1625 values[resind] = results[curNode];
1632 * form the new result tuple (in the "normal" context)
1635 newTuple = (HeapTuple)
1636 heap_formtuple(targettype, values, null_head);
1639 * free the nulls array if we allocated one..
1649 /* ----------------------------------------------------------------
1652 * projects a tuple based in projection info and stores
1653 * it in the specified tuple table slot.
1655 * Note: someday soon the executor can be extended to eliminate
1656 * redundant projections by storing pointers to datums
1657 * in the tuple table and then passing these around when
1658 * possible. this should make things much quicker.
1660 * ----------------------------------------------------------------
1663 ExecProject(ProjectionInfo *projInfo, bool *isDone)
1665 TupleTableSlot *slot;
1670 ExprContext *econtext;
1677 if (projInfo == NULL)
1678 return (TupleTableSlot *) NULL;
1681 * get the projection info we want
1684 slot = projInfo->pi_slot;
1685 targetlist = projInfo->pi_targetlist;
1686 len = projInfo->pi_len;
1687 tupType = slot->ttc_tupleDescriptor;
1689 tupValue = projInfo->pi_tupValue;
1690 econtext = projInfo->pi_exprContext;
1692 if (targetlist == NIL)
1695 return (TupleTableSlot *) NULL;
1699 * form a new (result) tuple
1702 newTuple = ExecTargetList(targetlist,
1710 * store the tuple in the projection slot and return the slot.
1712 * If there's no projection target list we don't want to pfree
1713 * the bogus tuple that ExecTargetList passes back to us.
1717 return (TupleTableSlot *)
1718 ExecStoreTuple(newTuple,/* tuple to store */
1719 slot, /* slot to store in */
1720 InvalidBuffer, /* tuple has no buffer */