aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execQual.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>1999-09-18 23:26:37 +0000
committerTom Lane <tgl@sss.pgh.pa.us>1999-09-18 23:26:37 +0000
commite1a8b0f2ce75e55dedae46286dd2253c322c499a (patch)
tree3da7f2342df2c915176bc17f37e696fff464dd0f /src/backend/executor/execQual.c
parentf9f5dfbf10a30cff7255b896277d5e9836f2623b (diff)
downloadpostgresql-e1a8b0f2ce75e55dedae46286dd2253c322c499a.tar.gz
postgresql-e1a8b0f2ce75e55dedae46286dd2253c322c499a.zip
Fix CASE bug identified by Keith Parks: CASE didn't reliably
treat a NULL condition result as FALSE. Clean up some bogus comments here and there, too.
Diffstat (limited to 'src/backend/executor/execQual.c')
-rw-r--r--src/backend/executor/execQual.c47
1 files changed, 16 insertions, 31 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index a3eb943ab96..a44030aa406 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.58 1999/07/19 00:26:15 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.59 1999/09/18 23:26:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -616,8 +616,7 @@ ExecEvalFuncArgs(FunctionCachePtr fcache,
bool *argIsDone)
{
int i;
- bool argIsNull,
- *nullVect;
+ bool *nullVect;
List *arg;
nullVect = fcache->nullVect;
@@ -631,12 +630,10 @@ ExecEvalFuncArgs(FunctionCachePtr fcache,
* as arguments but we make an exception in the case of nested dot
* expressions. We have to watch out for this case here.
*/
- argV[i] = (Datum)
- ExecEvalExpr((Node *) lfirst(arg),
- econtext,
- &argIsNull,
- argIsDone);
-
+ argV[i] = ExecEvalExpr((Node *) lfirst(arg),
+ econtext,
+ & nullVect[i],
+ argIsDone);
if (!(*argIsDone))
{
@@ -644,10 +641,6 @@ ExecEvalFuncArgs(FunctionCachePtr fcache,
fcache->setArg = (char *) argV[0];
fcache->hasSetArg = true;
}
- if (argIsNull)
- nullVect[i] = true;
- else
- nullVect[i] = false;
i++;
}
}
@@ -1108,7 +1101,7 @@ ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull)
* ExecEvalCase
*
* Evaluate a CASE clause. Will have boolean expressions
- * inside the WHEN clauses, and will have constants
+ * inside the WHEN clauses, and will have expressions
* for results.
* - thomas 1998-11-09
* ----------------------------------------------------------------
@@ -1118,7 +1111,6 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull)
{
List *clauses;
List *clause;
- CaseWhen *wclause;
Datum const_value = 0;
bool isDone;
@@ -1127,17 +1119,16 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull)
/*
* we evaluate each of the WHEN clauses in turn, as soon as one is
* true we return the corresponding result. If none are true then we
- * return the value of the default clause, or NULL.
+ * return the value of the default clause, or NULL if there is none.
*/
foreach(clause, clauses)
{
+ CaseWhen *wclause = lfirst(clause);
/*
* We don't iterate over sets in the quals, so pass in an isDone
* flag, but ignore it.
*/
-
- wclause = lfirst(clause);
const_value = ExecEvalExpr((Node *) wclause->expr,
econtext,
isNull,
@@ -1145,16 +1136,16 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull)
/*
* if we have a true test, then we return the result, since the
- * case statement is satisfied.
+ * case statement is satisfied. A NULL result from the test is
+ * not considered true.
*/
- if (DatumGetInt32(const_value) != 0)
+ if (DatumGetInt32(const_value) != 0 && ! *isNull)
{
const_value = ExecEvalExpr((Node *) wclause->result,
econtext,
isNull,
&isDone);
return (Datum) const_value;
-
}
}
@@ -1318,7 +1309,7 @@ ExecQualClause(Node *clause, ExprContext *econtext)
bool isNull;
bool isDone;
- /* when there is a null clause, consider the qualification to be true */
+ /* when there is a null clause, consider the qualification to fail */
if (clause == NULL)
return true;
@@ -1326,20 +1317,14 @@ ExecQualClause(Node *clause, ExprContext *econtext)
* pass isDone, but ignore it. We don't iterate over multiple returns
* in the qualifications.
*/
- expr_value = (Datum)
- ExecEvalExpr(clause, econtext, &isNull, &isDone);
+ expr_value = ExecEvalExpr(clause, econtext, &isNull, &isDone);
/*
- * this is interesting behaviour here. When a clause evaluates to
- * null, then we consider this as passing the qualification. it seems
- * kind of like, if the qual is NULL, then there's no qual..
+ * remember, we return true when the qualification fails;
+ * NULL is considered failure.
*/
if (isNull)
return true;
-
- /*
- * remember, we return true when the qualification fails..
- */
if (DatumGetInt32(expr_value) == 0)
return true;