blob: 5b0db3f5ca9fda18d614d10285138a0118e4da92 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You 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.
*/
/*
* Created on Feb 24, 2005
*
*
*/
package org.apache.geode.cache.query.functional;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.query.CacheUtils;
import org.apache.geode.cache.query.Query;
import org.apache.geode.cache.query.QueryService;
import org.apache.geode.cache.query.SelectResults;
import org.apache.geode.cache.query.Struct;
import org.apache.geode.cache.query.data.Portfolio;
import org.apache.geode.cache.query.internal.CompiledSelect;
import org.apache.geode.cache.query.internal.DefaultQuery;
import org.apache.geode.cache.query.internal.aggregate.AbstractAggregator;
import org.apache.geode.cache.query.types.ObjectType;
import org.apache.geode.cache.query.types.StructType;
/**
* Tests the group by queries with or without aggreagte functions
*
*
*
*/
public abstract class GroupByTestImpl implements GroupByTestInterface {
String queries[] = {"select p.status as status, p.ID from /portfolio p where p.ID > 0 "// ResultSet
};
public abstract Region createRegion(String regionName, Class constraint);
@Override
@Test
public void testConvertibleGroupByQuery_1() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i / 5);
region.put("" + i, pf);
}
String queryStr =
"select p.status as status, p.ID from /portfolio p where p.ID > 0 group by status, p.ID ";
QueryService qs = CacheUtils.getQueryService();
Query query = qs.newQuery(queryStr);
CompiledSelect cs = ((DefaultQuery) query).getSelect();
assertTrue(cs.isDistinct());
assertTrue(cs.isOrderBy());
assertFalse(cs.isGroupBy());
}
@Override
@Test
public void testConvertibleGroupByQuery_refer_column() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i / 5);
region.put("" + i, pf);
}
String queryStr = "select p.shortID from /portfolio p where p.ID >= 0 group by p.shortID ";
QueryService qs = CacheUtils.getQueryService();
Query query = qs.newQuery(queryStr);
SelectResults<Short> results = (SelectResults<Short>) query.execute();
Iterator<Short> iter = results.asList().iterator();
int counter = 0;
while (iter.hasNext()) {
Short shortID = iter.next();
assertEquals(counter++, shortID.intValue());
}
assertEquals(39, counter - 1);
}
@Override
@Test
public void testConvertibleGroupByQuery_refer_column_alias_Bug520141() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i / 5);
region.put("" + i, pf);
}
String queryStr =
"select p.shortID as short_id from /portfolio p where p.ID >= 0 group by short_id ";
QueryService qs = CacheUtils.getQueryService();
Query query = qs.newQuery(queryStr);
SelectResults<Struct> results = (SelectResults<Struct>) query.execute();
Iterator<Struct> iter = results.asList().iterator();
int counter = 0;
while (iter.hasNext()) {
Struct str = iter.next();
assertEquals(counter++, ((Short) str.get("short_id")).intValue());
}
assertEquals(39, counter - 1);
}
@Override
@Test
public void testAggregateFuncCountStar() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i % 5);
region.put("" + i, pf);
}
String queryStr =
"select p.status as status, Count(*) as countt from /portfolio p where p.ID > 0 group by status ";
QueryService qs = CacheUtils.getQueryService();
Query query = qs.newQuery(queryStr);
CompiledSelect cs = ((DefaultQuery) query).getSelect();
SelectResults sr = (SelectResults) query.execute();
assertTrue(sr.getCollectionType().getElementType().isStructType());
assertEquals(2, sr.size());
Iterator iter = sr.iterator();
Region rgn = CacheUtils.getRegion("portfolio");
int activeCount = 0;
int inactiveCount = 0;
for (Object o : rgn.values()) {
Portfolio pf = (Portfolio) o;
if (pf.status.equals("active")) {
++activeCount;
} else if (pf.status.equals("inactive")) {
++inactiveCount;
} else {
fail("unexpected status");
}
}
while (iter.hasNext()) {
Struct struct = (Struct) iter.next();
StructType structType = struct.getStructType();
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Integer", fieldTypes[1].getSimpleClassName());
if (struct.get("status").equals("active")) {
assertEquals(activeCount, ((Integer) struct.get("countt")).intValue());
} else if (struct.get("status").equals("inactive")) {
assertEquals(inactiveCount, ((Integer) struct.get("countt")).intValue());
} else {
fail("unexpected value of status");
}
}
ObjectType elementType = sr.getCollectionType().getElementType();
assertTrue(elementType.isStructType());
StructType structType = (StructType) elementType;
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Integer", fieldTypes[1].getSimpleClassName());
}
@Override
@Test
public void testAggregateFuncCountDistinctStar_1() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i % 5);
region.put("" + i, pf);
}
String queryStr =
"select p.status as status, count(distinct p.shortID) as countt from /portfolio p where p.ID > 0 group by status ";
QueryService qs = CacheUtils.getQueryService();
Query query = qs.newQuery(queryStr);
CompiledSelect cs = ((DefaultQuery) query).getSelect();
SelectResults sr = (SelectResults) query.execute();
assertTrue(sr.getCollectionType().getElementType().isStructType());
assertEquals(2, sr.size());
Iterator iter = sr.iterator();
Region rgn = CacheUtils.getRegion("portfolio");
Set<Object> distinctShortIDActive = new HashSet<Object>();
Set<Object> distinctShortIDInactive = new HashSet<Object>();
int inactiveCount = 0;
for (Object o : rgn.values()) {
Portfolio pf = (Portfolio) o;
if (pf.status.equals("active")) {
distinctShortIDActive.add(pf.shortID);
} else if (pf.status.equals("inactive")) {
distinctShortIDInactive.add(pf.shortID);
} else {
fail("unexpected status");
}
}
while (iter.hasNext()) {
Struct struct = (Struct) iter.next();
StructType structType = struct.getStructType();
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Integer", fieldTypes[1].getSimpleClassName());
if (struct.get("status").equals("active")) {
assertEquals(distinctShortIDActive.size(), ((Integer) struct.get("countt")).intValue());
} else if (struct.get("status").equals("inactive")) {
assertEquals(distinctShortIDInactive.size(), ((Integer) struct.get("countt")).intValue());
} else {
fail("unexpected value of status");
}
}
ObjectType elementType = sr.getCollectionType().getElementType();
assertTrue(elementType.isStructType());
StructType structType = (StructType) elementType;
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Integer", fieldTypes[1].getSimpleClassName());
}
@Override
@Test
public void testAggregateFuncCountDistinctStar_2() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i / 5);
region.put("" + i, pf);
}
String queryStr =
"select p.status as status, COUNT(distinct p.shortID) as countt from /portfolio p where p.ID > 0 group by status ";
QueryService qs = CacheUtils.getQueryService();
Query query = qs.newQuery(queryStr);
CompiledSelect cs = ((DefaultQuery) query).getSelect();
SelectResults sr = (SelectResults) query.execute();
assertTrue(sr.getCollectionType().getElementType().isStructType());
assertEquals(2, sr.size());
Iterator iter = sr.iterator();
Region rgn = CacheUtils.getRegion("portfolio");
Set<Object> distinctShortIDActive = new HashSet<Object>();
Set<Object> distinctShortIDInactive = new HashSet<Object>();
int inactiveCount = 0;
for (Object o : rgn.values()) {
Portfolio pf = (Portfolio) o;
if (pf.status.equals("active")) {
distinctShortIDActive.add(pf.shortID);
} else if (pf.status.equals("inactive")) {
distinctShortIDInactive.add(pf.shortID);
} else {
fail("unexpected status");
}
}
while (iter.hasNext()) {
Struct struct = (Struct) iter.next();
StructType structType = struct.getStructType();
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Integer", fieldTypes[1].getSimpleClassName());
if (struct.get("status").equals("active")) {
assertEquals(distinctShortIDActive.size(), ((Integer) struct.get("countt")).intValue());
} else if (struct.get("status").equals("inactive")) {
assertEquals(distinctShortIDInactive.size(), ((Integer) struct.get("countt")).intValue());
} else {
fail("unexpected value of status");
}
}
ObjectType elementType = sr.getCollectionType().getElementType();
assertTrue(elementType.isStructType());
StructType structType = (StructType) elementType;
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Integer", fieldTypes[1].getSimpleClassName());
}
@Override
@Test
public void testAggregateFuncSum() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i / 5);
region.put("" + i, pf);
}
String queryStr =
"select p.status as status, Sum(p.ID) as summ from /portfolio p where p.ID > 0 group by status ";
QueryService qs = CacheUtils.getQueryService();
Query query = qs.newQuery(queryStr);
CompiledSelect cs = ((DefaultQuery) query).getSelect();
SelectResults sr = (SelectResults) query.execute();
assertTrue(sr.getCollectionType().getElementType().isStructType());
assertEquals(2, sr.size());
Iterator iter = sr.iterator();
Region rgn = CacheUtils.getRegion("portfolio");
int activeSum = 0;
int inactiveSum = 0;
for (Object o : rgn.values()) {
Portfolio pf = (Portfolio) o;
if (pf.status.equals("active")) {
activeSum += pf.ID;
} else if (pf.status.equals("inactive")) {
inactiveSum += pf.ID;
} else {
fail("unexpected value of status");
}
}
while (iter.hasNext()) {
Struct struct = (Struct) iter.next();
StructType structType = struct.getStructType();
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Number", fieldTypes[1].getSimpleClassName());
if (struct.get("status").equals("active")) {
assertEquals(activeSum, ((Integer) struct.get("summ")).intValue());
} else if (struct.get("status").equals("inactive")) {
assertEquals(inactiveSum, ((Integer) struct.get("summ")).intValue());
} else {
fail("unexpected value of status");
}
}
ObjectType elementType = sr.getCollectionType().getElementType();
assertTrue(elementType.isStructType());
StructType structType = (StructType) elementType;
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Number", fieldTypes[1].getSimpleClassName());
}
@Override
@Test
public void testAggregateFuncSumDistinct() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i / 5);
region.put("" + i, pf);
}
String queryStr =
"select p.status as status, SUM (distinct p.shortID) as summ from /portfolio p where p.ID > 0 group by status ";
QueryService qs = CacheUtils.getQueryService();
Query query = qs.newQuery(queryStr);
CompiledSelect cs = ((DefaultQuery) query).getSelect();
SelectResults sr = (SelectResults) query.execute();
assertTrue(sr.getCollectionType().getElementType().isStructType());
assertEquals(2, sr.size());
Iterator iter = sr.iterator();
Region rgn = CacheUtils.getRegion("portfolio");
Set<Short> activeSum = new HashSet<Short>();
Set<Short> inactiveSum = new HashSet<Short>();
for (Object o : rgn.values()) {
Portfolio pf = (Portfolio) o;
if (pf.status.equals("active")) {
activeSum.add(pf.shortID);
} else if (pf.status.equals("inactive")) {
inactiveSum.add(pf.shortID);
} else {
fail("unexpected value of status");
}
}
int activeSumm = 0, inactiveSumm = 0;
for (Short val : activeSum) {
activeSumm += val.intValue();
}
for (Short val : inactiveSum) {
inactiveSumm += val.intValue();
}
while (iter.hasNext()) {
Struct struct = (Struct) iter.next();
StructType structType = struct.getStructType();
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Number", fieldTypes[1].getSimpleClassName());
if (struct.get("status").equals("active")) {
assertEquals(activeSumm, ((Integer) struct.get("summ")).intValue());
} else if (struct.get("status").equals("inactive")) {
assertEquals(inactiveSumm, ((Integer) struct.get("summ")).intValue());
} else {
fail("unexpected value of status");
}
}
ObjectType elementType = sr.getCollectionType().getElementType();
assertTrue(elementType.isStructType());
StructType structType = (StructType) elementType;
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Number", fieldTypes[1].getSimpleClassName());
}
@Override
@Test
public void testAggregateFuncNoGroupBy() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i / 5);
region.put("" + i, pf);
}
String queryStr = "select sum(p.ID) as summ , Max(p.ID) as maxx, min(p.ID) as minn,"
+ " avg(p.ID) as average from /portfolio p where p.ID > 0 ";
QueryService qs = CacheUtils.getQueryService();
Query query = qs.newQuery(queryStr);
CompiledSelect cs = ((DefaultQuery) query).getSelect();
SelectResults sr = (SelectResults) query.execute();
assertTrue(sr.getCollectionType().getElementType().isStructType());
assertEquals(1, sr.size());
Iterator iter = sr.iterator();
Region rgn = CacheUtils.getRegion("portfolio");
int sum = 0;
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for (Object o : rgn.values()) {
Portfolio pf = (Portfolio) o;
sum += pf.ID;
if (pf.ID > max) {
max = pf.ID;
}
if (pf.ID < min) {
min = pf.ID;
}
}
float avg = sum / rgn.size();
while (iter.hasNext()) {
Struct struct = (Struct) iter.next();
assertEquals(sum, ((Integer) struct.get("summ")).intValue());
assertEquals(max, ((Integer) struct.get("maxx")).intValue());
assertEquals(min, ((Integer) struct.get("minn")).intValue());
assertEquals(avg, ((Number) struct.get("average")).floatValue(), 0.0f);
}
}
@Override
@Test
public void testAggregateFuncAvg() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i / 5);
region.put("" + i, pf);
}
String queryStr = "select p.status as status, Avg(p.ID) as average from "
+ "/portfolio p where p.ID > 0 group by status";
QueryService qs = CacheUtils.getQueryService();
Query query = qs.newQuery(queryStr);
CompiledSelect cs = ((DefaultQuery) query).getSelect();
SelectResults sr = (SelectResults) query.execute();
assertTrue(sr.getCollectionType().getElementType().isStructType());
assertEquals(2, sr.size());
Iterator iter = sr.iterator();
Region rgn = CacheUtils.getRegion("portfolio");
double sumIDActive = 0, sumIDInactive = 0;
int numActive = 0, numInactive = 0;
for (Object o : rgn.values()) {
Portfolio pf = (Portfolio) o;
if (pf.ID > 0) {
if (pf.status.equals("active")) {
sumIDActive += pf.ID;
++numActive;
} else if (pf.status.equals("inactive")) {
sumIDInactive += pf.ID;
++numInactive;
}
}
}
Number avgActive = AbstractAggregator.downCast(sumIDActive / numActive);
Number avgInactive = AbstractAggregator.downCast(sumIDInactive / numInactive);
while (iter.hasNext()) {
Struct struct = (Struct) iter.next();
StructType structType = struct.getStructType();
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Number", fieldTypes[1].getSimpleClassName());
if (struct.get("status").equals("active")) {
assertEquals(avgActive, struct.get("average"));
} else if (struct.get("status").equals("inactive")) {
assertEquals(avgInactive, struct.get("average"));
} else {
fail("unexpected value of status");
}
}
ObjectType elementType = sr.getCollectionType().getElementType();
assertTrue(elementType.isStructType());
StructType structType = (StructType) elementType;
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Number", fieldTypes[1].getSimpleClassName());
}
@Override
@Test
public void testAggregateFuncAvgDistinct() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i / 5);
region.put("" + i, pf);
}
String queryStr = "select p.status as status, avg(distinct p.shortID) as average from "
+ "/portfolio p where p.ID > 0 group by status";
QueryService qs = CacheUtils.getQueryService();
Query query = qs.newQuery(queryStr);
CompiledSelect cs = ((DefaultQuery) query).getSelect();
SelectResults sr = (SelectResults) query.execute();
assertTrue(sr.getCollectionType().getElementType().isStructType());
assertEquals(2, sr.size());
Iterator iter = sr.iterator();
Region rgn = CacheUtils.getRegion("portfolio");
Set<Short> sumIDActiveSet = new HashSet<Short>(), sumIDInactiveSet = new HashSet<Short>();
for (Object o : rgn.values()) {
Portfolio pf = (Portfolio) o;
if (pf.ID > 0) {
if (pf.status.equals("active")) {
sumIDActiveSet.add(pf.shortID);
} else if (pf.status.equals("inactive")) {
sumIDInactiveSet.add(pf.shortID);
}
}
}
double sumActive = 0, sumInactive = 0;
for (Short shortt : sumIDActiveSet) {
sumActive += shortt.doubleValue();
}
for (Short shortt : sumIDInactiveSet) {
sumInactive += shortt.doubleValue();
}
Number avgActive = AbstractAggregator.downCast(sumActive / sumIDActiveSet.size());
Number avgInactive = AbstractAggregator.downCast(sumInactive / sumIDInactiveSet.size());
while (iter.hasNext()) {
Struct struct = (Struct) iter.next();
StructType structType = struct.getStructType();
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Number", fieldTypes[1].getSimpleClassName());
if (struct.get("status").equals("active")) {
assertEquals(avgActive, struct.get("average"));
} else if (struct.get("status").equals("inactive")) {
assertEquals(avgInactive, struct.get("average"));
} else {
fail("unexpected value of status");
}
}
ObjectType elementType = sr.getCollectionType().getElementType();
assertTrue(elementType.isStructType());
StructType structType = (StructType) elementType;
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Number", fieldTypes[1].getSimpleClassName());
}
@Override
@Test
public void testAggregateFuncWithOrderBy() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 600; ++i) {
Portfolio pf = new Portfolio(i);
if (pf.status.equals("active")) {
pf.shortID = (short) ((short) i % 5);
} else {
pf.shortID = (short) ((short) i % 11);
}
region.put("" + i, pf);
}
String[] queries = {
"select p.status as status, avg(distinct p.shortID) as average from /portfolio p where p.ID > 0 group by status order by average",
"select p.shortID as shid, avg( p.ID) as average from /portfolio p where p.ID > 0 group by shid order by average desc",
"select p.shortID as shid, avg( p.ID) as average from /portfolio p where p.ID > 0 group by shid order by avg(p.ID)",
"select p.shortID as shid, avg( p.ID) as average from /portfolio p where p.ID > 0 group by shid order by avg(p.ID) desc, shid asc",
"select p.shortID as shid, avg( p.ID) as average from /portfolio p where p.ID > 0 group by shid order by avg(p.ID) desc, shid desc",
"select p.status as status, p.shortID as shid from /portfolio p where p.ID > 0 group by status, shid order by shid desc",
"select p.shortID as shid, count(*) as countt from /portfolio p where p.ID > 0 group by p.shortID order by count(*) desc"};
Object[][] r = new Object[queries.length][2];
QueryService qs = CacheUtils.getQueryService();
for (int i = 0; i < queries.length; ++i) {
Query query = qs.newQuery(queries[i]);
SelectResults sr = (SelectResults) query.execute();
r[i][0] = sr;
}
StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
// Compare each of the query results with queries fired without order by ,
// but without order by
ssOrrs.compareExternallySortedQueriesWithOrderBy(queries, r);
}
@Override
@Test
public void testComplexValueAggregateFuncAvgDistinct() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i / 5);
region.put("" + i, pf);
}
String queryStr =
"select p.status as status, avg(distinct element(select iter.shortID from /portfolio iter where iter.ID = p.ID) ) as average from "
+ "/portfolio p where p.ID > 0 group by status";
QueryService qs = CacheUtils.getQueryService();
Query query = qs.newQuery(queryStr);
CompiledSelect cs = ((DefaultQuery) query).getSelect();
SelectResults sr = (SelectResults) query.execute();
assertTrue(sr.getCollectionType().getElementType().isStructType());
assertEquals(2, sr.size());
Iterator iter = sr.iterator();
Region rgn = CacheUtils.getRegion("portfolio");
Set<Short> sumIDActiveSet = new HashSet<Short>(), sumIDInactiveSet = new HashSet<Short>();
for (Object o : rgn.values()) {
Portfolio pf = (Portfolio) o;
if (pf.ID > 0) {
if (pf.status.equals("active")) {
sumIDActiveSet.add(pf.shortID);
} else if (pf.status.equals("inactive")) {
sumIDInactiveSet.add(pf.shortID);
}
}
}
double sumActive = 0, sumInactive = 0;
for (Short shortt : sumIDActiveSet) {
sumActive += shortt.doubleValue();
}
for (Short shortt : sumIDInactiveSet) {
sumInactive += shortt.doubleValue();
}
Number avgActive = AbstractAggregator.downCast(sumActive / sumIDActiveSet.size());
Number avgInactive = AbstractAggregator.downCast(sumInactive / sumIDInactiveSet.size());
while (iter.hasNext()) {
Struct struct = (Struct) iter.next();
StructType structType = struct.getStructType();
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Number", fieldTypes[1].getSimpleClassName());
if (struct.get("status").equals("active")) {
assertEquals(avgActive, struct.get("average"));
} else if (struct.get("status").equals("inactive")) {
assertEquals(avgInactive, struct.get("average"));
} else {
fail("unexpected value of status");
}
}
ObjectType elementType = sr.getCollectionType().getElementType();
assertTrue(elementType.isStructType());
StructType structType = (StructType) elementType;
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Number", fieldTypes[1].getSimpleClassName());
}
@Override
@Test
public void testAggregateFuncMax() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i / 5);
region.put("" + i, pf);
}
String queryStr =
"select p.status as status, Max(p.ID) as Maxx from /portfolio p where p.ID > 0 group by status ";
QueryService qs = CacheUtils.getQueryService();
Query query = qs.newQuery(queryStr);
CompiledSelect cs = ((DefaultQuery) query).getSelect();
SelectResults sr = (SelectResults) query.execute();
assertTrue(sr.getCollectionType().getElementType().isStructType());
assertEquals(2, sr.size());
Iterator iter = sr.iterator();
Region rgn = CacheUtils.getRegion("portfolio");
int activeMaxID = 0;
int inactiveMaxID = 0;
for (Object o : rgn.values()) {
Portfolio pf = (Portfolio) o;
if (pf.status.equals("active")) {
if (pf.ID > activeMaxID) {
activeMaxID = pf.ID;
}
} else if (pf.status.equals("inactive")) {
if (pf.ID > inactiveMaxID) {
inactiveMaxID = pf.ID;
}
} else {
fail("unexpected value of status");
}
}
while (iter.hasNext()) {
Struct struct = (Struct) iter.next();
StructType structType = struct.getStructType();
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Number", fieldTypes[1].getSimpleClassName());
if (struct.get("status").equals("active")) {
assertEquals(activeMaxID, ((Integer) struct.get("Maxx")).intValue());
} else if (struct.get("status").equals("inactive")) {
assertEquals(inactiveMaxID, ((Integer) struct.get("Maxx")).intValue());
} else {
fail("unexpected value of status");
}
}
ObjectType elementType = sr.getCollectionType().getElementType();
assertTrue(elementType.isStructType());
StructType structType = (StructType) elementType;
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Number", fieldTypes[1].getSimpleClassName());
}
@Override
@Test
public void testSumWithMultiColumnGroupBy() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i % 5);
region.put("" + i, pf);
}
Map<String, Integer> expectedData = new HashMap<String, Integer>();
for (Object o : region.values()) {
Portfolio pf = (Portfolio) o;
String key = pf.status + "_" + pf.shortID;
if (expectedData.containsKey(key)) {
int sum = expectedData.get(key).intValue() + pf.ID;
expectedData.put(key, sum);
} else {
expectedData.put(key, pf.ID);
}
}
String queryStr =
"select p.status as status, p.shortID as shortID, sum(p.ID) as summ from /portfolio p"
+ " where p.ID > 0 group by status, shortID ";
QueryService qs = CacheUtils.getQueryService();
Query query = qs.newQuery(queryStr);
CompiledSelect cs = ((DefaultQuery) query).getSelect();
SelectResults sr = (SelectResults) query.execute();
assertTrue(sr.getCollectionType().getElementType().isStructType());
assertEquals(expectedData.size(), sr.size());
Iterator iter = sr.iterator();
while (iter.hasNext()) {
Struct struct = (Struct) iter.next();
StructType structType = struct.getStructType();
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Short", fieldTypes[1].getSimpleClassName());
assertEquals("Number", fieldTypes[2].getSimpleClassName());
String key = struct.get("status") + "_" + struct.get("shortID");
int sum = ((Integer) struct.get("summ")).intValue();
assertTrue(expectedData.containsKey(key));
assertEquals(expectedData.get(key).intValue(), sum);
}
ObjectType elementType = sr.getCollectionType().getElementType();
assertTrue(elementType.isStructType());
StructType structType = (StructType) elementType;
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Short", fieldTypes[1].getSimpleClassName());
assertEquals("Number", fieldTypes[2].getSimpleClassName());
}
@Override
@Test
public void testAggregateFuncMin() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i / 5);
region.put("" + i, pf);
}
String queryStr =
"select p.status as status, Min(p.ID) as Minn from /portfolio p where p.ID > 0 group by status ";
QueryService qs = CacheUtils.getQueryService();
Query query = qs.newQuery(queryStr);
CompiledSelect cs = ((DefaultQuery) query).getSelect();
SelectResults sr = (SelectResults) query.execute();
assertTrue(sr.getCollectionType().getElementType().isStructType());
assertEquals(2, sr.size());
Iterator iter = sr.iterator();
Region rgn = CacheUtils.getRegion("portfolio");
int activeMinID = Integer.MAX_VALUE;
int inactiveMinID = Integer.MAX_VALUE;
for (Object o : rgn.values()) {
Portfolio pf = (Portfolio) o;
if (pf.status.equals("active")) {
if (pf.ID < activeMinID) {
activeMinID = pf.ID;
}
} else if (pf.status.equals("inactive")) {
if (pf.ID < inactiveMinID) {
inactiveMinID = pf.ID;
}
} else {
fail("unexpected value of status");
}
}
while (iter.hasNext()) {
Struct struct = (Struct) iter.next();
StructType structType = struct.getStructType();
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Number", fieldTypes[1].getSimpleClassName());
if (struct.get("status").equals("active")) {
assertEquals(activeMinID, ((Integer) struct.get("Minn")).intValue());
} else if (struct.get("status").equals("inactive")) {
assertEquals(inactiveMinID, ((Integer) struct.get("Minn")).intValue());
} else {
fail("unexpected value of status");
}
}
ObjectType elementType = sr.getCollectionType().getElementType();
assertTrue(elementType.isStructType());
StructType structType = (StructType) elementType;
ObjectType[] fieldTypes = structType.getFieldTypes();
assertEquals("String", fieldTypes[0].getSimpleClassName());
assertEquals("Number", fieldTypes[1].getSimpleClassName());
}
@Override
@Test
public void testCompactRangeIndex() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i / 5);
region.put("" + i, pf);
}
QueryService qs = CacheUtils.getQueryService();
String[] queries = {
"select pos.secId from /portfolio p, p.positions.values pos where NOT (pos.secId IN SET('SUN', 'ORCL')) group by pos.secId ", // 6
"select pos.secId , count(pos.ID) from /portfolio p, p.positions.values pos where pos.secId > 'APPL' group by pos.secId ",// 7
};
Object r[][] = new Object[queries.length][2];
// Execute Queries without Indexes
for (int i = 0; i < queries.length; i++) {
Query q = null;
try {
q = CacheUtils.getQueryService().newQuery(queries[i]);
CacheUtils.getLogger().info("Executing query: " + queries[i]);
SelectResults sr = (SelectResults) q.execute();
r[i][0] = sr;
assertTrue(sr.size() > 0);
} catch (Exception e) {
e.printStackTrace();
fail(q.getQueryString());
}
}
// Create Indexes
qs.createIndex("statusIndex", "status", "/portfolio");
// Execute Queries with Indexes
for (int i = 0; i < queries.length; i++) {
Query q = null;
try {
q = CacheUtils.getQueryService().newQuery(queries[i]);
CacheUtils.getLogger().info("Executing query: " + queries[i]);
r[i][1] = q.execute();
SelectResults rcw = (SelectResults) r[i][1];
int indexLimit = queries[i].indexOf("limit");
int limit = -1;
boolean limitQuery = indexLimit != -1;
if (limitQuery) {
limit = Integer.parseInt(queries[i].substring(indexLimit + 5).trim());
}
assertTrue("Result size is " + rcw.size() + " and limit is " + limit,
!limitQuery || rcw.size() <= limit);
String colType = rcw.getCollectionType().getSimpleClassName();
} catch (Exception e) {
e.printStackTrace();
fail(q.getQueryString());
}
}
StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
ssOrrs.CompareQueryResultsWithoutAndWithIndexes(r, queries.length, true, queries);
}
@Override
public void testDistinctCountWithoutGroupBy() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i / 5);
region.put("" + i, pf);
}
QueryService qs = CacheUtils.getQueryService();
String[] queries = {
"select count(distinct pos.secId) from /portfolio p, p.positions.values pos where pos.secId > 'APPL' ",// 10
};
Object r[][] = new Object[queries.length][2];
// Execute Queries without Indexes
for (int i = 0; i < queries.length; i++) {
Query q = null;
try {
q = CacheUtils.getQueryService().newQuery(queries[i]);
CacheUtils.getLogger().info("Executing query: " + queries[i]);
SelectResults sr = (SelectResults) q.execute();
r[i][0] = sr;
assertTrue(sr.size() > 0);
} catch (Exception e) {
e.printStackTrace();
fail(q.getQueryString());
}
}
// Create Indexes
qs.createIndex("secIdIndex", "pos.secId", "/portfolio p, p.positions.values pos");
// Execute Queries with Indexes
for (int i = 0; i < queries.length; i++) {
Query q = null;
try {
q = CacheUtils.getQueryService().newQuery(queries[i]);
CacheUtils.getLogger().info("Executing query: " + queries[i]);
r[i][1] = q.execute();
SelectResults rcw = (SelectResults) r[i][1];
int indexLimit = queries[i].indexOf("limit");
int limit = -1;
boolean limitQuery = indexLimit != -1;
if (limitQuery) {
limit = Integer.parseInt(queries[i].substring(indexLimit + 5).trim());
}
assertTrue("Result size is " + rcw.size() + " and limit is " + limit,
!limitQuery || rcw.size() <= limit);
String colType = rcw.getCollectionType().getSimpleClassName();
} catch (Exception e) {
e.printStackTrace();
fail(q.getQueryString());
}
}
StructSetOrResultsSet ssOrrs = new StructSetOrResultsSet();
ssOrrs.CompareQueryResultsWithoutAndWithIndexes(r, queries.length, true, queries);
}
@Override
public void testLimitWithGroupBy() throws Exception {
Region region = this.createRegion("portfolio", Portfolio.class);
for (int i = 1; i < 200; ++i) {
Portfolio pf = new Portfolio(i);
pf.shortID = (short) ((short) i / 5);
region.put("" + i, pf);
}
QueryService qs = CacheUtils.getQueryService();
String queryStr =
"select pos.secId as a, count( *) as x from /portfolio p, p.positions.values pos group by a limit 5 ";
Query q = qs.newQuery(queryStr);
SelectResults sr = (SelectResults) q.execute();
assertEquals(5, sr.size());
queryStr =
"select pos.secId as a, count( *) as x from /portfolio p, p.positions.values pos group by a limit 0 ";
q = qs.newQuery(queryStr);
sr = (SelectResults) q.execute();
assertEquals(0, sr.size());
queryStr =
"select pos.secId as a, count( *) as x from /portfolio p, p.positions.values pos group by a order by count(*) limit 5 ";
q = qs.newQuery(queryStr);
sr = (SelectResults) q.execute();
assertEquals(5, sr.size());
StructSetOrResultsSet ss = new StructSetOrResultsSet();
ss.compareExternallySortedQueriesWithOrderBy(new String[] {queryStr},
new Object[][] {{sr, null}});
}
@Before
public void setUp() throws Exception {
CacheUtils.startCache();
CacheUtils.getCache();
}
@After
public void tearDown() throws Exception {
CacheUtils.closeCache();
}
}