Skip to content

Commit

Permalink
[MONDRIAN-1126] - tests demonstrate the issue isn't reproduced
Browse files Browse the repository at this point in the history
  • Loading branch information
YuryBY committed Dec 24, 2015
1 parent 729c343 commit 1033547
Show file tree
Hide file tree
Showing 2 changed files with 262 additions and 23 deletions.
253 changes: 239 additions & 14 deletions testsrc/main/mondrian/olap/HierarchyBugTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@
// You must accept the terms of that agreement to use this software.
//
// Copyright (C) 2003-2005 Julian Hyde
// Copyright (C) 2005-2011 Pentaho
// Copyright (C) 2005-2015 Pentaho
// All Rights Reserved.
//
// remberson, Jan 31, 2006
*/

package mondrian.olap;

import mondrian.test.FoodMartTestCase;
import mondrian.test.TestContext;

import org.olap4j.*;

import java.sql.SQLException;
import java.util.List;

public class HierarchyBugTest extends FoodMartTestCase {
public HierarchyBugTest(String name) {
Expand All @@ -23,18 +28,18 @@ public HierarchyBugTest() {
super();
}

/*
This is code that demonstrates a bug that appears when using
JPivot with the current version of Mondrian. With the previous
version of Mondrian (and JPivot), pre compilation Mondrian,
this was not a bug (or at least Mondrian did not have a null
hierarchy).
Here the Time dimension is not returned in axis == 0, rather
null is returned. This causes a NullPointer exception in JPivot
when it tries to access the (null) hierarchy's name.
If the Time hierarchy is miss named in the query string, then
the parse ought to pick it up.
*/
/**
* This is code that demonstrates a bug that appears when using
* JPivot with the current version of Mondrian. With the previous
* version of Mondrian (and JPivot), pre compilation Mondrian,
* this was not a bug (or at least Mondrian did not have a null
* hierarchy).
* Here the Time dimension is not returned in axis == 0, rather
* null is returned. This causes a NullPointer exception in JPivot
* when it tries to access the (null) hierarchy's name.
* If the Time hierarchy is miss named in the query string, then
* the parse ought to pick it up.
**/
public void testNoHierarchy() {
String queryString =
"select NON EMPTY "
Expand Down Expand Up @@ -72,6 +77,226 @@ public void testNoHierarchy() {
fail(failStr);
}
}

/**
* Test case for <a href="http://jira.pentaho.com/browse/MONDRIAN-1126">
* MONDRIAN-1126:
* member getHierarchy vs. level.getHierarchy differences in Time Dimension
* </a>
*/
public void testNamesIdentitySsasCompatible() {
propSaver.set(
MondrianProperties.instance().SsasCompatibleNaming, true);
verifyMemberLevelNamesIdentity();
}

public void testNamesIdentitySsasInCompatible() {
// SsasCompatibleNaming defaults to false
verifyMemberLevelNamesIdentity();
}

private void verifyMemberLevelNamesIdentity() {
String mdxTime = "SELECT\n"
+ " [Measures].[Unit Sales] ON COLUMNS,\n"
+ " [Time].[Time].[Year].Members ON ROWS\n"
+ "FROM [Sales]";
String mdxWeekly = "SELECT\n"
+ " [Measures].[Unit Sales] ON COLUMNS,\n"
+ " [Time.Weekly].[Year].Members ON ROWS\n"
+ "FROM [Sales]";

Result resultTime = executeQuery(mdxTime);
String unitSalesHierarchyName =
verifyMemberLevelNamesIdentityMeasureAxis(
resultTime.getAxes()[0], "[Measures]");
verifyMemberLevelNamesIdentityDimAxis(
resultTime.getAxes()[1], "[Time]");

Result resultWeekly = executeQuery(mdxWeekly);
// check if both are the "[Measures]"
verifyMemberLevelNamesIdentityMeasureAxis(
resultWeekly.getAxes()[0], unitSalesHierarchyName);
verifyMemberLevelNamesIdentityDimAxis(
resultWeekly.getAxes()[1], "[Time.Weekly]");
flushContextSchemaCache();
}

private String verifyMemberLevelNamesIdentityMeasureAxis(
Axis axis, String expected)
{
OlapElement unitSales =
axis.getPositions().get(0).get(0);
String unitSalesHierarchyName =
unitSales.getHierarchy().getUniqueName();
assertEquals(expected, unitSalesHierarchyName);
return unitSalesHierarchyName;
}

private void verifyMemberLevelNamesIdentityDimAxis(
Axis axis, String expected)
{
Member year1997 = axis.getPositions().get(0).get(0);
String year1997HierarchyName = year1997.getHierarchy().getUniqueName();
assertEquals(expected, year1997HierarchyName);
Level year = year1997.getLevel();
String yearHierarchyName = year.getHierarchy().getUniqueName();
assertEquals(year1997HierarchyName, yearHierarchyName);
}

public void testNamesIdentitySsasCompatibleOlap4j() throws SQLException {
propSaver.set(
MondrianProperties.instance().SsasCompatibleNaming, true);
verifyLevelMemberNamesIdentityOlap4jTimeHierarchy();
}

public void testNamesIdentitySsasInCompatibleOlap4j() throws SQLException {
// SsasCompatibleNaming defaults to false
verifyLevelMemberNamesIdentityOlap4jTimeHierarchy();
}

private void verifyLevelMemberNamesIdentityOlap4jTimeHierarchy()
throws SQLException
{
// essential here, in time hierarchy, is hasAll="false"
// so that we expect "[Time]"
String mdx = "SELECT\n"
+ " [Measures].[Unit Sales] ON COLUMNS,\n"
+ " [Time].[Time].[Year].Members ON ROWS\n"
+ "FROM [Sales]";
verifyLevelMemberNamesIdentityOlap4j(mdx, getTestContext(), "[Time]");
}

public void testNamesIdentitySsasCompatibleOlap4jWeekly()
throws SQLException
{
propSaver.set(
MondrianProperties.instance().SsasCompatibleNaming, true);
String mdx = "SELECT\n"
+ " [Measures].[Unit Sales] ON COLUMNS,\n"
+ " [Time].[Weekly].[Year].Members ON ROWS\n"
+ "FROM [Sales]";
verifyLevelMemberNamesIdentityOlap4j(
mdx, getTestContext(), "[Time].[Weekly]");
}

public void testNamesIdentitySsasInCompatibleOlap4jWeekly()
throws SQLException
{
// SsasCompatibleNaming defaults to false
String mdx = "SELECT\n"
+ " [Measures].[Unit Sales] ON COLUMNS,\n"
+ " [Time.Weekly].[Year].Members ON ROWS\n"
+ "FROM [Sales]";
verifyLevelMemberNamesIdentityOlap4j(
mdx, getTestContext(), "[Time.Weekly]");
}

public void testNamesIdentitySsasCompatibleOlap4jDateDim()
throws SQLException
{
propSaver.set(
MondrianProperties.instance().SsasCompatibleNaming, true);
verifyMemberLevelNamesIdentityOlap4jDateDim();
}

public void testNameSsasInCompatibleOlap4jDateDim()
throws SQLException
{
// SsasCompatibleNaming defaults to false
verifyMemberLevelNamesIdentityOlap4jDateDim();
}

private void verifyMemberLevelNamesIdentityOlap4jDateDim()
throws SQLException
{
String mdx =
"SELECT\n"
+ " [Measures].[Unit Sales] ON COLUMNS,\n"
+ " [Date].[Date].[Year].Members ON ROWS\n"
+ "FROM [Sales]";
TestContext context = getTestContext();
String dateDim =
"<Dimension name=\"Date\" type=\"TimeDimension\" foreignKey=\"time_id\">\n"
+ " <Hierarchy hasAll=\"false\" primaryKey=\"time_id\">\n"
+ " <Table name=\"time_by_day\"/>\n"
+ " <Level name=\"Year\" column=\"the_year\" type=\"Numeric\" uniqueMembers=\"true\"\n"
+ " levelType=\"TimeYears\"/>\n"
+ " <Level name=\"Quarter\" column=\"quarter\" uniqueMembers=\"false\"\n"
+ " levelType=\"TimeQuarters\"/>\n"
+ " <Level name=\"Month\" column=\"month_of_year\" uniqueMembers=\"false\" type=\"Numeric\"\n"
+ " levelType=\"TimeMonths\"/>\n"
+ " </Hierarchy>\n"
+ " </Dimension>";
context = context.createSubstitutingCube("Sales", dateDim);
verifyLevelMemberNamesIdentityOlap4j(mdx, context, "[Date]");
}

public void testNamesIdentitySsasCompatibleOlap4jDateDimWeekly()
throws SQLException
{
propSaver.set(
MondrianProperties.instance().SsasCompatibleNaming, true);
String mdx = "SELECT\n"
+ " [Measures].[Unit Sales] ON COLUMNS,\n"
+ " [Date].[Weekly].[Year].Members ON ROWS\n"
+ "FROM [Sales]";
verifyMemberLevelNamesIdentityOlap4jDateDimWeekly(
mdx, "[Date].[Weekly]");
}

public void testNamesIdentitySsasInCompatibleOlap4jDateDim()
throws SQLException
{
// SsasCompatibleNaming defaults to false
String mdx = "SELECT\n"
+ " [Measures].[Unit Sales] ON COLUMNS,\n"
+ " [Date.Weekly].[Year].Members ON ROWS\n"
+ "FROM [Sales]";
verifyMemberLevelNamesIdentityOlap4jDateDimWeekly(
mdx, "[Date.Weekly]");
}

private void verifyMemberLevelNamesIdentityOlap4jDateDimWeekly(
String mdx, String expected) throws SQLException
{
TestContext context = getTestContext();
String dateDim =
"<Dimension name=\"Date\" type=\"TimeDimension\" foreignKey=\"time_id\">\n"
+ " <Hierarchy hasAll=\"true\" name=\"Weekly\" primaryKey=\"time_id\">\n"
+ " <Table name=\"time_by_day\"/>\n"
+ " <Level name=\"Year\" column=\"the_year\" type=\"Numeric\" uniqueMembers=\"true\"\n"
+ " levelType=\"TimeYears\"/>\n"
+ " <Level name=\"Week\" column=\"week_of_year\" type=\"Numeric\" uniqueMembers=\"false\"\n"
+ " levelType=\"TimeWeeks\"/>\n"
+ " <Level name=\"Day\" column=\"day_of_month\" uniqueMembers=\"false\" type=\"Numeric\"\n"
+ " levelType=\"TimeDays\"/>\n"
+ " </Hierarchy>\n"
+ " </Dimension>";
context = context.createSubstitutingCube("Sales", dateDim);
verifyLevelMemberNamesIdentityOlap4j(mdx, context, expected);
}

private void verifyLevelMemberNamesIdentityOlap4j(
String mdx, TestContext context, String expected) throws SQLException
{
CellSet result = context.executeOlap4jQuery(mdx);

List<org.olap4j.Position> positions =
result.getAxes().get(1).getPositions();
org.olap4j.metadata.Member year1997 =
positions.get(0).getMembers().get(0);
String year1997HierarchyName = year1997.getHierarchy().getUniqueName();
assertEquals(expected, year1997HierarchyName);

org.olap4j.metadata.Level year = year1997.getLevel();
String yearHierarchyName = year.getHierarchy().getUniqueName();
assertEquals(year1997HierarchyName, yearHierarchyName);
flushContextSchemaCache();
}

private void flushContextSchemaCache() {
getTestContext().flushSchemaCache();
}
}

// End HierarchyBugTest.java
32 changes: 23 additions & 9 deletions testsrc/main/mondrian/test/BasicQueryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// You must accept the terms of that agreement to use this software.
//
// Copyright (C) 2003-2005 Julian Hyde
// Copyright (C) 2005-2014 Pentaho
// Copyright (C) 2005-2015 Pentaho
// All Rights Reserved.
//
// jhyde, Feb 14, 2003
Expand All @@ -17,7 +17,12 @@
import mondrian.olap.Cell;
import mondrian.olap.Connection;
import mondrian.olap.*;
import mondrian.olap.Dimension;
import mondrian.olap.Hierarchy;
import mondrian.olap.Level;
import mondrian.olap.Member;
import mondrian.olap.Position;
import mondrian.olap.Property;
import mondrian.olap.type.NumericType;
import mondrian.olap.type.Type;
import mondrian.rolap.RolapConnection;
Expand All @@ -39,6 +44,7 @@

import org.olap4j.*;
import org.olap4j.layout.RectangularCellSetFormatter;
import org.olap4j.metadata.*;

import java.io.PrintWriter;
import java.io.StringWriter;
Expand Down Expand Up @@ -8323,11 +8329,11 @@ public void testArrayIndexOutOfBoundsWithEmptySegment() {
// Some DBs return 0 when we ask for null. Like Oracle.
final String returnedValue;
switch (getTestContext().getDialect().getDatabaseProduct()) {
case ORACLE:
returnedValue = "0";
break;
default:
returnedValue = "";
case ORACLE:
returnedValue = "0";
break;
default:
returnedValue = "";
}

testContext.assertQueryReturns(
Expand Down Expand Up @@ -8409,21 +8415,28 @@ public void testNameExpressionSnowflake() {
+ " <Level name=\"IsZero\" visible=\"true\" table=\"product\" column=\"product_id\" type=\"Integer\" uniqueMembers=\"false\" levelType=\"Regular\" hideMemberIf=\"Never\">\n"
+ " <NameExpression>\n"
+ " <SQL dialect=\"generic\">\n"
+ " <![CDATA[case when " + dialect.quoteIdentifier("product","product_id") + "=0 then 'Zero' else 'Non-Zero' end]]>\n"
+ " <![CDATA[case when "
+ dialect.quoteIdentifier(
"product", "product_id")
+ "=0 then 'Zero' else 'Non-Zero' end]]>\n"
+ " </SQL>\n"
+ " </NameExpression>\n"
+ " </Level>\n"
+ " <Level name=\"SubCat\" visible=\"true\" table=\"product_class\" column=\"product_class_id\" type=\"String\" uniqueMembers=\"false\" levelType=\"Regular\" hideMemberIf=\"Never\">\n"
+ " <NameExpression>\n"
+ " <SQL dialect=\"generic\">\n"
+ " <![CDATA[" + dialect.quoteIdentifier("product_class","product_subcategory") + "]]>\n"
+ " <![CDATA["
+ dialect.quoteIdentifier(
"product_class", "product_subcategory")
+ "]]>\n"
+ " </SQL>\n"
+ " </NameExpression>\n"
+ " </Level>\n"
+ " <Level name=\"ProductName\" visible=\"true\" table=\"product\" column=\"product_id\" type=\"Integer\" uniqueMembers=\"false\" levelType=\"Regular\" hideMemberIf=\"Never\">\n"
+ " <NameExpression>\n"
+ " <SQL dialect=\"generic\">\n"
+ " <![CDATA["+ dialect.quoteIdentifier("product","product_name") + "]]>\n"
+ " <![CDATA["
+ dialect.quoteIdentifier("product", "product_name") + "]]>\n"
+ " </SQL>\n"
+ " </NameExpression>\n"
+ " </Level>\n"
Expand All @@ -8441,6 +8454,7 @@ public void testNameExpressionSnowflake() {
"[Example.Example Hierarchy].[Non-Zero].[Juice].Children",
"[Example.Example Hierarchy].[Non-Zero].[Juice].[Washington Berry Juice]");
}

}

// End BasicQueryTest.java

0 comments on commit 1033547

Please sign in to comment.