/* *************************************************************************************** * Copyright (C) 2006 EsperTech, Inc. All rights reserved. * * http://www.espertech.com/esper * * http://www.espertech.com * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the GPL license * * a copy of which has been included with this distribution in the license.txt file. * *************************************************************************************** */ package com.espertech.esper.regression.resultset; import com.espertech.esper.client.Configuration; import com.espertech.esper.client.EPServiceProvider; import com.espertech.esper.client.EPServiceProviderManager; import com.espertech.esper.client.EPStatement; import com.espertech.esper.client.annotation.HookType; import com.espertech.esper.client.soda.EPStatementObjectModel; import com.espertech.esper.epl.agg.service.AggregationGroupByRollupLevel; import com.espertech.esper.epl.agg.rollup.GroupByRollupPlanDesc; import com.espertech.esper.epl.expression.core.ExprNodeUtility; import com.espertech.esper.metrics.instrumentation.InstrumentationHelper; import com.espertech.esper.supportregression.client.SupportConfigFactory; import com.espertech.esper.supportregression.epl.SupportGroupRollupPlanHook; import junit.framework.TestCase; import java.io.StringWriter; public class TestAggregateWithRollupPlanningAndSODA extends TestCase { public final static String PLAN_CALLBACK_HOOK = "@Hook(type=" + HookType.class.getName() + ".INTERNAL_GROUPROLLUP_PLAN,hook='" + SupportGroupRollupPlanHook.class.getName() + "')"; private EPServiceProvider epService; public void setUp() { Configuration config = SupportConfigFactory.getConfiguration(); epService = EPServiceProviderManager.getDefaultProvider(config); epService.initialize(); if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());} } protected void tearDown() throws Exception { if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();} } public void testGroupByPlanning() { epService.getEPAdministrator().getConfiguration().addEventType(ABCProp.class); // plain rollup validate("a", "rollup(a)", new String[]{"a", ""}); validate("a, b", "rollup(a, b)", new String[]{"a,b", "a", ""}); validate("a, b, c", "rollup(a, b, c)", new String[]{"a,b,c", "a,b", "a", ""}); validate("a, b, c, d", "rollup(a, b, c, d)", new String[]{"a,b,c,d", "a,b,c", "a,b", "a", ""}); // rollup with unenclosed validate("a, b", "a, rollup(b)", new String[]{"a,b", "a"}); validate("a, b, c", "a, b, rollup(c)", new String[]{"a,b,c", "a,b"}); validate("a, b, c", "a, rollup(b, c)", new String[]{"a,b,c", "a,b", "a"}); validate("a, b, c, d", "a, b, rollup(c, d)", new String[]{"a,b,c,d", "a,b,c", "a,b"}); validate("a, b, c, d, e", "a, b, rollup(c, d, e)", new String[]{"a,b,c,d,e", "a,b,c,d", "a,b,c", "a,b"}); // plain cube validate("a", "cube(a)", new String[]{"a", ""}); validate("a, b", "cube(a, b)", new String[]{"a,b", "a", "b", ""}); validate("a, b, c", "cube(a, b, c)", new String[]{"a,b,c", "a,b", "a,c", "a", "b,c", "b", "c", ""}); validate("a, b, c, d", "cube(a, b, c, d)", new String[]{"a,b,c,d", "a,b,c", "a,b,d", "a,b", "a,c,d", "a,c", "a,d", "a", "b,c,d", "b,c", "b,d", "b", "c,d", "c", "d", ""}); // cube with unenclosed validate("a, b", "a, cube(b)", new String[]{"a,b", "a"}); validate("a, b, c", "a, cube(b, c)", new String[]{"a,b,c", "a,b", "a,c", "a"}); validate("a, b, c, d", "a, cube(b, c, d)", new String[]{"a,b,c,d", "a,b,c", "a,b,d", "a,b", "a,c,d", "a,c", "a,d", "a"}); validate("a, b, c, d", "a, b, cube(c, d)", new String[]{"a,b,c,d", "a,b,c", "a,b,d", "a,b"}); // plain grouping set validate("a", "grouping sets(a)", new String[]{"a"}); validate("a", "grouping sets(a)", new String[]{"a"}); validate("a, b", "grouping sets(a, b)", new String[]{"a", "b"}); validate("a, b", "grouping sets(a, b, (a, b), ())", new String[]{"a", "b", "a,b", ""}); validate("a, b", "grouping sets(a, (a, b), (), b)", new String[]{"a", "a,b", "", "b"}); validate("a, b, c", "grouping sets((a, b), (a, c), (), (b, c))", new String[]{"a,b", "a,c", "", "b,c"}); validate("a, b", "grouping sets((a, b))", new String[]{"a,b"}); validate("a, b, c", "grouping sets((a, b, c), ())", new String[]{"a,b,c", ""}); validate("a, b, c", "grouping sets((), (a, b, c), (b, c))", new String[]{"", "a,b,c", "b,c"}); // grouping sets with unenclosed validate("a, b", "a, grouping sets(b)", new String[]{"a,b"}); validate("a, b, c", "a, grouping sets(b, c)", new String[]{"a,b", "a,c"}); validate("a, b, c", "a, grouping sets((b, c))", new String[]{"a,b,c"}); validate("a, b, c, d", "a, b, grouping sets((), c, d, (c, d))", new String[]{"a,b", "a,b,c", "a,b,d", "a,b,c,d"}); // multiple grouping sets validate("a, b", "grouping sets(a), grouping sets(b)", new String[]{"a,b"}); validate("a, b, c", "grouping sets(a), grouping sets(b, c)", new String[]{"a,b", "a,c"}); validate("a, b, c, d", "grouping sets(a, b), grouping sets(c, d)", new String[]{"a,c", "a,d", "b,c", "b,d"}); validate("a, b, c", "grouping sets((), a), grouping sets(b, c)", new String[]{"b", "c", "a,b", "a,c"}); validate("a, b, c, d", "grouping sets(a, b, c), grouping sets(d)", new String[]{"a,d", "b,d", "c,d"}); validate("a, b, c, d, e", "grouping sets(a, b, c), grouping sets(d, e)", new String[]{"a,d", "a,e", "b,d", "b,e", "c,d", "c,e"}); // multiple rollups validate("a, b, c", "rollup(a, b), rollup(c)", new String[]{"a,b,c", "a,b", "a,c", "a", "c", ""}); validate("a, b, c, d", "rollup(a, b), rollup(c, d)", new String[]{"a,b,c,d", "a,b,c", "a,b", "a,c,d", "a,c", "a", "c,d", "c", ""}); // grouping sets with rollup or cube inside validate("a, b, c", "grouping sets(a, rollup(b, c))", new String[]{"a", "b,c", "b", ""}); validate("a, b, c", "grouping sets(a, cube(b, c))", new String[]{"a", "b,c", "b", "c", ""}); validate("a, b", "grouping sets(rollup(a, b))", new String[]{"a,b", "a", ""}); validate("a, b", "grouping sets(cube(a, b))", new String[]{"a,b", "a", "b", ""}); validate("a, b, c, d", "grouping sets((a, b), rollup(c, d))", new String[]{"a,b", "c,d", "c", ""}); validate("a, b, c, d", "grouping sets(a, b, rollup(c, d))", new String[]{"a", "b", "c,d", "c", ""}); // cube and rollup with combined expression validate("a, b, c", "cube((a, b), c)", new String[]{"a,b,c", "a,b", "c", ""}); validate("a, b, c", "rollup((a, b), c)", new String[]{"a,b,c", "a,b", ""}); validate("a, b, c, d", "cube((a, b), (c, d))", new String[]{"a,b,c,d", "a,b", "c,d", ""}); validate("a, b, c, d", "rollup((a, b), (c, d))", new String[]{"a,b,c,d", "a,b", ""}); validate("a, b, c", "cube(a, (b, c))", new String[]{"a,b,c", "a", "b,c", ""}); validate("a, b, c", "rollup(a, (b, c))", new String[]{"a,b,c", "a", ""}); validate("a, b, c", "grouping sets(rollup((a, b), c))", new String[]{"a,b,c", "a,b", ""}); // multiple cubes and rollups validate("a, b, c, d", "rollup(a, b), rollup(c, d)", new String[]{"a,b,c,d", "a,b,c", "a,b", "a,c,d", "a,c", "a", "c,d", "c", ""}); validate("a, b", "cube(a), cube(b)", new String[]{"a,b", "a", "b", ""}); validate("a, b, c", "cube(a, b), cube(c)", new String[]{"a,b,c", "a,b", "a,c", "a", "b,c", "b", "c", ""}); } private void validate(String selectClause, String groupByClause, String[] expectedCSV) { String epl = PLAN_CALLBACK_HOOK + " select " + selectClause + ", count(*) from ABCProp group by " + groupByClause; SupportGroupRollupPlanHook.reset(); EPStatement stmt = epService.getEPAdministrator().createEPL(epl); comparePlan(expectedCSV); stmt.destroy(); EPStatementObjectModel model = epService.getEPAdministrator().compileEPL(epl); assertEquals(epl, model.toEPL()); SupportGroupRollupPlanHook.reset(); stmt = epService.getEPAdministrator().create(model); comparePlan(expectedCSV); assertEquals(epl, stmt.getText()); stmt.destroy(); } private void comparePlan(String[] expectedCSV) { GroupByRollupPlanDesc plan = SupportGroupRollupPlanHook.getPlan(); AggregationGroupByRollupLevel[] levels = plan.getRollupDesc().getLevels(); String[][] received = new String[levels.length][]; for (int i = 0; i < levels.length; i++) { AggregationGroupByRollupLevel level = levels[i]; if (level.isAggregationTop()) { received[i] = new String[0]; } else { received[i] = new String[level.getRollupKeys().length]; for (int j = 0; j < received[i].length; j++) { int key = level.getRollupKeys()[j]; received[i][j] = ExprNodeUtility.toExpressionStringMinPrecedenceSafe(plan.getExpressions()[key]);; } } } assertEquals("Received: " + toCSV(received), expectedCSV.length, received.length); for (int i = 0; i < expectedCSV.length; i++) { String receivedCSV = toCSV(received[i]); assertEquals("Failed at row " + i, expectedCSV[i], receivedCSV); } } private String toCSV(String[][] received) { StringWriter writer = new StringWriter(); String delimiter = ""; for (String[] item : received) { writer.append(delimiter); writer.append(toCSV(item)); delimiter = " "; } return writer.toString(); } private String toCSV(String[] received) { StringWriter writer = new StringWriter(); String delimiter = ""; for (String item : received) { writer.append(delimiter); writer.append(item); delimiter = ","; } return writer.toString(); } private static class ABCProp { private final String a; private final String b; private final String c; private final String d; private final String e; private final String f; private final String g; private final String h; private ABCProp(String a, String b, String c, String d, String e, String f, String g, String h) { this.a = a; this.b = b; this.c = c; this.d = d; this.e = e; this.f = f; this.g = g; this.h = h; } public String getA() { return a; } public String getB() { return b; } public String getC() { return c; } public String getD() { return d; } public String getE() { return e; } public String getF() { return f; } public String getG() { return g; } public String getH() { return h; } } }