7
7
*
8
8
*
9
9
* 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 $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -956,8 +956,8 @@ ExecEvalFunc(Expr *funcClause,
956
956
static Datum
957
957
ExecEvalNot (Expr * notclause ,ExprContext * econtext ,bool * isNull )
958
958
{
959
- Datum expr_value ;
960
959
Node * clause ;
960
+ Datum expr_value ;
961
961
bool isDone ;
962
962
963
963
clause = lfirst (notclause -> args );
@@ -995,67 +995,47 @@ ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
995
995
List * clauses ;
996
996
List * clause ;
997
997
bool isDone ;
998
- bool IsNull ;
999
- Datum const_value = 0 ;
998
+ bool AnyNull ;
999
+ Datum clause_value ;
1000
1000
1001
- IsNull = false;
1002
1001
clauses = orExpr -> args ;
1002
+ AnyNull = false;
1003
1003
1004
1004
/*
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.
1011
1016
*/
1012
1017
foreach (clause ,clauses )
1013
1018
{
1014
-
1015
1019
/*
1016
1020
* We don't iterate over sets in the quals, so pass in an isDone
1017
1021
* flag, but ignore it.
1018
1022
*/
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 );
1024
1027
/*
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.
1028
1029
*/
1029
1030
if (* 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 ;
1054
1034
}
1055
1035
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 ;
1059
1039
}
1060
1040
1061
1041
/* ----------------------------------------------------------------
@@ -1067,49 +1047,43 @@ ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull)
1067
1047
{
1068
1048
List * clauses ;
1069
1049
List * clause ;
1070
- Datum const_value = 0 ;
1071
1050
bool isDone ;
1072
- bool IsNull ;
1073
-
1074
- IsNull = false;
1051
+ bool AnyNull ;
1052
+ Datum clause_value ;
1075
1053
1076
1054
clauses = andExpr -> args ;
1055
+ AnyNull = false;
1077
1056
1078
1057
/*
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.
1082
1064
*/
1083
1065
foreach (clause ,clauses )
1084
1066
{
1085
-
1086
1067
/*
1087
1068
* We don't iterate over sets in the quals, so pass in an isDone
1088
1069
* flag, but ignore it.
1089
1070
*/
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 );
1095
1075
/*
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.
1099
1077
*/
1100
1078
if (* 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 ;
1109
1082
}
1110
1083
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 );
1113
1087
}
1114
1088
1115
1089
/* ----------------------------------------------------------------
@@ -1126,7 +1100,7 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull)
1126
1100
{
1127
1101
List * clauses ;
1128
1102
List * clause ;
1129
- Datum const_value = 0 ;
1103
+ Datum clause_value ;
1130
1104
bool isDone ;
1131
1105
1132
1106
clauses = caseExpr -> args ;
@@ -1144,37 +1118,35 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull)
1144
1118
* We don't iterate over sets in the quals, so pass in an isDone
1145
1119
* flag, but ignore it.
1146
1120
*/
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 );
1151
1125
1152
1126
/*
1153
1127
* if we have a true test, then we return the result, since the
1154
1128
* case statement is satisfied. A NULL result from the test is
1155
1129
* not considered true.
1156
1130
*/
1157
- if (DatumGetInt32 (const_value )!= 0 && !* isNull )
1131
+ if (DatumGetInt32 (clause_value )!= 0 && !* isNull )
1158
1132
{
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 );
1164
1137
}
1165
1138
}
1166
1139
1167
1140
if (caseExpr -> defresult )
1168
1141
{
1169
- const_value = ExecEvalExpr (( Node * ) caseExpr -> defresult ,
1170
- econtext ,
1171
- isNull ,
1172
- & isDone );
1142
+ return ExecEvalExpr (caseExpr -> defresult ,
1143
+ econtext ,
1144
+ isNull ,
1145
+ & isDone );
1173
1146
}
1174
- else
1175
- * isNull = true;
1176
1147
1177
- return const_value ;
1148
+ * isNull = true;
1149
+ return (Datum )0 ;
1178
1150
}
1179
1151
1180
1152
/* ----------------------------------------------------------------
@@ -1357,7 +1329,6 @@ bool
1357
1329
ExecQual (List * qual ,ExprContext * econtext )
1358
1330
{
1359
1331
List * clause ;
1360
- bool result ;
1361
1332
1362
1333
/*
1363
1334
* debugging stuff
@@ -1378,27 +1349,17 @@ ExecQual(List *qual, ExprContext *econtext)
1378
1349
* a "qual" is a list of clauses. To evaluate the qual, we evaluate
1379
1350
* each of the clauses in the list.
1380
1351
*
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
1383
1354
* failed or there are no more clauses.
1384
1355
*/
1385
- result = false;
1386
1356
1387
1357
foreach (clause ,qual )
1388
1358
{
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 */
1392
1361
}
1393
1362
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
-
1402
1363
return true;
1403
1364
}
1404
1365