Search in sources :

Example 1 with CellRequest

use of mondrian.rolap.agg.CellRequest in project mondrian by pentaho.

the class SqlConstraintUtils method addContextConstraint.

/**
 * For every restricting member in the current context, generates
 * a WHERE condition and a join to the fact table.
 *
 * @param sqlQuery the query to modify
 * @param aggStar Aggregate table, or null if query is against fact table
 * @param restrictMemberTypes defines the behavior if the current context
 *   contains calculated members. If true, thows an exception.
 * @param evaluator Evaluator
 */
public static void addContextConstraint(SqlQuery sqlQuery, AggStar aggStar, Evaluator evaluator, RolapCube baseCube, boolean restrictMemberTypes) {
    if (baseCube == null && evaluator instanceof RolapEvaluator) {
        baseCube = ((RolapEvaluator) evaluator).getCube();
    }
    RolapEvaluator rEvaluator = (RolapEvaluator) evaluator;
    // decide if we should use the tuple-based version instead
    TupleList slicerTuples = rEvaluator.getOptimizedSlicerTuples(baseCube);
    boolean disjointSlicerTuples = false;
    if (slicerTuples != null && slicerTuples.size() > 0 && (SqlConstraintUtils.isDisjointTuple(slicerTuples) || rEvaluator.isMultiLevelSlicerTuple())) {
        disjointSlicerTuples = true;
    }
    TupleConstraintStruct expandedSet = makeContextConstraintSet(rEvaluator, restrictMemberTypes, disjointSlicerTuples);
    final CellRequest request = RolapAggregationManager.makeRequest(expandedSet.getMembersArray());
    if (request == null) {
        if (restrictMemberTypes) {
            throw Util.newInternal("CellRequest is null - why?");
        }
        // request is impossible to satisfy.
        return;
    }
    List<TupleList> slicerTupleList = expandedSet.getDisjoinedTupleLists();
    if (disjointSlicerTuples) {
        slicerTupleList.add(slicerTuples);
    }
    // add slicer tuples from the expanded members
    if (slicerTupleList.size() > 0) {
        LOG.warn("Using tuple-based native slicer.");
        for (TupleList tuple : slicerTupleList) {
            addContextConstraintTuples(sqlQuery, aggStar, rEvaluator, baseCube, restrictMemberTypes, request, tuple);
        }
        return;
    }
    RolapStar.Column[] columns = request.getConstrainedColumns();
    Object[] values = request.getSingleValues();
    Map<MondrianDef.Expression, Set<RolapMember>> mapOfSlicerMembers = null;
    HashMap<MondrianDef.Expression, Boolean> done = new HashMap<MondrianDef.Expression, Boolean>();
    for (int i = 0; i < columns.length; i++) {
        final RolapStar.Column column = columns[i];
        final String value = String.valueOf(values[i]);
        // choose from agg or regular star
        String expr = getColumnExpr(sqlQuery, aggStar, column);
        if ((RolapUtil.mdxNullLiteral().equalsIgnoreCase(value)) || (value.equalsIgnoreCase(RolapUtil.sqlNullValue.toString()))) {
            sqlQuery.addWhere(expr, " is ", RolapUtil.sqlNullLiteral);
        } else {
            if (column.getDatatype().isNumeric()) {
                // make sure it can be parsed
                Double.valueOf(value);
            }
            if (mapOfSlicerMembers == null) {
                mapOfSlicerMembers = getSlicerMemberMap(evaluator);
            }
            final MondrianDef.Expression keyForSlicerMap = column.getExpression();
            if (mapOfSlicerMembers.containsKey(keyForSlicerMap)) {
                if (!done.containsKey(keyForSlicerMap)) {
                    Set<RolapMember> slicerMembersSet = mapOfSlicerMembers.get(keyForSlicerMap);
                    // get only constraining members
                    // TODO: can we do this right at getSlicerMemberMap?
                    List<RolapMember> slicerMembers = getNonAllMembers(slicerMembersSet);
                    if (slicerMembers.size() > 0) {
                        // get level
                        final int levelIndex = slicerMembers.get(0).getHierarchy().getLevels().length - 1;
                        RolapLevel levelForWhere = (RolapLevel) slicerMembers.get(0).getHierarchy().getLevels()[levelIndex];
                        // build where constraint
                        final String where = generateSingleValueInExpr(sqlQuery, baseCube, aggStar, slicerMembers, levelForWhere, restrictMemberTypes, false, false);
                        if (!where.equals("")) {
                            // The where clause might be null because if the
                            // list of members is greater than the limit
                            // permitted, we won't constraint.
                            sqlQuery.addWhere(where);
                        }
                    } else {
                        addSimpleColumnConstraint(sqlQuery, column, expr, value);
                    }
                    done.put(keyForSlicerMap, Boolean.TRUE);
                }
            // if done, no op
            } else {
                // column not constrained by slicer
                addSimpleColumnConstraint(sqlQuery, column, expr, value);
            }
        }
    }
    // force Role based Access filtering
    addRoleAccessConstraints(sqlQuery, aggStar, restrictMemberTypes, baseCube, evaluator);
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) CellRequest(mondrian.rolap.agg.CellRequest) Column(mondrian.rolap.RolapStar.Column) TupleList(mondrian.calc.TupleList) MondrianDef(mondrian.olap.MondrianDef) Column(mondrian.rolap.RolapStar.Column)

