/* * Copyright (c) 2008-2012, Hazel Bilisim Ltd. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hazelcast.query; import com.hazelcast.core.MapEntry; import com.hazelcast.impl.TestUtil; import org.junit.Test; import org.junit.runner.RunWith; import java.sql.Timestamp; import java.util.Date; import static org.junit.Assert.*; @RunWith(com.hazelcast.util.RandomBlockJUnit4ClassRunner.class) public class PredicatesTest { @Test public void testEqual() { TestUtil.Employee value = new QueryTest.Employee("abc-123-xvz", 34, true, 10D); value.setState(TestUtil.State.STATE2); TestUtil.Employee nullNameValue = new QueryTest.Employee(null, 34, true, 10D); assertTrue(new SqlPredicate("state == TestUtil.State.STATE2").apply(createEntry("1", value))); assertTrue(new SqlPredicate("state == " + TestUtil.State.STATE2).apply(createEntry("1", value))); assertFalse(new SqlPredicate("state == TestUtil.State.STATE1").apply(createEntry("1", value))); assertFalse(new SqlPredicate("state == TestUtil.State.STATE1").apply(createEntry("1", nullNameValue))); assertTrue(new SqlPredicate("state == NULL").apply(createEntry("1", nullNameValue))); assertTrue(new SqlPredicate("date >= '" + new Timestamp(0) + "'").apply(createEntry("1", value))); assertTrue(new SqlPredicate("createDate >= '" + new Date(0) + "'").apply(createEntry("1", value))); assertTrue(new SqlPredicate("sqlDate >= '" + new java.sql.Date(0) + "'").apply(createEntry("1", value))); assertFalse(new SqlPredicate("name = 'null'").apply(createEntry("1", nullNameValue))); assertTrue(new SqlPredicate("name = null").apply(createEntry("1", nullNameValue))); assertTrue(new SqlPredicate("name = NULL").apply(createEntry("1", nullNameValue))); assertTrue(new SqlPredicate("name != null").apply(createEntry("1", value))); assertTrue(new SqlPredicate("name != NULL").apply(createEntry("1", value))); assertTrue(new SqlPredicate("(age >= " + 20 + ") AND (age <= " + 40 + ")").apply(createEntry("1", value))); assertTrue(new SqlPredicate("(age >= " + 20 + ") AND (age <= " + 34 + ")").apply(createEntry("1", value))); assertTrue(new SqlPredicate("(age >= " + 34 + ") AND (age <= " + 35 + ")").apply(createEntry("1", value))); assertTrue(new SqlPredicate("age IN (" + 34 + ", " + 35 + ")").apply(createEntry("1", value))); assertTrue(new SqlPredicate(" (name LIKE 'abc-%') AND (age <= " + 40 + ")").apply(createEntry("1", value))); assertTrue(new SqlPredicate("age = -33").apply(createEntry("1", new QueryTest.Employee("abc-123-xvz", -33, true, 10D)))); assertFalse(new SqlPredicate("age = 33").apply(createEntry("1", value))); assertTrue(new SqlPredicate("age = 34").apply(createEntry("1", value))); assertTrue(new SqlPredicate("age > 5").apply(createEntry("1", value))); assertTrue(new SqlPredicate("salary > 5").apply(createEntry("1", value))); assertTrue(new SqlPredicate("salary > 5 and salary < 11").apply(createEntry("1", value))); assertFalse(new SqlPredicate("salary > 15 or salary < 10").apply(createEntry("1", value))); assertTrue(new SqlPredicate("salary between 9.99 and 10.01").apply(createEntry("1", value))); assertTrue(new SqlPredicate("salary between 5 and 15").apply(createEntry("1", value))); assertTrue(new SqlPredicate("name='abc-123-xvz'").apply(createEntry("1", value))); assertTrue(new SqlPredicate("name='abc 123-xvz'").apply(createEntry("1", new QueryTest.Employee("abc 123-xvz", 34, true, 10D)))); assertTrue(new SqlPredicate("name='abc 123-xvz+(123)'").apply(createEntry("1", new QueryTest.Employee("abc 123-xvz+(123)", 34, true, 10D)))); assertFalse(new SqlPredicate("name='abc 123-xvz+(123)'").apply(createEntry("1", new QueryTest.Employee("abc123-xvz+(123)", 34, true, 10D)))); assertTrue(new SqlPredicate("name LIKE 'abc-%'").apply(createEntry("1", new QueryTest.Employee("abc-123", 34, true, 10D)))); assertTrue(Predicates.equal(new DummyExpression("value"), "value").apply(null)); assertFalse(Predicates.equal(new DummyExpression("value1"), "value").apply(null)); assertFalse(Predicates.equal(new DummyExpression("value"), "value1").apply(null)); assertTrue(Predicates.equal(new DummyExpression(true), Boolean.TRUE).apply(null)); assertTrue(Predicates.equal(new DummyExpression(Boolean.TRUE), true).apply(null)); assertFalse(Predicates.equal(new DummyExpression(Boolean.FALSE), true).apply(null)); assertFalse(Predicates.equal(new DummyExpression(15.23), 15.22).apply(null)); assertFalse(Predicates.equal(new DummyExpression(15.23), 15.22).apply(null)); assertTrue(Predicates.equal(new DummyExpression(15.22), 15.22).apply(null)); assertFalse(Predicates.equal(new DummyExpression(15), 16).apply(null)); assertTrue(Predicates.greaterThan(new DummyExpression(6), 5).apply(null)); assertFalse(Predicates.greaterThan(new DummyExpression(4), 5).apply(null)); assertFalse(Predicates.greaterThan(new DummyExpression(5), 5).apply(null)); assertTrue(Predicates.greaterEqual(new DummyExpression(5), 5).apply(null)); assertTrue(Predicates.lessThan(new DummyExpression(6), 7).apply(null)); assertFalse(Predicates.lessThan(new DummyExpression(4), 3).apply(null)); assertFalse(Predicates.lessThan(new DummyExpression(4), 4).apply(null)); assertTrue(Predicates.lessEqual(new DummyExpression(4), 4).apply(null)); assertTrue(Predicates.between(new DummyExpression(5), 4, 6).apply(null)); assertTrue(Predicates.between(new DummyExpression(5), 5, 6).apply(null)); assertFalse(Predicates.between(new DummyExpression(5), 6, 7).apply(null)); assertTrue(Predicates.in(new DummyExpression(5), 4, 7, 8, 5).apply(null)); assertTrue(Predicates.in(new DummyExpression(5), 5, 7, 8).apply(null)); assertFalse(Predicates.in(new DummyExpression(5), 6, 7, 8).apply(null)); assertFalse(Predicates.in(new DummyExpression(9), 6, 7, 8).apply(null)); assertTrue(Predicates.like(new DummyExpression<String>("Java"), "J%").apply(null)); assertTrue(Predicates.like(new DummyExpression<String>("Java"), "Ja%").apply(null)); assertTrue(Predicates.like(new DummyExpression<String>("Java"), "J_v_").apply(null)); assertTrue(Predicates.like(new DummyExpression<String>("Java"), "_av_").apply(null)); assertTrue(Predicates.like(new DummyExpression<String>("Java"), "_a__").apply(null)); assertTrue(Predicates.like(new DummyExpression<String>("Java"), "J%v_").apply(null)); assertTrue(Predicates.like(new DummyExpression<String>("Java"), "J%_").apply(null)); assertFalse(Predicates.like(new DummyExpression<String>("Java"), "java").apply(null)); assertFalse(Predicates.like(new DummyExpression<String>("Java"), "j%").apply(null)); assertFalse(Predicates.like(new DummyExpression<String>("Java"), "J_a").apply(null)); assertFalse(Predicates.like(new DummyExpression<String>("Java"), "J_ava").apply(null)); assertFalse(Predicates.like(new DummyExpression<String>("Java"), "J_a_a").apply(null)); assertFalse(Predicates.like(new DummyExpression<String>("Java"), "J_av__").apply(null)); assertFalse(Predicates.like(new DummyExpression<String>("Java"), "J_Va").apply(null)); assertTrue(Predicates.like(new DummyExpression<String>("Java World"), "Java World").apply(null)); assertTrue(Predicates.like(new DummyExpression<String>("Java World"), "Java%ld").apply(null)); assertTrue(Predicates.like(new DummyExpression<String>("Java World"), "%World").apply(null)); assertTrue(Predicates.like(new DummyExpression<String>("Java World"), "Java_World").apply(null)); assertFalse(Predicates.like(new DummyExpression<String>("Java World"), "JavaWorld").apply(null)); } @Test public void testCriteriaAPI() { Object value = new QueryTest.Employee(12, "abc-123-xvz", 34, true, 10D); EntryObject e = new PredicateBuilder().getEntryObject(); EntryObject e2 = e.get("age"); Predicate predicate = e2.greaterEqual(29).and(e2.lessEqual(36)); assertTrue(predicate.apply(createEntry("1", value))); e = new PredicateBuilder().getEntryObject(); assertTrue(e.get("id").equal(12).apply(createEntry("1", value))); } @Test public void testSqlPredicate() { assertEquals("name IN (name0,name2)", sql("name in ('name0', 'name2')")); assertEquals("(name LIKE 'joe' AND id=5)", sql("name like 'joe' AND id = 5")); assertEquals("active=true", sql("active")); assertEquals("(active=true AND name=abc xyz 123)", sql("active AND name='abc xyz 123'")); assertEquals("(name LIKE 'abc-xyz+(123)' AND name=abc xyz 123)", sql("name like 'abc-xyz+(123)' AND name='abc xyz 123'")); assertEquals("(active=true AND age>4)", sql("active and age > 4")); assertEquals("(active=true AND age>4)", sql("active and age>4")); assertEquals("(active=false AND age<=4)", sql("active=false AND age<=4")); assertEquals("(active=false AND age<=4)", sql("active= false and age <= 4")); assertEquals("(active=false AND age>=4)", sql("active=false AND (age>=4)")); assertEquals("(active=false OR age>=4)", sql("active =false or (age>= 4)")); assertEquals("name LIKE 'J%'", sql("name like 'J%'")); assertEquals("NOT(name LIKE 'J%')", sql("name not like 'J%'")); assertEquals("(active=false OR name LIKE 'J%')", sql("active =false or name like 'J%'")); assertEquals("(active=false OR name LIKE 'Java World')", sql("active =false or name like 'Java World'")); assertEquals("(active=false OR name LIKE 'Java W% Again')", sql("active =false or name like 'Java W% Again'")); assertEquals("i<=-1", sql("i<= -1")); assertEquals("age IN (-1)", sql("age in (-1)")); assertEquals("age IN (10,15)", sql("age in (10, 15)")); assertEquals("NOT(age IN (10,15))", sql("age not in ( 10 , 15 )")); assertEquals("(active=true AND age BETWEEN 10 AND 15)", sql("active and age between 10 and 15")); assertEquals("(age IN (10,15) AND active=true)", sql("age IN (10, 15) and active")); assertEquals("(active=true OR age IN (10,15))", sql("active or (age in ( 10,15))")); assertEquals("(age>10 AND (active=true OR age IN (10,15)))", sql("age>10 AND (active or (age IN (10, 15 )))")); assertEquals("(age<=10 AND (active=true OR NOT(age IN (10,15))))", sql("age<=10 AND (active or (age not in (10 , 15)))")); assertEquals("age BETWEEN 10 AND 15", sql("age between 10 and 15")); assertEquals("NOT(age BETWEEN 10 AND 15)", sql("age not between 10 and 15")); assertEquals("(active=true AND age BETWEEN 10 AND 15)", sql("active and age between 10 and 15")); assertEquals("(age BETWEEN 10 AND 15 AND active=true)", sql("age between 10 and 15 and active")); assertEquals("(active=true OR age BETWEEN 10 AND 15)", sql("active or (age between 10 and 15)")); assertEquals("(age>10 AND (active=true OR age BETWEEN 10 AND 15))", sql("age>10 AND (active or (age between 10 and 15))")); assertEquals("(age<=10 AND (active=true OR NOT(age BETWEEN 10 AND 15)))", sql("age<=10 AND (active or (age not between 10 and 15))")); } @Test(expected = RuntimeException.class) public void testInvalidSqlPredicate1() { new SqlPredicate("invalid sql"); } @Test(expected = RuntimeException.class) public void testInvalidSqlPredicate2() { new SqlPredicate(""); } private String sql(String sql) { return new SqlPredicate(sql).toString(); } class DummyExpression<T> implements Expression<T> { T value; DummyExpression(T value) { this.value = value; } public T getValue(Object obj) { return value; } } static MapEntry createEntry(final Object key, final Object value) { return new MapEntry() { public long getCost() { return 0; } public long getCreationTime() { return 0; } public long getExpirationTime() { return 0; } public int getHits() { return 0; } public long getLastAccessTime() { return 0; } public long getLastStoredTime() { return 0; } public long getLastUpdateTime() { return 0; } public long getVersion() { return 0; } public boolean isValid() { return true; } public Object getKey() { return key; } public Object getValue() { return value; } public Object setValue(Object value) { return value; } }; } }