Skip to content

Commit

Permalink
MONDRIAN: fixed bug 799652 - Arithmetic operators should return null …
Browse files Browse the repository at this point in the history
…when applied to null

[git-p4: depot-paths = "//open/mondrian/": change = 1283]
  • Loading branch information
Andreas Voss committed Feb 2, 2004
1 parent 0ab3be7 commit 34abaab
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 22 deletions.
49 changes: 29 additions & 20 deletions src/main/mondrian/olap/fun/BuiltinFunTable.java
Expand Up @@ -1467,13 +1467,13 @@ public void testAggregate2(FoodMartTestCase test) {
"Row #1: 84,595.89" + nl +
"Row #1: 70,333.90" + nl +
"Row #1: 138,013.72" + nl +
"Row #2: .00" + nl +
"Row #2: .00" + nl +
"Row #2: .00" + nl +
"Row #2: .00" + nl +
"Row #2: .00" + nl +
"Row #2: .00" + nl +
"Row #2: .00" + nl +
"Row #2: (null)" + nl +
"Row #2: (null)" + nl +
"Row #2: (null)" + nl +
"Row #2: (null)" + nl +
"Row #2: (null)" + nl +
"Row #2: (null)" + nl +
"Row #2: (null)" + nl +
"Row #2: 10,023.94" + nl +
"Row #2: -1,609.27" + nl +
"Row #2: 12,234.22" + nl);
Expand Down Expand Up @@ -1634,7 +1634,7 @@ public void testCovarianceN(FoodMartTestCase test) {
define(new FunDefBase("IIf", "IIf(<Logical Expression>, <Numeric Expression1>, <Numeric Expression2>)", "Returns one of two numeric values determined by a logical test.", "fnbnn") {
public Object evaluate(Evaluator evaluator, Exp[] args) {
boolean logical = getBooleanArg(evaluator, args, 0);
return getDoubleArg(evaluator, args, logical ? 1 : 2);
return getDoubleArg(evaluator, args, logical ? 1 : 2, null);
}

public void testIIfNumeric(FoodMartTestCase test) {
Expand Down Expand Up @@ -4397,7 +4397,7 @@ public void testPropertyInCalculatedMember(FoodMartTestCase test) {
cell = result.getCell(new int[] {0,3});
Assert.assertEquals("(null)", cell.getFormattedValue());
cell = result.getCell(new int[] {1,3});
Assert.assertEquals("NaN", cell.getFormattedValue());
Assert.assertEquals("(null)", cell.getFormattedValue());
}
});

Expand Down Expand Up @@ -4489,8 +4489,10 @@ protected FunDef createFunDef(Exp[] args, FunDef dummyFunDef) {
// OPERATORS
define(new FunDefBase("+", "<Numeric Expression> + <Numeric Expression>", "Adds two numbers.", "innn") {
public Object evaluate(Evaluator evaluator, Exp[] args) {
Double o0 = getDoubleArg(evaluator, args, 0),
o1 = getDoubleArg(evaluator, args, 1);
Double o0 = getDoubleArg(evaluator, args, 0, null),
o1 = getDoubleArg(evaluator, args, 1, null);
if (o0 == null || o1 == null)
return null;
return new Double(o0.doubleValue() + o1.doubleValue());
}
public void testPlus(FoodMartTestCase test) {
Expand All @@ -4500,8 +4502,10 @@ public void testPlus(FoodMartTestCase test) {
});
define(new FunDefBase("-", "<Numeric Expression> - <Numeric Expression>", "Subtracts two numbers.", "innn") {
public Object evaluate(Evaluator evaluator, Exp[] args) {
Double o0 = getDoubleArg(evaluator, args, 0),
o1 = getDoubleArg(evaluator, args, 1);
Double o0 = getDoubleArg(evaluator, args, 0, null),
o1 = getDoubleArg(evaluator, args, 1, null);
if (o0 == null || o1 == null)
return null;
return new Double(o0.doubleValue() - o1.doubleValue());
}
public void testMinus(FoodMartTestCase test) {
Expand All @@ -4516,8 +4520,10 @@ public void testMinusAssociativity(FoodMartTestCase test) {
});
define(new FunDefBase("*", "<Numeric Expression> * <Numeric Expression>", "Multiplies two numbers.", "innn") {
public Object evaluate(Evaluator evaluator, Exp[] args) {
Double o0 = getDoubleArg(evaluator, args, 0),
o1 = getDoubleArg(evaluator, args, 1);
Double o0 = getDoubleArg(evaluator, args, 0, null),
o1 = getDoubleArg(evaluator, args, 1, null);
if (o0 == null || o1 == null)
return null;
return new Double(o0.doubleValue() * o1.doubleValue());
}
public void testMultiply(FoodMartTestCase test) {
Expand Down Expand Up @@ -4567,10 +4573,11 @@ public void testMultiplyBug774807(FoodMartTestCase test) {
});
define(new FunDefBase("/", "<Numeric Expression> / <Numeric Expression>", "Divides two numbers.", "innn") {
public Object evaluate(Evaluator evaluator, Exp[] args) {
Double o0 = getDoubleArg(evaluator, args, 0),
o1 = getDoubleArg(evaluator, args, 1);
Double result = new Double(o0.doubleValue() / o1.doubleValue());
return result;
Double o0 = getDoubleArg(evaluator, args, 0, null),
o1 = getDoubleArg(evaluator, args, 1, null);
if (o0 == null || o1 == null)
return null;
return new Double(o0.doubleValue() / o1.doubleValue());
}
// todo: use this, via reflection
public double evaluate(double d1, double d2) {
Expand All @@ -4591,7 +4598,9 @@ public void testDividePrecedence(FoodMartTestCase test) {
});
define(new FunDefBase("-", "- <Numeric Expression>", "Returns the negative of a number.", "Pnn") {
public Object evaluate(Evaluator evaluator, Exp[] args) {
Double o0 = getDoubleArg(evaluator, args, 0);
Double o0 = getDoubleArg(evaluator, args, 0, null);
if (o0 == null)
return null;
return new Double(- o0.doubleValue());
}
public void testUnaryMinus(FoodMartTestCase test) {
Expand Down
11 changes: 9 additions & 2 deletions src/main/mondrian/olap/fun/FunUtil.java
Expand Up @@ -141,16 +141,23 @@ static BigDecimal getDecimalArg(Evaluator evaluator, Exp[] args, int index) {
}
}


private static final Double nullValue = new Double(0);

static Double getDoubleArg(Evaluator evaluator, Exp[] args, int index) {
return getDoubleArg(evaluator, args, index, nullValue);
}

static Double getDoubleArg(Evaluator evaluator, Exp[] args, int index, Double nullValue) {
Object o = getScalarArg(evaluator, args, index);
if (o instanceof Double) {
return (Double) o;
} else if (o instanceof Number) {
return new Double(((Number) o).doubleValue());
} else if (o instanceof Throwable) {
return new Double(Double.NaN);
} else if (o == Util.nullValue) {
return new Double(0);
} else if (o == null || o == Util.nullValue) {
return nullValue;
} else {
throw Util.newInternal("arg " + o + " cannot be converted to Double");
}
Expand Down

0 comments on commit 34abaab

Please sign in to comment.