Example 2 with CellRequest

use of mondrian.rolap.agg.CellRequest in project mondrian by pentaho.

the class GroupingSetQueryTest method testGroupingSetForSingleColumnConstraint.

public void testGroupingSetForSingleColumnConstraint() {
    propSaver.set(prop.DisableCaching, false);
    CellRequest request1 = createRequest(cubeNameSales2, measureUnitSales, tableCustomer, fieldGender, "M");
    CellRequest request2 = createRequest(cubeNameSales2, measureUnitSales, tableCustomer, fieldGender, "F");
    CellRequest request3 = createRequest(cubeNameSales2, measureUnitSales, null, "", "");
    SqlPattern[] patternsWithGsets = { new SqlPattern(ORACLE_TERADATA, "select \"customer\".\"gender\" as \"c0\", sum(\"sales_fact_1997\".\"unit_sales\") as \"m0\", " + "grouping(\"customer\".\"gender\") as \"g0\" " + "from \"customer\" =as= \"customer\", \"sales_fact_1997\" =as= \"sales_fact_1997\" " + "where \"sales_fact_1997\".\"customer_id\" = \"customer\".\"customer_id\" " + "group by grouping sets ((\"customer\".\"gender\"), ())", 26) };
    // If aggregates are enabled, mondrian should use them. Results should
    // be the same with or without grouping sets enabled.
    SqlPattern[] patternsWithAggs = { new SqlPattern(ORACLE_TERADATA, "select sum(\"agg_c_10_sales_fact_1997\".\"unit_sales\") as \"m0\"" + " from \"agg_c_10_sales_fact_1997\" \"agg_c_10_sales_fact_1997\"", null), new SqlPattern(ORACLE_TERADATA, "select \"agg_g_ms_pcat_sales_fact_1997\".\"gender\" as \"c0\"," + " sum(\"agg_g_ms_pcat_sales_fact_1997\".\"unit_sales\") as \"m0\" " + "from \"agg_g_ms_pcat_sales_fact_1997\" \"agg_g_ms_pcat_sales_fact_1997\" " + "group by \"agg_g_ms_pcat_sales_fact_1997\".\"gender\"", null) };
    SqlPattern[] patternsWithoutGsets = { new SqlPattern(Dialect.DatabaseProduct.ACCESS, "select \"customer\".\"gender\" as \"c0\", sum(\"sales_fact_1997\".\"unit_sales\") as \"m0\" " + "from \"customer\" as \"customer\", \"sales_fact_1997\" as \"sales_fact_1997\" " + "where \"sales_fact_1997\".\"customer_id\" = \"customer\".\"customer_id\" " + "group by \"customer\".\"gender\"", 26), new SqlPattern(ORACLE_TERADATA, "select \"customer\".\"gender\" as \"c0\", sum(\"sales_fact_1997\".\"unit_sales\") as \"m0\" " + "from \"customer\" =as= \"customer\", \"sales_fact_1997\" =as= \"sales_fact_1997\" " + "where \"sales_fact_1997\".\"customer_id\" = \"customer\".\"customer_id\" " + "group by \"customer\".\"gender\"", 26) };
    propSaver.set(prop.EnableGroupingSets, true);
    if (prop.ReadAggregates.get() && prop.UseAggregates.get()) {
        assertRequestSql(new CellRequest[] { request3, request1, request2 }, patternsWithAggs);
    } else {
        assertRequestSql(new CellRequest[] { request3, request1, request2 }, patternsWithGsets);
    }
    propSaver.set(prop.EnableGroupingSets, false);
    if (prop.ReadAggregates.get() && prop.UseAggregates.get()) {
        assertRequestSql(new CellRequest[] { request3, request1, request2 }, patternsWithAggs);
    } else {
        assertRequestSql(new CellRequest[] { request3, request1, request2 }, patternsWithoutGsets);
    }
}
Also used : CellRequest(mondrian.rolap.agg.CellRequest) SqlPattern(mondrian.test.SqlPattern)

