Skip to content

Commit

Permalink
MONDRIAN: Implement functions <Named Set>.Current, <Named Set>.Curren…
Browse files Browse the repository at this point in the history
…tOrdinal.

    Move implementation of InStr function from BuiltinFunTable to Vba.java,
    and implement another couple of overloadings.
    Make compiled expressions more typesafe with respect to members vs. tuples.
    Allow the key functions Order, Generate, Crossjoin to consume iterables as
    well as lists. This is necessary for named set ordinals to work correctly,
    but also allows us to handle large dimensions with less memory.

[git-p4: depot-paths = "//open/mondrian/": change = 11947]
  • Loading branch information
julianhyde committed Nov 12, 2008
1 parent 324afb8 commit 7e16461
Show file tree
Hide file tree
Showing 44 changed files with 3,642 additions and 1,238 deletions.
3 changes: 0 additions & 3 deletions src/main/mondrian/calc/IterCalc.java
Expand Up @@ -29,9 +29,6 @@ public interface IterCalc extends Calc {
* @return An Iterable of members or tuples, never null.
*/
Iterable evaluateIterable(Evaluator evaluator);
Iterable<Member> evaluateMemberIterable(Evaluator evaluator);
Iterable<Member[]> evaluateTupleIterable(Evaluator evaluator);

}

// End IterCalc.java
2 changes: 2 additions & 0 deletions src/main/mondrian/calc/ListCalc.java
Expand Up @@ -12,6 +12,8 @@
import java.util.List;

import mondrian.olap.Evaluator;
import mondrian.olap.type.Type;
import mondrian.olap.type.SetType;

/**
* Expression which evaluates a set of members or tuples to a list.
Expand Down
36 changes: 36 additions & 0 deletions src/main/mondrian/calc/MemberIterCalc.java
@@ -0,0 +1,36 @@
/*
// $Id$
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// Copyright (C) 2008-2008 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
package mondrian.calc;

import mondrian.olap.Evaluator;
import mondrian.olap.Member;
import mondrian.olap.type.SetType;

/**
* Expression which evaluates to an iterator over a set of members.
*
* @author jhyde
* @version $Id$
* @since Oct 26, 2008
*/
public interface MemberIterCalc extends IterCalc {
/**
* Evaluates an expression to yield a member iterator.
*
* @param evaluator Evaluation context
* @return A member iterator, never null.
*/
Iterable<Member> evaluateMemberIterable(Evaluator evaluator);

// override Calc.getType with stricter return type
SetType getType();
}

// End MemberIterCalc.java
4 changes: 4 additions & 0 deletions src/main/mondrian/calc/ResultStyle.java
Expand Up @@ -119,6 +119,10 @@ public enum ResultStyle {
ITERABLE,
MUTABLE_LIST,
LIST);

public static final List<ResultStyle> ANY_ONLY =
Arrays.asList(
ANY);
}

// End ResultStyle.java
37 changes: 37 additions & 0 deletions src/main/mondrian/calc/TupleIterCalc.java
@@ -0,0 +1,37 @@
/*
// $Id$
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// Copyright (C) 2008-2008 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
package mondrian.calc;

import mondrian.olap.Evaluator;
import mondrian.olap.Member;
import mondrian.olap.type.SetType;

/**
* Expression which evaluates to an iterator over a set of members.
*
* @author jhyde
* @version $Id$
* @since Oct 26, 2008
*/
public interface TupleIterCalc extends IterCalc {
/**
* Evaluates an expression to yield an iterator over tuples (arrays of
* members).
*
* @param evaluator Evaluation context
* @return A tuple iterator, never null.
*/
Iterable<Member []> evaluateTupleIterable(Evaluator evaluator);

// override Calc.getType with stricter return type
SetType getType();
}

// End TupleIterCalc.java
2 changes: 0 additions & 2 deletions src/main/mondrian/calc/TupleListCalc.java
Expand Up @@ -14,8 +14,6 @@
import mondrian.olap.Evaluator;
import mondrian.olap.Member;

