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);
}
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);
}
}
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);
}
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);
}
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);
}
Aggregations