Example 3 with CellRequest

use of mondrian.rolap.agg.CellRequest in project mondrian by pentaho.

the class GroupingSetQueryTest method testNotUsingGroupingSet.

public void testNotUsingGroupingSet() {
    if (prop.ReadAggregates.get() && prop.UseAggregates.get()) {
        return;
    }
    propSaver.set(prop.EnableGroupingSets, true);
    CellRequest request1 = createRequest(cubeNameSales2, measureUnitSales, tableCustomer, fieldGender, "M");
    CellRequest request2 = createRequest(cubeNameSales2, measureUnitSales, tableCustomer, fieldGender, "F");
    SqlPattern[] patternsWithGsets = { new SqlPattern(ORACLE_TERADATA, "select \"customer\".\"gender\" as \"c0\", sum(\"sales_fact_1997\".\"unit_sales\") as \"m0\" " + "from \"customer\" =as= \"customer\", \"sales_fact_1997\" =as= \"sales_fact_1997\" " + "where \"sales_fact_1997\".\"customer_id\" = \"customer\".\"customer_id\" " + "group by \"customer\".\"gender\"", 72) };
    assertRequestSql(new CellRequest[] { request1, request2 }, patternsWithGsets);
    propSaver.set(prop.EnableGroupingSets, false);
    SqlPattern[] patternsWithoutGsets = { new SqlPattern(Dialect.DatabaseProduct.ACCESS, "select \"customer\".\"gender\" as \"c0\", sum(\"sales_fact_1997\".\"unit_sales\") as \"m0\" " + "from \"customer\" as \"customer\", \"sales_fact_1997\" as \"sales_fact_1997\" " + "where \"sales_fact_1997\".\"customer_id\" = \"customer\".\"customer_id\" " + "group by \"customer\".\"gender\"", 72), new SqlPattern(ORACLE_TERADATA, "select \"customer\".\"gender\" as \"c0\", sum(\"sales_fact_1997\".\"unit_sales\") as \"m0\" " + "from \"customer\" =as= \"customer\", \"sales_fact_1997\" =as= \"sales_fact_1997\" " + "where \"sales_fact_1997\".\"customer_id\" = \"customer\".\"customer_id\" " + "group by \"customer\".\"gender\"", 72) };
    assertRequestSql(new CellRequest[] { request1, request2 }, patternsWithoutGsets);
}
Also used : CellRequest(mondrian.rolap.agg.CellRequest) SqlPattern(mondrian.test.SqlPattern)

Example 4 with CellRequest

use of mondrian.rolap.agg.CellRequest in project mondrian by pentaho.

the class GroupingSetQueryTest method testGroupingSetForMultipleColumnConstraintAndCompoundConstraint.

public void testGroupingSetForMultipleColumnConstraintAndCompoundConstraint() {
    if (prop.ReadAggregates.get() && prop.UseAggregates.get()) {
        return;
    }
    List<String[]> compoundMembers = new ArrayList<String[]>();
    compoundMembers.add(new String[] { "USA", "OR" });
    compoundMembers.add(new String[] { "CANADA", "BC" });
    CellRequestConstraint constraint = makeConstraintCountryState(compoundMembers);
    CellRequest request1 = createRequest(cubeNameSales2, measureCustomerCount, new String[] { tableCustomer, tableTime }, new String[] { fieldGender, fieldYear }, new String[] { "M", "1997" }, constraint);
    CellRequest request2 = createRequest(cubeNameSales2, measureCustomerCount, new String[] { tableCustomer, tableTime }, new String[] { fieldGender, fieldYear }, new String[] { "F", "1997" }, constraint);
    CellRequest request3 = createRequest(cubeNameSales2, measureCustomerCount, tableTime, fieldYear, "1997", constraint);
    String sqlWithoutGS = "select \"time_by_day\".\"the_year\" as \"c0\", \"customer\".\"gender\" as \"c1\", " + "count(distinct \"sales_fact_1997\".\"customer_id\") as \"m0\" from \"time_by_day\" =as= \"time_by_day\", " + "\"sales_fact_1997\" =as= \"sales_fact_1997\", \"customer\" =as= \"customer\", \"store\" =as= \"store\" " + "where \"sales_fact_1997\".\"time_id\" = \"time_by_day\".\"time_id\" and \"time_by_day\".\"the_year\" = 1997 " + "and \"sales_fact_1997\".\"customer_id\" = \"customer\".\"customer_id\" and " + "\"sales_fact_1997\".\"store_id\" = \"store\".\"store_id\" and " + "((\"store\".\"store_country\" = 'USA' and \"store\".\"store_state\" = 'OR') or " + "(\"store\".\"store_country\" = 'CANADA' and \"store\".\"store_state\" = 'BC')) " + "group by \"time_by_day\".\"the_year\", \"customer\".\"gender\"";
    SqlPattern[] patternsGSDisabled = { new SqlPattern(ORACLE_TERADATA, sqlWithoutGS, sqlWithoutGS) };
    // as of change 12310 GS has been removed from distinct count queries,
    // since there is little or no performance benefit and there is a bug
    // related to it (2207515)
    SqlPattern[] patternsGSEnabled = patternsGSDisabled;
    propSaver.set(prop.EnableGroupingSets, true);
    assertRequestSql(new CellRequest[] { request3, request1, request2 }, patternsGSEnabled);
    propSaver.set(prop.EnableGroupingSets, false);
    assertRequestSql(new CellRequest[] { request3, request1, request2 }, patternsGSDisabled);
}
Also used : CellRequest(mondrian.rolap.agg.CellRequest) SqlPattern(mondrian.test.SqlPattern)