// End ListCalc.java

/**
* Expression which evaluates a set of members or tuples to a list.
*
Expand Down
102 changes: 99 additions & 3 deletions src/main/mondrian/calc/impl/AbstractExpCompiler.java
Expand Up @@ -228,15 +228,75 @@ public ListCalc compileList(Exp exp) {
}

public ListCalc compileList(Exp exp, boolean mutable) {
final List<ResultStyle> resultStyleList;
if (mutable) {
return (ListCalc) compileAs(exp, null, ResultStyle.MUTABLELIST_ONLY);
resultStyleList = ResultStyle.MUTABLELIST_ONLY;
} else {
return (ListCalc) compileAs(exp, null, ResultStyle.LIST_ONLY);
resultStyleList = ResultStyle.LIST_ONLY;
}
Calc calc = compileAs(exp, null, resultStyleList);
if (calc instanceof ListCalc) {
return (ListCalc) calc;
}
if (calc == null) {
calc = compileAs(exp, null, ResultStyle.ITERABLE_ANY);
assert calc != null;
}
if (calc instanceof IterCalc) {
if (((SetType) calc.getType()).getArity() == 1) {
return toList((MemberIterCalc) calc);
} else {
return toList((TupleIterCalc) calc);
}
} else {
// A set can only be implemented as a list or an iterable.
throw Util.newInternal("Cannot convert calc to list: " + calc);
}
}

/**
* Converts an iterable to a list.
*
* @param calc Calc
* @return List calculation.
*/
private MemberListCalc toList(MemberIterCalc calc) {
return new IterableMemberListCalc(calc);
}

/**
* Converts an iterable to a list.
*
* @param calc Calc
* @return List calculation.
*/
private TupleListCalc toList(TupleIterCalc calc) {
return new IterableTupleListCalc(calc);
}

public IterCalc compileIter(Exp exp) {
return (IterCalc) compileAs(exp, null, ResultStyle.ITERABLE_ONLY);
Calc calc = compileAs(exp, null, ResultStyle.ITERABLE_ONLY);
if (calc == null) {
calc = compileAs(exp, null, ResultStyle.ANY_ONLY);
assert calc != null;
}
if (calc instanceof IterCalc) {
return (IterCalc) calc;
} else {
if (((SetType) calc.getType()).getArity() == 1) {
return toIter((MemberListCalc) calc);
} else {
return toIter((TupleListCalc) calc);
}
}
}

private MemberIterCalc toIter(final MemberListCalc memberListCalc) {
return new MemberListIterCalc(memberListCalc);
}

private TupleIterCalc toIter(final TupleListCalc tupleListCalc) {
return new TupleListIterCalc(tupleListCalc);
}

public BooleanCalc compileBoolean(Exp exp) {
Expand Down Expand Up @@ -422,6 +482,42 @@ public Object getCachedDefaultValue() {
return cachedDefaultValue;
}
}

/**
* Adapter that converts a member list calc into a member iter calc.
*/
private static class MemberListIterCalc extends AbstractMemberIterCalc {
private final MemberListCalc memberListCalc;

public MemberListIterCalc(MemberListCalc memberListCalc) {
super(
new DummyExp(memberListCalc.getType()),
new Calc[]{memberListCalc});
this.memberListCalc = memberListCalc;
}

public Iterable<Member> evaluateMemberIterable(Evaluator evaluator) {
return memberListCalc.evaluateMemberList(evaluator);
}
}

/**
* Adapter that converts a tuple list calc into a tuple iter calc.
*/
private static class TupleListIterCalc extends AbstractTupleIterCalc {
private final TupleListCalc tupleListCalc;

public TupleListIterCalc(TupleListCalc tupleListCalc) {
super(
new DummyExp(tupleListCalc.getType()),
new Calc[]{tupleListCalc});
this.tupleListCalc = tupleListCalc;
}

public Iterable<Member[]> evaluateTupleIterable(Evaluator evaluator) {
return tupleListCalc.evaluateTupleList(evaluator);
}
}
}

