/* * Copyright (c) 2008-2017, Hazelcast, Inc. 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.map.impl.query; import com.hazelcast.config.CacheDeserializedValues; import com.hazelcast.config.Config; import com.hazelcast.config.MapConfig; import com.hazelcast.config.MapIndexConfig; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; import com.hazelcast.nio.serialization.Portable; import com.hazelcast.nio.serialization.PortableFactory; import com.hazelcast.nio.serialization.PortableTest.ChildPortableObject; import com.hazelcast.nio.serialization.PortableTest.GrandParentPortableObject; import com.hazelcast.nio.serialization.PortableTest.ParentPortableObject; import com.hazelcast.query.EntryObject; import com.hazelcast.query.Predicate; import com.hazelcast.query.PredicateBuilder; import com.hazelcast.query.Predicates; import com.hazelcast.query.QueryException; import com.hazelcast.query.SampleObjects; import com.hazelcast.query.SampleObjects.Employee; import com.hazelcast.query.SampleObjects.State; import com.hazelcast.query.SampleObjects.Value; import com.hazelcast.query.SampleObjects.ValueType; import com.hazelcast.query.SqlPredicate; import com.hazelcast.spi.properties.GroupProperty; import com.hazelcast.spi.properties.HazelcastProperties; import com.hazelcast.test.HazelcastParallelClassRunner; import com.hazelcast.test.HazelcastTestSupport; import com.hazelcast.test.TestHazelcastInstanceFactory; import com.hazelcast.test.annotation.ParallelTest; import com.hazelcast.test.annotation.QuickTest; import com.hazelcast.util.UuidUtil; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @RunWith(HazelcastParallelClassRunner.class) @Category({QuickTest.class, ParallelTest.class}) public class QueryBasicTest extends HazelcastTestSupport { @Test public void testPredicatedEvaluatedSingleThreadedByDefault() { Config config = getConfig(); HazelcastProperties properties = new HazelcastProperties(config); boolean parallelEvaluation = properties.getBoolean(GroupProperty.QUERY_PREDICATE_PARALLEL_EVALUATION); assertFalse(parallelEvaluation); } @Test(timeout = 1000 * 60) public void testInPredicateWithEmptyArray() { TestHazelcastInstanceFactory nodeFactory = createHazelcastInstanceFactory(2); Config cfg = getConfig(); HazelcastInstance instance = nodeFactory.newHazelcastInstance(cfg); final IMap<String, Value> map = instance.getMap("default"); for (int i = 0; i < 10; i++) { final Value v = new Value("name" + i, new ValueType("type" + i), i); map.put("" + i, v); } String[] emptyArray = new String[2]; final Predicate predicate = new PredicateBuilder().getEntryObject().get("name").in(emptyArray); final Collection<Value> values = map.values(predicate); assertEquals(values.size(), 0); } @Test(timeout = 1000 * 60) public void issue393SqlIn() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<String, Value> map = instance.getMap("default"); map.addIndex("name", true); for (int i = 0; i < 4; i++) { Value v = new Value("name" + i); map.put("" + i, v); } Predicate predicate = new SqlPredicate("name IN ('name0', 'name2')"); Collection<Value> values = map.values(predicate); String[] expectedValues = new String[]{"name0", "name2"}; assertEquals(expectedValues.length, values.size()); List<String> names = new ArrayList<String>(); for (Value configObject : values) { names.add(configObject.getName()); } String[] array = names.toArray(new String[names.size()]); Arrays.sort(array); assertArrayEquals(names.toString(), expectedValues, array); } @Test(timeout = 1000 * 60) public void issue393SqlInInteger() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<String, Value> map = instance.getMap("default"); map.addIndex("index", false); for (int i = 0; i < 4; i++) { Value v = new Value("name" + i, new ValueType("type" + i), i); map.put("" + i, v); } Predicate predicate = new SqlPredicate("index IN (0, 2)"); Collection<Value> values = map.values(predicate); String[] expectedValues = new String[]{"name0", "name2"}; assertEquals(expectedValues.length, values.size()); List<String> names = new ArrayList<String>(); for (Value configObject : values) { names.add(configObject.getName()); } String[] array = names.toArray(new String[names.size()]); Arrays.sort(array); assertArrayEquals(names.toString(), expectedValues, array); } @Test(timeout = 1000 * 60) public void testInPredicate() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<String, SampleObjects.ValueType> map = instance.getMap("testIteratorContract"); map.put("1", new ValueType("one")); map.put("2", new ValueType("two")); map.put("3", new ValueType("three")); map.put("4", new ValueType("four")); map.put("5", new ValueType("five")); map.put("6", new ValueType("six")); map.put("7", new ValueType("seven")); Predicate predicate = new SqlPredicate("typeName in ('one','two')"); for (int i = 0; i < 10; i++) { Collection<SampleObjects.ValueType> values = map.values(predicate); assertEquals(2, values.size()); } } @Test(timeout = 1000 * 60) public void testInstanceOfPredicate() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<String, Object> map = instance.getMap("testInstanceOfPredicate"); LinkedList linkedList = new LinkedList(); Predicate linkedListPredicate = Predicates.instanceOf(LinkedList.class); map.put("1", "someString"); map.put("2", new ArrayList()); map.put("3", linkedList); Collection<Object> values = map.values(linkedListPredicate); assertEquals(1, values.size()); assertContains(values, linkedList); } @Test(timeout = 1000 * 60) public void testIteratorContract() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<String, SampleObjects.ValueType> map = instance.getMap("testIteratorContract"); map.put("1", new ValueType("one")); map.put("2", new ValueType("two")); map.put("3", new ValueType("three")); Predicate predicate = new SqlPredicate("typeName in ('one','two')"); assertEquals(2, map.values(predicate).size()); assertEquals(2, map.keySet(predicate).size()); testIterator(map.keySet().iterator(), 3); testIterator(map.keySet(predicate).iterator(), 2); testIterator(map.entrySet().iterator(), 3); testIterator(map.entrySet(predicate).iterator(), 2); testIterator(map.values().iterator(), 3); testIterator(map.values(predicate).iterator(), 2); } private void testIterator(Iterator it, int size) { for (int i = 0; i < size * 2; i++) { assertTrue("i is " + i, it.hasNext()); } for (int i = 0; i < size; i++) { assertTrue(it.hasNext()); assertNotNull(it.next()); } assertFalse(it.hasNext()); assertFalse(it.hasNext()); } @Test(timeout = 1000 * 60) public void issue393Fail() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<String, Value> map = instance.getMap("default"); map.addIndex("qwe", true); Value v = new Value("name"); try { map.put("0", v); fail(); } catch (Throwable e) { assertContains(e.getMessage(), "There is no suitable accessor for 'qwe'"); } } @Test(timeout = 1000 * 60) public void negativeDouble() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<String, Employee> map = instance.getMap("default"); map.addIndex("salary", false); map.put("" + 4, new Employee(1, "default", 1, true, -70D)); map.put("" + 3, new Employee(1, "default", 1, true, -60D)); map.put("" + 1, new Employee(1, "default", 1, true, -10D)); map.put("" + 2, new Employee(2, "default", 2, true, 10D)); Predicate predicate = new SqlPredicate("salary >= -60"); Collection<Employee> values = map.values(predicate); assertEquals(3, values.size()); predicate = new SqlPredicate("salary between -20 and 20"); values = map.values(predicate); assertEquals(2, values.size()); } @Test(timeout = 1000 * 60) public void issue393SqlEq() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<String, Value> map = instance.getMap("default"); map.addIndex("name", true); for (int i = 0; i < 4; i++) { Value v = new Value("name" + i); map.put("" + i, v); } Predicate predicate = new SqlPredicate("name='name0'"); Collection<Value> values = map.values(predicate); String[] expectedValues = new String[]{"name0"}; assertEquals(expectedValues.length, values.size()); List<String> names = new ArrayList<String>(); for (Value configObject : values) { names.add(configObject.getName()); } String[] array = names.toArray(new String[names.size()]); Arrays.sort(array); assertArrayEquals(names.toString(), expectedValues, array); } @Test(timeout = 1000 * 60) public void issue393() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<String, Value> map = instance.getMap("default"); map.addIndex("name", true); for (int i = 0; i < 4; i++) { Value v = new Value("name" + i); map.put("" + i, v); } Predicate predicate = new PredicateBuilder().getEntryObject().get("name").in("name0", "name2"); Collection<Value> values = map.values(predicate); String[] expectedValues = new String[]{"name0", "name2"}; assertEquals(expectedValues.length, values.size()); List<String> names = new ArrayList<String>(); for (Value configObject : values) { names.add(configObject.getName()); } String[] array = names.toArray(new String[names.size()]); Arrays.sort(array); assertArrayEquals(names.toString(), expectedValues, array); } @Test(timeout = 1000 * 60) public void testWithDashInTheNameAndSqlPredicate() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<String, Employee> map = instance.getMap("employee"); Employee toto = new Employee("toto", 23, true, 165765.0); map.put("1", toto); Employee toto2 = new Employee("toto-super+hero", 23, true, 165765.0); map.put("2", toto2); // works well Set<Map.Entry<String, Employee>> entries = map.entrySet(new SqlPredicate("name='toto-super+hero'")); assertTrue(entries.size() > 0); for (Map.Entry<String, Employee> entry : entries) { Employee e = entry.getValue(); assertEquals(e, toto2); } } @Test(timeout = 1000 * 60) public void queryWithThis() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<String, String> map = instance.getMap("queryWithThis"); map.addIndex("this", false); for (int i = 0; i < 1000; i++) { map.put("" + i, "" + i); } Predicate predicate = new PredicateBuilder().getEntryObject().get("this").equal("10"); Collection<String> set = map.values(predicate); assertEquals(1, set.size()); assertEquals(1, map.values(new SqlPredicate("this=15")).size()); } /** * Test for issue 711 */ @Test(timeout = 1000 * 60) public void testPredicateWithEntryKeyObject() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<String, Integer> map = instance.getMap("testPredicateWithEntryKeyObject"); map.put("1", 11); map.put("2", 22); map.put("3", 33); map.put("4", 44); map.put("5", 55); map.put("6", 66); Predicate predicate = new PredicateBuilder().getEntryObject().key().equal("1"); assertEquals(1, map.values(predicate).size()); predicate = new PredicateBuilder().getEntryObject().key().in("2", "3"); assertEquals(2, map.keySet(predicate).size()); predicate = new PredicateBuilder().getEntryObject().key().in("2", "3", "5", "6", "7"); assertEquals(4, map.keySet(predicate).size()); } /** * Github issues 98 and 131 */ @Test(timeout = 1000 * 60) public void testPredicateStringAttribute() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<Integer, Value> map = instance.getMap("testPredicateStringWithString"); testPredicateStringAttribute(map); } /** * Github issues 98 and 131 */ @Test(timeout = 1000 * 60) public void testPredicateStringAttributesWithIndex() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<Integer, Value> map = instance.getMap("testPredicateStringWithStringIndex"); map.addIndex("name", false); testPredicateStringAttribute(map); } private void testPredicateStringAttribute(IMap<Integer, Value> map) { map.put(1, new Value("abc")); map.put(2, new Value("xyz")); map.put(3, new Value("aaa")); map.put(4, new Value("zzz")); map.put(5, new Value("klm")); map.put(6, new Value("prs")); map.put(7, new Value("prs")); map.put(8, new Value("def")); map.put(9, new Value("qwx")); assertEquals(8, map.values(new SqlPredicate("name > 'aac'")).size()); assertEquals(9, map.values(new SqlPredicate("name between 'aaa' and 'zzz'")).size()); assertEquals(7, map.values(new SqlPredicate("name < 't'")).size()); assertEquals(6, map.values(new SqlPredicate("name >= 'gh'")).size()); assertEquals(8, map.values(new PredicateBuilder().getEntryObject().get("name").greaterThan("aac")).size()); assertEquals(9, map.values(new PredicateBuilder().getEntryObject().get("name").between("aaa", "zzz")).size()); assertEquals(7, map.values(new PredicateBuilder().getEntryObject().get("name").lessThan("t")).size()); assertEquals(6, map.values(new PredicateBuilder().getEntryObject().get("name").greaterEqual("gh")).size()); } @Test(timeout = 1000 * 60) public void testPredicateDateAttribute() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<Integer, Date> map = instance.getMap("testPredicateDateAttribute"); testPredicateDateAttribute(map); } @Test(timeout = 1000 * 60) public void testPredicateDateAttributeWithIndex() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<Integer, Date> map = instance.getMap("testPredicateDateAttribute"); map.addIndex("this", true); testPredicateDateAttribute(map); } private void testPredicateDateAttribute(IMap<Integer, Date> map) { Calendar cal = Calendar.getInstance(); cal.set(2012, Calendar.JUNE, 5); map.put(1, cal.getTime()); cal.set(2011, Calendar.NOVEMBER, 10); map.put(2, cal.getTime()); cal.set(2011, Calendar.FEBRUARY, 1); map.put(3, cal.getTime()); cal.set(2010, Calendar.SEPTEMBER, 5); map.put(4, cal.getTime()); cal.set(2000, Calendar.JUNE, 5); map.put(5, cal.getTime()); cal.set(2011, Calendar.JANUARY, 1); assertEquals(3, map.values(new PredicateBuilder().getEntryObject().get("this").greaterThan(cal.getTime())).size()); assertEquals(3, map.values(new SqlPredicate("this > 'Sat Jan 01 11:43:05 EET 2011'")).size()); assertEquals(2, map.values(new PredicateBuilder().getEntryObject().get("this").lessThan(cal.getTime())).size()); assertEquals(2, map.values(new SqlPredicate("this < 'Sat Jan 01 11:43:05 EET 2011'")).size()); cal.set(2003, Calendar.NOVEMBER, 10); Date d1 = cal.getTime(); cal.set(2012, Calendar.FEBRUARY, 10); Date d2 = cal.getTime(); assertEquals(3, map.values(new PredicateBuilder().getEntryObject().get("this").between(d1, d2)).size()); assertEquals(3, map.values(new SqlPredicate("this between 'Mon Nov 10 11:43:05 EET 2003'" + " and 'Fri Feb 10 11:43:05 EET 2012'")).size()); } @Test(timeout = 1000 * 60) public void testPredicateEnumAttribute() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<Integer, NodeType> map = instance.getMap("testPredicateEnumAttribute"); testPredicateEnumAttribute(map); } @Test(timeout = 1000 * 60) public void testPredicateEnumAttributeWithIndex() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<Integer, NodeType> map = instance.getMap("testPredicateEnumAttribute"); map.addIndex("this", true); testPredicateEnumAttribute(map); } private void testPredicateEnumAttribute(IMap<Integer, NodeType> map) { map.put(1, NodeType.MEMBER); map.put(2, NodeType.LITE_MEMBER); map.put(3, NodeType.JAVA_CLIENT); assertEquals(NodeType.MEMBER, map.values(new SqlPredicate("this=MEMBER")).iterator().next()); assertEquals(2, map.values(new SqlPredicate("this in (MEMBER, LITE_MEMBER)")).size()); assertEquals(NodeType.JAVA_CLIENT, map.values(new PredicateBuilder().getEntryObject() .get("this").equal(NodeType.JAVA_CLIENT)).iterator().next()); assertEquals(0, map.values(new PredicateBuilder().getEntryObject() .get("this").equal(NodeType.CSHARP_CLIENT)).size()); assertEquals(2, map.values(new PredicateBuilder().getEntryObject() .get("this").in(NodeType.LITE_MEMBER, NodeType.MEMBER)).size()); } private enum NodeType { MEMBER, LITE_MEMBER, JAVA_CLIENT, CSHARP_CLIENT } @Test(timeout = 1000 * 60) public void testPredicateCustomAttribute() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<Integer, CustomObject> map = instance.getMap("testPredicateCustomAttribute"); CustomAttribute attribute = new CustomAttribute(78, 145); CustomObject customObject = new CustomObject("name1", UuidUtil.newUnsecureUUID(), attribute); map.put(1, customObject); CustomObject object2 = new CustomObject("name2", UuidUtil.newUnsecureUUID(), attribute); map.put(2, object2); assertEquals(customObject, map.values(new PredicateBuilder().getEntryObject().get("uuid").equal(customObject.getUuid())) .iterator().next()); assertEquals(2, map.values(new PredicateBuilder().getEntryObject().get("attribute").equal(attribute)).size()); assertEquals(object2, map.values(new PredicateBuilder().getEntryObject().get("uuid").in(object2.getUuid())) .iterator().next()); assertEquals(2, map.values(new PredicateBuilder().getEntryObject().get("attribute").in(attribute)).size()); } public static void doFunctionalSQLQueryTest(IMap<String, Employee> map) { map.put("1", new Employee("joe", 33, false, 14.56)); map.put("2", new Employee("ali", 23, true, 15.00)); for (int i = 3; i < 103; i++) { map.put(String.valueOf(i), new Employee("name" + i, i % 60, ((i & 1) == 1), i)); } Set<Map.Entry<String, Employee>> entries = map.entrySet(); assertEquals(102, entries.size()); int entryCount = 0; for (Map.Entry entry : entries) { Employee employee = (Employee) entry.getValue(); assertNotNull(employee); entryCount++; } assertEquals(102, entryCount); entries = map.entrySet(new SqlPredicate("active=true and age=23")); assertEquals(3, entries.size()); for (Map.Entry entry : entries) { Employee employee = (Employee) entry.getValue(); assertEquals(employee.getAge(), 23); assertTrue(employee.isActive()); } map.remove("2"); entries = map.entrySet(new SqlPredicate("active=true and age=23")); assertEquals(2, entries.size()); for (Map.Entry entry : entries) { Employee employee = (Employee) entry.getValue(); assertEquals(employee.getAge(), 23); assertTrue(employee.isActive()); } entries = map.entrySet(new SqlPredicate("age!=33")); for (Map.Entry entry : entries) { Employee employee = (Employee) entry.getValue(); assertTrue(employee.getAge() != 33); } entries = map.entrySet(new SqlPredicate("active!=false")); for (Map.Entry entry : entries) { Employee employee = (Employee) entry.getValue(); assertTrue(employee.isActive()); } } public static void doFunctionalQueryTest(IMap<String, Employee> map) { map.put("1", new Employee("joe", 33, false, 14.56)); map.put("2", new Employee("ali", 23, true, 15.00)); for (int i = 3; i < 103; i++) { map.put(String.valueOf(i), new Employee("name" + i, i % 60, ((i & 1) == 1), i)); } Set<Map.Entry<String, Employee>> entries = map.entrySet(); assertEquals(102, entries.size()); int entryCount = 0; for (Map.Entry entry : entries) { Employee employee = (Employee) entry.getValue(); assertNotNull(employee); entryCount++; } assertEquals(102, entryCount); EntryObject entryObject = new PredicateBuilder().getEntryObject(); Predicate predicate = entryObject.is("active").and(entryObject.get("age").equal(23)); entries = map.entrySet(predicate); for (Map.Entry entry : entries) { Employee employee = (Employee) entry.getValue(); assertEquals(employee.getAge(), 23); assertTrue(employee.isActive()); } map.remove("2"); entries = map.entrySet(predicate); assertEquals(2, entries.size()); for (Map.Entry entry : entries) { Employee employee = (Employee) entry.getValue(); assertEquals(employee.getAge(), 23); assertTrue(employee.isActive()); } entries = map.entrySet(new SqlPredicate(" (age >= " + 30 + ") AND (age <= " + 40 + ")")); assertEquals(23, entries.size()); for (Map.Entry entry : entries) { Employee employee = (Employee) entry.getValue(); assertTrue(employee.getAge() >= 30); assertTrue(employee.getAge() <= 40); } } @Test(timeout = 1000 * 60) public void testInvalidSqlPredicate() { Config cfg = getConfig(); TestHazelcastInstanceFactory nodeFactory = createHazelcastInstanceFactory(1); HazelcastInstance instance = nodeFactory.newHazelcastInstance(cfg); IMap<Integer, Employee> map = instance.getMap("employee"); map.put(1, new Employee("e", 1, false, 0)); map.put(2, new Employee("e2", 1, false, 0)); try { map.values(new SqlPredicate("invalid_sql")); fail("Should fail because of invalid SQL!"); } catch (RuntimeException e) { assertContains(e.getMessage(), "There is no suitable accessor for 'invalid_sql'"); } try { map.values(new SqlPredicate("invalid sql")); fail("Should fail because of invalid SQL!"); } catch (RuntimeException e) { assertContains(e.getMessage(), "Invalid SQL: [invalid sql]"); } try { map.values(new SqlPredicate("invalid and sql")); fail("Should fail because of invalid SQL!"); } catch (RuntimeException e) { assertContains(e.getMessage(), "There is no suitable accessor for 'invalid'"); } try { map.values(new SqlPredicate("invalid sql and")); fail("Should fail because of invalid SQL!"); } catch (RuntimeException e) { assertContains(e.getMessage(), "There is no suitable accessor for 'invalid'"); } try { map.values(new SqlPredicate("")); fail("Should fail because of invalid SQL!"); } catch (RuntimeException e) { assertContains(e.getMessage(), "Invalid SQL: []"); } assertEquals(2, map.values(new SqlPredicate("age=1 and name like 'e%'")).size()); } @Test(timeout = 1000 * 60) public void testIndexingEnumAttributeIssue597() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<Integer, Value> map = instance.getMap("default"); map.addIndex("state", true); for (int i = 0; i < 4; i++) { Value v = new Value(i % 2 == 0 ? State.STATE1 : State.STATE2, new ValueType(), i); map.put(i, v); } Predicate predicate = new PredicateBuilder().getEntryObject().get("state").equal(State.STATE1); Collection<Value> values = map.values(predicate); int[] expectedValues = new int[]{0, 2}; assertEquals(expectedValues.length, values.size()); int[] indexes = new int[2]; int index = 0; for (Value configObject : values) { indexes[index++] = configObject.getIndex(); } Arrays.sort(indexes); assertArrayEquals(indexes, expectedValues); } /** * see pull request 616 */ @Test(timeout = 1000 * 60) public void testIndexingEnumAttributeWithSqlIssue597() { HazelcastInstance instance = createHazelcastInstance(getConfig()); IMap<Integer, Value> map = instance.getMap("default"); map.addIndex("state", true); for (int i = 0; i < 4; i++) { Value v = new Value(i % 2 == 0 ? State.STATE1 : State.STATE2, new ValueType(), i); map.put(i, v); } Collection<Value> values = map.values(new SqlPredicate("state = 'STATE1'")); int[] expectedValues = new int[]{0, 2}; assertEquals(expectedValues.length, values.size()); int[] indexes = new int[2]; int index = 0; for (Value configObject : values) { indexes[index++] = configObject.getIndex(); } Arrays.sort(indexes); assertArrayEquals(indexes, expectedValues); } @Test(timeout = 1000 * 60) public void testMultipleOrPredicatesIssue885WithoutIndex() { TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); HazelcastInstance instance = factory.newHazelcastInstance(getConfig()); factory.newHazelcastInstance(new Config()); IMap<Integer, Employee> map = instance.getMap("default"); testMultipleOrPredicates(map); } @Test(timeout = 1000 * 60) public void testMultipleOrPredicatesIssue885WithIndex() { TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); HazelcastInstance instance = factory.newHazelcastInstance(getConfig()); factory.newHazelcastInstance(new Config()); IMap<Integer, Employee> map = instance.getMap("default"); map.addIndex("name", true); testMultipleOrPredicates(map); } @Test(timeout = 1000 * 60) public void testMultipleOrPredicatesIssue885WithDoubleIndex() { TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); HazelcastInstance instance = factory.newHazelcastInstance(getConfig()); factory.newHazelcastInstance(new Config()); IMap<Integer, Employee> map = instance.getMap("default"); map.addIndex("name", true); map.addIndex("city", true); testMultipleOrPredicates(map); } private void testMultipleOrPredicates(IMap<Integer, Employee> map) { for (int i = 0; i < 10; i++) { map.put(i, new Employee(i, "name" + i, "city" + i, i, true, i)); } Collection<Employee> values; values = map.values(new SqlPredicate("name = 'name1' OR name = 'name2' OR name LIKE 'name3'")); assertEquals(3, values.size()); values = map.values(new SqlPredicate("name = 'name1' OR name LIKE 'name2%' OR name LIKE 'name3'")); assertEquals(3, values.size()); values = map.values(new SqlPredicate("name = 'name1' OR name LIKE 'name2%' OR name == 'name3'")); assertEquals(3, values.size()); values = map.values(new SqlPredicate("name LIKE '%name1' OR name LIKE 'name2%' OR name LIKE '%name3%'")); assertEquals(3, values.size()); values = map.values(new SqlPredicate("name == 'name1' OR name == 'name2' OR name = 'name3'")); assertEquals(3, values.size()); values = map.values(new SqlPredicate("name = 'name1' OR name = 'name2' OR city LIKE 'city3'")); assertEquals(3, values.size()); values = map.values(new SqlPredicate("name = 'name1' OR name LIKE 'name2%' OR city LIKE 'city3'")); assertEquals(3, values.size()); values = map.values(new SqlPredicate("name = 'name1' OR name LIKE 'name2%' OR city == 'city3'")); assertEquals(3, values.size()); values = map.values(new SqlPredicate("name LIKE '%name1' OR name LIKE 'name2%' OR city LIKE '%city3%'")); assertEquals(3, values.size()); values = map.values(new SqlPredicate("name == 'name1' OR name == 'name2' OR city = 'city3'")); assertEquals(3, values.size()); } @Test public void testSqlQueryUsing__KeyField() { Config config = getConfig(); TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); HazelcastInstance instance1 = factory.newHazelcastInstance(config); HazelcastInstance instance2 = factory.newHazelcastInstance(config); IMap<Object, Object> map = instance2.getMap(randomMapName()); Object key = generateKeyOwnedBy(instance1); Object value = "value"; map.put(key, value); Collection<Object> values = map.values(new SqlPredicate("__key = '" + key + "'")); assertEquals(1, values.size()); assertEquals(value, values.iterator().next()); } @Test public void testSqlQueryUsingNested__KeyField() { Config config = getConfig(); TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); factory.newHazelcastInstance(config); HazelcastInstance instance = factory.newHazelcastInstance(config); IMap<Object, Object> map = instance.getMap(randomMapName()); Object key = new CustomAttribute(12, 123L); Object value = "value"; map.put(key, value); Collection<Object> values = map.values(new SqlPredicate("__key.age = 12 and __key.height = 123")); assertEquals(1, values.size()); assertEquals(value, values.iterator().next()); } @Test public void testSqlQueryUsingPortable__KeyField() { Config config = getConfig(); TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); factory.newHazelcastInstance(config); HazelcastInstance instance = factory.newHazelcastInstance(config); IMap<Object, Object> map = instance.getMap(randomMapName()); Object key = new ChildPortableObject(123L); Object value = "value"; map.put(key, value); Collection<Object> values = map.values(new SqlPredicate("__key.timestamp = 123")); assertEquals(1, values.size()); assertEquals(value, values.iterator().next()); } @Test public void testQueryPortableObject_serial() { Config config = getConfig(); testQueryUsingPortableObject(config, randomMapName()); } @Test public void testQueryPortableObject_parallel() { Config config = getConfig(); config.setProperty(GroupProperty.QUERY_PREDICATE_PARALLEL_EVALUATION.getName(), "true"); testQueryUsingPortableObject(config, randomMapName()); } @Test public void testQueryPortableObjectAndAlwaysCacheValues() { String name = randomMapName(); Config config = getConfig(); config.addMapConfig(new MapConfig(name).setCacheDeserializedValues(CacheDeserializedValues.ALWAYS)); testQueryUsingPortableObject(config, name); } private void testQueryUsingPortableObject(Config config, String mapName) { addPortableFactories(config); TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); HazelcastInstance instance1 = factory.newHazelcastInstance(config); HazelcastInstance instance2 = factory.newHazelcastInstance(config); IMap<Object, Object> map = instance2.getMap(mapName); Object key = generateKeyOwnedBy(instance1); map.put(key, new ParentPortableObject(1L)); waitAllForSafeState(instance1, instance2); Collection<Object> values = map.values(new SqlPredicate("timestamp > 0")); assertEquals(1, values.size()); } private void addPortableFactories(Config config) { config.getSerializationConfig() .addPortableFactory(1, new PortableFactory() { @Override public Portable create(int classId) { return new GrandParentPortableObject(1L); } }).addPortableFactory(2, new PortableFactory() { @Override public Portable create(int classId) { return new ParentPortableObject(1L); } }).addPortableFactory(3, new PortableFactory() { @Override public Portable create(int classId) { return new ChildPortableObject(1L); } }); } @Test(expected = QueryException.class) public void testQueryPortableField() { Config config = getConfig(); HazelcastInstance instance = createHazelcastInstance(config); IMap<Object, Object> map = instance.getMap(randomMapName()); map.put(1, new GrandParentPortableObject(1, new ParentPortableObject(1L, new ChildPortableObject(1L)))); Collection<Object> values = map.values(new SqlPredicate("child > 0")); values.size(); } @Test public void testQueryUsingNestedPortableObject() { Config config = getConfig(); testQueryUsingNestedPortableObject(config, randomMapName()); } @Test public void testQueryUsingNestedPortableObjectWithIndex() { String name = randomMapName(); Config config = getConfig(); config.addMapConfig(new MapConfig(name) .addMapIndexConfig(new MapIndexConfig("child.timestamp", false)) .addMapIndexConfig(new MapIndexConfig("child.child.timestamp", true))); testQueryUsingNestedPortableObject(config, name); } @Test public void testQueryPortableObjectWithIndex() { String name = randomMapName(); Config config = getConfig(); config.addMapConfig(new MapConfig(name) .addMapIndexConfig(new MapIndexConfig("timestamp", true))); testQueryUsingPortableObject(config, name); } @Test public void testQueryPortableObjectWithIndexAndAlwaysCacheValues() { String name = randomMapName(); Config config = getConfig(); config.addMapConfig(new MapConfig(name) .setCacheDeserializedValues(CacheDeserializedValues.ALWAYS) .addMapIndexConfig(new MapIndexConfig("timestamp", true))); testQueryUsingPortableObject(config, name); } private void testQueryUsingNestedPortableObject(Config config, String name) { addPortableFactories(config); TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); HazelcastInstance instance1 = factory.newHazelcastInstance(config); HazelcastInstance instance2 = factory.newHazelcastInstance(config); IMap<String, GrandParentPortableObject> map = instance2.getMap(name); String key = generateKeyOwnedBy(instance1); map.put(key, new GrandParentPortableObject(1, new ParentPortableObject(1L, new ChildPortableObject(1L)))); waitAllForSafeState(instance1, instance2); Collection<GrandParentPortableObject> values = map.values(new SqlPredicate("child.timestamp > 0")); assertEquals(1, values.size()); values = map.values(new SqlPredicate("child.child.timestamp > 0")); assertEquals(1, values.size()); } }