Skip to content

Commit

Permalink
MONDRIAN: Fix for Bug 1603653
Browse files Browse the repository at this point in the history
Replaced AbstractCalcs with AbstractDoubleCalcs and GenericCalcs, to fix the bug occuring when functions were called in iif() statements.  Also checked in a basic test case.

[git-p4: depot-paths = "//open/mondrian/": change = 9054]
  • Loading branch information
Will Gorman committed Apr 5, 2007
1 parent 6423acd commit c5a03a2
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 70 deletions.
4 changes: 2 additions & 2 deletions src/main/mondrian/olap/fun/AggregateFunDef.java
Expand Up @@ -11,7 +11,7 @@

import mondrian.olap.*;
import mondrian.calc.*;
import mondrian.calc.impl.AbstractCalc;
import mondrian.calc.impl.GenericCalc;
import mondrian.calc.impl.ValueCalc;
import mondrian.mdx.ResolvedFunCall;

Expand Down Expand Up @@ -41,7 +41,7 @@ public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final Calc calc = call.getArgCount() > 1 ?
compiler.compileScalar(call.getArg(1), true) :
new ValueCalc(call);
return new AbstractCalc(call) {
return new GenericCalc(call) {
public Object evaluate(Evaluator evaluator) {
Aggregator aggregator =
(Aggregator) evaluator.getProperty(
Expand Down
15 changes: 5 additions & 10 deletions src/main/mondrian/olap/fun/AvgFunDef.java
Expand Up @@ -16,7 +16,7 @@
import mondrian.calc.ExpCompiler;
import mondrian.calc.ListCalc;
import mondrian.calc.impl.ValueCalc;
import mondrian.calc.impl.AbstractCalc;
import mondrian.calc.impl.AbstractDoubleCalc;
import mondrian.mdx.ResolvedFunCall;

import java.util.List;
Expand All @@ -41,19 +41,14 @@ public AvgFunDef(FunDef dummyFunDef) {
}

public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final ListCalc listCalc =
compiler.compileList(call.getArg(0));
final ListCalc listCalc = compiler.compileList(call.getArg(0));
final Calc calc = call.getArgCount() > 1 ?
compiler.compileScalar(call.getArg(1), true) :
new ValueCalc(call);
return new AbstractCalc(call) {
public Object evaluate(Evaluator evaluator) {
return new AbstractDoubleCalc(call, new Calc[]{listCalc, calc}) {
public double evaluateDouble(Evaluator evaluator) {
List memberList = evaluateCurrentList(listCalc, evaluator);
return avg(evaluator.push(), memberList, calc);
}

public Calc[] getCalcs() {
return new Calc[] {listCalc, calc};
return (Double)avg(evaluator.push(), memberList, calc);
}

public boolean dependsOn(Dimension dimension) {
Expand Down
4 changes: 2 additions & 2 deletions src/main/mondrian/olap/fun/BuiltinFunTable.java
Expand Up @@ -623,7 +623,7 @@ public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final HierarchyCalc hierarchyCalc =
compiler.compileHierarchy(call.getArg(0));
final Calc valueCalc = new ValueCalc(call);
return new AbstractCalc(call) {
return new GenericCalc(call) {
public Object evaluate(Evaluator evaluator) {
Hierarchy hierarchy =
hierarchyCalc.evaluateHierarchy(evaluator);
Expand Down Expand Up @@ -835,7 +835,7 @@ public int evaluateInteger(Evaluator evaluator) {
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final MemberCalc memberCalc =
compiler.compileMember(call.getArg(0));
return new AbstractCalc(call) {
return new GenericCalc(call) {
public Object evaluate(Evaluator evaluator) {
Member member = memberCalc.evaluateMember(evaluator);
Member old = evaluator.setContext(member);
Expand Down
11 changes: 4 additions & 7 deletions src/main/mondrian/olap/fun/CovarianceFunDef.java
Expand Up @@ -17,6 +17,7 @@
import mondrian.calc.ListCalc;
import mondrian.calc.impl.ValueCalc;
import mondrian.calc.impl.AbstractCalc;
import mondrian.calc.impl.AbstractDoubleCalc;
import mondrian.mdx.ResolvedFunCall;

import java.util.List;
Expand Down Expand Up @@ -58,18 +59,14 @@ public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final Calc calc2 = call.getArgCount() > 2 ?
compiler.compileScalar(call.getArg(2), true) :
new ValueCalc(call);
return new AbstractCalc(call) {
public Object evaluate(Evaluator evaluator) {
return new AbstractDoubleCalc(call, new Calc[] {listCalc, calc1, calc2}) {
public double evaluateDouble(Evaluator evaluator) {
List memberList = listCalc.evaluateList(evaluator);
return covariance(
return (Double)covariance(
evaluator.push(), memberList,
calc1, calc2, biased);
}

public Calc[] getCalcs() {
return new Calc[] {listCalc, calc1, calc2};
}

public boolean dependsOn(Dimension dimension) {
return anyDependsButFirst(getCalcs(), dimension);
}
Expand Down
12 changes: 4 additions & 8 deletions src/main/mondrian/olap/fun/MedianFunDef.java
Expand Up @@ -16,7 +16,7 @@
import mondrian.calc.ExpCompiler;
import mondrian.calc.ListCalc;
import mondrian.calc.impl.ValueCalc;
import mondrian.calc.impl.AbstractCalc;
import mondrian.calc.impl.AbstractDoubleCalc;
import mondrian.mdx.ResolvedFunCall;

import java.util.List;
Expand Down Expand Up @@ -46,14 +46,10 @@ public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final Calc calc = call.getArgCount() > 1 ?
compiler.compileScalar(call.getArg(1), true) :
new ValueCalc(call);
return new AbstractCalc(call) {
public Object evaluate(Evaluator evaluator) {
return new AbstractDoubleCalc(call, new Calc[] {listCalc, calc}) {
public double evaluateDouble(Evaluator evaluator) {
List memberList = evaluateCurrentList(listCalc, evaluator);
return median(evaluator.push(), memberList, calc);
}

public Calc[] getCalcs() {
return new Calc[] {listCalc, calc};
return (Double)median(evaluator.push(), memberList, calc);
}

public boolean dependsOn(Dimension dimension) {
Expand Down
14 changes: 5 additions & 9 deletions src/main/mondrian/olap/fun/MinMaxFunDef.java
Expand Up @@ -16,7 +16,7 @@
import mondrian.calc.ExpCompiler;
import mondrian.calc.ListCalc;
import mondrian.calc.impl.ValueCalc;
import mondrian.calc.impl.AbstractCalc;
import mondrian.calc.impl.AbstractDoubleCalc;
import mondrian.mdx.ResolvedFunCall;

import java.util.List;
Expand Down Expand Up @@ -56,16 +56,12 @@ public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final Calc calc = call.getArgCount() > 1 ?
compiler.compileScalar(call.getArg(1), true) :
new ValueCalc(call);
return new AbstractCalc(call) {
public Object evaluate(Evaluator evaluator) {
return new AbstractDoubleCalc(call, new Calc[] {listCalc, calc}) {
public double evaluateDouble(Evaluator evaluator) {
List memberList = evaluateCurrentList(listCalc, evaluator);
return max ?
return (Double)(max ?
max(evaluator.push(), memberList, calc) :
min(evaluator.push(), memberList, calc);
}

public Calc[] getCalcs() {
return new Calc[] {listCalc, calc};
min(evaluator.push(), memberList, calc));
}

public boolean dependsOn(Dimension dimension) {
Expand Down
12 changes: 4 additions & 8 deletions src/main/mondrian/olap/fun/StdevFunDef.java
Expand Up @@ -16,7 +16,7 @@
import mondrian.calc.ExpCompiler;
import mondrian.calc.ListCalc;
import mondrian.calc.impl.ValueCalc;
import mondrian.calc.impl.AbstractCalc;
import mondrian.calc.impl.AbstractDoubleCalc;
import mondrian.mdx.ResolvedFunCall;

import java.util.List;
Expand Down Expand Up @@ -54,14 +54,10 @@ public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final Calc calc = call.getArgCount() > 1 ?
compiler.compileScalar(call.getArg(1), true) :
new ValueCalc(call);
return new AbstractCalc(call) {
public Object evaluate(Evaluator evaluator) {
return new AbstractDoubleCalc(call, new Calc[] {listCalc, calc}) {
public double evaluateDouble(Evaluator evaluator) {
List memberList = evaluateCurrentList(listCalc, evaluator);
return stdev(evaluator.push(), memberList, calc, false);
}

public Calc[] getCalcs() {
return new Calc[] {listCalc, calc};
return (Double)stdev(evaluator.push(), memberList, calc, false);
}

public boolean dependsOn(Dimension dimension) {
Expand Down
12 changes: 4 additions & 8 deletions src/main/mondrian/olap/fun/StdevPFunDef.java
Expand Up @@ -17,7 +17,7 @@
import mondrian.calc.ExpCompiler;
import mondrian.calc.ListCalc;
import mondrian.calc.impl.ValueCalc;
import mondrian.calc.impl.AbstractCalc;
import mondrian.calc.impl.AbstractDoubleCalc;
import mondrian.mdx.ResolvedFunCall;

import java.util.List;
Expand Down Expand Up @@ -56,14 +56,10 @@ public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final Calc calc = call.getArgCount() > 1 ?
compiler.compileScalar(call.getArg(1), true) :
new ValueCalc(call);
return new AbstractCalc(call) {
public Object evaluate(Evaluator evaluator) {
return new AbstractDoubleCalc(call, new Calc[] {listCalc, calc}) {
public double evaluateDouble(Evaluator evaluator) {
List memberList = evaluateCurrentList(listCalc, evaluator);
return stdev(evaluator.push(), memberList, calc, true);
}

public Calc[] getCalcs() {
return new Calc[] {listCalc, calc};
return (Double)stdev(evaluator.push(), memberList, calc, true);
}

public boolean dependsOn(Dimension dimension) {
Expand Down
12 changes: 4 additions & 8 deletions src/main/mondrian/olap/fun/VarFunDef.java
Expand Up @@ -16,7 +16,7 @@
import mondrian.calc.ExpCompiler;
import mondrian.calc.ListCalc;
import mondrian.calc.impl.ValueCalc;
import mondrian.calc.impl.AbstractCalc;
import mondrian.calc.impl.AbstractDoubleCalc;
import mondrian.mdx.ResolvedFunCall;

import java.util.List;
Expand Down Expand Up @@ -53,14 +53,10 @@ public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final Calc calc = call.getArgCount() > 1 ?
compiler.compileScalar(call.getArg(1), true) :
new ValueCalc(call);
return new AbstractCalc(call) {
public Object evaluate(Evaluator evaluator) {
return new AbstractDoubleCalc(call, new Calc[] {listCalc, calc}) {
public double evaluateDouble(Evaluator evaluator) {
List memberList = evaluateCurrentList(listCalc, evaluator);
return var(evaluator.push(), memberList, calc, false);
}

public Calc[] getCalcs() {
return new Calc[] {listCalc, calc};
return (Double)var(evaluator.push(), memberList, calc, false);
}

public boolean dependsOn(Dimension dimension) {
Expand Down
12 changes: 4 additions & 8 deletions src/main/mondrian/olap/fun/VarPFunDef.java
Expand Up @@ -16,7 +16,7 @@
import mondrian.calc.ExpCompiler;
import mondrian.calc.ListCalc;
import mondrian.calc.impl.ValueCalc;
import mondrian.calc.impl.AbstractCalc;
import mondrian.calc.impl.AbstractDoubleCalc;
import mondrian.mdx.ResolvedFunCall;

import java.util.List;
Expand Down Expand Up @@ -54,14 +54,10 @@ public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final Calc calc = call.getArgCount() > 1 ?
compiler.compileScalar(call.getArg(1), true) :
new ValueCalc(call);
return new AbstractCalc(call) {
public Object evaluate(Evaluator evaluator) {
return new AbstractDoubleCalc(call, new Calc[] {listCalc, calc}) {
public double evaluateDouble(Evaluator evaluator) {
List memberList = evaluateCurrentList(listCalc, evaluator);
return var(evaluator.push(), memberList, calc, true);
}

public Calc[] getCalcs() {
return new Calc[] {listCalc, calc};
return (Double)var(evaluator.push(), memberList, calc, true);
}

public boolean dependsOn(Dimension dimension) {
Expand Down
31 changes: 31 additions & 0 deletions testsrc/main/mondrian/test/BasicQueryTest.java
Expand Up @@ -5436,6 +5436,37 @@ public void testFormatInheritanceWorksWithFirstFormatItFinds() {
);
}

/**
* This tests a fix for bug #1603653
*/
public void testAvgCastProblem() {
assertQueryReturns(
"with member measures.bar as " +
"'iif(measures.profit>3000,min([Education Level].[Education Level].Members),min([Education Level].[Education Level].Members))' " +
"select {[Store].[All Stores].[USA].[WA].children} on 0 " +
"from sales where measures.bar"
, fold(
"Axis #0:\n" +
"{[Measures].[bar]}\n" +
"Axis #1:\n" +
"{[Store].[All Stores].[USA].[WA].[Bellingham]}\n" +
"{[Store].[All Stores].[USA].[WA].[Bremerton]}\n" +
"{[Store].[All Stores].[USA].[WA].[Seattle]}\n" +
"{[Store].[All Stores].[USA].[WA].[Spokane]}\n" +
"{[Store].[All Stores].[USA].[WA].[Tacoma]}\n" +
"{[Store].[All Stores].[USA].[WA].[Walla Walla]}\n" +
"{[Store].[All Stores].[USA].[WA].[Yakima]}\n" +
"Row #0: $95.00\n" +
"Row #0: $1,835.00\n" +
"Row #0: $1,277.00\n" +
"Row #0: $1,434.00\n" +
"Row #0: $1,084.00\n" +
"Row #0: $129.00\n" +
"Row #0: $958.00\n"
)
);
}

public void testFormatInheritanceToPickupFormatFromSecondMeasureWhenTheFirstDoesNotHaveOne() {
assertQueryReturns("with member measures.foo as 'measures.bar+measures.blah'" +
" member measures.bar as '10'" +
Expand Down

0 comments on commit c5a03a2

Please sign in to comment.