aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/expr/BuiltinOperators.java4
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java12
-rw-r--r--src/test/java/com/healthmarketscience/jackcess/impl/expr/ExpressionatorTest.java48
3 files changed, 61 insertions, 3 deletions
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/BuiltinOperators.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/BuiltinOperators.java
index e0f6e25..407ec52 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/BuiltinOperators.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/BuiltinOperators.java
@@ -485,6 +485,10 @@ public class BuiltinOperators
return toValue(pattern.matcher(param1.getAsString()).matches());
}
+ public static Value notLike(Value param1, Pattern pattern) {
+ return not(like(param1, pattern));
+ }
+
public static Value between(Value param1, Value param2, Value param3) {
// null propagate any param. uses short circuit eval of params
if(anyParamIsNull(param1, param2, param3)) {
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java
index 7bd7396..96deb27 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java
@@ -325,6 +325,11 @@ public class Expressionator
return BuiltinOperators.like(param1, (Pattern)param2);
}
},
+ NOT_LIKE("Not Like") {
+ @Override public Value eval(Value param1, Object param2, Object param3) {
+ return BuiltinOperators.notLike(param1, (Pattern)param2);
+ }
+ },
BETWEEN("Between") {
@Override public Value eval(Value param1, Object param2, Object param3) {
return BuiltinOperators.between(param1, (Value)param2, (Value)param3);
@@ -371,7 +376,8 @@ public class Expressionator
new OpType[]{BinaryOp.PLUS, BinaryOp.MINUS},
new OpType[]{BinaryOp.CONCAT},
new OpType[]{CompOp.LT, CompOp.GT, CompOp.NE, CompOp.LTE, CompOp.GTE,
- CompOp.EQ, SpecOp.LIKE, SpecOp.IS_NULL, SpecOp.IS_NOT_NULL},
+ CompOp.EQ, SpecOp.LIKE, SpecOp.NOT_LIKE,
+ SpecOp.IS_NULL, SpecOp.IS_NOT_NULL},
new OpType[]{UnaryOp.NOT},
new OpType[]{LogOp.AND},
new OpType[]{LogOp.OR},
@@ -846,6 +852,7 @@ public class Expressionator
break;
case LIKE:
+ case NOT_LIKE:
Token t = buf.next();
if((t.getType() != TokenType.LITERAL) ||
(t.getValueType() != Value.Type.STRING)) {
@@ -941,6 +948,9 @@ public class Expressionator
} else if(isString(t, "in")) {
buf.next();
return SpecOp.NOT_IN;
+ } else if(isString(t, "like")) {
+ buf.next();
+ return SpecOp.NOT_LIKE;
}
return SpecOp.NOT;
}
diff --git a/src/test/java/com/healthmarketscience/jackcess/impl/expr/ExpressionatorTest.java b/src/test/java/com/healthmarketscience/jackcess/impl/expr/ExpressionatorTest.java
index 227ffdc..ef5cef3 100644
--- a/src/test/java/com/healthmarketscience/jackcess/impl/expr/ExpressionatorTest.java
+++ b/src/test/java/com/healthmarketscience/jackcess/impl/expr/ExpressionatorTest.java
@@ -280,6 +280,7 @@ public class ExpressionatorTest extends TestCase
{
assertEquals(TRUE_NUM, eval("='blah'<'fuzz'"));
assertEquals(FALSE_NUM, eval("=23>56"));
+ assertEquals(FALSE_NUM, eval("=23>=56"));
assertEquals(TRUE_NUM, eval("=13.2<=45.8"));
assertEquals(FALSE_NUM, eval("='blah'='fuzz'"));
assertEquals(TRUE_NUM, eval("='blah'<>'fuzz'"));
@@ -288,7 +289,11 @@ public class ExpressionatorTest extends TestCase
assertEquals(FALSE_NUM, eval("='blah' Is Null"));
assertEquals(TRUE_NUM, eval("='blah' Is Not Null"));
+ assertEquals(TRUE_NUM, eval("=Null Is Null"));
+ assertEquals(FALSE_NUM, eval("=Null Is Not Null"));
+
assertEquals(TRUE_NUM, eval("='blah' Between 'a' And 'z'"));
+ assertEquals(TRUE_NUM, eval("='blah' Between 'z' And 'a'"));
assertEquals(FALSE_NUM, eval("='blah' Not Between 'a' And 'z'"));
assertEquals(TRUE_NUM, eval("='blah' In ('foo','bar','blah')"));
@@ -296,6 +301,7 @@ public class ExpressionatorTest extends TestCase
assertEquals(TRUE_NUM, eval("=True Xor False"));
assertEquals(TRUE_NUM, eval("=True Or False"));
+ assertEquals(TRUE_NUM, eval("=False Or True"));
assertEquals(FALSE_NUM, eval("=True Imp False"));
assertEquals(FALSE_NUM, eval("=True Eqv False"));
assertEquals(TRUE_NUM, eval("=Not(True Eqv False)"));
@@ -304,6 +310,45 @@ public class ExpressionatorTest extends TestCase
public void testDateArith() throws Exception
{
assertEquals(new Date(1041508800000L), eval("=#01/02/2003# + #7:00:00#"));
+ assertEquals(new Date(1041458400000L), eval("=#01/02/2003# - #7:00:00#"));
+ assertEquals(new Date(1044680400000L), eval("=#01/02/2003# + '37'"));
+ assertEquals(new Date(1044680400000L), eval("='37' + #01/02/2003#"));
+ assertEquals(new Date(1041508800000L), eval("=#01/02/2003 7:00:00#"));
+ }
+
+ public void testNull() throws Exception
+ {
+ assertNull(eval("=37 + Null"));
+ assertNull(eval("=37 - Null"));
+ assertNull(eval("=37 / Null"));
+ assertNull(eval("=37 * Null"));
+ assertNull(eval("=37 ^ Null"));
+ assertEquals("37", eval("=37 & Null"));
+ assertEquals("37", eval("=Null & 37"));
+ assertNull(eval("=37 Mod Null"));
+ assertNull(eval("=37 \\ Null"));
+ assertNull(eval("=-(Null)"));
+ assertNull(eval("=+(Null)"));
+ assertNull(eval("=Not Null"));
+ assertEquals(TRUE_NUM, eval("=37 Or Null"));
+ assertNull(eval("=Null Or 37"));
+ assertNull(eval("=37 And Null"));
+ assertNull(eval("=Null And 37"));
+ assertNull(eval("=37 Xor Null"));
+ assertNull(eval("=37 Imp Null"));
+ assertNull(eval("=Null Imp Null"));
+ assertEquals(TRUE_NUM, eval("=Null Imp 37"));
+ assertNull(eval("=37 Eqv Null"));
+ assertNull(eval("=37 < Null"));
+ assertNull(eval("=37 > Null"));
+ assertNull(eval("=37 = Null"));
+ assertNull(eval("=37 <> Null"));
+ assertNull(eval("=37 <= Null"));
+ assertNull(eval("=37 >= Null"));
+
+ assertNull(eval("=37 Between Null And 54"));
+ assertEquals(FALSE_NUM, eval("=37 In (23, Null, 45)"));
+ assertNull(eval("=Null In (23, Null, 45)"));
}
public void testTrickyMathExpressions() throws Exception
@@ -356,8 +401,7 @@ public class ExpressionatorTest extends TestCase
"<THIS_COL> Like \"[abc*\"");
assertFalse(evalCondition("Like \"[abc*\"", "afcd"));
assertFalse(evalCondition("Like \"[abc*\"", "fcd"));
- // FIXME, does access support "not like"
- //assertTrue(evalCondition("Not Like \"[abc*\"", "fcd"));
+ assertTrue(evalCondition("Not Like \"[abc*\"", "fcd"));
assertFalse(evalCondition("Like \"[abc*\"", ""));
}