| /*========================================================================= |
| * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved. |
| * This product is protected by U.S. and international copyright |
| * and intellectual property laws. Pivotal products are covered by |
| * one or more patents listed at http://www.pivotal.io/patents. |
| *========================================================================= |
| */ |
| /** |
| * |
| */ |
| package com.gemstone.gemfire.cache.query.functional; |
| |
| 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; |
| |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.experimental.categories.Category; |
| |
| import com.gemstone.gemfire.cache.Region; |
| import com.gemstone.gemfire.cache.query.CacheUtils; |
| import com.gemstone.gemfire.cache.query.Index; |
| import com.gemstone.gemfire.cache.query.IndexType; |
| import com.gemstone.gemfire.cache.query.Query; |
| import com.gemstone.gemfire.cache.query.QueryService; |
| import com.gemstone.gemfire.cache.query.SelectResults; |
| import com.gemstone.gemfire.cache.query.data.Portfolio; |
| import com.gemstone.gemfire.cache.query.data.Position; |
| import com.gemstone.gemfire.cache.query.internal.CompiledValue; |
| import com.gemstone.gemfire.cache.query.internal.QueryObserver; |
| import com.gemstone.gemfire.cache.query.internal.QueryObserverAdapter; |
| import com.gemstone.gemfire.cache.query.internal.QueryObserverHolder; |
| import com.gemstone.gemfire.cache.query.internal.index.IndexManager; |
| import com.gemstone.gemfire.cache.query.types.StructType; |
| import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; |
| import com.gemstone.gemfire.internal.cache.LocalRegion; |
| import com.gemstone.gemfire.test.junit.categories.IntegrationTest; |
| |
| /** |
| * @author asif |
| * |
| */ |
| @Category(IntegrationTest.class) |
| public class LimitClauseJUnitTest { |
| |
| Region region; |
| |
| QueryService qs; |
| |
| @Before |
| public void setUp() throws Exception { |
| CacheUtils.startCache(); |
| region = CacheUtils.createRegion("portfolios", Portfolio.class); |
| // Add 10 unique objects |
| Position.cnt = 0; |
| for (int i = 1; i < 11; ++i) { |
| Object p = new Portfolio(i); |
| GemFireCacheImpl.getInstance().getLogger().fine(p.toString()); |
| region.put(Integer.toString(i), p); |
| } |
| // Add 5 pairs of same Object starting from 11 to 20 |
| /* |
| * for(int i=11; i< 21 ;) { region.put( Integer.toString(i), new |
| * Portfolio(i)); region.put( Integer.toString(i+1), new Portfolio(i)); i |
| * +=2; } |
| */ |
| qs = CacheUtils.getQueryService(); |
| } |
| |
| @After |
| public void tearDown() throws Exception { |
| CacheUtils.closeCache(); |
| IndexManager indexManager = ((LocalRegion)region).getIndexManager(); |
| if (indexManager != null) |
| indexManager.destroy(); |
| } |
| |
| |
| @Test |
| public void testLikeWithLimitWithParameter() throws Exception { |
| String queryString = "SELECT DISTINCT entry FROM $1 entry WHERE entry.key like $2 ORDER BY entry.key LIMIT $3 "; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i < 100; i++) { |
| region.put( "p"+i, new Portfolio(i)); |
| } |
| |
| Object[] params = new Object[3]; |
| params[0] = region.entrySet(); |
| params[1] = "p%"; |
| params[2] = 5; |
| |
| SelectResults results = (SelectResults)qs.newQuery(queryString).execute(params); |
| assertEquals(5, results.size()); |
| } |
| |
| @Test |
| public void testDistinctLimitWithParameter() throws Exception { |
| String queryString = "SELECT DISTINCT entry FROM $1 entry LIMIT $2 "; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i < 100; i++) { |
| region.put( i, new Portfolio(i)); |
| } |
| |
| Object[] params = new Object[2]; |
| params[0] = region; |
| params[1] = 5; |
| |
| SelectResults results = (SelectResults)qs.newQuery(queryString).execute(params); |
| assertEquals(5, results.size()); |
| } |
| |
| @Test |
| public void testLimitWithParameter() throws Exception { |
| String queryString = "SELECT * from /portfolios1 LIMIT $1 "; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i < 100; i++) { |
| region.put( i, new Portfolio(i)); |
| } |
| |
| int limit = 5; |
| Object[] params = new Object[1]; |
| params[0] = limit; |
| |
| SelectResults results = (SelectResults)qs.newQuery(queryString).execute(params); |
| assertEquals(limit, results.size()); |
| |
| limit = 1; |
| params[0] = limit; |
| results = (SelectResults)qs.newQuery(queryString).execute(params); |
| assertEquals(limit, results.size()); |
| |
| limit = 0; |
| params[0] = limit; |
| results = (SelectResults)qs.newQuery(queryString).execute(params); |
| assertEquals(limit, results.size()); |
| |
| limit = 10; |
| params[0] = limit; |
| results = (SelectResults)qs.newQuery(queryString).execute(params); |
| assertEquals(limit, results.size()); |
| } |
| |
| @Test |
| public void testLimitWithParameterNotSet() throws Exception { |
| String queryString = "SELECT * from /portfolios1 LIMIT $1 "; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i < 100; i++) { |
| region.put( i, new Portfolio(i)); |
| } |
| |
| Object[] params = new Object[1]; |
| SelectResults results = (SelectResults)qs.newQuery(queryString).execute(params); |
| assertEquals(region.size(), results.size()); |
| } |
| |
| @Test |
| public void testLimitWithNullParameterObject() throws Exception { |
| String queryString = "SELECT * from /portfolios1 LIMIT $1 "; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i < 100; i++) { |
| region.put( i, new Portfolio(i)); |
| } |
| try { |
| SelectResults results = (SelectResults)qs.newQuery(queryString).execute(); |
| } |
| catch (IllegalArgumentException e) { |
| //we expect an illegal argument exception |
| assertTrue(true); |
| } |
| } |
| |
| //Test to see if bind argument limit is applied correctly for indexed and non indexed |
| //queries. |
| @Test |
| public void testLimitWithParameterForNonAndIndexedQuery() throws Exception { |
| String queryString = "SELECT * from /portfolios1 WHERE shortID = $1 LIMIT $2 "; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i < 100; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = Integer.valueOf(i % 10).shortValue(); |
| region.put( i, p); |
| } |
| |
| Object[] params = new Object[2]; |
| params[0] = 5; |
| int[] limits = {1,5,0,10}; |
| for (int i = 0; i < limits.length; i++) { |
| params[1] = limits[i]; |
| |
| SelectResults results = helpTestIndexForQuery(queryString, "shortID", "/portfolios1", params); |
| assertEquals(limits[i], results.size()); |
| //clear out indexes for next query. |
| qs.removeIndexes(); |
| } |
| |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for ResultBag wrapped by a |
| * SelectResults |
| * |
| * Tests ResultBag behaviour |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryForResultBag() { |
| try { |
| Query query; |
| SelectResults result; |
| String queryString = "SELECT DISTINCT * FROM /portfolios pf WHERE pf.ID > 0 limit 5"; |
| query = qs.newQuery(queryString); |
| final int[] num = new int[1]; |
| num[0] = 0; |
| QueryObserver old = QueryObserverHolder |
| .setInstance(new QueryObserverAdapter() { |
| public void afterIterationEvaluation(Object result) { |
| num[0] += 1; |
| } |
| }); |
| result = (SelectResults)query.execute(); |
| assertEquals(5, num[0]); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(5, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(5, wrapper.asSet().size()); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for ResultBag wrapped by a |
| * SelectResults . This test contains projection attributes. Since |
| * the attribute is unique every time, the limit will be satisfied with first |
| * 5 iterations |
| * |
| * Tests ResultBag behaviour |
| * |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryForResultBagWithProjectionAttribute() { |
| try { |
| Query query; |
| SelectResults result; |
| String queryString = "SELECT DISTINCT pf.ID FROM /portfolios pf WHERE pf.ID > 0 limit 5"; |
| query = qs.newQuery(queryString); |
| final int[] num = new int[1]; |
| num[0] = 0; |
| QueryObserver old = QueryObserverHolder |
| .setInstance(new QueryObserverAdapter() { |
| public void afterIterationEvaluation(Object result) { |
| num[0] += 1; |
| } |
| }); |
| result = (SelectResults)query.execute(); |
| assertEquals(5, num[0]); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(5, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(5, wrapper.asSet().size()); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for ResultBag wrapped by a |
| * SelectResults if the iteration included duplicate elements. If |
| * the distinct clause is present then duplicate elements even if satisfying |
| * the where clause should not be considered as part of the resultset as |
| * distinct will eliminate them |
| * |
| * Tests ResultBag behaviour |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryWithDuplicatesInIterationForResultBag() { |
| try { |
| Region region1 = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| // Add 5 pairs of same Object starting from 11 to 20 |
| for (int i = 11; i < 21;) { |
| region1.put(Integer.toString(i), new Portfolio(i)); |
| region1.put(Integer.toString(i + 1), new Portfolio(i)); |
| i += 2; |
| } |
| Query query; |
| SelectResults result; |
| final int[] num = new int[1]; |
| final int[] numRepeat = new int[1]; |
| numRepeat[0] = 0; |
| final Set data = new HashSet(); |
| num[0] = 0; |
| // In the worst possible case all the unique values come in |
| // consecutive order & hence only 5 iterations will yield the |
| // result |
| QueryObserver old = QueryObserverHolder |
| .setInstance(new QueryObserverAdapter() { |
| public void afterIterationEvaluation(Object result) { |
| num[0] += 1; |
| } |
| |
| public void beforeIterationEvaluation(CompiledValue ritr, |
| Object currObject) { |
| if (data.contains(currObject)) { |
| numRepeat[0] += 1; |
| } |
| else { |
| data.add(currObject); |
| } |
| } |
| |
| }); |
| String queryString = "SELECT DISTINCT * FROM /portfolios1 pf WHERE pf.ID > 10 limit 5"; |
| query = qs.newQuery(queryString); |
| result = (SelectResults)query.execute(); |
| assertEquals((5 + numRepeat[0]), num[0]); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(5, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(5, wrapper.asSet().size()); |
| |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for ResultBag wrapped by a |
| * SelectResults if the iteration included duplicate elements. If |
| * the distinct clause is present then duplicate elements even if satisfying |
| * the where clause should not be considered as part as distinct will |
| * eliminate them. This test validates the above behaviour if projection |
| * sttribute is present and the projection attribute may be duplicate |
| * |
| * Tests ResultBag behaviour |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryWithDuplicatesInIterationWithProjectionAttributeForResultBag() { |
| try { |
| Region region1 = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| // Add 5 pairs of same Object starting from 11 to 20 |
| for (int i = 11; i < 21;) { |
| region1.put(Integer.toString(i), new Portfolio(i)); |
| region1.put(Integer.toString(i + 1), new Portfolio(i)); |
| i += 2; |
| } |
| Query query; |
| SelectResults result; |
| final int[] num = new int[1]; |
| num[0] = 0; |
| final int[] numRepeat = new int[1]; |
| numRepeat[0] = 0; |
| final Set data = new HashSet(); |
| QueryObserver old = QueryObserverHolder |
| .setInstance(new QueryObserverAdapter() { |
| public void afterIterationEvaluation(Object result) { |
| num[0] += 1; |
| } |
| |
| public void beforeIterationEvaluation(CompiledValue ritr, |
| Object currObject) { |
| if (data.contains(currObject)) { |
| numRepeat[0] += 1; |
| } |
| else { |
| data.add(currObject); |
| } |
| } |
| }); |
| String queryString = "SELECT DISTINCT pf.ID FROM /portfolios1 pf WHERE pf.ID > 10 limit 5"; |
| query = qs.newQuery(queryString); |
| result = (SelectResults)query.execute(); |
| assertEquals((5 + numRepeat[0]), num[0]); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(5, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(5, wrapper.asSet().size()); |
| |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for StructBag wrapped by a |
| * SelectResults . This test contains projection attributes. Since |
| * the attribute is unique every time, the limit will be satisfied with first |
| * 5 iterations |
| * |
| * Tests StructBag behaviour |
| * |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryForStructBagWithProjectionAttribute() { |
| try { |
| Query query; |
| SelectResults result; |
| query = qs |
| .newQuery("SELECT DISTINCT pf.ID, pf.createTime FROM /portfolios pf WHERE pf.ID > 0 limit 5"); |
| final int[] num = new int[1]; |
| num[0] = 0; |
| QueryObserver old = QueryObserverHolder |
| .setInstance(new QueryObserverAdapter() { |
| public void afterIterationEvaluation(Object result) { |
| num[0] += 1; |
| } |
| }); |
| result = (SelectResults)query.execute(); |
| assertEquals(5, num[0]); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(5, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(5, wrapper.asSet().size()); |
| assertTrue(wrapper.getCollectionType().getElementType() instanceof StructType); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for StructBag wrapped by a |
| * SelectResults |
| * |
| * Tests StructBag behaviour |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryForStructBag() { |
| try { |
| Query query; |
| SelectResults result; |
| String queryString = "SELECT DISTINCT * FROM /portfolios pf, pf.positions.values WHERE pf.ID > 0 limit 5"; |
| query = qs.newQuery(queryString); |
| final int[] num = new int[1]; |
| num[0] = 0; |
| QueryObserver old = QueryObserverHolder |
| .setInstance(new QueryObserverAdapter() { |
| public void afterIterationEvaluation(Object result) { |
| num[0] += 1; |
| } |
| }); |
| result = (SelectResults)query.execute(); |
| assertEquals(5, num[0]); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(5, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(5, wrapper.asSet().size()); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for StructBag wrapped by a |
| * SelectResults |
| * |
| * Tests StructBag behaviour |
| */ |
| public void xtestLimitQueryForStructBagWithRangeIndex() { |
| try { |
| Query query; |
| SelectResults result; |
| String queryString = "SELECT * FROM /portfolios pf, pf.positions.values pos WHERE pf.ID > 1 AND pos.secId = 'GOOG' limit 1"; |
| query = qs.newQuery(queryString); |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| Index index = qs.createIndex("idIndex", "pf.ID", "/portfolios pf"); |
| Index posindex = qs.createIndex("posIndex", "pos.secId", "/portfolios pf, pf.positions.values pos"); |
| assertNotNull(index); |
| assertNotNull(posindex); |
| result = (SelectResults)query.execute(); |
| assertEquals(1, result.size()); |
| assertFalse(observer.limitAppliedAtIndex); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for StructBag wrapped by a |
| * SelectResults if the iteration included duplicate elements. If |
| * the distinct clause is present then duplicate elements even if satisfying |
| * the where clause should not be considered as part as distinct will |
| * eliminate them. This test validates the above behaviour if projection |
| * attribute is present and the projection attribute may be duplicate |
| * |
| * Tests StructBag behaviour |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryWithDuplicatesInIterationWithProjectionAttributeForStructBag() { |
| try { |
| Region region1 = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| // Add 5 pairs of same Object starting from 11 to 20 |
| for (int i = 11; i < 21;) { |
| region1.put(Integer.toString(i), new Portfolio(i)); |
| region1.put(Integer.toString(i + 1), new Portfolio(i)); |
| i += 2; |
| } |
| Query query; |
| SelectResults result; |
| final int[] num = new int[1]; |
| num[0] = 0; |
| final int[] numRepeat = new int[1]; |
| numRepeat[0] = 0; |
| final Set data = new HashSet(); |
| |
| QueryObserver old = QueryObserverHolder |
| .setInstance(new QueryObserverAdapter() { |
| public void afterIterationEvaluation(Object result) { |
| num[0] += 1; |
| } |
| |
| public void beforeIterationEvaluation(CompiledValue ritr, |
| Object currObject) { |
| if (data.contains(currObject)) { |
| numRepeat[0] += 1; |
| } |
| else { |
| data.add(currObject); |
| } |
| } |
| }); |
| String queryString = "SELECT DISTINCT pf.ID , pf.createTime FROM /portfolios1 pf WHERE pf.ID > 10 limit 5"; |
| query = qs.newQuery(queryString); |
| result = (SelectResults)query.execute(); |
| assertEquals((5 + numRepeat[0]), num[0]); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(5, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(5, wrapper.asSet().size()); |
| |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for StructBag wrapped by a |
| * SelectResults if the iteration included duplicate elements. If |
| * the distinct clause is present then duplicate elements even if satisfying |
| * the where clause should not be considered as part of the resultset as |
| * distinct will eliminate them |
| * |
| * Tests StructBag behaviour |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryWithDuplicatesInIterationForStructBag() { |
| try { |
| Region region1 = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| // Add 5 pairs of same Object starting from 11 to 20 |
| for (int i = 11; i < 21;) { |
| region1.put(Integer.toString(i), new Portfolio(i)); |
| region1.put(Integer.toString(i + 1), new Portfolio(i)); |
| i += 2; |
| } |
| Query query; |
| SelectResults result; |
| final int[] num = new int[1]; |
| num[0] = 0; |
| final int[] numRepeat = new int[1]; |
| numRepeat[0] = 0; |
| final Set data = new HashSet(); |
| QueryObserver old = QueryObserverHolder |
| .setInstance(new QueryObserverAdapter() { |
| public void afterIterationEvaluation(Object result) { |
| num[0] += 1; |
| } |
| |
| public void beforeIterationEvaluation(CompiledValue ritr, |
| Object currObject) { |
| if (data.contains(currObject)) { |
| numRepeat[0] += 1; |
| } |
| else if (currObject instanceof Portfolio) { |
| data.add(currObject); |
| } |
| } |
| }); |
| String queryString = "SELECT DISTINCT * FROM /portfolios1 pf, pf.collectionHolderMap.keySet WHERE pf.ID > 10 limit 20"; |
| query = qs.newQuery(queryString); |
| result = (SelectResults)query.execute(); |
| assertEquals((20 + 4 * numRepeat[0]), num[0]); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(20, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(20, wrapper.asSet().size()); |
| |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| //Asif:Test the index results behaviour also |
| |
| //Shobhit: Testing the Limit behavior now with indexes for all above test cases. |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for ResultBag wrapped by a |
| * SelectResults |
| * |
| * Tests ResultBag behaviour |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryForResultBagWithIndex() { |
| try { |
| Query query; |
| SelectResults result; |
| String queryString = "SELECT DISTINCT * FROM /portfolios pf WHERE pf.ID > 0 limit 5"; |
| query = qs.newQuery(queryString); |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| Index index = qs.createIndex("idIndex", "pf.ID", "/portfolios pf"); |
| assertNotNull(index); |
| result = (SelectResults)query.execute(); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(5, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(5, wrapper.asSet().size()); |
| assertTrue(observer.limitAppliedAtIndex); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for ResultBag wrapped by a |
| * SelectResults . This test contains projection attributes. Since |
| * the attribute is unique every time, the limit will be satisfied with first |
| * 5 iterations |
| * |
| * Tests ResultBag behaviour |
| * |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryForResultBagWithProjectionAttributeWithIndex() { |
| try { |
| Query query; |
| SelectResults result; |
| String queryString = "SELECT DISTINCT pf.ID FROM /portfolios pf WHERE pf.ID > 0 limit 5"; |
| query = qs.newQuery(queryString); |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| Index index = qs.createIndex("idIndex", "pf.ID", "/portfolios pf"); |
| assertNotNull(index); |
| |
| result = (SelectResults)query.execute(); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(5, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(5, wrapper.asSet().size()); |
| assertTrue(observer.limitAppliedAtIndex); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for ResultBag wrapped by a |
| * SelectResults if the iteration included duplicate elements. If |
| * the distinct clause is present then duplicate elements even if satisfying |
| * the where clause should not be considered as part of the resultset as |
| * distinct will eliminate them |
| * |
| * Tests ResultBag behaviour |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryWithDuplicatesInIterationForResultBagWithIndex() { |
| try { |
| Region region1 = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| // Add 5 pairs of same Object starting from 11 to 20 |
| for (int i = 11; i < 21;) { |
| region1.put(Integer.toString(i), new Portfolio(i)); |
| region1.put(Integer.toString(i + 1), new Portfolio(i)); |
| i += 2; |
| } |
| Query query; |
| SelectResults result; |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| Index index = qs.createIndex("idIndex", "pf.ID", "/portfolios1 pf"); |
| assertNotNull(index); |
| |
| String queryString = "SELECT DISTINCT * FROM /portfolios1 pf WHERE pf.ID > 10 limit 5"; |
| query = qs.newQuery(queryString); |
| result = (SelectResults)query.execute(); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(5, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(5, wrapper.asSet().size()); |
| assertTrue(observer.limitAppliedAtIndex); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for ResultBag wrapped by a |
| * SelectResults if the iteration included duplicate elements. If |
| * the distinct clause is present then duplicate elements even if satisfying |
| * the where clause should not be considered as part as distinct will |
| * eliminate them. This test validates the above behaviour if projection |
| * sttribute is present and the projection attribute may be duplicate |
| * |
| * Tests ResultBag behaviour |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryWithDuplicatesInIterationWithProjectionAttributeForResultBagWithIndex() { |
| try { |
| Region region1 = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| // Add 5 pairs of same Object starting from 11 to 20 |
| for (int i = 11; i < 21;) { |
| region1.put(Integer.toString(i), new Portfolio(i)); |
| region1.put(Integer.toString(i + 1), new Portfolio(i)); |
| i += 2; |
| } |
| Query query; |
| SelectResults result; |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| Index index = qs.createIndex("idIndex", "pf.ID", "/portfolios1 pf"); |
| assertNotNull(index); |
| String queryString = "SELECT DISTINCT pf.ID FROM /portfolios1 pf WHERE pf.ID > 10 limit 5"; |
| query = qs.newQuery(queryString); |
| result = (SelectResults)query.execute(); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(5, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(5, wrapper.asSet().size()); |
| assertTrue(observer.limitAppliedAtIndex); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for StructBag wrapped by a |
| * SelectResults . This test contains projection attributes. Since |
| * the attribute is unique every time, the limit will be satisfied with first |
| * 5 iterations |
| * |
| * Tests StructBag behaviour |
| * |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryForStructBagWithProjectionAttributeWithIndex() { |
| try { |
| Query query; |
| SelectResults result; |
| query = qs |
| .newQuery("SELECT DISTINCT pf.ID, pf.createTime FROM /portfolios pf WHERE pf.ID > 0 limit 5"); |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| Index index = qs.createIndex("idIndex", "pf.ID", "/portfolios pf"); |
| assertNotNull(index); |
| result = (SelectResults)query.execute(); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(5, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(5, wrapper.asSet().size()); |
| assertTrue(wrapper.getCollectionType().getElementType() instanceof StructType); |
| assertTrue(observer.limitAppliedAtIndex); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for StructBag wrapped by a |
| * SelectResults |
| * |
| * Tests StructBag behaviour |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryForStructBagWithIndex() { |
| try { |
| Query query; |
| SelectResults result; |
| String queryString = "SELECT DISTINCT * FROM /portfolios pf, pf.positions.values WHERE pf.ID > 0 limit 5"; |
| query = qs.newQuery(queryString); |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| Index index = qs.createIndex("idIndex", "pf.ID", "/portfolios pf, pf.positions.values"); |
| assertNotNull(index); |
| result = (SelectResults)query.execute(); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(5, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(5, wrapper.asSet().size()); |
| //currently this is false because we disabled limit application at the range index level |
| assertFalse(observer.limitAppliedAtIndex); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for StructBag wrapped by a |
| * SelectResults if the iteration included duplicate elements. If |
| * the distinct clause is present then duplicate elements even if satisfying |
| * the where clause should not be considered as part as distinct will |
| * eliminate them. This test validates the above behaviour if projection |
| * attribute is present and the projection attribute may be duplicate |
| * |
| * Tests StructBag behaviour |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryWithDuplicatesInIterationWithProjectionAttributeForStructBagWithIndex() { |
| try { |
| Region region1 = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| // Add 5 pairs of same Object starting from 11 to 20 |
| for (int i = 11; i < 21;) { |
| region1.put(Integer.toString(i), new Portfolio(i)); |
| region1.put(Integer.toString(i + 1), new Portfolio(i)); |
| i += 2; |
| } |
| Query query; |
| SelectResults result; |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| Index index = qs.createIndex("idIndex", "pf.ID", "/portfolios1 pf"); |
| assertNotNull(index); |
| String queryString = "SELECT DISTINCT pf.ID , pf.createTime FROM /portfolios1 pf WHERE pf.ID > 10 limit 5"; |
| query = qs.newQuery(queryString); |
| result = (SelectResults)query.execute(); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(5, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(5, wrapper.asSet().size()); |
| assertTrue(observer.limitAppliedAtIndex); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for Iter evaluated query with distinct clause |
| * This tests the basic limit functionality for StructBag wrapped by a |
| * SelectResults if the iteration included duplicate elements. If |
| * the distinct clause is present then duplicate elements even if satisfying |
| * the where clause should not be considered as part of the resultset as |
| * distinct will eliminate them |
| * |
| * Tests StructBag behaviour |
| */ |
| @Test |
| public void testLimitDistinctIterEvaluatedQueryWithDuplicatesInIterationForStructBagWithIndex() { |
| try { |
| Region region1 = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| // Add 5 pairs of same Object starting from 11 to 20 |
| for (int i = 11; i < 21;) { |
| region1.put(Integer.toString(i), new Portfolio(i)); |
| region1.put(Integer.toString(i + 1), new Portfolio(i)); |
| i += 2; |
| } |
| Query query; |
| SelectResults result; |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| Index index = qs.createIndex("idIndex", "pf.ID", "/portfolios1 pf, pf.collectionHolderMap.keySet"); |
| assertNotNull(index); |
| |
| String queryString = "SELECT DISTINCT * FROM /portfolios1 pf, pf.collectionHolderMap.keySet WHERE pf.ID > 10 limit 20"; |
| query = qs.newQuery(queryString); |
| result = (SelectResults)query.execute(); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(20, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(20, wrapper.asSet().size()); |
| //currently this is false because we disabled limit application at the range index level |
| assertFalse(observer.limitAppliedAtIndex); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| /** |
| * Tests the limit functionality for query which has three conditions with AND |
| * operator and two conditions can be evaluated using index but not the 3rd one. |
| * |
| * This tests the limit application on intermediate results from Index which should not |
| * be true in this test. |
| * |
| */ |
| @Test |
| public void testLimitDistinctQueryWithTwoCondButOneIndex() { |
| try { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 1; i < 100; i++) { |
| Portfolio p = new Portfolio(i); |
| if (i < 50) p.status = "active"; |
| region.put(Integer.toString(i), p); |
| } |
| |
| //Create Index on ID |
| Index index = qs.createIndex("idIndex", "ID", "/portfolios1"); |
| assertNotNull(index); |
| String queryString = "select DISTINCT * from /portfolios1 where status ='inactive' AND (ID > 0 AND ID < 100) limit 10"; |
| query = qs.newQuery(queryString); |
| result = (SelectResults)query.execute(); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(10, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(10, wrapper.asSet().size()); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| @Test |
| public void testLimitDistinctQueryWithTwoCondWithTwoIndex() { |
| try { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 1; i < 100; i++) { |
| Portfolio p = new Portfolio(i); |
| if (i < 50) p.status = "active"; |
| region.put(Integer.toString(i), p); |
| } |
| |
| //Create Index on ID |
| Index index = qs.createIndex("idIndex", "ID", "/portfolios1"); |
| assertNotNull(index); |
| index = qs.createIndex("statusIndex", "status", "/portfolios1"); |
| assertNotNull(index); |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| String queryString = "select DISTINCT * from /portfolios1 where status ='inactive' AND (ID > 0 AND ID < 100) limit 10"; |
| query = qs.newQuery(queryString); |
| result = (SelectResults)query.execute(); |
| assertTrue(result instanceof SelectResults); |
| assertEquals(10, result.size()); |
| SelectResults wrapper = (SelectResults)result; |
| assertEquals(10, wrapper.asSet().size()); |
| assertFalse(observer.limitAppliedAtIndex && observer.indexName.equals("idIndex")); |
| assertTrue(observer.limitAppliedAtIndex && observer.indexName.equals("statusIndex")); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| @Test |
| public void testLimitNonDistinctQueryWithTwoCondButOneIndex() { |
| try { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 1; i < 100; i++) { |
| Portfolio p = new Portfolio(i); |
| if (i < 50) p.status = "active"; |
| region.put(Integer.toString(i), p); |
| } |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| //Create Index on ID |
| Index index = qs.createIndex("idIndex", "ID", "/portfolios1"); |
| assertNotNull(index); |
| String[] queryString = new String[] { |
| "select * from /portfolios1 where status ='inactive' AND (ID > 0 AND ID < 100) limit 10", |
| "select * from /portfolios1 where (status > 'inactiva' AND status < 'xyz') AND (ID > 0 AND ID < 100) limit 10", |
| "select * from /portfolios1 where (status > 'inactiva' AND status < 'xyz') AND (ID > 0 AND ID < 100) AND (\"type\"='type1' OR \"type\"='type2') limit 10",}; |
| for (String qstr: queryString) { |
| query = qs.newQuery(qstr); |
| result = (SelectResults)query.execute(); |
| assertEquals(10, result.size()); |
| assertFalse(observer.limitAppliedAtIndex); |
| } |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| @Test |
| public void testLimitNonDistinctQueryWithTwoCondTwoIndex() { |
| try { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 1; i < 100; i++) { |
| Portfolio p = new Portfolio(i); |
| if (i < 50) p.status = "active"; |
| region.put(Integer.toString(i), p); |
| } |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| //Create Index on ID |
| Index index = qs.createIndex("idIndex", "ID", "/portfolios1"); |
| assertNotNull(index); |
| index = qs.createIndex("statusIndex", "status", "/portfolios1"); |
| assertNotNull(index); |
| String[] queryString = new String[] { |
| "select * from /portfolios1 where status ='inactive' AND (ID > 0 AND ID < 100) limit 10", |
| }; |
| for (String qstr: queryString) { |
| query = qs.newQuery(qstr); |
| result = (SelectResults)query.execute(); |
| assertEquals(10, result.size()); |
| assertTrue(observer.limitAppliedAtIndex && observer.indexName.equals("statusIndex")); |
| } |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| @Test |
| public void testLimitNonDistinctQueryWithTwoRangeCondTwoIndex() { |
| try { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 1; i < 100; i++) { |
| Portfolio p = new Portfolio(i); |
| if (i < 50) p.status = "active"; |
| region.put(Integer.toString(i), p); |
| } |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| //Create Index on ID |
| Index index = qs.createIndex("idIndex", "ID", "/portfolios1"); |
| assertNotNull(index); |
| index = qs.createIndex("statusIndex", "status", "/portfolios1"); |
| assertNotNull(index); |
| String[] queryString = new String[] { |
| "select * from /portfolios1 where (status > 'inactiva' AND status < 'xyz') AND (ID > 70 AND ID < 100) limit 10", |
| "select * from /portfolios1 where (status > 'inactiva' AND status < 'xyz') AND (ID > 60 AND ID < 100) AND (\"type\"='type1' OR \"type\"='type2') limit 10",}; |
| for (String qstr: queryString) { |
| query = qs.newQuery(qstr); |
| result = (SelectResults)query.execute(); |
| assertEquals(10, result.size()); |
| assertFalse(observer.limitAppliedAtIndex); |
| } |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| @Test |
| public void testLimitDistinctQueryWithDuplicateValues() { |
| try { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 1; i < 10; i++) { |
| Portfolio p = new Portfolio(i); |
| if (i == 2) p = new Portfolio(1); |
| region.put(Integer.toString(i), p); |
| } |
| |
| //Create Index on ID |
| Index index = qs.createIndex("idIndex", "ID", "/portfolios1"); |
| assertNotNull(index); |
| String queryString = "select DISTINCT * from /portfolios1 where status ='inactive' AND ID > 0 limit 2"; |
| query = qs.newQuery(queryString); |
| result = (SelectResults)query.execute(); |
| assertEquals(2, result.size()); |
| } |
| catch (Exception e) { |
| CacheUtils.getLogger().error(e); |
| fail(e.toString()); |
| } |
| finally { |
| QueryObserverHolder.setInstance(new QueryObserverAdapter()); |
| } |
| } |
| |
| @Test |
| public void testNotApplyingLimitAtIndexLevelForMultiIndexAndClauseUsage() throws Exception { |
| //try { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 15; i > 0; i--) { |
| Portfolio p = new Portfolio(i); |
| //CacheUtils.log(p); |
| p.positions.clear(); |
| p.positions.put("IBM", new Position("IBM", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| String queryString = "<trace>SELECT * FROM /portfolios1 P, P.positions.values POS WHERE P.ID > 5 AND POS.secId = 'IBM' LIMIT 5"; |
| query = qs.newQuery(queryString); |
| SelectResults resultsNoIndex = (SelectResults) query.execute(); |
| |
| //Create Index on ID and secId |
| Index secIndex = qs.createIndex("secIdIndex", "pos.secId", "/portfolios1 p, p.positions.values pos"); |
| Index idIndex = qs.createIndex("idIndex", IndexType.FUNCTIONAL, "P.ID", "/portfolios1 P"); |
| |
| assertNotNull(secIndex); |
| assertNotNull(idIndex); |
| SelectResults resultsWithIndex = (SelectResults) query.execute(); |
| |
| assertEquals(resultsNoIndex.size(), resultsWithIndex.size()); |
| } |
| |
| /* |
| This test shows an error with order by. Limit does not affect this and will enable this test |
| after the bug for order by is logged and fixed |
| @Test |
| public void testNotApplyingLimitAtIndexLevelForMultiIndexAndClauseUsageWithOrderBy() throws Exception { |
| //try { |
| Query query; |
| SelectResults result; |
| int limit = 25; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 30; i > 0; i--) { |
| Portfolio p = new Portfolio(i); |
| p.positions.clear(); |
| p.positions.put("IBM", new Position("IBM", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| String queryString = "<trace>SELECT distinct P FROM /portfolios1 P, P.positions.values POS WHERE P.ID > 5 AND POS.secId = 'IBM' ORDER BY P.ID"; |
| query = qs.newQuery(queryString); |
| SelectResults resultsNoIndex = (SelectResults) query.execute(); |
| |
| //Create Index on ID and secId |
| //Index secIndex = qs.createIndex("secIdIndex", "pos.secId", "/portfolios1 p, p.positions.values pos"); |
| Index idIndex = qs.createIndex("idIndex", IndexType.FUNCTIONAL, "P.ID", "/portfolios1 P"); |
| |
| //assertNotNull(secIndex); |
| assertNotNull(idIndex); |
| assertTrue(idIndex instanceof CompactRangeIndex); |
| SelectResults resultsWithIndex = (SelectResults) query.execute(); |
| |
| assertEquals(resultsNoIndex.size(), resultsWithIndex.size()); |
| assertEquals(limit, resultsWithIndex.size()); |
| |
| int expectedId = 6; |
| Iterator iterator = resultsNoIndex.iterator(); |
| while (iterator.hasNext()) { |
| Portfolio p = (Portfolio) iterator.next(); |
| assertEquals(expectedId++, p.ID); |
| } |
| |
| //check order by results |
| expectedId = 6; |
| iterator = resultsWithIndex.iterator(); |
| while (iterator.hasNext()) { |
| Portfolio p = (Portfolio) iterator.next(); |
| assertEquals(expectedId++, p.ID); |
| } |
| } |
| */ |
| |
| |
| @Test |
| public void testNotLimitAtIndexLevelForMultiSingleIndexAndClauseUsage() throws Exception { |
| //try { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 15; i > 0; i--) { |
| Portfolio p = new Portfolio(i); |
| //CacheUtils.log(p); |
| p.positions.clear(); |
| p.positions.put("IBM", new Position("IBM", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| String queryString = "<trace>SELECT * FROM /portfolios1 P, P.positions.values POS WHERE P.ID > 4 and P.ID < 11 AND P.ID != 8 LIMIT 5"; |
| query = qs.newQuery(queryString); |
| SelectResults resultsNoIndex = (SelectResults) query.execute(); |
| |
| //Create Index on ID and secId |
| Index secIndex = qs.createIndex("secIdIndex", "pos.secId", "/portfolios1 p, p.positions.values pos"); |
| Index idIndex = qs.createIndex("idIndex", IndexType.FUNCTIONAL, "P.ID", "/portfolios1 P, P.positions.values pos"); |
| |
| //assertNotNull(secIndex); |
| assertNotNull(idIndex); |
| SelectResults resultsWithIndex = (SelectResults) query.execute(); |
| |
| assertEquals(resultsNoIndex.size(), resultsWithIndex.size()); |
| } |
| |
| |
| @Test |
| public void testNotLimitAtIndexLevelForMultiSingleIndexOrClauseUsage() throws Exception { |
| //try { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 15; i > 0; i--) { |
| Portfolio p = new Portfolio(i); |
| //CacheUtils.log(p); |
| p.positions.clear(); |
| p.positions.put("IBM", new Position("IBM", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| String queryString = "<trace>SELECT * FROM /portfolios1 P, P.positions.values POS WHERE P.ID < 4 OR P.ID > 11 AND P.ID != 13 LIMIT 5"; |
| query = qs.newQuery(queryString); |
| SelectResults resultsNoIndex = (SelectResults) query.execute(); |
| |
| //Create Index on ID and secId |
| Index secIndex = qs.createIndex("secIdIndex", "pos.secId", "/portfolios1 p, p.positions.values pos"); |
| Index idIndex = qs.createIndex("idIndex", IndexType.FUNCTIONAL, "P.ID", "/portfolios1 P, P.positions.values pos"); |
| |
| //assertNotNull(secIndex); |
| assertNotNull(idIndex); |
| SelectResults resultsWithIndex = (SelectResults) query.execute(); |
| |
| assertEquals(resultsNoIndex.size(), resultsWithIndex.size()); |
| } |
| |
| @Test |
| public void testLimitJunctionOnCompactRangeIndexedFieldWithAndClauseOnNonIndexedField() throws Exception { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i <= 15; i++) { |
| Portfolio p = new Portfolio(i); |
| p.positions.clear(); |
| p.positions.put("IBM", new Position("IBM", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| for (int i = 16; i < 21; i++) { |
| Portfolio p = new Portfolio(i); |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| //Create Index on ID |
| Index idIndex = qs.createIndex("idIndex", IndexType.FUNCTIONAL, "P.ID", "/portfolios1 P"); |
| |
| String queryString = "SELECT * FROM /portfolios1 P, P.positions.values POS WHERE P.ID > 9 AND P.ID < 21 AND POS.secId = 'VMW' LIMIT 5"; |
| query = qs.newQuery(queryString); |
| |
| assertNotNull(idIndex); |
| SelectResults resultsWithIndex = (SelectResults) query.execute(); |
| assertFalse(observer.limitAppliedAtIndex); |
| assertEquals(5, resultsWithIndex.size()); |
| } |
| |
| @Test |
| public void testLimitJunctionOnRangeIndexedFieldWithAndClauseOnNonIndexedField() throws Exception { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i <= 15; i++) { |
| Portfolio p = new Portfolio(i); |
| p.positions.clear(); |
| p.positions.put("IBM", new Position("IBM", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| for (int i = 16; i < 21; i++) { |
| Portfolio p = new Portfolio(i); |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| //Create Index on ID |
| Index idIndex = qs.createIndex("idIndex", IndexType.FUNCTIONAL, "P.ID", "/portfolios1 P, P.positions.values POS"); |
| |
| String queryString = "SELECT * FROM /portfolios1 P, P.positions.values POS WHERE P.ID > 9 AND P.ID < 21 AND POS.secId = 'VMW' LIMIT 5"; |
| query = qs.newQuery(queryString); |
| |
| assertNotNull(idIndex); |
| SelectResults resultsWithIndex = (SelectResults) query.execute(); |
| assertFalse(observer.limitAppliedAtIndex); |
| assertEquals(5, resultsWithIndex.size()); |
| } |
| |
| //This is one where we are no longer applying index due to multiple index usage but old code would. should take a look and see how/ or why old code can |
| @Test |
| public void testLimitJunctionOnRangeIndexedFieldWithAndClauseCompactRangeIndexedField() throws Exception { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i <= 15; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = 1; |
| p.positions.clear(); |
| p.positions.put("IBM", new Position("IBM", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| for (int i = 21; i < 100; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = 2; |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| for (int i = 16; i < 21; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = 2; |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| //MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| //QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| //Create Index on ID |
| Index idIndex = qs.createIndex("idIndex", IndexType.FUNCTIONAL, "P.ID", "/portfolios1 P, P.positions.values POS"); |
| Index shortIdIndex = qs.createIndex("shortIdIndex", IndexType.FUNCTIONAL, "P.shortID", "/portfolios1 P"); |
| |
| String queryString = "<trace>SELECT * FROM /portfolios1 P WHERE P.ID > 9 AND P.ID < 21 AND P.shortID = 2 LIMIT 5"; |
| query = qs.newQuery(queryString); |
| |
| assertNotNull(idIndex); |
| SelectResults resultsWithIndex = (SelectResults) query.execute(); |
| //assertFalse(observer.limitAppliedAtIndex); |
| assertEquals(5, resultsWithIndex.size()); |
| } |
| @Test |
| public void testLimitJunctionOnRangeIndexedFieldWithAndClauseRangeIndexedField() throws Exception { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i <= 15; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = 1; |
| p.positions.clear(); |
| p.positions.put("IBM", new Position("IBM", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| for (int i = 21; i < 100; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = 2; |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| for (int i = 16; i < 21; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = 2; |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| //Create Index on ID |
| Index idIndex = qs.createIndex("idIndex", IndexType.FUNCTIONAL, "P.ID", "/portfolios1 P, P.positions.values POS"); |
| Index shortIdIndex = qs.createIndex("shortIdIndex", IndexType.FUNCTIONAL, "P.shortID", "/portfolios1 P, P.positions.values POS"); |
| |
| String queryString = "SELECT * FROM /portfolios1 P WHERE P.ID > 9 AND P.ID < 21 AND P.shortID = 2 LIMIT 5"; |
| query = qs.newQuery(queryString); |
| |
| assertNotNull(idIndex); |
| SelectResults resultsWithIndex = (SelectResults) query.execute(); |
| //assertFalse(observer.limitAppliedAtIndex); |
| assertEquals(5, resultsWithIndex.size()); |
| } |
| |
| @Test |
| public void testLimitOnEqualsCompactRangeIndexedFieldWithAndClauseNonIndexedField() throws Exception { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i <= 15; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = 1; |
| p.positions.clear(); |
| p.positions.put("IBM", new Position("IBM", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| for (int i = 16; i < 21; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = 2; |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| //Create Index on ID |
| Index idIndex = qs.createIndex("idIndex", "P.ID", "/portfolios1 P"); |
| |
| String queryString = "SELECT * FROM /portfolios1 P WHERE P.ID = 10 AND P.shortID = 2 LIMIT 5"; |
| query = qs.newQuery(queryString); |
| |
| assertNotNull(idIndex); |
| SelectResults resultsWithIndex = (SelectResults) query.execute(); |
| assertTrue(observer.limitAppliedAtIndex); |
| assertEquals(5, resultsWithIndex.size()); |
| } |
| |
| |
| //This is one where the old code could apply limit but we do not. Should investigate... index being used is on ShortId |
| @Test |
| public void testLimitOnEqualsCompactRangeIndexedFieldWithAndClauseCompactRangeIndexedField() throws Exception { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i <= 15; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = 1; |
| p.positions.clear(); |
| p.positions.put("IBM", new Position("IBM", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| for (int i = 16; i < 20; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = 2; |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| for (int i = 20; i < 24; i++) { |
| Portfolio p = new Portfolio(11); |
| p.shortID = 2; |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| for (int i = 24; i < 28; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = (short) (i % 3); |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| for (int i = 100; i < 200; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = 0; |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| //MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| // QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| //Create Index on ID |
| Index idIndex = qs.createIndex("idIndex", "P.ID", "/portfolios1 P"); |
| Index shortIdIndex = qs.createIndex("shortIdIndex", "P.shortID", "/portfolios1 P"); |
| |
| String queryString = "<trace>SELECT * FROM /portfolios1 P WHERE P.ID = 10 AND P.shortID = 2 LIMIT 5"; |
| query = qs.newQuery(queryString); |
| |
| assertNotNull(idIndex); |
| SelectResults resultsWithIndex = (SelectResults) query.execute(); |
| //assertFalse(observer.limitAppliedAtIndex); |
| assertEquals(5, resultsWithIndex.size()); |
| } |
| |
| //This is one where limit is applied at index for old code but we do not apply |
| @Test |
| public void testLimitOnEqualsRangeIndexedFieldWithAndClauseCompactRangeIndexedField() throws Exception { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i <= 15; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = 1; |
| p.positions.clear(); |
| p.positions.put("IBM", new Position("IBM", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| for (int i = 16; i < 21; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = 2; |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| //Create Index on ID |
| Index idIndex = qs.createIndex("idIndex", "P.ID", "/portfolios1 P, P.positions.values POS"); |
| Index shortIdIndex = qs.createIndex("shortIdIndex", "P.shortID", "/portfolios1 P"); |
| |
| String queryString = "SELECT * FROM /portfolios1 P WHERE P.ID = 10 AND P.shortID = 2 LIMIT 5"; |
| query = qs.newQuery(queryString); |
| |
| assertNotNull(idIndex); |
| SelectResults resultsWithIndex = (SelectResults) query.execute(); |
| // assertFalse(observer.limitAppliedAtIndex); |
| assertEquals(5, resultsWithIndex.size()); |
| } |
| |
| |
| // This is one where we do not apply limit at index but old code does |
| @Test |
| public void testLimitOnJunctionWithCompactRangeIndexedFieldWithAndClauseJunctionCompactRangeIndexedField() |
| throws Exception { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i <= 15; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = 1; |
| p.positions.clear(); |
| p.positions.put("IBM", new Position("IBM", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| for (int i = 16; i < 21; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = 2; |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| // Create Index on ID |
| Index idIndex = qs.createIndex("idIndex", "P.ID", "/portfolios1 P"); |
| Index shortIdIndex = qs.createIndex("shortIdIndex", "P.shortID", |
| "/portfolios1 P"); |
| |
| String queryString = "SELECT * FROM /portfolios1 P WHERE P.ID > 9 AND P.ID < 20 AND P.shortID > 1 AND P.shortID < 3 LIMIT 5"; |
| query = qs.newQuery(queryString); |
| |
| assertNotNull(idIndex); |
| SelectResults resultsWithIndex = (SelectResults) query.execute(); |
| // assertFalse(observer.limitAppliedAtIndex); |
| assertEquals(5, resultsWithIndex.size()); |
| } |
| |
| @Test |
| public void testLimitOnJunctionWithCompactRangeIndexedFieldWithAndClauseJunctionNonIndexedField() |
| throws Exception { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i <= 15; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = 1; |
| p.positions.clear(); |
| p.positions.put("IBM", new Position("IBM", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| for (int i = 16; i < 21; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = 2; |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| // Create Index on ID |
| Index idIndex = qs.createIndex("idIndex", "P.ID", "/portfolios1 P"); |
| |
| String queryString = "SELECT * FROM /portfolios1 P WHERE P.ID > 9 AND P.ID < 20 AND P.shortID > 1 AND P.shortID < 3 LIMIT 5"; |
| query = qs.newQuery(queryString); |
| |
| assertNotNull(idIndex); |
| SelectResults resultsWithIndex = (SelectResults) query.execute(); |
| assertFalse(observer.limitAppliedAtIndex); |
| assertEquals(5, resultsWithIndex.size()); |
| } |
| |
| @Test |
| public void testLimitOnCompactRangeIndexedFieldWithAndClauseJunctionNonIndexedField() throws Exception { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i <= 15; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = 1; |
| p.positions.clear(); |
| p.positions.put("IBM", new Position("IBM", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| for (int i = 16; i < 21; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = 2; |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| //Create Index on ID |
| Index idIndex = qs.createIndex("idIndex", "P.ID", "/portfolios1 P"); |
| |
| String queryString = "SELECT * FROM /portfolios1 P WHERE P.ID = 10 AND P.shortID > 1 AND P.shortID < 3 LIMIT 5"; |
| query = qs.newQuery(queryString); |
| |
| assertNotNull(idIndex); |
| SelectResults resultsWithIndex = (SelectResults) query.execute(); |
| assertTrue(observer.limitAppliedAtIndex); |
| assertEquals(5, resultsWithIndex.size()); |
| } |
| |
| |
| @Test |
| public void testLimitOnJunctionWithCompactRangeIndexedFieldWithAndOnCompactRangeIndexedField() throws Exception { |
| Query query; |
| SelectResults result; |
| Region region = CacheUtils.createRegion("portfolios1", Portfolio.class); |
| for (int i = 0; i <= 15; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = 1; |
| p.positions.clear(); |
| p.positions.put("IBM", new Position("IBM", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| for (int i = 16; i < 21; i++) { |
| Portfolio p = new Portfolio(10); |
| p.shortID = 2; |
| p.positions.clear(); |
| p.positions.put("VMW", new Position("VMW", i)); |
| region.put("KEY" + i, p); |
| } |
| |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserver old = QueryObserverHolder.setInstance(observer); |
| |
| //Create Index on ID |
| Index idIndex = qs.createIndex("idIndex", "P.ID", "/portfolios1 P"); |
| Index shortIdIndex = qs.createIndex("shortIdIndex", "P.shortID", "/portfolios1 P"); |
| |
| String queryString = "SELECT * FROM /portfolios1 P WHERE P.ID > 9 AND P.ID < 20 AND P.shortID = 2 LIMIT 5"; |
| query = qs.newQuery(queryString); |
| |
| assertNotNull(idIndex); |
| SelectResults resultsWithIndex = (SelectResults) query.execute(); |
| //assertFalse(observer.limitAppliedAtIndex); |
| assertEquals(5, resultsWithIndex.size()); |
| } |
| /* |
| * helper method to test against a compact range index |
| * @param query |
| * @throws Exception |
| */ |
| private SelectResults helpTestIndexForQuery(String query, String indexedExpression, String regionPath, Object[] params) throws Exception { |
| QueryService qs = CacheUtils.getQueryService(); |
| MyQueryObserverAdapter observer = new MyQueryObserverAdapter(); |
| QueryObserverHolder.setInstance(observer); |
| SelectResults nonIndexedResults = (SelectResults)qs.newQuery(query).execute(params); |
| assertFalse(observer.indexUsed); |
| |
| qs.createIndex("newIndex", indexedExpression, regionPath); |
| SelectResults indexedResults = (SelectResults)qs.newQuery(query).execute(params); |
| assertEquals(nonIndexedResults.size(), indexedResults.size()); |
| assertTrue(observer.indexUsed); |
| return indexedResults; |
| } |
| |
| class MyQueryObserverAdapter extends QueryObserverAdapter { |
| public boolean limitAppliedAtIndex = false; |
| public String indexName; |
| public boolean indexUsed = false; |
| |
| public void limitAppliedAtIndexLevel(Index index, int limit , Collection indexResult){ |
| this.limitAppliedAtIndex = true; |
| this.indexName = index.getName(); |
| } |
| |
| public void afterIndexLookup(Collection results) { |
| if(results != null){ |
| indexUsed = true; |
| } |
| } |
| }; |
| } |