Skip to content

Commit

Permalink
Cosmetic stuff. Mainly checkFile exceptions.
Browse files Browse the repository at this point in the history
git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@306 c6a108a4-781c-0410-a6c6-c2d559e19af0
  • Loading branch information
julianhyde committed Apr 5, 2010
1 parent 764f203 commit 518c99b
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 162 deletions.
212 changes: 120 additions & 92 deletions src/org/olap4j/query/Olap4jNodeConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2007-2009 Julian Hyde
// Copyright (C) 2007-2010 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
Expand Down Expand Up @@ -82,93 +82,119 @@ private static CallNode generateListTupleCall(List<ParseTreeNode> cnodes) {
Syntax.Parentheses,
cnodes);
}

protected static CallNode generateCrossJoin(List<Selection> selections) {
ParseTreeNode sel1 = toOlap4j(selections.remove(0));
if (sel1 instanceof MemberNode) {
sel1 = generateSetCall(sel1);
}
if (selections.size() == 1) {
ParseTreeNode sel2 = toOlap4j(selections.get(0));
if (sel2 instanceof MemberNode) {
sel2 = generateSetCall(sel2);
}

return new CallNode( null, "CrossJoin", Syntax.Function, sel1, sel2);
} else {
return new CallNode( null, "CrossJoin", Syntax.Function, sel1, generateCrossJoin(selections));
}
ParseTreeNode sel1 = toOlap4j(selections.remove(0));
if (sel1 instanceof MemberNode) {
sel1 = generateSetCall(sel1);
}
if (selections.size() == 1) {
ParseTreeNode sel2 = toOlap4j(selections.get(0));
if (sel2 instanceof MemberNode) {
sel2 = generateSetCall(sel2);
}
return new CallNode(
null, "CrossJoin", Syntax.Function, sel1, sel2);
} else {
return new CallNode(
null, "CrossJoin", Syntax.Function, sel1,
generateCrossJoin(selections));
}
}

protected static CallNode generateUnion(List<List<Selection>> unions) {
if (unions.size() > 2) {
List<Selection> first = unions.remove(0);
return new CallNode( null, "Union", Syntax.Function, generateCrossJoin(first), generateUnion(unions));
} else {
return new CallNode( null, "Union", Syntax.Function, generateCrossJoin(unions.get(0)), generateCrossJoin(unions.get(1)));
}
if (unions.size() > 2) {
List<Selection> first = unions.remove(0);
return new CallNode(
null, "Union", Syntax.Function,
generateCrossJoin(first),
generateUnion(unions));
} else {
return new CallNode(
null, "Union", Syntax.Function,
generateCrossJoin(unions.get(0)),
generateCrossJoin(unions.get(1)));
}
}

