GEODE-100: Nested count(*) query on pr causes NullPointerException Query object in query execution was being used without being set for nested queries.
Reviewed by agingade Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/6ff83bcd Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/6ff83bcd Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/6ff83bcd Branch: refs/heads/feature/GEODE-77 Commit: 6ff83bcd64a14b2fe731f4468f9ab798f8cc85f7 Parents: 9d79495 Author: Jason Huynh <jhu...@pivotal.io> Authored: Fri Jul 24 13:05:54 2015 -0700 Committer: Jason Huynh <jhu...@pivotal.io> Committed: Fri Jul 24 13:09:17 2015 -0700 ---------------------------------------------------------------------- .../cache/query/internal/CompiledSelect.java | 5 ++-- .../internal/cache/PartitionedRegion.java | 2 +- .../query/partitioned/PRQueryDUnitTest.java | 8 +++--- .../query/partitioned/PRQueryJUnitTest.java | 30 ++++++++++++++++++++ 4 files changed, 38 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6ff83bcd/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledSelect.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledSelect.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledSelect.java index be06404..0b07211 100644 --- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledSelect.java +++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/CompiledSelect.java @@ -23,6 +23,7 @@ import com.gemstone.gemfire.cache.query.FunctionDomainException; import com.gemstone.gemfire.cache.query.Index; import com.gemstone.gemfire.cache.query.NameNotFoundException; import com.gemstone.gemfire.cache.query.NameResolutionException; +import com.gemstone.gemfire.cache.query.Query; import com.gemstone.gemfire.cache.query.QueryInvalidException; import com.gemstone.gemfire.cache.query.QueryInvocationTargetException; import com.gemstone.gemfire.cache.query.QueryService; @@ -360,9 +361,9 @@ public class CompiledSelect extends AbstractCompiledValue { * @param cache the cache the query will be executed in the context of * @return the empty result set of the appropriate type */ - public SelectResults getEmptyResultSet(Object[] parameters, Cache cache) + public SelectResults getEmptyResultSet(Object[] parameters, Cache cache, Query query) throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException { - ExecutionContext context = new QueryExecutionContext(parameters, cache); + ExecutionContext context = new QueryExecutionContext(parameters, cache, query); computeDependencies(context); context.newScope(this.scopeID); context.pushExecCache(scopeID); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6ff83bcd/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java index b11d7f6..c007891 100644 --- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java +++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java @@ -1979,7 +1979,7 @@ public class PartitionedRegion extends LocalRegion implements // this can return a BAG even if it's a DISTINCT select expression, // since the expectation is that the duplicates will be removed at the end SelectResults results = selectExpr - .getEmptyResultSet(parameters, getCache()); + .getEmptyResultSet(parameters, getCache(), query); PartitionedRegionQueryEvaluator prqe = new PartitionedRegionQueryEvaluator(this.getSystem(), this, query, parameters, results, allBuckets); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6ff83bcd/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/partitioned/PRQueryDUnitTest.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/partitioned/PRQueryDUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/partitioned/PRQueryDUnitTest.java index caeac58..5fb711c 100755 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/partitioned/PRQueryDUnitTest.java +++ b/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/partitioned/PRQueryDUnitTest.java @@ -398,7 +398,7 @@ public class PRQueryDUnitTest extends PartitionedRegionDUnitTestCase final DefaultQuery query = (DefaultQuery)getCache().getQueryService() .newQuery("select distinct * from " + pr.getFullPath()); final SelectResults results = query.getSimpleSelect().getEmptyResultSet( - params, getCache()); + params, getCache(), query); // TODO assert this is the correct set of bucket Ids, final HashSet<Integer> buckets = new HashSet<Integer>(); @@ -477,7 +477,7 @@ public class PRQueryDUnitTest extends PartitionedRegionDUnitTestCase for (int q=0; q < queries.length; q++) { Object[] params = new Object[0]; final DefaultQuery query = (DefaultQuery)getCache().getQueryService().newQuery(queries[q]); - final SelectResults results = query.getSimpleSelect().getEmptyResultSet(params, getCache()); + final SelectResults results = query.getSimpleSelect().getEmptyResultSet(params, getCache(), query); // TODO assert this is the correct set of bucket Ids, final HashSet<Integer> buckets = new HashSet<Integer>(); @@ -583,7 +583,7 @@ public class PRQueryDUnitTest extends PartitionedRegionDUnitTestCase for (int q=0; q < queries.length; q++) { Object[] params = new Object[0]; final DefaultQuery query = (DefaultQuery)getCache().getQueryService().newQuery(queries[q]); - final SelectResults results = query.getSimpleSelect().getEmptyResultSet(params, getCache()); + final SelectResults results = query.getSimpleSelect().getEmptyResultSet(params, getCache(), query); // TODO assert this is the correct set of bucket Ids, final HashSet<Integer> buckets = new HashSet<Integer>(); @@ -688,7 +688,7 @@ public class PRQueryDUnitTest extends PartitionedRegionDUnitTestCase final DefaultQuery query = (DefaultQuery)getCache().getQueryService() .newQuery("select distinct * from " + pr.getFullPath()); final SelectResults results = query.getSimpleSelect() - .getEmptyResultSet(params, getCache()); + .getEmptyResultSet(params, getCache(), query); // Fake data loss final HashSet<Integer> buckets = new HashSet<Integer>(); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6ff83bcd/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/partitioned/PRQueryJUnitTest.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/partitioned/PRQueryJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/partitioned/PRQueryJUnitTest.java index 97bf2df..ccc9db2 100644 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/partitioned/PRQueryJUnitTest.java +++ b/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/partitioned/PRQueryJUnitTest.java @@ -10,14 +10,19 @@ package com.gemstone.gemfire.cache.query.partitioned; import static org.junit.Assert.fail; import java.util.HashMap; +import java.util.Iterator; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import com.gemstone.gemfire.LogWriter; +import com.gemstone.gemfire.cache.Cache; import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.RegionShortcut; +import com.gemstone.gemfire.cache.query.CacheUtils; 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.PortfolioData; import com.gemstone.gemfire.internal.Assert; @@ -134,6 +139,31 @@ public class PRQueryJUnitTest } } + @Test + public void testNestedPRQuery() throws Exception { + Cache cache = CacheUtils.getCache(); + QueryService queryService = CacheUtils.getCache().getQueryService(); + Region region = cache.createRegionFactory(RegionShortcut.PARTITION).create("TEST_REGION"); + Query query = queryService.newQuery("SELECT distinct COUNT(*) FROM (SELECT DISTINCT tr.id, tr.domain FROM /TEST_REGION tr)"); + region.put("1", cache.createPdxInstanceFactory("obj1").writeString("id", "1").writeString("domain", "domain1").create()); + region.put("2", cache.createPdxInstanceFactory("obj2").writeString("id", "1").writeString("domain", "domain1").create()); + region.put("3", cache.createPdxInstanceFactory("obj3").writeString("id", "1").writeString("domain", "domain1").create()); + region.put("4", cache.createPdxInstanceFactory("obj4").writeString("id", "1").writeString("domain", "domain1").create()); + region.put("5", cache.createPdxInstanceFactory("obj5").writeString("id", "1").writeString("domain", "domain1").create()); + region.put("6", cache.createPdxInstanceFactory("obj6").writeString("id", "1").writeString("domain", "domain2").create()); + region.put("7", cache.createPdxInstanceFactory("obj7").writeString("id", "1").writeString("domain", "domain2").create()); + region.put("8", cache.createPdxInstanceFactory("obj8").writeString("id", "1").writeString("domain", "domain2").create()); + region.put("9", cache.createPdxInstanceFactory("obj9").writeString("id", "1").writeString("domain", "domain2").create()); + region.put("10", cache.createPdxInstanceFactory("obj10").writeString("id", "1").writeString("domain", "domain2").create()); + region.put("11", cache.createPdxInstanceFactory("obj11").writeString("id", "1").writeString("domain", "domain2").create()); + + SelectResults queryResults = (SelectResults) query.execute(); + Assert.assertTrue(queryResults.size() == 1); + Iterator iterator = queryResults.iterator(); + Assert.assertTrue(iterator.hasNext()); + Assert.assertTrue(("" + iterator.next()).equals("2")); + } + /** * Populates the region with the Objects stores in the data Object array. *