Skip to content

Commit

Permalink
MONDRIAN: fixing IndexOutOfBounds exception being thrown when the def…
Browse files Browse the repository at this point in the history
…ault measure is calculated on a virtual cube. see NonEmptyTest.testCalculatedDefaultMeasureOnVirtualCubeNoThrowException for more information.

[git-p4: depot-paths = "//open/mondrian-release/3.2/": change = 13372]
  • Loading branch information
Matt Campbell authored and Matt Campbell committed Feb 4, 2010
1 parent 281036b commit 2d9a0db
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 4 deletions.
8 changes: 6 additions & 2 deletions src/main/mondrian/rolap/RolapAggregationManager.java
Expand Up @@ -191,13 +191,17 @@ private static CellRequest makeCellRequest(
if (cube == null) {
return null;
}
if (members[0] instanceof RolapStoredMeasure) {
if (members.length > 0
&& members[0] instanceof RolapStoredMeasure)
{
measure = (RolapStoredMeasure) members[0];
} else {
measure = (RolapStoredMeasure) cube.getMeasures().get(0);
}
} else {
if (members[0] instanceof RolapStoredMeasure) {
if (members.length > 0
&& members[0] instanceof RolapStoredMeasure)
{
measure = (RolapStoredMeasure) members[0];
} else {
return null;
Expand Down
8 changes: 6 additions & 2 deletions src/main/mondrian/rolap/SqlConstraintUtils.java
Expand Up @@ -147,8 +147,12 @@ public static void addContextConstraint(
*/
private static List<Member> removeDefaultMembers(List<Member> members) {
List<Member> result = new ArrayList<Member>();
result.add(members.get(0)); // add the measure
for (int i = 1; i < members.size(); i++) {
int startIndex = 0;
if (members.size() > 0 && members.get(0).isMeasure()) {
result.add(members.get(0)); // add the measure
startIndex = 1;
}
for (int i = startIndex; i < members.size(); i++) {
Member m = members.get(i);
if (m.getHierarchy().getDefaultMember().equals(m)) {
continue;
Expand Down
62 changes: 62 additions & 0 deletions testsrc/main/mondrian/rolap/NonEmptyTest.java
Expand Up @@ -3968,6 +3968,68 @@ public void testContextAtAllWorksWithConstraint() {
+ "Row #1: 135,215\n");
}

/***
* Before the fix this test would throw an IndexOutOfBounds exception
* in SqlConstraintUtils.removeDefaultMembers. The method assumed that the
* first member in the list would exist and be a measure. But, when the
* default measure is calculated, it would have already been removed from
* the list by removeCalculatedMembers, and thus the assumption was wrong.
*/
public void testCalculatedDefaultMeasureOnVirtualCubeNoThrowException() {
propSaver.set(MondrianProperties.instance().EnableNativeNonEmpty, true);
final TestContext context =
TestContext.create(
"<Schema name=\"FoodMart\">"
+ " <Dimension name=\"Store\">"
+ " <Hierarchy hasAll=\"true\" primaryKey=\"store_id\">"
+ " <Table name=\"store\" />"
+ " <Level name=\"Store Country\" column=\"store_country\" uniqueMembers=\"true\" />"
+ " <Level name=\"Store State\" column=\"store_state\" uniqueMembers=\"true\" />"
+ " <Level name=\"Store City\" column=\"store_city\" uniqueMembers=\"false\" />"
+ " <Level name=\"Store Name\" column=\"store_name\" uniqueMembers=\"true\">"
+ " <Property name=\"Store Type\" column=\"store_type\" />"
+ " <Property name=\"Store Manager\" column=\"store_manager\" />"
+ " <Property name=\"Store Sqft\" column=\"store_sqft\" type=\"Numeric\" />"
+ " <Property name=\"Grocery Sqft\" column=\"grocery_sqft\" type=\"Numeric\" />"
+ " <Property name=\"Frozen Sqft\" column=\"frozen_sqft\" type=\"Numeric\" />"
+ " <Property name=\"Meat Sqft\" column=\"meat_sqft\" type=\"Numeric\" />"
+ " <Property name=\"Has coffee bar\" column=\"coffee_bar\" type=\"Boolean\" />"
+ " <Property name=\"Street address\" column=\"store_street_address\" type=\"String\" />"
+ " </Level>"
+ " </Hierarchy>"
+ " </Dimension>"
+ " <Cube name=\"Sales\" defaultMeasure=\"Unit Sales\">"
+ " <Table name=\"sales_fact_1997\" />"
+ " <DimensionUsage name=\"Store\" source=\"Store\" foreignKey=\"store_id\" />"
+ " <Measure name=\"Unit Sales\" column=\"unit_sales\" aggregator=\"sum\" formatString=\"Standard\" />"
+ " <CalculatedMember name=\"dummyMeasure\" dimension=\"Measures\">"
+ " <Formula>1</Formula>"
+ " </CalculatedMember>"
+ " </Cube>"
+ " <VirtualCube defaultMeasure=\"dummyMeasure\" name=\"virtual\">"
+ " <VirtualCubeDimension name=\"Store\" />"
+ " <VirtualCubeMeasure cubeName=\"Sales\" name=\"[Measures].[Unit Sales]\" />"
+ " <VirtualCubeMeasure name=\"[Measures].[dummyMeasure]\" cubeName=\"Sales\" />"
+ " </VirtualCube>"
+ "</Schema>");
context.assertQueryReturns(
"select "
+ " [Measures].[Unit Sales] on COLUMNS, "
+ " NON EMPTY {[Store].[Store State].Members} ON ROWS "
+ " from [virtual] ",
"Axis #0:\n"
+ "{}\n"
+ "Axis #1:\n"
+ "{[Measures].[Unit Sales]}\n"
+ "Axis #2:\n"
+ "{[Store].[All Stores].[USA].[CA]}\n"
+ "{[Store].[All Stores].[USA].[OR]}\n"
+ "{[Store].[All Stores].[USA].[WA]}\n"
+ "Row #0: 74,748\n"
+ "Row #1: 67,659\n"
+ "Row #2: 124,366\n");
}

void clearAndHardenCache(MemberCacheHelper helper) {
helper.mapLevelToMembers.setCache(
new HardSmartCache<
Expand Down

0 comments on commit 2d9a0db

Please sign in to comment.