protected static CallNode generateHierarchizeUnion(List<List<Selection>> unions) {
return new CallNode(null, "Hierarchize", Syntax.Function,
generateUnion(unions)
);

protected static CallNode generateHierarchizeUnion(
List<List<Selection>> unions)
{
return new CallNode(
null, "Hierarchize", Syntax.Function,
generateUnion(unions));
}

/**
*
* Algorithm:
* - generate all combinations of dimension groups
* - skip the selection if has a context
* - for all the selections with context, resolve them last
* - union all combinations
* Algorithm:<ul>
* <li>generate all combinations of dimension groups
* <li>skip the selection if has a context
* <li>for all the selections with context, resolve them last
* <li>union all combinations
* </ul>
*/
private static void generateUnionsRecursively(QueryAxis axis, int dim, List<Selection> curr, List<List<Selection>> unions, List<Selection> selsWithContext, List<List<Selection>> contextUnions) {
for (Selection sel : axis.getDimensions().get(dim).getInclusions()) {

if (sel.getSelectionContext() != null && sel.getSelectionContext().size() > 0) {
// selections that have a context are treated differently than the
// rest of the MDX generation
if (!selsWithContext.contains(sel)) {
ArrayList<Selection> sels = new ArrayList<Selection>();
for (int i = 0; i < axis.getDimensions().size(); i++) {
if (dim == i) {
sels.add(sel);
} else {
// return the selections in the correct dimensional order
QueryDimension dimension = axis.getDimensions().get(i);
boolean found = false;
for (Selection selection : sel.getSelectionContext()) {
if (selection.getDimension().equals(dimension.getDimension())) {
sels.add(selection);
found = true;
}
}
if (!found) {
// add the first selection of the dimension
if (dimension.getInclusions().size() > 0) {
sels.add(dimension.getInclusions().get(0));
}
}
}
}
contextUnions.add(sels);
selsWithContext.add(sel);
}
} else {
List<Selection> ncurr = new ArrayList<Selection>();
if (curr != null) {
ncurr.addAll(curr);
}
ncurr.add(sel);
if (dim == axis.getDimensions().size() - 1) {
// last dimension
unions.add(ncurr);
} else {
generateUnionsRecursively(axis, dim + 1, ncurr, unions, selsWithContext, contextUnions);
}
}
}
private static void generateUnionsRecursively(
QueryAxis axis,
int dim,
List<Selection> curr,
List<List<Selection>> unions,
List<Selection> selsWithContext,
List<List<Selection>> contextUnions)
{
for (Selection sel : axis.getDimensions().get(dim).getInclusions()) {
if (sel.getSelectionContext() != null
&& sel.getSelectionContext().size() > 0)
{
// selections that have a context are treated
// differently than the rest of the MDX generation
if (!selsWithContext.contains(sel)) {
ArrayList<Selection> sels = new ArrayList<Selection>();
for (int i = 0; i < axis.getDimensions().size(); i++) {
if (dim == i) {
sels.add(sel);
} else {
// return the selections in the correct
// dimensional order
QueryDimension dimension =
axis.getDimensions().get(i);
boolean found = false;
for (Selection selection
: sel.getSelectionContext())
{
if (selection.getDimension().equals(
dimension.getDimension()))
{
sels.add(selection);
found = true;
}
}
if (!found) {
// add the first selection of the dimension
if (dimension.getInclusions().size() > 0) {
sels.add(dimension.getInclusions().get(0));
}
}
}
}
contextUnions.add(sels);
selsWithContext.add(sel);
}
} else {
List<Selection> ncurr = new ArrayList<Selection>();
if (curr != null) {
ncurr.addAll(curr);
}
ncurr.add(sel);
if (dim == axis.getDimensions().size() - 1) {
// last dimension
unions.add(ncurr);
} else {
generateUnionsRecursively(
axis, dim + 1, ncurr, unions, selsWithContext,
contextUnions);
}
}
}
}

/*
Expand Down Expand Up @@ -198,17 +224,19 @@ private static AxisNode toOlap4j(QueryAxis axis) {
List<ParseTreeNode> members = toOlap4j(dimension);
callNode = generateListSetCall(members);
} else {
// generate union sets of selections in each dimension
List<List<Selection>> unions = new ArrayList<List<Selection>>();
List<Selection> selsWithContext = new ArrayList<Selection>();
List<List<Selection>> contextUnions = new ArrayList<List<Selection>>();
generateUnionsRecursively(axis, 0, null, unions, selsWithContext, contextUnions);
unions.addAll(contextUnions);
if (unions.size() > 1) {
callNode = generateHierarchizeUnion(unions);
} else {
callNode = generateCrossJoin(unions.get(0));
}
// generate union sets of selections in each dimension
List<List<Selection>> unions = new ArrayList<List<Selection>>();
List<Selection> selsWithContext = new ArrayList<Selection>();
List<List<Selection>> contextUnions =
new ArrayList<List<Selection>>();
generateUnionsRecursively(
axis, 0, null, unions, selsWithContext, contextUnions);
unions.addAll(contextUnions);
if (unions.size() > 1) {
callNode = generateHierarchizeUnion(unions);
} else {
callNode = generateCrossJoin(unions.get(0));
}
}

// We might need to sort the whole axis.
Expand Down
28 changes: 19 additions & 9 deletions src/org/olap4j/query/QueryDimension.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2007-2009 Julian Hyde
// Copyright (C) 2007-2010 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
Expand Down Expand Up @@ -116,7 +116,7 @@ public Selection include(String... nameParts) throws OlapException {
}

public Selection createSelection(String... nameParts) throws OlapException {
return this.createSelection(Selection.Operator.MEMBER, nameParts);
return this.createSelection(Selection.Operator.MEMBER, nameParts);
}

/**
Expand Down Expand Up @@ -145,7 +145,7 @@ public Selection include(
member);
}
}

public Selection createSelection(
Selection.Operator operator,
String... nameParts) throws OlapException
Expand Down Expand Up @@ -173,7 +173,7 @@ public Selection include(Member member) {
}

public Selection createSelection(Member member) {
return createSelection(Selection.Operator.MEMBER, member);
return createSelection(Selection.Operator.MEMBER, member);
}

/**
Expand Down Expand Up @@ -487,9 +487,12 @@ public void clearSort() {
/**
* Returns the current mode of hierarchization, or null
* if no hierarchization is currently performed.
* This capability is only available when a single dimension is selected on an axis.
*
* <p>This capability is only available when a single dimension is
* selected on an axis
*
* @return Either a hierarchization mode value or null
* if no hierarchization is currently performed.
* if no hierarchization is currently performed.
*/
public HierarchizeMode getHierarchizeMode() {
return hierarchizeMode;
Expand All @@ -498,9 +501,13 @@ public HierarchizeMode getHierarchizeMode() {
/**
* Triggers the hierarchization of the included members within this
* QueryDimension.
*
* <p>The dimension inclusions will be wrapped in an MDX Hierarchize
* function call.
* This capability is only available when a single dimension is selected on an axis.
*
* <p>This capability is only available when a single dimension is
* selected on an axis.
*
* @param hierarchizeMode If parents should be included before or after
* their children. (Equivalent to the POST/PRE MDX literal for the
* Hierarchize() function)
Expand All @@ -511,8 +518,11 @@ public void setHierarchizeMode(HierarchizeMode hierarchizeMode) {
}

/**
* Tells the QueryDimension not to hierarchize it's included selections.
* This capability is only available when a single dimension is selected on an axis.
* Tells the QueryDimension not to hierarchize its included
* selections.
*
* <p>This capability is only available when a single dimension is
* selected on an axis.
*/
public void clearHierarchizeMode() {
this.hierarchizeMode = null;
Expand Down
8 changes: 5 additions & 3 deletions src/org/olap4j/query/Selection.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2007-2008 Julian Hyde
// Copyright (C) 2007-2010 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
Expand Down Expand Up @@ -46,8 +46,10 @@ public interface Selection extends QueryNode {
String getHierarchyName();

/**
* The selection context includes selections from other dimensions that help determine the entire
* context of a selection, so drill down is possible.
* The selection context includes selections from other dimensions that
* help determine the entire context of a selection, so drill down is
* possible.
*
* @return list of selections
*/
List<Selection> getSelectionContext();
Expand Down
14 changes: 7 additions & 7 deletions src/org/olap4j/query/SelectionImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2007-2008 Julian Hyde
// Copyright (C) 2007-2010 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
Expand Down Expand Up @@ -113,18 +113,18 @@ void tearDown() {
}

public List<Selection> getSelectionContext() {
return selectionContext;
return selectionContext;
}

public void addContext(Selection selection) {
if (selectionContext == null) {
selectionContext = new ArrayList<Selection>();
}
selectionContext.add(selection);
if (selectionContext == null) {
selectionContext = new ArrayList<Selection>();
}
selectionContext.add(selection);
}

public void removeContext(Selection selection) {
selectionContext.remove(selection);
selectionContext.remove(selection);
}
}

Expand Down
6 changes: 4 additions & 2 deletions testsrc/org/olap4j/ConnectionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2556,15 +2556,17 @@ public void testCubeDimensionsOrder() throws Exception {
* <p>Test case for
* <a href="http://sourceforge.net/tracker/?func=detail&aid=2951656&group_id=168953&atid=848534">
* bug 2951656, "Olap4j should not throw IllegalArgumentException"</a>.
*
* @throws java.sql.SQLException on error
*/
public void _testDimensionProperties() throws SQLException {
public void testDimensionProperties() throws SQLException {
connection = tester.createConnection();
OlapConnection olapConnection =
tester.getWrapper().unwrap(connection, OlapConnection.class);
String mdx =
"select {[Product].[Product Family].Members} ON COLUMNS,\n"
+ "{[Store].[Store Name].Members}\n"
+ " DIMENSION PROPERTIES [Store].[Store Sqft] ON ROWS\n"
+ " DIMENSION PROPERTIES [Store].[Store Name].[Store Sqft] ON ROWS\n"
+ "from [Sales]\n"
+ "where [Measures].[Unit Sales]";
PreparedOlapStatement pstmt =
Expand Down
Loading

0 comments on commit 518c99b

Please sign in to comment.