use of org.olap4j.layout.RectangularCellSetFormatter in project mondrian by pentaho.
the class MonitorTest method testMe.
/**
* Exercises as many fields of the monitoring stats classes as possible.
* So that we can check that they are being populated.
*/
public void testMe() throws SQLException {
String queryString = "WITH MEMBER [Measures].[Foo] AS\n" + " [Measures].[Unit Sales]" + " + case when [Measures].[Unit Sales] > 0\n" + " then CInt( ([Measures].[Foo], [Time].PrevMember) )\n" + " end\n" + "SELECT [Measures].[Foo] on 0\n" + "from [Sales]\n" + "where [Time].[1997].[Q3].[9]";
final OlapStatement statement1 = getTestContext().getOlap4jConnection().createStatement();
CellSet cellSet = statement1.executeOlapQuery(queryString);
StringWriter stringWriter = new StringWriter();
new RectangularCellSetFormatter(true).format(cellSet, new PrintWriter(stringWriter));
statement1.close();
println(stringWriter);
final MondrianServer mondrianServer = MondrianServer.forConnection(getConnection());
final Monitor monitor = mondrianServer.getMonitor();
final ServerInfo server = monitor.getServer();
println("# stmts open: " + server.getStatementCurrentlyOpenCount());
println("# connections open: " + server.getConnectionCurrentlyOpenCount());
println("# rows fetched: " + server.sqlStatementRowFetchCount);
println("# sql stmts open: " + server.getSqlStatementCurrentlyOpenCount());
// # sql stmts by category (cell query, member query, other)
// -- if you want to do this, capture sql statement events
// cell cache requests
// cell cache misses
// cell cache hits
final List<ConnectionInfo> connections = monitor.getConnections();
ConnectionInfo lastConnection = connections.get(connections.size() - 1);
// Cannot reliably retrieve the last statement, since statements are
// removed from the map on completion.
// final List<StatementInfo> statements = monitor.getStatements();
// StatementInfo lastStatement = statements.get(statements.size() - 1);
println("# cell cache requests, misses, hits; " + "by server, connection, mdx statement: " + server.cellCacheRequestCount + ", " + server.getCellCacheMissCount() + ", " + server.cellCacheHitCount + "; " + lastConnection.cellCacheRequestCount + ", " + (lastConnection.cellCacheRequestCount - lastConnection.cellCacheHitCount) + ", " + lastConnection.cellCacheHitCount);
// cache misses in the last minute
// cache hits in the last minute
// -- build a layer on top of monitor that polls say every 15 seconds,
// and keeps results for a few minutes
println("number of mdx statements currently open: " + server.getStatementCurrentlyOpenCount());
println("number of mdx statements currently executing: " + server.getStatementCurrentlyExecutingCount());
println("jvm memory: " + server.jvmHeapBytesUsed + ", max: " + server.jvmHeapBytesMax + ", committed: " + server.jvmHeapBytesCommitted);
println("number of segments: " + server.segmentCount + ", ever created: " + server.segmentCreateCount + ", number of cells: " + server.cellCount + ", number of cell coordinates: " + server.cellCoordinateCount + ", average cell dimensionality: " + ((float) server.cellCoordinateCount / (float) server.cellCount));
println("Connection: " + lastConnection);
println("Server: " + server);
// number of mdx function calls cumulative
// how many operations have been evaluated in sql?
// number of members in cache
// number of cells in segments
// mdx query time
// sql query time
// sql rows
// olap4j connection pool size
// sql connection pool size
// thread count
// # schemas in schema cache
// cells fulfilled by sql statements
// mondrian server count (other stats relate to just one server)
//
// Events:
//
// SQL statement start
// SQL statment stop
// external cache call
// sort
// (other expensive operations similar to sort?)
}
use of org.olap4j.layout.RectangularCellSetFormatter in project mondrian by pentaho.
the class BasicQueryTest method testExplainComplex.
public void testExplainComplex() throws SQLException {
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" + " 1(name=1, 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 String[] strings = { null, null };
((mondrian.server.Statement) statement).enableProfiling(new ProfileHandler() {
public void explain(String plan, QueryTiming timing) {
strings[0] = plan;
strings[1] = String.valueOf(timing);
}
});
final CellSet cellSet = statement.executeOlapQuery(mdx);
new RectangularCellSetFormatter(true).format(cellSet, new PrintWriter(new StringWriter()));
cellSet.close();
final String actual = strings[0].replaceAll("callMillis=[0-9]+", "callMillis=nnn").replaceAll("[0-9]+ms", "nnnms");
TestContext.assertStubbedEqualsVerbose("Axis (FILTER):\n" + "SetListCalc(name=SetListCalc, class=class mondrian.olap.fun.SetFunDef$SetListCalc, type=SetType<MemberType<member=[Gender].[F]>>, resultStyle=MUTABLE_LIST, callCount=2, callMillis=nnn, elementCount=2, elementSquaredCount=2)\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], callCount=2, callMillis=nnn)\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, callCount=2, callMillis=nnn, elementCount=4, elementSquaredCount=8)\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], callCount=2, callMillis=nnn)\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], callCount=2, callMillis=nnn)\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, callCount=2, callMillis=nnn, elementCount=0, elementSquaredCount=0)\n" + " 1(name=1, 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], callCount=2, callMillis=nnn)\n" + "\n", actual);
assertTrue(strings[1], strings[1].contains("SqlStatement-SqlTupleReader.readTuples [[Product].[Product " + "Category]] invoked 1 times for total of "));
}
Aggregations