Skip to content

Commit

Permalink
MONDRIAN: Addition to changelist 8977(Formatting Inheritance). Added …
Browse files Browse the repository at this point in the history
…more tests, refactored code and added comments.

[git-p4: depot-paths = "//open/mondrian/": change = 9003]
  • Loading branch information
thiyagu committed Mar 30, 2007
1 parent d17f1b9 commit 7f417e8
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 11 deletions.
35 changes: 26 additions & 9 deletions src/main/mondrian/olap/Formula.java
Expand Up @@ -441,33 +441,47 @@ public FoundOne(Exp exp) {
}
}

//A visitor for burrowing format information given a formula
/**
*A visitor for burrowing format information given a member.
*/
private static class FormatFinder extends MdxVisitorImpl {
private final Validator validator;

/**
*
* @param validator to resolve unresolved expressions
*/
public FormatFinder(Validator validator) {
this.validator = validator;
}

public Object visit(MemberExpr memberExpr) {
Member member = memberExpr.getMember();
returnFormula(member);
if (member.isCalculated() && member instanceof RolapCalculatedMember && !checkRecursion(memberExpr)){
RolapCalculatedMember rcm = (RolapCalculatedMember) member;
Formula formula = rcm.getFormula();
if (member.isCalculated()
&& member instanceof RolapCalculatedMember
&& !hasCyclicReference(memberExpr)){

Formula formula = ((RolapCalculatedMember) member).getFormula();
formula.accept(validator);
returnFormula(member);
}

return super.visit(memberExpr);
}

private boolean checkRecursion(Exp expr) {
/**
*
* @param expr
* @return true if there is cyclic reference in expression.
* This check is required to avoid infinite recursion
*/
private boolean hasCyclicReference(Exp expr) {
List<MemberExpr> expList = new ArrayList<MemberExpr>();
return checkRecursion(expr,expList);
return hasCyclicReference(expr,expList);
}

private boolean checkRecursion(Exp expr, List<MemberExpr> expList) {
private boolean hasCyclicReference(Exp expr, List<MemberExpr> expList) {
if (expr instanceof MemberExpr) {
MemberExpr memberExpr = (MemberExpr) expr;
if(expList.contains(expr)){
Expand All @@ -477,14 +491,17 @@ private boolean checkRecursion(Exp expr, List<MemberExpr> expList) {
Member member = memberExpr.getMember();
if (member instanceof RolapCalculatedMember) {
RolapCalculatedMember calculatedMember = (RolapCalculatedMember) member;
return checkRecursion(calculatedMember.getExpression().accept(validator),expList);
Exp exp1 = calculatedMember.getExpression().accept(validator);
return hasCyclicReference(exp1,expList);
}
}
if (expr instanceof FunCall) {
FunCall funCall = (FunCall) expr;
Exp[] exps = funCall.getArgs();
for (int i = 0; i < exps.length; i++) {
if(checkRecursion(exps[i], cloneForEachBranch(expList))) return true;
if(hasCyclicReference(exps[i], cloneForEachBranch(expList))) {
return true;
}
}
}
return false;
Expand Down
81 changes: 79 additions & 2 deletions testsrc/main/mondrian/test/BasicQueryTest.java
Expand Up @@ -5378,7 +5378,9 @@ public void testQueryTimeout()

public void testFormatInheritance() {
assertQueryReturns(
"with member measures.foo as 'measures.bar' member measures.bar as 'measures.profit' select {measures.foo} on 0 from sales",
"with member measures.foo as 'measures.bar' " +
"member measures.bar as " +
"'measures.profit' select {measures.foo} on 0 from sales",
fold("Axis #0:\n" +
"{}\n" +
"Axis #1:\n" +
Expand All @@ -5389,14 +5391,89 @@ public void testFormatInheritance() {

public void testFormatInheritanceWithIIF() {
assertQueryReturns(
"with member measures.foo as 'measures.bar' member measures.bar as 'iif(not isempty(measures.profit),measures.profit,null)' select from sales where measures.foo",
"with member measures.foo as 'measures.bar' " +
"member measures.bar as " +
"'iif(not isempty(measures.profit),measures.profit,null)' " +
"select from sales where measures.foo",
fold(
"Axis #0:\n" +
"{[Measures].[foo]}\n" +
"$339,610.90")
);
}

/**
* For a calulated member picks up the format of first member that has a format.
* in this particular case foo will use profit's format,
* i.e neither [unit sales] nor [customer count] format is used.
*/
public void testFormatInheritanceWorksWithFirstFormatItFinds() {
assertQueryReturns(
"with member measures.foo as 'measures.bar' " +
"member measures.bar as " +
"'iif(measures.profit>3000,measures.[unit sales],measures.[Customer Count])' " +
"select {[Store].[All Stores].[USA].[WA].children} on 0 " +
"from sales where measures.foo"
, fold(
"Axis #0:\n" +
"{[Measures].[foo]}\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: $190.00\n" +
"Row #0: $24,576.00\n" +
"Row #0: $25,011.00\n" +
"Row #0: $23,591.00\n" +
"Row #0: $35,257.00\n" +
"Row #0: $96.00\n" +
"Row #0: $11,491.00\n"
)
);
}

public void testThatFormatFromSeconfMeasureIsPickedUpWhenTheFirstDoesNotHaveOne() {
assertQueryReturns("with member measures.foo as 'measures.bar+measures.blah'" +
" member measures.bar as '10'" +
" member measures.blah as '20',format_string='$##.###.00' " +
"select from sales where measures.foo"
, fold(
"Axis #0:\n" +
"{[Measures].[foo]}\n" +
"$30.00"
)
);
}


public void testFormatInheritanceWithComplexExpressionToAssertThatTheFormatOfTheFisrtMemberThatHasAValidFormatIsUsed() {
assertQueryReturns(
"with member measures.foo as '13+31*measures.[Unit Sales]/" +
"iif(measures.profit>0,measures.profit,measures.[Customer Count])'" +
" select {[Store].[All Stores].[USA].[CA].children} on 0 " +
"from sales where measures.foo"
, fold(
"Axis #0:\n" +
"{[Measures].[foo]}\n" +
"Axis #1:\n" +
"{[Store].[All Stores].[USA].[CA].[Alameda]}\n" +
"{[Store].[All Stores].[USA].[CA].[Beverly Hills]}\n" +
"{[Store].[All Stores].[USA].[CA].[Los Angeles]}\n" +
"{[Store].[All Stores].[USA].[CA].[San Diego]}\n" +
"{[Store].[All Stores].[USA].[CA].[San Francisco]}\n" +
"Row #0: 13\n" +
"Row #0: 37\n" +
"Row #0: 37\n" +
"Row #0: 37\n" +
"Row #0: 38\n"
)
);
}

public void testQueryIterationLimit()
{
// Query will need to iterate 4*3 times to compute aggregates,
Expand Down

0 comments on commit 7f417e8

Please sign in to comment.