Search in sources :

Example 1 with QueryTiming

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);
}
Also used : QueryTiming(mondrian.olap.QueryTiming) OlapConnection(org.olap4j.OlapConnection) OlapStatement(org.olap4j.OlapStatement) ProfileHandler(mondrian.spi.ProfileHandler) ArrayList(java.util.ArrayList) RectangularCellSetFormatter(org.olap4j.layout.RectangularCellSetFormatter) OlapStatement(org.olap4j.OlapStatement) StringWriter(java.io.StringWriter) ResultSet(java.sql.ResultSet) Level(org.apache.logging.log4j.Level) CellSet(org.olap4j.CellSet) PrintWriter(java.io.PrintWriter)

Example 2 with QueryTiming

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;
}
Also used : QueryTiming(mondrian.olap.QueryTiming) OlapConnection(org.olap4j.OlapConnection) OlapStatement(org.olap4j.OlapStatement) ProfileHandler(mondrian.spi.ProfileHandler) ArrayList(java.util.ArrayList) OlapStatement(org.olap4j.OlapStatement) Cube(mondrian.olap.Cube) CacheControl(mondrian.olap.CacheControl) CellSet(org.olap4j.CellSet)

Aggregations

ArrayList (java.util.ArrayList)2 QueryTiming (mondrian.olap.QueryTiming)2 ProfileHandler (mondrian.spi.ProfileHandler)2 CellSet (org.olap4j.CellSet)2 OlapConnection (org.olap4j.OlapConnection)2 OlapStatement (org.olap4j.OlapStatement)2 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 ResultSet (java.sql.ResultSet)1 CacheControl (mondrian.olap.CacheControl)1 Cube (mondrian.olap.Cube)1 Level (org.apache.logging.log4j.Level)1 RectangularCellSetFormatter (org.olap4j.layout.RectangularCellSetFormatter)1