Skip to content

Commit

Permalink
Added a function to QueryDimension to allow hierarchization of the in…
Browse files Browse the repository at this point in the history
…cluded member selections. Also added a regression test to OlapTest.

git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@271 c6a108a4-781c-0410-a6c6-c2d559e19af0
  • Loading branch information
lucboudreau committed Jul 21, 2009
1 parent f7363a7 commit 72cf6cc
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 1 deletion.
36 changes: 35 additions & 1 deletion src/org/olap4j/query/Olap4jNodeConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,41 @@ private static List<ParseTreeNode> toOlap4j(QueryDimension dimension) {
} else {
listWithExclusions.addAll(orderedList);
}
return listWithExclusions;

// Do we need to wrap it all in a Hierarchize function?
List<ParseTreeNode> listWithHierarchy =
new ArrayList<ParseTreeNode>();
if (dimension.getHierarchizeMode() != null) {
CallNode hierarchyNode;
// There are two modes available, PRE and POST.
if (dimension.getHierarchizeMode().equals(
QueryDimension.HierarchizeMode.PRE))
{
// In pre mode, we don't add the "POST" literal.
hierarchyNode = new CallNode(
null,
"Hierarchize",
Syntax.Function,
generateListSetCall(listWithExclusions));
} else if (dimension.getHierarchizeMode().equals(
QueryDimension.HierarchizeMode.POST))
{
hierarchyNode = new CallNode(
null,
"Hierarchize",
Syntax.Function,
generateListSetCall(listWithExclusions),
LiteralNode.createSymbol(
null, dimension.getHierarchizeMode().name()));
} else {
throw new RuntimeException("Missing value handler.");
}
listWithHierarchy.add(hierarchyNode);
} else {
listWithHierarchy.addAll(listWithExclusions);
}

return listWithHierarchy;
}

private static ParseTreeNode toOlap4j(Selection selection) {
Expand Down
26 changes: 26 additions & 0 deletions src/org/olap4j/query/QueryDimension.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class QueryDimension extends QueryNodeImpl {
private final Query query;
protected Dimension dimension;
private SortOrder sortOrder = null;
private HierarchizeMode hierarchizeMode = null;

public QueryDimension(Query query, Dimension dimension) {
super();
Expand Down Expand Up @@ -314,6 +315,20 @@ public SortOrder getSortOrder() {
return this.sortOrder;
}

public HierarchizeMode getHierarchizeMode() {
return hierarchizeMode;
}

/**
* Triggers the hierarchization of the included members within this
* QueryDimension.
* @param hierarchizeMode Whether or not to include the POST litteral
* inside the Hierarchize() MDX function call.
*/
public void setHierarchizeMode(HierarchizeMode hierarchizeMode) {
this.hierarchizeMode = hierarchizeMode;
}

private class SelectionList extends AbstractList<Selection> {
private final List<Selection> list = new ArrayList<Selection>();

Expand Down Expand Up @@ -353,6 +368,17 @@ public static enum SortOrder {
DESC
}

public static enum HierarchizeMode {
/**
* Parents are placed before children.
*/
PRE,
/**
* Parents are placed after children
*/
POST
}

void tearDown() {
for (Selection node : this.inclusions) {
((QueryNodeImpl)node).clearListeners();
Expand Down
68 changes: 68 additions & 0 deletions testsrc/org/olap4j/OlapTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.olap4j.mdx.SelectNode;
import org.olap4j.metadata.*;
import org.olap4j.query.*;
import org.olap4j.query.QueryDimension.HierarchizeMode;
import org.olap4j.query.QueryDimension.SortOrder;
import org.olap4j.query.Selection.Operator;
import org.olap4j.test.TestContext;
Expand Down Expand Up @@ -612,6 +613,73 @@ public void testDimensionsOrder() {
}
}

public void testDimensionsHierarchize() {
try {
Cube cube = getFoodmartCube("Sales");
if (cube == null) {
fail("Could not find Sales cube");
}
Query query = new Query("my query", cube);

// create selections

QueryDimension productDimension = query.getDimension("Product");
productDimension.include(
Selection.Operator.CHILDREN, "Product", "Drink");

QueryDimension storeDimension = query.getDimension("Store");
storeDimension.include(
Selection.Operator.INCLUDE_CHILDREN, "Store", "USA");
storeDimension.setHierarchizeMode(HierarchizeMode.POST);

QueryDimension timeDimension = query.getDimension("Time");

timeDimension.include(Selection.Operator.CHILDREN, "Time", "1997");

QueryDimension measuresDimension = query.getDimension("Measures");
measuresDimension.include("Measures", "Store Sales");


query.getAxis(Axis.ROWS).addDimension(productDimension);
query.getAxis(Axis.ROWS).addDimension(storeDimension);
query.getAxis(Axis.ROWS).addDimension(timeDimension);
query.getAxis(Axis.COLUMNS).addDimension(measuresDimension);

query.validate();

SelectNode mdx = query.getSelect();
String mdxString = mdx.toString();
TestContext.assertEqualsVerbose(
"SELECT\n"
+ "{[Measures].[Store Sales]} ON COLUMNS,\n"
+ "CrossJoin({[Product].[All Products].[Drink].Children}, "
+ "CrossJoin({Hierarchize({{[Store].[All Stores].[USA], "
+ "[Store].[All Stores].[USA].Children}}, POST)}, "
+ "{[Time].[1997].Children})) ON ROWS\n"
+ "FROM [Sales]",
mdxString);

storeDimension.setHierarchizeMode(HierarchizeMode.PRE);

query.validate();

mdx = query.getSelect();
mdxString = mdx.toString();
TestContext.assertEqualsVerbose(
"SELECT\n"
+ "{[Measures].[Store Sales]} ON COLUMNS,\n"
+ "CrossJoin({[Product].[All Products].[Drink].Children}, "
+ "CrossJoin({Hierarchize({{[Store].[All Stores].[USA], "
+ "[Store].[All Stores].[USA].Children}})}, "
+ "{[Time].[1997].Children})) ON ROWS\n"
+ "FROM [Sales]",
mdxString);
} catch (Exception e) {
e.printStackTrace();
fail();
}
}

/**
* This test makes sure that the generated MDX model is not affected
* by subsequent operations performed on the source query model.
Expand Down

0 comments on commit 72cf6cc

Please sign in to comment.