Skip to content

Commit

Permalink
treat filter axis like any other, fix sort order and exclusions for c…
Browse files Browse the repository at this point in the history
…rossjoin queries on an axis

git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@354 c6a108a4-781c-0410-a6c6-c2d559e19af0
  • Loading branch information
pstoellberger committed Oct 7, 2010
1 parent a07775e commit 633b604
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 31 deletions.
37 changes: 37 additions & 0 deletions src/org/olap4j/mdx/CallNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,43 @@ public CallNode deepCopy() {
this.syntax,
MdxUtil.deepCopyList(argList));
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((argList == null) ? 0 : argList.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((syntax == null) ? 0 : syntax.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CallNode other = (CallNode) obj;
if (argList == null) {
if (other.argList != null)
return false;
} else if (!argList.equals(other.argList))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (syntax == null) {
if (other.syntax != null)
return false;
} else if (!syntax.equals(other.syntax))
return false;
return true;
}
}

// End CallNode.java
105 changes: 74 additions & 31 deletions src/org/olap4j/query/Olap4jNodeConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,14 @@ private static CallNode generateListTupleCall(List<ParseTreeNode> cnodes) {
cnodes);
}

protected static CallNode generateCrossJoin(List<Selection> selections) {
ParseTreeNode sel1 = toOlap4j(selections.remove(0));
protected static CallNode generateCrossJoin(List<ParseTreeNode> selections)
{
ParseTreeNode sel1 = selections.remove(0);
if (sel1 instanceof MemberNode) {
sel1 = generateSetCall(sel1);
}
if (selections.size() == 1) {
ParseTreeNode sel2 = toOlap4j(selections.get(0));
ParseTreeNode sel2 = selections.get(0);
if (sel2 instanceof MemberNode) {
sel2 = generateSetCall(sel2);
}
Expand All @@ -102,9 +103,9 @@ protected static CallNode generateCrossJoin(List<Selection> selections) {
}
}

protected static CallNode generateUnion(List<List<Selection>> unions) {
protected static CallNode generateUnion(List<List<ParseTreeNode>> unions) {
if (unions.size() > 2) {
List<Selection> first = unions.remove(0);
List<ParseTreeNode> first = unions.remove(0);
return new CallNode(
null, "Union", Syntax.Function,
generateCrossJoin(first),
Expand All @@ -118,7 +119,7 @@ protected static CallNode generateUnion(List<List<Selection>> unions) {
}

protected static CallNode generateHierarchizeUnion(
List<List<Selection>> unions)
List<List<ParseTreeNode>> unions)
{
return new CallNode(
null, "Hierarchize", Syntax.Function,
Expand All @@ -136,42 +137,94 @@ protected static CallNode generateHierarchizeUnion(
private static void generateUnionsRecursively(
QueryAxis axis,
int dim,
List<Selection> curr,
List<List<Selection>> unions,
List<ParseTreeNode> curr,
List<List<ParseTreeNode>> unions,
List<Selection> selsWithContext,
List<List<Selection>> contextUnions)
List<List<ParseTreeNode>> contextUnions)
{
for (Selection sel : axis.getDimensions().get(dim).getInclusions()) {
ParseTreeNode exceptSet = null;
QueryDimension qDim = axis.getDimensions().get(dim);

List<Selection> exclusionSelections = qDim.getExclusions();
List<ParseTreeNode> exclusionNodes = new ArrayList<ParseTreeNode>();

// Check if any exclusions are selected for this dimension
// and convert them to a list of nodes and then later a set
for (Selection exclusion : exclusionSelections) {
exclusionNodes.add(toOlap4j(exclusion));
}
if (exclusionNodes.size() > 0) {
exceptSet = generateListSetCall(exclusionNodes);
}

for (Selection sel : qDim.getInclusions()) {
ParseTreeNode selectionNode = toOlap4j(sel);
// If a sort Order was specified for this dimension
// apply it for this inclusion
if (qDim.getSortOrder() != null) {
CallNode currentMemberNode = new CallNode(
null,
"CurrentMember",
Syntax.Property,
new DimensionNode(null, sel.getDimension()));
CallNode currentMemberNameNode = new CallNode(
null,
"Name",
Syntax.Property,
currentMemberNode);
selectionNode =
new CallNode(
null,
"Order",
Syntax.Function,
generateSetCall(selectionNode),
currentMemberNameNode,
LiteralNode.createSymbol(
null,
qDim.getSortOrder().name()));
}
// If there are exlclusions wrap the ordered selection
// in an Except() function
if (exceptSet != null) {
selectionNode = new CallNode(
null,
"Except",
Syntax.Function,
generateSetCall(selectionNode),
exceptSet);
}
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>();
ArrayList<ParseTreeNode> sels =
new ArrayList<ParseTreeNode>();
for (int i = 0; i < axis.getDimensions().size(); i++) {
if (dim == i) {
sels.add(sel);
sels.add(selectionNode);
} 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);
sels.add(toOlap4j(selection));
found = true;
}
}
if (!found) {
// add the first selection of the dimension
if (dimension.getInclusions().size() > 0) {
sels.add(dimension.getInclusions().get(0));
sels.add(toOlap4j(dimension.getInclusions().get(0)));
}
}
}
Expand All @@ -180,11 +233,11 @@ private static void generateUnionsRecursively(
selsWithContext.add(sel);
}
} else {
List<Selection> ncurr = new ArrayList<Selection>();
List<ParseTreeNode> ncurr = new ArrayList<ParseTreeNode>();
if (curr != null) {
ncurr.addAll(curr);
}
ncurr.add(sel);
ncurr.add(selectionNode);
if (dim == axis.getDimensions().size() - 1) {
// last dimension
unions.add(ncurr);
Expand All @@ -206,29 +259,19 @@ private static void generateUnionsRecursively(
private static AxisNode toOlap4j(QueryAxis axis) {
CallNode callNode = null;
int numDimensions = axis.getDimensions().size();
if (axis.getLocation() == Axis.FILTER) {
// REVIEW : This part is not right. Fix this.
List<ParseTreeNode> members = new ArrayList<ParseTreeNode>();
for (int dimNo = 0; dimNo < numDimensions; dimNo++) {
QueryDimension dimension =
axis.getDimensions().get(dimNo);
if (dimension.getInclusions().size() == 1) {
members.addAll(toOlap4j(dimension));
}
}
callNode = generateListTupleCall(members);
} else if (numDimensions == 0) {
if (numDimensions == 0) {
return null;
} else if (numDimensions == 1) {
QueryDimension dimension = axis.getDimensions().get(0);
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<List<ParseTreeNode>> unions =
new ArrayList<List<ParseTreeNode>>();
List<Selection> selsWithContext = new ArrayList<Selection>();
List<List<Selection>> contextUnions =
new ArrayList<List<Selection>>();
List<List<ParseTreeNode>> contextUnions =
new ArrayList<List<ParseTreeNode>>();
generateUnionsRecursively(
axis, 0, null, unions, selsWithContext, contextUnions);
unions.addAll(contextUnions);
Expand Down

0 comments on commit 633b604

Please sign in to comment.