8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.97 2002/07/06 20:16:35 momjian Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.98 2002/07/18 04:41:44 momjian Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
38
38
#include "executor/execdebug.h"
39
39
#include "executor/functions.h"
40
40
#include "executor/nodeSubplan.h"
41
+ #include "nodes/makefuncs.h"
42
+ #include "parser/parse.h"
43
+ #include "parser/parse_expr.h"
41
44
#include "utils/array.h"
42
45
#include "utils/builtins.h"
43
46
#include "utils/fcache.h"
@@ -62,6 +65,8 @@ static Datum ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull);
62
65
static Datum ExecEvalOr (Expr * orExpr , ExprContext * econtext , bool * isNull );
63
66
static Datum ExecEvalCase (CaseExpr * caseExpr , ExprContext * econtext ,
64
67
bool * isNull , ExprDoneCond * isDone );
68
+ static Datum ExecEvalBetweenExpr (BetweenExpr * btest , ExprContext * econtext ,
69
+ bool * isNull , ExprDoneCond * isDone );
65
70
static Datum ExecEvalNullTest (NullTest * ntest , ExprContext * econtext ,
66
71
bool * isNull , ExprDoneCond * isDone );
67
72
static Datum ExecEvalBooleanTest (BooleanTest * btest , ExprContext * econtext ,
@@ -1188,6 +1193,104 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext,
1188
1193
return (Datum ) 0 ;
1189
1194
}
1190
1195
1196
+ /* ----------------------------------------------------------------
1197
+ * ExecEvalBetweenExpr
1198
+ *
1199
+ * Evaluate a BetweenExpr node. Result is
1200
+ * a boolean. If any of the three expression
1201
+ * parameters are NULL, result is NULL.
1202
+ * ----------------------------------------------------------------
1203
+ */
1204
+ static Datum
1205
+ ExecEvalBetweenExpr (BetweenExpr * btest ,
1206
+ ExprContext * econtext ,
1207
+ bool * isNull ,
1208
+ ExprDoneCond * isDone )
1209
+ {
1210
+ Datum expr_result ;
1211
+ Datum lexpr_result ;
1212
+ Datum rexpr_result ;
1213
+ bool result = FALSE;
1214
+ Node * expr_const ;
1215
+ Node * lexpr_const ;
1216
+ Node * rexpr_const ;
1217
+
1218
+ /* Evaluate subexpressons and Auto-return if we find a NULL */
1219
+ expr_result = ExecEvalExpr (btest -> expr , econtext , isNull , isDone );
1220
+ if (* isNull )
1221
+ return (Datum ) 0 ;
1222
+
1223
+ lexpr_result = ExecEvalExpr (btest -> lexpr , econtext , isNull , isDone );
1224
+ if (* isNull )
1225
+ return (Datum ) 0 ;
1226
+
1227
+ rexpr_result = ExecEvalExpr (btest -> rexpr , econtext , isNull , isDone );
1228
+ if (* isNull )
1229
+ return (Datum ) 0 ;
1230
+
1231
+ /*
1232
+ * Make a Constant out of our newly found Datums
1233
+ * Types were coerced during transformExpr to be common
1234
+ */
1235
+ expr_const = (Node * ) makeConst (btest -> typeId , btest -> typeLen ,
1236
+ expr_result , false,
1237
+ btest -> typeByVal , false, true);
1238
+
1239
+ lexpr_const = (Node * ) makeConst (btest -> typeId , btest -> typeLen ,
1240
+ lexpr_result , false,
1241
+ btest -> typeByVal , false, true);
1242
+
1243
+ rexpr_const = (Node * ) makeConst (btest -> typeId , btest -> typeLen ,
1244
+ rexpr_result , false,
1245
+ btest -> typeByVal , false, true);
1246
+
1247
+ /*
1248
+ * Test the between case which for the straight forward method.
1249
+ * expr >= lexpr and expr <= rexpr
1250
+ *
1251
+ * Of course, can't use makeA_Expr here without requiring another
1252
+ * transform, so we've already prepared a gthan and lthan operator
1253
+ * set in the parsing stage.
1254
+ */
1255
+ btest -> gthan -> args = makeList2 (expr_const , lexpr_const );
1256
+ if (DatumGetBool (ExecEvalExpr ((Node * ) btest -> gthan ,
1257
+ econtext ,
1258
+ isNull , isDone )))
1259
+ {
1260
+ btest -> lthan -> args = makeList2 (expr_const , rexpr_const );
1261
+ result = DatumGetBool (ExecEvalExpr ((Node * ) btest -> lthan ,
1262
+ econtext ,
1263
+ isNull , isDone ));
1264
+ }
1265
+
1266
+ /*
1267
+ * If this is a symmetric BETWEEN, we win a second try with the operators
1268
+ * reversed. (a >= min(b,c) and a <= max(b,c))
1269
+ */
1270
+ if (!result && btest -> symmetric )
1271
+ {
1272
+ btest -> gthan -> args = makeList2 (expr_const , rexpr_const );
1273
+ if (DatumGetBool (ExecEvalExpr ((Node * ) btest -> gthan ,
1274
+ econtext ,
1275
+ isNull , isDone )))
1276
+ {
1277
+ btest -> lthan -> args = makeList2 (expr_const , lexpr_const );
1278
+ result = DatumGetBool (ExecEvalExpr ((Node * ) btest -> lthan ,
1279
+ econtext ,
1280
+ isNull , isDone ));
1281
+ }
1282
+ }
1283
+
1284
+ /* Apply NOT as necessary */
1285
+ if (btest -> not )
1286
+ result = !result ;
1287
+
1288
+ /* We're not returning a null */
1289
+ * isNull = false;
1290
+
1291
+ return (BoolGetDatum (result ));
1292
+ }
1293
+
1191
1294
/* ----------------------------------------------------------------
1192
1295
* ExecEvalNullTest
1193
1296
*
@@ -1524,6 +1627,12 @@ ExecEvalExpr(Node *expression,
1524
1627
isNull ,
1525
1628
isDone );
1526
1629
break ;
1630
+ case T_BetweenExpr :
1631
+ retDatum = ExecEvalBetweenExpr ((BetweenExpr * ) expression ,
1632
+ econtext ,
1633
+ isNull ,
1634
+ isDone );
1635
+ break ;
1527
1636
case T_NullTest :
1528
1637
retDatum = ExecEvalNullTest ((NullTest * ) expression ,
1529
1638
econtext ,
@@ -1536,7 +1645,6 @@ ExecEvalExpr(Node *expression,
1536
1645
isNull ,
1537
1646
isDone );
1538
1647
break ;
1539
-
1540
1648
default :
1541
1649
elog (ERROR , "ExecEvalExpr: unknown expression type %d" ,
1542
1650
nodeTag (expression ));
0 commit comments