Example 5 with CellRequest

use of mondrian.rolap.agg.CellRequest in project mondrian by pentaho.

the class GroupingSetQueryTest method testGroupingSetForASummaryCanBeGroupedWith2DetailBatch.

public void testGroupingSetForASummaryCanBeGroupedWith2DetailBatch() {
    if (prop.ReadAggregates.get() && prop.UseAggregates.get()) {
        return;
    }
    propSaver.set(prop.EnableGroupingSets, true);
    CellRequest request1 = createRequest(cubeNameSales2, measureUnitSales, tableCustomer, fieldGender, "M");
    CellRequest request2 = createRequest(cubeNameSales2, measureUnitSales, tableCustomer, fieldGender, "F");
    CellRequest request3 = createRequest(cubeNameSales2, measureUnitSales, null, "", "");
    CellRequest request4 = createRequest(cubeNameSales2, measureUnitSales, tableCustomer, fieldNameMaritalStatus, "M");
    CellRequest request5 = createRequest(cubeNameSales2, measureUnitSales, tableCustomer, fieldNameMaritalStatus, "S");
    CellRequest request6 = createRequest(cubeNameSales2, measureUnitSales, null, "", "");
    SqlPattern[] patternWithGsets = { new SqlPattern(ORACLE_TERADATA, "select \"customer\".\"gender\" as \"c0\", sum(\"sales_fact_1997\".\"unit_sales\") as \"m0\", " + "grouping(\"customer\".\"gender\") as \"g0\" " + "from \"customer\" =as= \"customer\", \"sales_fact_1997\" =as= \"sales_fact_1997\" " + "where \"sales_fact_1997\".\"customer_id\" = \"customer\".\"customer_id\" " + "group by grouping sets ((\"customer\".\"gender\"), ())", 26), new SqlPattern(ORACLE_TERADATA, "select \"customer\".\"marital_status\" as \"c0\", sum(\"sales_fact_1997\".\"unit_sales\") as \"m0\" " + "from \"customer\" =as= \"customer\", \"sales_fact_1997\" =as= \"sales_fact_1997\" " + "where \"sales_fact_1997\".\"customer_id\" = \"customer\".\"customer_id\" " + "group by \"customer\".\"marital_status\"", 26) };
    assertRequestSql(new CellRequest[] { request1, request2, request3, request4, request5, request6 }, patternWithGsets);
    propSaver.set(prop.EnableGroupingSets, false);
    SqlPattern[] patternWithoutGsets = { new SqlPattern(Dialect.DatabaseProduct.ACCESS, "select sum(\"sales_fact_1997\".\"unit_sales\") as \"m0\" " + "from \"sales_fact_1997\" as \"sales_fact_1997\"", 40), new SqlPattern(ORACLE_TERADATA, "select sum(\"sales_fact_1997\".\"unit_sales\") as \"m0\" " + "from \"sales_fact_1997\" =as= \"sales_fact_1997\"", 40) };
    assertRequestSql(new CellRequest[] { request1, request2, request3, request4, request5, request6 }, patternWithoutGsets);
}
Also used : CellRequest(mondrian.rolap.agg.CellRequest) SqlPattern(mondrian.test.SqlPattern)

Aggregations

CellRequest (mondrian.rolap.agg.CellRequest)10 SqlPattern (mondrian.test.SqlPattern)7 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1 LinkedHashSet (java.util.LinkedHashSet)1 Set (java.util.Set)1 TupleList (mondrian.calc.TupleList)1 MondrianDef (mondrian.olap.MondrianDef)1 Column (mondrian.rolap.RolapStar.Column)1