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.49 1999/03/19 22:31:39 momjian 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
61 * XXX Used so we can get rid of use of Const nodes in the executor.
62 * Currently only used by ExecHashGetBucket and set only by ExecMakeVarConst
63 * and by ExecEvalArrayRef.
68 /* static functions decls */
69 static Datum ExecEvalAggref(Aggref *aggref, ExprContext *econtext, bool *isNull);
70 static Datum ExecEvalArrayRef(ArrayRef *arrayRef, ExprContext *econtext,
71 bool *isNull, bool *isDone);
72 static Datum ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull);
73 static Datum ExecEvalFunc(Expr *funcClause, ExprContext *econtext,
74 bool *isNull, bool *isDone);
75 static void ExecEvalFuncArgs(FunctionCachePtr fcache, ExprContext *econtext,
76 List *argList, Datum argV[], bool *argIsDone);
77 static Datum ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull);
78 static Datum ExecEvalOper(Expr *opClause, ExprContext *econtext,
80 static Datum ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull);
81 static Datum ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull);
82 static Datum ExecMakeFunctionResult(Node *node, List *arguments,
83 ExprContext *econtext, bool *isNull, bool *isDone);
84 static bool ExecQualClause(Node *clause, ExprContext *econtext);
89 * This function takes an ArrayRef and returns a Const Node if it
90 * is an array reference or returns the changed Array Node if it is
91 * an array assignment.
94 ExecEvalArrayRef(ArrayRef *arrayRef,
95 ExprContext *econtext,
102 ArrayType *array_scanner;
113 array_scanner = (ArrayType *) ExecEvalExpr(arrayRef->refexpr,
120 upperIndexpr = arrayRef->refupperindexpr;
122 foreach(elt, upperIndexpr)
124 upper.indx[i++] = (int32) ExecEvalExpr((Node *) lfirst(elt),
132 lowerIndexpr = arrayRef->reflowerindexpr;
134 if (lowerIndexpr != NIL)
136 foreach(elt, lowerIndexpr)
138 lower.indx[j++] = (int32) ExecEvalExpr((Node *) lfirst(elt),
147 "ExecEvalArrayRef: upper and lower indices mismatch");
151 assgnexpr = arrayRef->refassgnexpr;
152 if (assgnexpr != NULL)
154 dataPtr = (char *) ExecEvalExpr((Node *)
159 execConstByVal = arrayRef->refelembyval;
160 execConstLen = arrayRef->refelemlength;
162 return (Datum) array_set(array_scanner, i, upper.indx, dataPtr,
163 arrayRef->refelembyval,
164 arrayRef->refelemlength,
165 arrayRef->refattrlength, isNull);
166 return (Datum) array_assgn(array_scanner, i, upper.indx,
168 (ArrayType *) dataPtr,
169 arrayRef->refelembyval,
170 arrayRef->refelemlength, isNull);
172 execConstByVal = arrayRef->refelembyval;
173 execConstLen = arrayRef->refelemlength;
175 return (Datum) array_ref(array_scanner, i, upper.indx,
176 arrayRef->refelembyval,
177 arrayRef->refelemlength,
178 arrayRef->refattrlength, isNull);
179 return (Datum) array_clip(array_scanner, i, upper.indx, lower.indx,
180 arrayRef->refelembyval,
181 arrayRef->refelemlength, isNull);
185 /* ----------------------------------------------------------------
188 * Returns a Datum whose value is the value of the precomputed
189 * aggregate found in the given expression context.
190 * ----------------------------------------------------------------
193 ExecEvalAggref(Aggref *aggref, ExprContext *econtext, bool *isNull)
195 *isNull = econtext->ecxt_nulls[aggref->aggno];
196 return econtext->ecxt_values[aggref->aggno];
199 /* ----------------------------------------------------------------
202 * Returns a Datum whose value is the value of a range
203 * variable with respect to given expression context.
206 * As an entry condition, we expect that the datatype the
207 * plan expects to get (as told by our "variable" argument) is in
208 * fact the datatype of the attribute the plan says to fetch (as
209 * seen in the current context, identified by our "econtext"
212 * If we fetch a Type A attribute and Caller treats it as if it
213 * were Type B, there will be undefined results (e.g. crash).
214 * One way these might mismatch now is that we're accessing a
215 * catalog class and the type information in the pg_attribute
216 * class does not match the hardcoded pg_attribute information
217 * (in pg_attribute.h) for the class in question.
219 * We have an Assert to make sure this entry condition is met.
221 * ---------------------------------------------------------------- */
223 ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
226 TupleTableSlot *slot;
229 TupleDesc tuple_type;
235 * get the slot we want
237 switch (variable->varno)
239 case INNER: /* get the tuple from the inner node */
240 slot = econtext->ecxt_innertuple;
243 case OUTER: /* get the tuple from the outer node */
244 slot = econtext->ecxt_outertuple;
247 default: /* get the tuple from the relation being
249 slot = econtext->ecxt_scantuple;
254 * extract tuple information from the slot
256 heapTuple = slot->val;
257 tuple_type = slot->ttc_tupleDescriptor;
258 buffer = slot->ttc_buffer;
260 attnum = variable->varattno;
262 /* (See prolog for explanation of this Assert) */
263 Assert(attnum <= 0 ||
264 (attnum - 1 <= tuple_type->natts - 1 &&
265 tuple_type->attrs[attnum - 1] != NULL &&
266 variable->vartype == tuple_type->attrs[attnum - 1]->atttypid))
269 * If the attribute number is invalid, then we are supposed to return
270 * the entire tuple, we give back a whole slot so that callers know
271 * what the tuple looks like.
273 if (attnum == InvalidAttrNumber)
275 TupleTableSlot *tempSlot;
279 tempSlot = makeNode(TupleTableSlot);
280 tempSlot->ttc_shouldFree = false;
281 tempSlot->ttc_descIsNew = true;
282 tempSlot->ttc_tupleDescriptor = (TupleDesc) NULL,
283 tempSlot->ttc_buffer = InvalidBuffer;
284 tempSlot->ttc_whichplan = -1;
286 tup = heap_copytuple(heapTuple);
287 td = CreateTupleDescCopy(slot->ttc_tupleDescriptor);
289 ExecSetSlotDescriptor(tempSlot, td);
291 ExecStoreTuple(tup, tempSlot, InvalidBuffer, true);
292 return (Datum) tempSlot;
295 result = heap_getattr(heapTuple, /* tuple containing attribute */
296 attnum, /* attribute number of desired
298 tuple_type, /* tuple descriptor of tuple */
299 isNull); /* return: is attribute null? */
302 * return null if att is null
308 * get length and type information..
309 * ??? what should we do about variable length attributes
310 * - variable length attributes have their length stored
311 * in the first 4 bytes of the memory pointed to by the
312 * returned value.. If we can determine that the type
313 * is a variable length type, we can do the right thing.
319 * If this is a pseudo-att, we get the type and fake the length.
320 * There ought to be a routine to return the real lengths, so
321 * we'll mark this one ... XXX -mao
323 len = heap_sysattrlen(attnum); /* XXX see -mao above */
324 byval = heap_sysattrbyval(attnum); /* XXX see -mao above */
328 len = tuple_type->attrs[attnum - 1]->attlen;
329 byval = tuple_type->attrs[attnum - 1]->attbyval ? true : false;
332 execConstByVal = byval;
338 /* ----------------------------------------------------------------
341 * Returns the value of a parameter. A param node contains
342 * something like ($.name) and the expression context contains
343 * the current parameter bindings (name = "sam") (age = 34)...
344 * so our job is to replace the param node with the datum
345 * containing the appropriate information ("sam").
347 * Q: if we have a parameter ($.foo) without a binding, i.e.
348 * there is no (foo = xxx) in the parameter list info,
349 * is this a fatal error or should this be a "not available"
350 * (in which case we shoud return a Const node with the
351 * isnull flag) ? -cim 10/13/89
353 * Minor modification: Param nodes now have an extra field,
354 * `paramkind' which specifies the type of parameter
355 * (see params.h). So while searching the paramList for
356 * a paramname/value pair, we have also to check for `kind'.
358 * NOTE: The last entry in `paramList' is always an
359 * entry with kind == PARAM_INVALID.
360 * ----------------------------------------------------------------
363 ExecEvalParam(Param *expression, ExprContext *econtext, bool *isNull)
366 char *thisParameterName;
367 int thisParameterKind = expression->paramkind;
368 AttrNumber thisParameterId = expression->paramid;
370 ParamListInfo paramList;
372 if (thisParameterKind == PARAM_EXEC)
374 ParamExecData *prm = &(econtext->ecxt_param_exec_vals[thisParameterId]);
376 if (prm->execPlan != NULL)
377 ExecSetParamPlan(prm->execPlan);
378 Assert(prm->execPlan == NULL);
379 *isNull = prm->isnull;
383 thisParameterName = expression->paramname;
384 paramList = econtext->ecxt_param_list_info;
389 * search the list with the parameter info to find a matching name. An
390 * entry with an InvalidName denotes the last element in the array.
393 if (paramList != NULL)
397 * search for an entry in 'paramList' that matches the
400 while (paramList->kind != PARAM_INVALID && !matchFound)
402 switch (thisParameterKind)
405 if (thisParameterKind == paramList->kind &&
406 strcmp(paramList->name, thisParameterName) == 0)
410 if (thisParameterKind == paramList->kind &&
411 paramList->id == thisParameterId)
416 if (thisParameterKind == paramList->kind &&
417 paramList->id == thisParameterId)
424 if (strcmp(paramList->name, thisParameterName) != 0)
427 "ExecEvalParam: new/old params with same id & diff names");
434 * oops! this is not supposed to happen!
436 elog(ERROR, "ExecEvalParam: invalid paramkind %d",
448 * ooops! we couldn't find this parameter in the parameter list.
451 elog(ERROR, "ExecEvalParam: Unknown value for parameter %s",
458 if (paramList->isnull)
464 if (expression->param_tlist != NIL)
468 List *tlist = expression->param_tlist;
469 TargetEntry *tle = (TargetEntry *) lfirst(tlist);
470 TupleTableSlot *slot = (TupleTableSlot *) paramList->value;
473 value = ProjectAttribute(slot->ttc_tupleDescriptor,
477 return paramList->value;
481 /* ----------------------------------------------------------------
482 * ExecEvalOper / ExecEvalFunc support routines
483 * ----------------------------------------------------------------
490 * These are functions which return the value of the
491 * named attribute out of the tuple from the arg slot. User defined
492 * C functions which take a tuple as an argument are expected
493 * to use this. Ex: overpaid(EMP) might call GetAttributeByNum().
495 /* static but gets called from external functions */
497 GetAttributeByNum(TupleTableSlot *slot,
503 if (!AttributeNumberIsValid(attrno))
504 elog(ERROR, "GetAttributeByNum: Invalid attribute number");
506 if (!AttrNumberIsForUserDefinedAttr(attrno))
507 elog(ERROR, "GetAttributeByNum: cannot access system attributes here");
509 if (isNull == (bool *) NULL)
510 elog(ERROR, "GetAttributeByNum: a NULL isNull flag was passed");
515 return (char *) NULL;
518 retval = heap_getattr(slot->val,
520 slot->ttc_tupleDescriptor,
523 return (char *) NULL;
524 return (char *) retval;
527 /* XXX name for catalogs */
530 att_by_num(TupleTableSlot *slot,
534 return GetAttributeByNum(slot, attrno, isNull);
540 GetAttributeByName(TupleTableSlot *slot, char *attname, bool *isNull)
549 elog(ERROR, "GetAttributeByName: Invalid attribute name");
551 if (isNull == (bool *) NULL)
552 elog(ERROR, "GetAttributeByName: a NULL isNull flag was passed");
557 return (char *) NULL;
560 tupdesc = slot->ttc_tupleDescriptor;
561 natts = slot->val->t_data->t_natts;
563 attrno = InvalidAttrNumber;
564 for (i = 0; i < tupdesc->natts; i++)
566 if (namestrcmp(&(tupdesc->attrs[i]->attname), attname) == 0)
568 attrno = tupdesc->attrs[i]->attnum;
573 if (attrno == InvalidAttrNumber)
574 elog(ERROR, "GetAttributeByName: attribute %s not found", attname);
576 retval = heap_getattr(slot->val,
581 return (char *) NULL;
582 return (char *) retval;
585 /* XXX name for catalogs */
588 att_by_name(TupleTableSlot *slot, char *attname, bool *isNull)
590 return GetAttributeByName(slot, attname, isNull);
596 ExecEvalFuncArgs(FunctionCachePtr fcache,
597 ExprContext *econtext,
607 nullVect = fcache->nullVect;
610 foreach(arg, argList)
613 * evaluate the expression, in general functions cannot take
614 * sets as arguments but we make an exception in the case of
615 * nested dot expressions. We have to watch out for this case
619 ExecEvalExpr((Node *) lfirst(arg),
628 fcache->setArg = (char *) argV[0];
629 fcache->hasSetArg = true;
640 * ExecMakeFunctionResult
643 ExecMakeFunctionResult(Node *node,
645 ExprContext *econtext,
649 Datum argV[MAXFMGRARGS];
650 FunctionCachePtr fcache;
651 Func *funcNode = NULL;
652 Oper *operNode = NULL;
653 bool funcisset = false;
656 * This is kind of ugly, Func nodes now have targetlists so that we
657 * know when and what to project out from postquel function results.
658 * This means we have to pass the func node all the way down instead
659 * of using only the fcache struct as before. ExecMakeFunctionResult
660 * becomes a little bit more of a dual personality as a result.
664 funcNode = (Func *) node;
665 fcache = funcNode->func_fcache;
669 operNode = (Oper *) node;
670 fcache = operNode->op_fcache;
674 * arguments is a list of expressions to evaluate
675 * before passing to the function manager.
676 * We collect the results of evaluating the expressions
677 * into a datum array (argV) and pass this array to arrayFmgr()
679 if (fcache->nargs != 0)
683 if (fcache->nargs > MAXFMGRARGS)
684 elog(ERROR, "ExecMakeFunctionResult: too many arguments");
687 * If the setArg in the fcache is set we have an argument
688 * returning a set of tuples (i.e. a nested dot expression). We
689 * don't want to evaluate the arguments again until the function
690 * is done. hasSetArg will always be false until we eval the args
691 * for the first time. We should set this in the parser.
693 if ((fcache->hasSetArg) && fcache->setArg != NULL)
695 argV[0] = (Datum) fcache->setArg;
699 ExecEvalFuncArgs(fcache, econtext, arguments, argV, &argDone);
701 if ((fcache->hasSetArg) && (argDone))
710 * If this function is really a set, we have to diddle with things. If
711 * the function has already been called at least once, then the setArg
712 * field of the fcache holds the OID of this set in pg_proc. (This is
713 * not quite legit, since the setArg field is really for functions
714 * which take sets of tuples as input - set functions take no inputs
715 * at all. But it's a nice place to stash this value, for now.)
717 * If this is the first call of the set's function, then the call to
718 * ExecEvalFuncArgs above just returned the OID of the pg_proc tuple
719 * which defines this set. So replace the existing funcid in the
720 * funcnode with the set's OID. Also, we want a new fcache which
721 * points to the right function, so get that, now that we have the
722 * right OID. Also zero out the argV, since the real set doesn't take
725 if (((Func *) node)->funcid == F_SETEVAL)
732 ((Func *) node)->funcid = (Oid) PointerGetDatum(fcache->setArg);
737 ((Func *) node)->funcid = (Oid) argV[0];
738 setFcache(node, argV[0], NIL, econtext);
739 fcache = ((Func *) node)->func_fcache;
740 fcache->setArg = (char *) argV[0];
746 * now return the value gotten by calling the function manager,
747 * passing the function the evaluated parameter values.
749 if (fcache->language == SQLlanguageId)
754 result = postquel_function(funcNode, (char **) argV, isNull, isDone);
757 * finagle the situation where we are iterating through all
758 * results in a nested dot function (whose argument function
759 * returns a set of tuples) and the current function finally
760 * finishes. We need to get the next argument in the set and run
761 * the function all over again. This is getting unclean.
763 if ((*isDone) && (fcache->hasSetArg))
767 ExecEvalFuncArgs(fcache, econtext, arguments, argV, &argDone);
771 fcache->setArg = (char *) NULL;
773 result = (Datum) NULL;
776 result = postquel_function(funcNode,
785 * reset the funcid so that next call to this routine will
786 * still recognize this func as a set. Note that for now we
787 * assume that the set function in pg_proc must be a Postquel
788 * function - the funcid is not reset below for C functions.
790 ((Func *) node)->funcid = F_SETEVAL;
793 * If we're done with the results of this function, get rid of
797 ((Func *) node)->func_fcache = NULL;
807 for (i = 0; i < fcache->nargs; i++)
808 if (fcache->nullVect[i] == true)
811 return (Datum) fmgr_c(&fcache->func, (FmgrValues *) argV, isNull);
816 /* ----------------------------------------------------------------
820 * Evaluate the functional result of a list of arguments by calling the
821 * function manager. Note that in the case of operator expressions, the
822 * optimizer had better have already replaced the operator OID with the
823 * appropriate function OID or we're hosed.
826 * Presumably the function manager will not take null arguments, so we
827 * check for null arguments before sending the arguments to (fmgr).
829 * Returns the value of the functional expression.
830 * ----------------------------------------------------------------
833 /* ----------------------------------------------------------------
835 * ----------------------------------------------------------------
838 ExecEvalOper(Expr *opClause, ExprContext *econtext, bool *isNull)
842 FunctionCachePtr fcache;
846 * an opclause is a list (op args). (I think)
848 * we extract the oid of the function associated with
849 * the op and then pass the work onto ExecMakeFunctionResult
850 * which evaluates the arguments and returns the result of
851 * calling the function on the evaluated arguments.
853 op = (Oper *) opClause->oper;
854 argList = opClause->args;
857 * get the fcache from the Oper node. If it is NULL, then initialize
860 fcache = op->op_fcache;
863 setFcache((Node *) op, op->opid, argList, econtext);
864 fcache = op->op_fcache;
868 * call ExecMakeFunctionResult() with a dummy isDone that we ignore.
869 * We don't have operator whose arguments are sets.
871 return ExecMakeFunctionResult((Node *) op, argList, econtext, isNull, &isDone);
874 /* ----------------------------------------------------------------
876 * ----------------------------------------------------------------
880 ExecEvalFunc(Expr *funcClause,
881 ExprContext *econtext,
887 FunctionCachePtr fcache;
890 * an funcclause is a list (func args). (I think)
892 * we extract the oid of the function associated with
893 * the func node and then pass the work onto ExecMakeFunctionResult
894 * which evaluates the arguments and returns the result of
895 * calling the function on the evaluated arguments.
897 * this is nearly identical to the ExecEvalOper code.
899 func = (Func *) funcClause->oper;
900 argList = funcClause->args;
903 * get the fcache from the Func node. If it is NULL, then initialize
906 fcache = func->func_fcache;
909 setFcache((Node *) func, func->funcid, argList, econtext);
910 fcache = func->func_fcache;
913 return ExecMakeFunctionResult((Node *) func, argList, econtext, isNull, isDone);
916 /* ----------------------------------------------------------------
921 * Evaluate boolean expressions. Evaluation of 'or' is
922 * short-circuited when the first true (or null) value is found.
924 * The query planner reformulates clause expressions in the
925 * qualification to conjunctive normal form. If we ever get
926 * an AND to evaluate, we can be sure that it's not a top-level
927 * clause in the qualification, but appears lower (as a function
928 * argument, for example), or in the target list. Not that you
929 * need to know this, mind you...
930 * ----------------------------------------------------------------
933 ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull)
939 clause = lfirst(notclause->args);
942 * We don't iterate over sets in the quals, so pass in an isDone
943 * flag, but ignore it.
945 expr_value = ExecEvalExpr(clause, econtext, isNull, &isDone);
948 * if the expression evaluates to null, then we just
949 * cascade the null back to whoever called us.
955 * evaluation of 'not' is simple.. expr is false, then
956 * return 'true' and vice versa.
958 if (DatumGetInt32(expr_value) == 0)
961 return (Datum) false;
964 /* ----------------------------------------------------------------
966 * ----------------------------------------------------------------
969 ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
975 Datum const_value = 0;
978 clauses = orExpr->args;
981 * we use three valued logic functions here...
982 * we evaluate each of the clauses in turn,
983 * as soon as one is true we return that
984 * value. If none is true and none of the
985 * clauses evaluate to NULL we return
986 * the value of the last clause evaluated (which
987 * should be false) with *isNull set to false else
988 * if none is true and at least one clause evaluated
989 * to NULL we set *isNull flag to true -
991 foreach(clause, clauses)
995 * We don't iterate over sets in the quals, so pass in an isDone
996 * flag, but ignore it.
998 const_value = ExecEvalExpr((Node *) lfirst(clause),
1004 * if the expression evaluates to null, then we
1005 * remember it in the local IsNull flag, if none of the
1006 * clauses are true then we need to set *isNull
1014 * Many functions don't (or can't!) check if an argument is NULL
1015 * or NOT_NULL and may return TRUE (1) with *isNull TRUE
1016 * (an_int4_column <> 1: int4ne returns TRUE for NULLs).
1017 * Not having time to fix the function manager I want to fix OR:
1018 * if we had 'x <> 1 OR x isnull' then when x is NULL
1019 * TRUE was returned by the 'x <> 1' clause ...
1020 * but ExecQualClause says that the qualification should *fail*
1021 * if isnull is TRUE for any value returned by ExecEvalExpr.
1022 * So, force this rule here:
1023 * if isnull is TRUE then the clause failed.
1024 * Note: nullvalue() & nonnullvalue() always sets isnull to FALSE for NULLs.
1031 * if we have a true result, then we return it.
1033 if (DatumGetInt32(const_value) != 0)
1037 /* IsNull is true if at least one clause evaluated to NULL */
1042 /* ----------------------------------------------------------------
1044 * ----------------------------------------------------------------
1047 ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull)
1051 Datum const_value = 0;
1057 clauses = andExpr->args;
1060 * we evaluate each of the clauses in turn,
1061 * as soon as one is false we return that
1062 * value. If none are false or NULL then we return
1063 * the value of the last clause evaluated, which
1066 foreach(clause, clauses)
1070 * We don't iterate over sets in the quals, so pass in an isDone
1071 * flag, but ignore it.
1073 const_value = ExecEvalExpr((Node *) lfirst(clause),
1079 * if the expression evaluates to null, then we
1080 * remember it in IsNull, if none of the clauses after
1081 * this evaluates to false we will have to set *isNull
1088 * if we have a false result, then we return it, since the
1089 * conjunction must be false.
1091 if (DatumGetInt32(const_value) == 0)
1099 /* ----------------------------------------------------------------
1102 * Evaluate a CASE clause. Will have boolean expressions
1103 * inside the WHEN clauses, and will have constants
1105 * - thomas 1998-11-09
1106 * ----------------------------------------------------------------
1109 ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull)
1114 Datum const_value = 0;
1117 clauses = caseExpr->args;
1120 * we evaluate each of the WHEN clauses in turn,
1121 * as soon as one is true we return the corresponding
1122 * result. If none are true then we return the value
1123 * of the default clause, or NULL.
1125 foreach(clause, clauses)
1129 * We don't iterate over sets in the quals, so pass in an isDone
1130 * flag, but ignore it.
1133 wclause = lfirst(clause);
1134 const_value = ExecEvalExpr((Node *) wclause->expr,
1140 * if we have a true test, then we return the result,
1141 * since the case statement is satisfied.
1143 if (DatumGetInt32(const_value) != 0)
1145 const_value = ExecEvalExpr((Node *) wclause->result,
1149 return (Datum) const_value;
1154 if (caseExpr->defresult)
1156 const_value = ExecEvalExpr((Node *) caseExpr->defresult,
1169 /* ----------------------------------------------------------------
1172 * Recursively evaluate a targetlist or qualification expression.
1174 * This routine is an inner loop routine and should be as fast
1177 * Node comparison functions were replaced by macros for speed and to plug
1178 * memory leaks incurred by using the planner's Lispy stuff for
1179 * comparisons. Order of evaluation of node comparisons IS IMPORTANT;
1180 * the macros do no checks. Order of evaluation:
1182 * o an isnull check, largely to avoid coredumps since greg doubts this
1183 * routine is called with a null ptr anyway in proper operation, but is
1184 * not completely sure...
1185 * o ExactNodeType checks.
1186 * o clause checks or other checks where we look at the lfirst of something.
1187 * ----------------------------------------------------------------
1190 ExecEvalExpr(Node *expression,
1191 ExprContext *econtext,
1200 * Some callers don't care about is done and only want 1 result. They
1201 * indicate this by passing NULL
1207 * here we dispatch the work to the appropriate type
1208 * of function given the type of our expression.
1210 if (expression == NULL)
1213 return (Datum) true;
1216 switch (nodeTag(expression))
1219 retDatum = (Datum) ExecEvalVar((Var *) expression, econtext, isNull);
1223 Const *con = (Const *) expression;
1225 if (con->constisnull)
1227 retDatum = con->constvalue;
1231 retDatum = (Datum) ExecEvalParam((Param *) expression, econtext, isNull);
1234 retDatum = (Datum) ExecEvalIter((Iter *) expression,
1240 retDatum = (Datum) ExecEvalAggref((Aggref *) expression,
1245 retDatum = (Datum) ExecEvalArrayRef((ArrayRef *) expression,
1252 Expr *expr = (Expr *) expression;
1254 switch (expr->opType)
1257 retDatum = (Datum) ExecEvalOper(expr, econtext, isNull);
1260 retDatum = (Datum) ExecEvalFunc(expr, econtext, isNull, isDone);
1263 retDatum = (Datum) ExecEvalOr(expr, econtext, isNull);
1266 retDatum = (Datum) ExecEvalAnd(expr, econtext, isNull);
1269 retDatum = (Datum) ExecEvalNot(expr, econtext, isNull);
1272 retDatum = (Datum) ExecSubPlan((SubPlan *) expr->oper, expr->args, econtext);
1275 elog(ERROR, "ExecEvalExpr: unknown expression type %d", expr->opType);
1281 retDatum = (Datum) ExecEvalCase((CaseExpr *) expression, econtext, isNull);
1285 elog(ERROR, "ExecEvalExpr: unknown expression type %d", nodeTag(expression));
1290 } /* ExecEvalExpr() */
1293 /* ----------------------------------------------------------------
1294 * ExecQual / ExecTargetList
1295 * ----------------------------------------------------------------
1298 /* ----------------------------------------------------------------
1301 * this is a workhorse for ExecQual. ExecQual has to deal
1302 * with a list of qualifications, so it passes each qualification
1303 * in the list to this function one at a time. ExecQualClause
1304 * returns true when the qualification *fails* and false if
1305 * the qualification succeeded (meaning we have to test the
1306 * rest of the qualification)
1307 * ----------------------------------------------------------------
1310 ExecQualClause(Node *clause, ExprContext *econtext)
1316 /* when there is a null clause, consider the qualification to be true */
1321 * pass isDone, but ignore it. We don't iterate over multiple returns
1322 * in the qualifications.
1324 expr_value = (Datum)
1325 ExecEvalExpr(clause, econtext, &isNull, &isDone);
1328 * this is interesting behaviour here. When a clause evaluates
1329 * to null, then we consider this as passing the qualification.
1330 * it seems kind of like, if the qual is NULL, then there's no
1337 * remember, we return true when the qualification fails..
1339 if (DatumGetInt32(expr_value) == 0)
1345 /* ----------------------------------------------------------------
1348 * Evaluates a conjunctive boolean expression and returns t
1349 * iff none of the subexpressions are false (or null).
1350 * ----------------------------------------------------------------
1353 ExecQual(List *qual, ExprContext *econtext)
1361 EV_printf("ExecQual: qual is ");
1362 EV_nodeDisplay(qual);
1368 * return true immediately if no qual
1374 * a "qual" is a list of clauses. To evaluate the
1375 * qual, we evaluate each of the clauses in the list.
1377 * ExecQualClause returns true when we know the qualification
1378 * *failed* so we just pass each clause in qual to it until
1379 * we know the qual failed or there are no more clauses.
1383 foreach(clause, qual)
1385 result = ExecQualClause((Node *) lfirst(clause), econtext);
1391 * if result is true, then it means a clause failed so we
1392 * return false. if result is false then it means no clause
1393 * failed so we return true.
1402 ExecTargetListLength(List *targetlist)
1406 TargetEntry *curTle;
1409 foreach(tl, targetlist)
1411 curTle = lfirst(tl);
1413 if (curTle->resdom != NULL)
1416 len += curTle->fjoin->fj_nNodes;
1421 /* ----------------------------------------------------------------
1424 * Evaluates a targetlist with respect to the current
1425 * expression context and return a tuple.
1426 * ----------------------------------------------------------------
1429 ExecTargetList(List *targetlist,
1431 TupleDesc targettype,
1433 ExprContext *econtext,
1436 char nulls_array[64];
1437 bool fjNullArray[64];
1452 EV_printf("ExecTargetList: tl is ");
1453 EV_nodeDisplay(targetlist);
1457 * Return a dummy tuple if the targetlist is empty.
1458 * the dummy tuple is necessary to differentiate
1459 * between passing and failing the qualification.
1461 if (targetlist == NIL)
1464 * I now think that the only time this makes
1465 * any sense is when we run a delete query. Then
1466 * we need to return something other than nil
1467 * so we know to delete the tuple associated
1468 * with the saved tupleid.. see what ExecutePlan
1469 * does with the returned tuple.. -cim 9/21/89
1471 * It could also happen in queries like:
1472 * retrieve (foo.all) where bar.a = 3
1474 * is this a new phenomenon? it might cause bogus behavior
1475 * if we try to free this tuple later!! I put a hook in
1476 * ExecProject to watch out for this case -mer 24 Aug 1992
1478 * We must return dummy tuple!!! Try
1479 * select t1.x from t1, t2 where t1.y = 1 and t2.y = 1
1480 * - t2 scan target list will be empty and so no one tuple
1481 * will be returned! But Mer was right - dummy tuple
1482 * must be palloced... - vadim 03/01/1999
1485 return (HeapTuple) palloc(1);
1489 * allocate an array of char's to hold the "null" information
1490 * only if we have a really large targetlist. otherwise we use
1495 null_head = (char *) palloc(nodomains + 1);
1496 fjIsNull = (bool *) palloc(nodomains + 1);
1500 null_head = &nulls_array[0];
1501 fjIsNull = &fjNullArray[0];
1505 * evaluate all the expressions in the target list
1507 EV_printf("ExecTargetList: setting target list values\n");
1510 foreach(tl, targetlist)
1513 * remember, a target list is a list of lists:
1515 * ((<resdom | fjoin> expr) (<resdom | fjoin> expr) ...)
1517 * tl is a pointer to successive cdr's of the targetlist
1518 * tle is a pointer to the target list entry in tl
1522 if (tle->resdom != NULL)
1525 resdom = tle->resdom;
1526 resind = resdom->resno - 1;
1527 constvalue = (Datum) ExecEvalExpr(expr,
1532 if ((IsA(expr, Iter)) && (*isDone))
1533 return (HeapTuple) NULL;
1535 values[resind] = constvalue;
1538 null_head[resind] = ' ';
1540 null_head[resind] = 'n';
1546 List *fjTlist = (List *) tle->expr;
1547 Fjoin *fjNode = tle->fjoin;
1548 int nNodes = fjNode->fj_nNodes;
1549 DatumPtr results = fjNode->fj_results;
1551 ExecEvalFjoin(tle, econtext, fjIsNull, isDone);
1553 return (HeapTuple) NULL;
1556 * get the result from the inner node
1558 fjRes = (Resdom *) fjNode->fj_innerNode;
1559 resind = fjRes->resno - 1;
1561 null_head[resind] = 'n';
1564 null_head[resind] = ' ';
1565 values[resind] = results[0];
1569 * Get results from all of the outer nodes
1573 curNode++, fjTlist = lnext(fjTlist))
1575 #ifdef NOT_USED /* what is this?? */
1576 Node *outernode = lfirst(fjTlist);
1578 fjRes = (Resdom *) outernode->iterexpr;
1580 resind = fjRes->resno - 1;
1581 if (fjIsNull[curNode])
1582 null_head[resind] = 'n';
1585 null_head[resind] = ' ';
1586 values[resind] = results[curNode];
1593 * form the new result tuple (in the "normal" context)
1595 newTuple = (HeapTuple) heap_formtuple(targettype, values, null_head);
1598 * free the nulls array if we allocated one..
1609 /* ----------------------------------------------------------------
1612 * projects a tuple based in projection info and stores
1613 * it in the specified tuple table slot.
1615 * Note: someday soon the executor can be extended to eliminate
1616 * redundant projections by storing pointers to datums
1617 * in the tuple table and then passing these around when
1618 * possible. this should make things much quicker.
1620 * ----------------------------------------------------------------
1623 ExecProject(ProjectionInfo *projInfo, bool *isDone)
1625 TupleTableSlot *slot;
1630 ExprContext *econtext;
1636 if (projInfo == NULL)
1637 return (TupleTableSlot *) NULL;
1640 * get the projection info we want
1642 slot = projInfo->pi_slot;
1643 targetlist = projInfo->pi_targetlist;
1644 len = projInfo->pi_len;
1645 tupType = slot->ttc_tupleDescriptor;
1647 tupValue = projInfo->pi_tupValue;
1648 econtext = projInfo->pi_exprContext;
1651 * form a new (result) tuple
1653 newTuple = ExecTargetList(targetlist,
1661 * store the tuple in the projection slot and return the slot.
1663 * If there's no projection target list we don't want to pfree
1664 * the bogus tuple that ExecTargetList passes back to us.
1667 return (TupleTableSlot *)
1668 ExecStoreTuple(newTuple,/* tuple to store */
1669 slot, /* slot to store in */
1670 InvalidBuffer, /* tuple has no buffer */