Skip to content

Commit

Permalink
MONDRIAN: Fix bug 1669104, "Negative Solve Orders broken".
Browse files Browse the repository at this point in the history
[git-p4: depot-paths = "//open/mondrian/": change = 8789]
  • Loading branch information
julianhyde committed Feb 26, 2007
1 parent 4e8ccbd commit b6ed8e9
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 9 deletions.
61 changes: 53 additions & 8 deletions src/main/mondrian/olap/Formula.java
Expand Up @@ -302,17 +302,62 @@ public Member getMdxMember() {
* Returns the solve order. (Not valid if this formula defines a set.)
*
* @pre isMember()
* @post return != null
* @return Solve order, or null if SOLVE_ORDER property is not specified
* or is not a number or is not constant
*/
public Number getSolveOrder() {
return getIntegerMemberProperty(Property.SOLVE_ORDER.name);
}

/**
* Returns the integer value of a given constant.
* If the property is not set, or its
* value is not an integer, or its value is not a constant,
* returns null.
*
* @param name Property name
* @return Value of the property, or null if the property is not set, or its
* value is not an integer, or its value is not a constant.
*/
public int getSolveOrder() {
Exp exp = getMemberProperty(Property.SOLVE_ORDER.name);
if (exp != null) {
final Type type = exp.getType();
if (type instanceof NumericType) {
return ((Literal) exp).getIntValue();
private Number getIntegerMemberProperty(String name) {
Exp exp = getMemberProperty(name);
if (exp != null && exp.getType() instanceof NumericType) {
return quickEval(exp);
}
return null;
}

/**
* Evaluates a constant numeric expression.
* @param exp Expression
* @return Result as a number, or null if the expression is not a constant
* or not a number.
*/
private static Number quickEval(Exp exp) {
if (exp instanceof Literal) {
Literal literal = (Literal) exp;
final Object value = literal.getValue();
if (value instanceof Number) {
return (Number) value;
} else {
return null;
}
}
if (exp instanceof FunCall) {
FunCall call = (FunCall) exp;
if (call.getFunName().equals("=") &&
call.getSyntax() == Syntax.Prefix) {
final Number number = quickEval(call.getArg(0));
if (number == null) {
return null;
} else if (number instanceof Integer) {
return -number.intValue();
} else {
return -number.doubleValue();
}
}
}
return 0;
return null;
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/main/mondrian/rolap/RolapCalculatedMember.java
Expand Up @@ -38,7 +38,8 @@ class RolapCalculatedMember extends RolapMember {

// override RolapMember
public int getSolveOrder() {
return formula.getSolveOrder();
final Number solveOrder = formula.getSolveOrder();
return solveOrder == null ? 0 : solveOrder.intValue();
}

public Object getPropertyValue(String propertyName, boolean matchCase) {
Expand Down
41 changes: 41 additions & 0 deletions testsrc/main/mondrian/test/TestCalculatedMembers.java
Expand Up @@ -787,6 +787,47 @@ public void testFormatString() {
"Row #4: 565,238\n" +
"Row #4: 339,611\n"));
}

/**
* Testcase for <a href="https://sourceforge.net/tracker/index.php?func=detail&aid=1669104&group_id=35302&atid=414613">
* bug 1669104, Negative Solve Orders broken</a>.
*/
public void testNegativeSolveOrder() {
// Negative solve orders are OK.
assertQueryReturns(
"with member measures.blah as 'measures.[unit sales]', SOLVE_ORDER = -6 select {measures.[unit sales], measures.blah} on 0 from sales",
fold("Axis #0:\n" +
"{}\n" +
"Axis #1:\n" +
"{[Measures].[Unit Sales]}\n" +
"{[Measures].[blah]}\n" +
"Row #0: 266,773\n" +
"Row #0: 266,773\n"));

// Member with a negative solve order is trumped by a stored measure
// (which has solve order 0), which in turn is trumped by a calc member
// with a positive solve order.
assertQueryReturns(
"with member [Product].[Foo] as ' 1 ', SOLVE_ORDER = -6\n" +
" member [Gender].[Bar] as ' 2 ', SOLVE_ORDER = 3\n" +
"select {[Measures].[Unit Sales]} on 0,\n" +
" {[Product].[Foo], [Product].[Drink]} *\n" +
" {[Gender].[M], [Gender].[Bar]} on 1\n" +
"from [Sales]",
fold("Axis #0:\n" +
"{}\n" +
"Axis #1:\n" +
"{[Measures].[Unit Sales]}\n" +
"Axis #2:\n" +
"{[Product].[Foo], [Gender].[All Gender].[M]}\n" +
"{[Product].[Foo], [Gender].[Bar]}\n" +
"{[Product].[All Products].[Drink], [Gender].[All Gender].[M]}\n" +
"{[Product].[All Products].[Drink], [Gender].[Bar]}\n" +
"Row #0: 1\n" +
"Row #1: 2\n" +
"Row #2: 12,395\n" +
"Row #3: 2\n"));
}
}

// End CalculatedMembersTestCase.java

0 comments on commit b6ed8e9

Please sign in to comment.