Skip to content

Commit

Permalink
MONDRIAN: fix one more case where expression cache content is
Browse files Browse the repository at this point in the history
invalid because agg cache miss is not detected correctly.

[git-p4: depot-paths = "//open/mondrian/": change = 10887]
  • Loading branch information
Rushan Chen committed Apr 16, 2008
1 parent 4386c82 commit 2059494
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 11 deletions.
10 changes: 8 additions & 2 deletions src/main/mondrian/rolap/CellReader.java
Expand Up @@ -56,10 +56,16 @@ interface CellReader {
Object get(RolapEvaluator evaluator);

/**
* Returns the number of times this cell reader has told a lie because the
* required cell value is not in the cache.
* Returns the number of times this cell reader has told a lie (since creation),
* because the required cell value is not in the cache.
*/
int getMissCount();

/**
* @return whether thus cell reader has any pending cell requests that are
* not loaded yet.
*/
boolean isDirty();
}

// End CellReader.java
2 changes: 1 addition & 1 deletion src/main/mondrian/rolap/FastBatchingCellReader.java
Expand Up @@ -150,7 +150,7 @@ public final void recordCellRequest(CellRequest request) {
* are pending batches to load or if {@link #setDirty(boolean)} has been
* called.
*/
boolean isDirty() {
public boolean isDirty() {
return dirty || !batches.isEmpty();
}

Expand Down
4 changes: 4 additions & 0 deletions src/main/mondrian/rolap/RolapAggregationManager.java
Expand Up @@ -706,6 +706,10 @@ public Object get(RolapEvaluator evaluator) {
public int getMissCount() {
return 0; // RolapAggregationManager never lies
}

public boolean isDirty() {
return false;
}
};
}

Expand Down
13 changes: 7 additions & 6 deletions src/main/mondrian/rolap/RolapEvaluator.java
Expand Up @@ -815,18 +815,19 @@ public final Object getCachedResult(ExpCacheDescriptor cacheDescriptor) {
final Object key = getExpResultCacheKey(cacheDescriptor);
Object result = root.getCacheResult(key);
if (result == null) {
boolean aggCacheDirty = cellReader.isDirty();
int aggregateCacheMissCountBefore = cellReader.getMissCount();
result = cacheDescriptor.evaluate(this);
int aggregateCacheMissCountAfter = cellReader.getMissCount();

boolean isValidResult;

if (aggregateCacheMissCountBefore ==
aggregateCacheMissCountAfter) {
// Cache the evaluation result as valid result if the
// evaluation did not use any missing aggregates. If missing
// aggregates are seen, the aggregateCacheMissCount will
// increase.
if (!aggCacheDirty &&
(aggregateCacheMissCountBefore == aggregateCacheMissCountAfter)) {
// Cache the evaluation result as valid result if the
// evaluation did not use any missing aggregates. Missing aggregates
// could be used when aggregate cache is not fully loaded, or if
// new missing aggregates are seen.
isValidResult = true;
} else {
// Cache the evaluation result as invalid result if the
Expand Down
35 changes: 33 additions & 2 deletions testsrc/main/mondrian/rolap/FastBatchingCellReaderTest.java
Expand Up @@ -34,7 +34,7 @@ protected void setUp() throws Exception {
getTestContext().clearConnection();
}

public void testMissingSubtotalBug() {
public void testMissingSubtotalBugMetricFilter() {
String query =
"With " +
"Set [*NATIVE_CJ_SET] as " +
Expand Down Expand Up @@ -64,7 +64,38 @@ public void testMissingSubtotalBug() {
assertQueryReturns(query, result);
}


public void testMissingSubtotalBugMultiLevelMetricFilter() {
String query =
"With " +
"Set [*NATIVE_CJ_SET] as 'NonEmptyCrossJoin([*BASE_MEMBERS_Product],[*BASE_MEMBERS_Education Level])' " +
"Set [*METRIC_CJ_SET] as 'Filter([*NATIVE_CJ_SET],[Measures].[*Store Cost_SEL~SUM] > 1000.0)' " +
"Set [*BASE_MEMBERS_Product] as '{[Product].[All Products].[Drink].[Beverages],[Product].[All Products].[Food].[Baked Goods]}' " +
"Set [*METRIC_MEMBERS_Product] as 'Generate([*METRIC_CJ_SET], {[Product].CurrentMember})' " +
"Set [*BASE_MEMBERS_Education Level] as '{[Education Level].[All Education Levels].[High School Degree],[Education Level].[All Education Levels].[Partial High School]}' " +
"Set [*METRIC_MEMBERS_Education Level] as 'Generate([*METRIC_CJ_SET], {[Education Level].CurrentMember})' " +
"Member [Measures].[*Store Cost_SEL~SUM] as '([Measures].[Store Cost],[Product].CurrentMember,[Education Level].CurrentMember)', SOLVE_ORDER=200 " +
"Member [Product].[All Products].[Drink].[*CTX_MEMBER_SEL~SUM] as 'Sum(Filter([*METRIC_MEMBERS_Product],[Product].CurrentMember.Parent = [Product].[All Products].[Drink]))', SOLVE_ORDER=-100 " +
"Member [Product].[All Products].[Food].[*CTX_MEMBER_SEL~SUM] as 'Sum(Filter([*METRIC_MEMBERS_Product],[Product].CurrentMember.Parent = [Product].[All Products].[Food]))', SOLVE_ORDER=-100 " +
"Member [Education Level].[*CTX_MEMBER_SEL~SUM] as 'Sum(Filter([*METRIC_MEMBERS_Education Level],[Measures].[*Store Cost_SEL~SUM] > 1000.0))', SOLVE_ORDER=-101 " +
"Select " +
"{[Measures].[Store Cost]} on columns, " +
"NonEmptyCrossJoin({[Product].[All Products].[Drink].[*CTX_MEMBER_SEL~SUM],[Product].[All Products].[Food].[*CTX_MEMBER_SEL~SUM]},{[Education Level].[*CTX_MEMBER_SEL~SUM]}) " +
"on rows From [Sales]";

String result =
"Axis #0:\n" +
"{}\n" +
"Axis #1:\n" +
"{[Measures].[Store Cost]}\n" +
"Axis #2:\n" +
"{[Product].[All Products].[Drink].[*CTX_MEMBER_SEL~SUM], [Education Level].[*CTX_MEMBER_SEL~SUM]}\n" +
"{[Product].[All Products].[Food].[*CTX_MEMBER_SEL~SUM], [Education Level].[*CTX_MEMBER_SEL~SUM]}\n" +
"Row #0: 6,535.30\n" +
"Row #1: 3,860.89\n";

assertQueryReturns(query, fold(result));
}

public void testShouldUseGroupingFunctionOnPropertyTrueAndOnSupportedDB() {
boolean oldValue = MondrianProperties.instance().EnableGroupingSets.get();
MondrianProperties.instance().EnableGroupingSets.set(true);
Expand Down

0 comments on commit 2059494

Please sign in to comment.