// End AbstractExpCompiler.java
26 changes: 21 additions & 5 deletions src/main/mondrian/calc/impl/AbstractIterCalc.java
Expand Up @@ -16,6 +16,7 @@
import mondrian.olap.Exp;
import mondrian.olap.Member;
import mondrian.olap.type.SetType;
import mondrian.olap.type.TupleType;

/**
* Abstract implementation of the {@link mondrian.calc.IterCalc} interface.
Expand All @@ -30,9 +31,11 @@
*/

public abstract class AbstractIterCalc
extends AbstractCalc
implements IterCalc {
extends AbstractCalc
implements IterCalc
{
private final Calc[] calcs;
protected final boolean tuple;

/**
* Creates an abstract implementation of a compiled expression which returns
Expand All @@ -46,11 +49,25 @@ protected AbstractIterCalc(Exp exp, Calc[] calcs) {
super(exp);
this.calcs = calcs;
assert getType() instanceof SetType : "expecting a set: " + getType();
this.tuple = ((SetType) exp.getType()).getArity() != 1;
}

public Object evaluate(Evaluator evaluator) {
final Iterable iter = evaluateIterable(evaluator);
return iter;
return evaluateIterable(evaluator);
}

/**
* Helper method with which to implement {@link #evaluateIterable}
* if you have implemented {@link #evaluateMemberIterable} and
* {@link #evaluateTupleIterable}.
*
* @param evaluator Evaluator
* @return List
*/
protected Iterable evaluateEitherIterable(Evaluator evaluator) {
return tuple
? evaluateTupleIterable(evaluator)
: evaluateMemberIterable(evaluator);
}

public Calc[] getCalcs() {
Expand All @@ -70,7 +87,6 @@ public Iterable<Member> evaluateMemberIterable(Evaluator evaluator) {
public Iterable<Member[]> evaluateTupleIterable(Evaluator evaluator) {
return (Iterable<Member[]>) evaluateIterable(evaluator);
}

}

// End AbstractIterCalc.java
23 changes: 22 additions & 1 deletion src/main/mondrian/calc/impl/AbstractListCalc.java
Expand Up @@ -16,6 +16,8 @@
import mondrian.olap.Exp;
import mondrian.olap.Member;
import mondrian.olap.type.SetType;
import mondrian.olap.type.TupleType;
import mondrian.olap.type.Type;

/**
* Abstract implementation of the {@link mondrian.calc.ListCalc} interface.
Expand All @@ -34,6 +36,7 @@ public abstract class AbstractListCalc
{
private final Calc[] calcs;
private final boolean mutable;
protected final boolean tuple;

/**
* Creates an abstract implementation of a compiled expression which returns
Expand All @@ -60,7 +63,12 @@ protected AbstractListCalc(Exp exp, Calc[] calcs, boolean mutable) {
super(exp);
this.calcs = calcs;
this.mutable = mutable;
assert getType() instanceof SetType : "expecting a set: " + getType();
assert type instanceof SetType : "expecting a set: " + getType();
this.tuple = getType().getArity() != 1;
}

public SetType getType() {
return (SetType) super.getType();
}

public Object evaluate(Evaluator evaluator) {
Expand Down Expand Up @@ -89,6 +97,19 @@ public List<Member[]> evaluateTupleList(Evaluator evaluator) {
return (List<Member[]>) evaluateList(evaluator);
}

/**
* Helper method with which to implement {@link #evaluateList}
* if you have implemented {@link #evaluateMemberList} and
* {@link #evaluateTupleList}.
*
* @param evaluator Evaluator
* @return List
*/
protected List evaluateEitherList(Evaluator evaluator) {
return tuple
? evaluateTupleList(evaluator)
: evaluateMemberList(evaluator);
}
}

// End AbstractListCalc.java

0 comments on commit 7e16461

Please sign in to comment.