77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.60 1999/09/24 00:24:23 tgl Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.61 1999/09/26 02:28:15 tgl Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -956,8 +956,8 @@ ExecEvalFunc(Expr *funcClause,
956956static Datum
957957ExecEvalNot (Expr * notclause ,ExprContext * econtext ,bool * isNull )
958958{
959- Datum expr_value ;
960959Node * clause ;
960+ Datum expr_value ;
961961bool isDone ;
962962
963963clause = lfirst (notclause -> args );
@@ -995,67 +995,47 @@ ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
995995List * clauses ;
996996List * clause ;
997997bool isDone ;
998- bool IsNull ;
999- Datum const_value = 0 ;
998+ bool AnyNull ;
999+ Datum clause_value ;
10001000
1001- IsNull = false;
10021001clauses = orExpr -> args ;
1002+ AnyNull = false;
10031003
10041004/*
1005- * we use three valued logic functions here... we evaluate each of the
1006- * clauses in turn, as soon as one is true we return that value. If
1007- * none is true and none of the clauses evaluate to NULL we return
1008- * the value of the last clause evaluated (which should be false) with
1009- * *isNull set to false else if none is true and at least one clause
1010- * evaluated to NULL we set *isNull flag to true -
1005+ * If any of the clauses is TRUE, the OR result is TRUE regardless
1006+ * of the states of the rest of the clauses, so we can stop evaluating
1007+ * and return TRUE immediately. If none are TRUE and one or more is
1008+ * NULL, we return NULL; otherwise we return FALSE. This makes sense
1009+ * when you interpret NULL as "don't know": if we have a TRUE then the
1010+ * OR is TRUE even if we aren't sure about some of the other inputs.
1011+ * If all the known inputs are FALSE, but we have one or more "don't
1012+ * knows", then we have to report that we "don't know" what the OR's
1013+ * result should be --- perhaps one of the "don't knows" would have been
1014+ * TRUE if we'd known its value. Only when all the inputs are known
1015+ * to be FALSE can we state confidently that the OR's result is FALSE.
10111016 */
10121017foreach (clause ,clauses )
10131018{
1014-
10151019/*
10161020 * We don't iterate over sets in the quals, so pass in an isDone
10171021 * flag, but ignore it.
10181022 */
1019- const_value = ExecEvalExpr ((Node * )lfirst (clause ),
1020- econtext ,
1021- isNull ,
1022- & isDone );
1023-
1023+ clause_value = ExecEvalExpr ((Node * )lfirst (clause ),
1024+ econtext ,
1025+ isNull ,
1026+ & isDone );
10241027/*
1025- * if the expression evaluates to null, then we remember it in the
1026- * local IsNull flag, if none of the clauses are true then we need
1027- * to set *isNull to true again.
1028+ * if we have a non-null true result, then return it.
10281029 */
10291030if (* isNull )
1030- {
1031- IsNull = * isNull ;
1032-
1033- /*
1034- * Many functions don't (or can't!) check if an argument is
1035- * NULL or NOT_NULL and may return TRUE (1) with *isNull TRUE
1036- * (an_int4_column <> 1: int4ne returns TRUE for NULLs). Not
1037- * having time to fix the function manager I want to fix OR:
1038- * if we had 'x <> 1 OR x isnull' then when x is NULL TRUE was
1039- * returned by the 'x <> 1' clause ... but ExecQualClause says
1040- * that the qualification should *fail* if isnull is TRUE for
1041- * any value returned by ExecEvalExpr. So, force this rule
1042- * here: if isnull is TRUE then the clause failed. Note:
1043- * nullvalue() & nonnullvalue() always sets isnull to FALSE
1044- * for NULLs. - vadim 09/22/97
1045- */
1046- const_value = 0 ;
1047- }
1048-
1049- /*
1050- * if we have a true result, then we return it.
1051- */
1052- if (DatumGetInt32 (const_value )!= 0 )
1053- return const_value ;
1031+ AnyNull = true;/* remember we got a null */
1032+ else if (DatumGetInt32 (clause_value )!= 0 )
1033+ return clause_value ;
10541034}
10551035
1056- /*IsNull is true if at least one clause evaluated to NULL */
1057- * isNull = IsNull ;
1058- return const_value ;
1036+ /*AnyNull is true if at least one clause evaluated to NULL */
1037+ * isNull = AnyNull ;
1038+ return ( Datum ) false ;
10591039}
10601040
10611041/* ----------------------------------------------------------------
@@ -1067,49 +1047,43 @@ ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull)
10671047{
10681048List * clauses ;
10691049List * clause ;
1070- Datum const_value = 0 ;
10711050bool isDone ;
1072- bool IsNull ;
1073-
1074- IsNull = false;
1051+ bool AnyNull ;
1052+ Datum clause_value ;
10751053
10761054clauses = andExpr -> args ;
1055+ AnyNull = false;
10771056
10781057/*
1079- * we evaluate each of the clauses in turn, as soon as one is false we
1080- * return that value. If none are false or NULL then we return the
1081- * value of the last clause evaluated, which should be true.
1058+ * If any of the clauses is FALSE, the AND result is FALSE regardless
1059+ * of the states of the rest of the clauses, so we can stop evaluating
1060+ * and return FALSE immediately. If none are FALSE and one or more is
1061+ * NULL, we return NULL; otherwise we return TRUE. This makes sense
1062+ * when you interpret NULL as "don't know", using the same sort of
1063+ * reasoning as for OR, above.
10821064 */
10831065foreach (clause ,clauses )
10841066{
1085-
10861067/*
10871068 * We don't iterate over sets in the quals, so pass in an isDone
10881069 * flag, but ignore it.
10891070 */
1090- const_value = ExecEvalExpr ((Node * )lfirst (clause ),
1091- econtext ,
1092- isNull ,
1093- & isDone );
1094-
1071+ clause_value = ExecEvalExpr ((Node * )lfirst (clause ),
1072+ econtext ,
1073+ isNull ,
1074+ & isDone );
10951075/*
1096- * if the expression evaluates to null, then we remember it in
1097- * IsNull, if none of the clauses after this evaluates to false we
1098- * will have to set *isNull to true again.
1076+ * if we have a non-null false result, then return it.
10991077 */
11001078if (* isNull )
1101- IsNull = * isNull ;
1102-
1103- /*
1104- * if we have a false result, then we return it, since the
1105- * conjunction must be false.
1106- */
1107- if (DatumGetInt32 (const_value )== 0 )
1108- return const_value ;
1079+ AnyNull = true;/* remember we got a null */
1080+ else if (DatumGetInt32 (clause_value )== 0 )
1081+ return clause_value ;
11091082}
11101083
1111- * isNull = IsNull ;
1112- return const_value ;
1084+ /* AnyNull is true if at least one clause evaluated to NULL */
1085+ * isNull = AnyNull ;
1086+ return (Datum ) (!AnyNull );
11131087}
11141088
11151089/* ----------------------------------------------------------------
@@ -1126,7 +1100,7 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull)
11261100{
11271101List * clauses ;
11281102List * clause ;
1129- Datum const_value = 0 ;
1103+ Datum clause_value ;
11301104bool isDone ;
11311105
11321106clauses = caseExpr -> args ;
@@ -1144,37 +1118,35 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull)
11441118 * We don't iterate over sets in the quals, so pass in an isDone
11451119 * flag, but ignore it.
11461120 */
1147- const_value = ExecEvalExpr (( Node * ) wclause -> expr ,
1148- econtext ,
1149- isNull ,
1150- & isDone );
1121+ clause_value = ExecEvalExpr (wclause -> expr ,
1122+ econtext ,
1123+ isNull ,
1124+ & isDone );
11511125
11521126/*
11531127 * if we have a true test, then we return the result, since the
11541128 * case statement is satisfied. A NULL result from the test is
11551129 * not considered true.
11561130 */
1157- if (DatumGetInt32 (const_value )!= 0 && !* isNull )
1131+ if (DatumGetInt32 (clause_value )!= 0 && !* isNull )
11581132{
1159- const_value = ExecEvalExpr ((Node * )wclause -> result ,
1160- econtext ,
1161- isNull ,
1162- & isDone );
1163- return (Datum )const_value ;
1133+ return ExecEvalExpr (wclause -> result ,
1134+ econtext ,
1135+ isNull ,
1136+ & isDone );
11641137}
11651138}
11661139
11671140if (caseExpr -> defresult )
11681141{
1169- const_value = ExecEvalExpr (( Node * ) caseExpr -> defresult ,
1170- econtext ,
1171- isNull ,
1172- & isDone );
1142+ return ExecEvalExpr (caseExpr -> defresult ,
1143+ econtext ,
1144+ isNull ,
1145+ & isDone );
11731146}
1174- else
1175- * isNull = true;
11761147
1177- return const_value ;
1148+ * isNull = true;
1149+ return (Datum )0 ;
11781150}
11791151
11801152/* ----------------------------------------------------------------
@@ -1357,7 +1329,6 @@ bool
13571329ExecQual (List * qual ,ExprContext * econtext )
13581330{
13591331List * clause ;
1360- bool result ;
13611332
13621333/*
13631334 * debugging stuff
@@ -1378,27 +1349,17 @@ ExecQual(List *qual, ExprContext *econtext)
13781349 * a "qual" is a list of clauses. To evaluate the qual, we evaluate
13791350 * each of the clauses in the list.
13801351 *
1381- * ExecQualClause returns true when we know the qualification *failed* so
1382- * we just pass each clause in qual to it until we know the qual
1352+ * ExecQualClause returns true when we know the qualification *failed*
1353+ *so we just pass each clause in qual to it until we know the qual
13831354 * failed or there are no more clauses.
13841355 */
1385- result = false;
13861356
13871357foreach (clause ,qual )
13881358{
1389- result = ExecQualClause ((Node * )lfirst (clause ),econtext );
1390- if (result == true)
1391- break ;
1359+ if (ExecQualClause ((Node * )lfirst (clause ),econtext ))
1360+ return false;/* qual failed, so return false */
13921361}
13931362
1394- /*
1395- * if result is true, then it means a clause failed so we return
1396- * false. if result is false then it means no clause failed so we
1397- * return true.
1398- */
1399- if (result == true)
1400- return false;
1401-
14021363return true;
14031364}
14041365