use of mondrian.olap.QueryTiming in project mondrian by pentaho.
the class ExplainPlanTest method testExplainComplex.
public void testExplainComplex() throws SQLException {
Level originalLevel = RolapUtil.PROFILE_LOGGER.getLevel();
// Must turn off in case test environment has enabled profiling
Util.setLevel(RolapUtil.PROFILE_LOGGER, Level.OFF);
// Must turn off in case test environment has enabled profiling
;
OlapConnection connection = TestContext.instance().getOlap4jConnection();
final OlapStatement statement = connection.createStatement();
final String mdx = "with member [Time].[Time].[1997].[H1] as\n" + " Aggregate({[Time].[1997].[Q1], [Time].[1997].[Q2]})\n" + " member [Measures].[Store Margin] as\n" + " [Measures].[Store Sales] - [Measures].[Store Cost],\n" + " format_string =\n" + " iif(\n" + " [Measures].[Unit Sales] > 50000,\n" + " \"\\<b\\>#.00\\<\\/b\\>\",\n" + " \"\\<i\\>#.00\\<\\/i\\>\")\n" + " set [Hi Val Products] as\n" + " Filter(\n" + " Descendants([Product].[Drink], , LEAVES),\n" + " [Measures].[Unit Sales] > 100)\n" + "select\n" + " {[Measures].[Unit Sales], [Measures].[Store Margin]} on 0,\n" + " [Hi Val Products] * [Marital Status].Members on 1\n" + "from [Sales]\n" + "where [Gender].[F]";
// Plan before execution.
final ResultSet resultSet = statement.executeQuery("explain plan for\n" + mdx);
assertTrue(resultSet.next());
String s = resultSet.getString(1);
TestContext.assertStubbedEqualsVerbose("Axis (FILTER):\n" + "SetListCalc(name=SetListCalc, class=class mondrian.olap.fun.SetFunDef$SetListCalc, " + "type=SetType<MemberType<member=[Gender].[F]>>, resultStyle=MUTABLE_LIST)\n" + " ()(name=(), class=class mondrian.olap.fun.SetFunDef$SetListCalc$2, type=MemberType<member=[Gender]" + ".[F]>, resultStyle=VALUE)\n" + " Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, type=MemberType<member=[Gender]" + ".[F]>, resultStyle=VALUE_NOT_NULL, value=[Gender].[F])\n" + "\n" + "Axis (COLUMNS):\n" + "SetListCalc(name=SetListCalc, class=class mondrian.olap.fun.SetFunDef$SetListCalc, " + "type=SetType<MemberType<member=[Measures].[Unit Sales]>>, resultStyle=MUTABLE_LIST)\n" + " 2(name=2, class=class mondrian.olap.fun.SetFunDef$SetListCalc$2, type=MemberType<member=[Measures]" + ".[Unit Sales]>, resultStyle=VALUE)\n" + " Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, " + "type=MemberType<member=[Measures].[Unit Sales]>, resultStyle=VALUE_NOT_NULL, value=[Measures].[Unit " + "Sales])\n" + " 2(name=2, class=class mondrian.olap.fun.SetFunDef$SetListCalc$2, type=MemberType<member=[Measures]" + ".[Store Margin]>, resultStyle=VALUE)\n" + " Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, " + "type=MemberType<member=[Measures].[Store Margin]>, resultStyle=VALUE_NOT_NULL, value=[Measures].[Store " + "Margin])\n" + "\n" + "Axis (ROWS):\n" + "CrossJoinIterCalc(name=CrossJoinIterCalc, class=class mondrian.olap.fun.CrossJoinFunDef$CrossJoinIterCalc," + " type=SetType<TupleType<MemberType<member=[Product].[Drink]>, MemberType<hierarchy=[Marital Status]>>>, " + "resultStyle=ITERABLE)\n" + " Hi Val Products(name=Hi Val Products, class=class mondrian.mdx.NamedSetExpr$1, type=SetType<MemberType<member=[Product].[Drink]>>," + " resultStyle=ITERABLE)\n" + " Members(name=Members, class=class mondrian.olap.fun.BuiltinFunTable$27$1, " + "type=SetType<MemberType<hierarchy=[Marital Status]>>, resultStyle=MUTABLE_LIST)\n" + " Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, " + "type=HierarchyType<hierarchy=[Marital Status]>, resultStyle=VALUE_NOT_NULL, value=[Marital Status])\n" + "\n", s);
// Plan after execution, including profiling.
final ArrayList<String> strings = new ArrayList<String>();
((mondrian.server.Statement) statement).enableProfiling(new ProfileHandler() {
public void explain(String plan, QueryTiming timing) {
strings.add(plan);
strings.add(String.valueOf(timing));
}
});
final CellSet cellSet = statement.executeOlapQuery(mdx);
new RectangularCellSetFormatter(true).format(cellSet, new PrintWriter(new StringWriter()));
cellSet.close();
assertEquals(8, strings.size());
String actual = strings.get(0).replaceAll("callMillis=[0-9]+", "callMillis=nnn").replaceAll("[0-9]+ms", "nnnms");
TestContext.assertStubbedEqualsVerbose("NamedSet (Hi Val Products):\n" + "MutableIterCalc(name=MutableIterCalc, class=class mondrian.olap.fun.FilterFunDef$MutableIterCalc, type=SetType<MemberType<member=[Product].[Drink]>>, resultStyle=ITERABLE, callCount=3, callMillis=nnn, elementCount=44, elementSquaredCount=968)\n" + " Descendants(name=Descendants, class=class mondrian.olap.fun.DescendantsFunDef$-anonymous-class-, type=SetType<MemberType<member=[Product].[Drink]>>, resultStyle=MUTABLE_LIST)\n" + " Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, type=MemberType<member=[Product].[Drink]>, resultStyle=VALUE_NOT_NULL, value=[Product].[Drink], callCount=3, callMillis=nnn)\n" + " >(name=>, class=class mondrian.olap.fun.BuiltinFunTable$-anonymous-class-$-anonymous-class-, type=BOOLEAN, resultStyle=VALUE, callCount=435, callMillis=nnn)\n" + " MemberValueCalc(name=MemberValueCalc, class=class mondrian.calc.impl.MemberValueCalc, type=SCALAR, resultStyle=VALUE, callCount=435, callMillis=nnn)\n" + " Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, type=MemberType<member=[Measures].[Unit Sales]>, resultStyle=VALUE_NOT_NULL, value=[Measures].[Unit Sales])\n" + " Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, type=NUMERIC, resultStyle=VALUE_NOT_NULL, value=100.0, callCount=435, callMillis=nnn)\n", actual);
assertTrue(strings.get(1), strings.get(1).contains("FilterFunDef invoked 6 times for total of"));
actual = strings.get(2).replaceAll("callMillis=[0-9]+", "callMillis=nnn").replaceAll("[0-9]+ms", "nnnms");
TestContext.assertStubbedEqualsVerbose("Axis (COLUMNS):\n" + "SetListCalc(name=SetListCalc, class=class mondrian.olap.fun.SetFunDef$SetListCalc, type=SetType<MemberType<member=[Measures].[Unit Sales]>>, resultStyle=MUTABLE_LIST, callCount=2, callMillis=nnn, elementCount=4, elementSquaredCount=8)\n" + " 2(name=2, class=class mondrian.olap.fun.SetFunDef$SetListCalc$-anonymous-class-, type=MemberType<member=[Measures].[Unit Sales]>, resultStyle=VALUE)\n" + " Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, type=MemberType<member=[Measures].[Unit Sales]>, resultStyle=VALUE_NOT_NULL, value=[Measures].[Unit Sales], callCount=2, callMillis=nnn)\n" + " 2(name=2, class=class mondrian.olap.fun.SetFunDef$SetListCalc$-anonymous-class-, type=MemberType<member=[Measures].[Store Margin]>, resultStyle=VALUE)\n" + " Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, type=MemberType<member=[Measures].[Store Margin]>, resultStyle=VALUE_NOT_NULL, value=[Measures].[Store Margin], callCount=2, callMillis=nnn)\n", actual);
actual = strings.get(4).replaceAll("callMillis=[0-9]+", "callMillis=nnn").replaceAll("[0-9]+ms", "nnnms");
TestContext.assertStubbedEqualsVerbose("Axis (ROWS):\n" + "CrossJoinIterCalc(name=CrossJoinIterCalc, class=class mondrian.olap.fun.CrossJoinFunDef$CrossJoinIterCalc, type=SetType<TupleType<MemberType<member=[Product].[Drink]>, MemberType<hierarchy=[Marital Status]>>>, resultStyle=ITERABLE, callCount=2, callMillis=nnn, elementCount=0, elementSquaredCount=0)\n" + " Hi Val Products(name=Hi Val Products, class=class mondrian.mdx.NamedSetExpr$-anonymous-class-, type=SetType<MemberType<member=[Product].[Drink]>>, resultStyle=ITERABLE)\n" + " Members(name=Members, class=class mondrian.olap.fun.BuiltinFunTable$-anonymous-class-$-anonymous-class-, type=SetType<MemberType<hierarchy=[Marital Status]>>, resultStyle=MUTABLE_LIST)\n" + " Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, type=HierarchyType<hierarchy=[Marital Status]>, resultStyle=VALUE_NOT_NULL, value=[Marital Status], callCount=2, callMillis=nnn)\n", actual);
actual = strings.get(6).replaceAll("callMillis=[0-9]+", "callMillis=nnn").replaceAll("[0-9]+ms", "nnnms");
TestContext.assertStubbedEqualsVerbose("QueryBody:\n", actual);
assertTrue(strings.get(3), strings.get(3).contains("SqlStatement-SqlTupleReader.readTuples [[Product].[Product " + "Category]] invoked 1 times for total of "));
Util.setLevel(RolapUtil.PROFILE_LOGGER, originalLevel);
}
use of mondrian.olap.QueryTiming in project mondrian by pentaho.
the class ExplainPlanTest method executeOlapQuery.
private ArrayList<String> executeOlapQuery(String mdx) throws SQLException {
OlapConnection connection = TestContext.instance().getOlap4jConnection();
final CacheControl cacheControl = TestContext.instance().getConnection().getCacheControl(null);
// Flush the entire cache.
final Cube salesCube = TestContext.instance().getConnection().getSchema().lookupCube("Sales", true);
final CacheControl.CellRegion measuresRegion = cacheControl.createMeasuresRegion(salesCube);
cacheControl.flush(measuresRegion);
final OlapStatement statement = connection.createStatement();
final ArrayList<String> strings = new ArrayList<String>();
((mondrian.server.Statement) statement).enableProfiling(new ProfileHandler() {
public void explain(String plan, QueryTiming timing) {
strings.add(plan);
strings.add(String.valueOf(timing));
}
});
CellSet cellSet = statement.executeOlapQuery(mdx);
cellSet.close();
return strings;
}
Aggregations