From ff357dd292ae7c0ba6e3e8e4fabd39e74efca52e Mon Sep 17 00:00:00 2001 From: Zelaine Fong Date: Wed, 22 Nov 2006 14:37:03 -0800 Subject: [PATCH] MONDRIAN - Additional changes to Eigenchange 8174. Also need to handle the case where a measure referenced in a virtual cube is also referenced in a base measure that's also referenced by the virtual cube. [git-p4: depot-paths = "//open/mondrian/": change = 8211] --- demo/FoodMart.xml | 1 + src/main/mondrian/rolap/RolapCube.java | 50 +++++++++++++------ .../main/mondrian/rolap/VirtualCubeTest.java | 3 ++ 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/demo/FoodMart.xml b/demo/FoodMart.xml index dad1794db4..d7b7663f9b 100644 --- a/demo/FoodMart.xml +++ b/demo/FoodMart.xml @@ -700,6 +700,7 @@ fullname + diff --git a/src/main/mondrian/rolap/RolapCube.java b/src/main/mondrian/rolap/RolapCube.java index a4c8d6d1a5..6135593104 100644 --- a/src/main/mondrian/rolap/RolapCube.java +++ b/src/main/mondrian/rolap/RolapCube.java @@ -345,7 +345,8 @@ private RolapCube(RolapSchema schema, new MondrianDef.CalculatedMember[ calculatedMemberList.size()]), new MondrianDef.NamedSet[0], - baseCube); + baseCube, + false); MeasureFinder measureFinder = new MeasureFinder(this, baseCube, measuresLevel); queryExp.accept(measureFinder); @@ -379,7 +380,8 @@ private RolapCube(RolapSchema schema, new MondrianDef.NamedSet[0], new ArrayList(), new ArrayList(), - this); + this, + false); // Note: virtual cubes do not get aggregate } @@ -534,7 +536,7 @@ private void init(MondrianDef.Cube xmlCube) { List formulaList = new ArrayList(); createCalcMembersAndNamedSets( xmlCube.calculatedMembers, xmlCube.namedSets, - memberList, formulaList, this); + memberList, formulaList, this, true); } @@ -605,19 +607,22 @@ private void checkOrdinals( * @param memberList Output list of {@link Member} objects * @param formulaList Output list of {@link Formula} objects * @param cube the cube that the calculated members originate from + * @param errOnDups throws an error if a duplicate member is found */ private void createCalcMembersAndNamedSets( MondrianDef.CalculatedMember[] xmlCalcMembers, MondrianDef.NamedSet[] xmlNamedSets, List memberList, List formulaList, - RolapCube cube) { + RolapCube cube, + boolean errOnDups) { final Query queryExp = resolveCalcMembers( xmlCalcMembers, xmlNamedSets, - cube); + cube, + errOnDups); if (queryExp == null) { return; } @@ -636,7 +641,8 @@ private void createCalcMembersAndNamedSets( private Query resolveCalcMembers( MondrianDef.CalculatedMember[] xmlCalcMembers, MondrianDef.NamedSet[] xmlNamedSets, - RolapCube cube) + RolapCube cube, + boolean errOnDups) { // If there are no objects to create, our generated SQL will be so // silly, the parser will laugh. @@ -649,7 +655,7 @@ private Query resolveCalcMembers( // Check the members individually, and generate SQL. for (int i = 0; i < xmlCalcMembers.length; i++) { - preCalcMember(xmlCalcMembers, i, buf, cube); + preCalcMember(xmlCalcMembers, i, buf, cube, errOnDups); } // Check the named sets individually (for uniqueness) and generate SQL. @@ -741,7 +747,8 @@ private void preCalcMember( MondrianDef.CalculatedMember[] xmlCalcMembers, int j, StringBuffer buf, - RolapCube cube) { + RolapCube cube, + boolean errOnDup) { MondrianDef.CalculatedMember xmlCalcMember = xmlCalcMembers[j]; // Lookup dimension @@ -753,19 +760,30 @@ private void preCalcMember( getUniqueName()); } - // Check there isn't another calc member with the same name and - // dimension. + // If we're processing a virtual cube, it's possible that we've + // already processed this calculated member because it's + // referenced in another measure; in that case, remove it from the + // list, since we'll add it back in later; otherwise, in the + // non-virtual cube case, throw an exception + List newCalcMemberList = new ArrayList(); for (int i = 0; i < calculatedMembers.length; i++) { Formula formula = calculatedMembers[i]; if (formula.getName().equals(xmlCalcMember.name) && formula.getMdxMember().getDimension().getName().equals( dimension.getName())) { - - throw MondrianResource.instance().CalcMemberNotUnique.ex( + if (errOnDup) { + throw MondrianResource.instance().CalcMemberNotUnique.ex( Util.makeFqName(dimension, xmlCalcMember.name), - getUniqueName()); + getUniqueName()); + } + continue; + } else { + newCalcMemberList.add(formula); } } + calculatedMembers = + (Formula []) + newCalcMemberList.toArray(new Formula[newCalcMemberList.size()]); // Check this calc member doesn't clash with one earlier in this // batch. @@ -2138,7 +2156,8 @@ public Member createCalculatedMember(String xml) { new MondrianDef.NamedSet[0], memberList, new ArrayList(), - this); + this, + true); assert memberList.size() == 1; return (Member) memberList.get(0); } @@ -2351,7 +2370,8 @@ public Object visit(MemberExpr memberExpr) new MondrianDef.NamedSet[0], new ArrayList(), new ArrayList(), - virtualCube); + virtualCube, + false); return null; } else if (member instanceof RolapBaseCubeMeasure) { diff --git a/testsrc/main/mondrian/rolap/VirtualCubeTest.java b/testsrc/main/mondrian/rolap/VirtualCubeTest.java index 3c69397ceb..f30a793e09 100644 --- a/testsrc/main/mondrian/rolap/VirtualCubeTest.java +++ b/testsrc/main/mondrian/rolap/VirtualCubeTest.java @@ -294,6 +294,7 @@ public void testCalculatedMeasure() assertQueryReturns( "select\n" + "{[Measures].[Profit Growth], " + + "[Measures].[Profit], " + "[Measures].[Average Warehouse Sale] }\n" + "ON COLUMNS\n" + "from [Warehouse and Sales]", @@ -301,8 +302,10 @@ public void testCalculatedMeasure() "{}\n" + "Axis #1:\n" + "{[Measures].[Profit Growth]}\n" + + "{[Measures].[Profit]}\n" + "{[Measures].[Average Warehouse Sale]}\n" + "Row #0: 0.0%\n" + + "Row #0: $339,610.90\n" + "Row #0: $2.21\n")); } }