[Mondrian] RE: When iif has tupletypes with unequal lengths asarguments, we get an exception

Harun Pathan harunap at gmail.com
Fri Feb 8 08:14:52 EST 2008

Sorry for late reply. We have been working on this issue, and added a new
IIF Tuple instance as

    static final FunDefBase TUPLE_INSTANCE =
        new IifFunDef(
            "Returns one of two tuples determined by a logical test.",
            public Calc compileCall(ResolvedFunCall call, ExpCompiler
compiler) {
                final BooleanCalc booleanCalc =
                final Calc calc1 = compiler.compileTuple(call.getArg(1));
                final Calc calc2 = compiler.compileTuple(call.getArg(2));
                return new GenericCalc(call) {
                    public Object evaluate(Evaluator evaluator) {
                        final boolean b =
                        Calc calc = b ? calc1 : calc2;
                        return calc.evaluate(evaluator);

                    public Calc[] getCalcs() {
                        return new Calc[] {booleanCalc, calc1, calc2};

By incrementing conversion count for Numeric and value instance the
IIF(<expression>,<Tuple>,<Tuple>) version gets resolved as the best match.

We have added a rule to create a commontype between two tuples of unequal
sizes as a larger tuple with scalar types for the extra element types.

As the common tuple might be larger than the smaller original one the
savedMembers array in TupleValueCalc needs to be equal to the size of the
tuple evaluated by it.

    public Object evaluate(Evaluator evaluator) {
        final Member[] members = tupleCalc.evaluateTuple(evaluator);
        if (members == null) {
            return null;
        for (int i = 0; i < members.length; i++) {
            savedMembers[i] = evaluator.setContext(members[i]);
        final Object o = evaluator.evaluateCurrent();

    //Currently it is just evaluator.setContext(savedMembers[i]);
        for (int i = 0; i < members.length; i++) {
        return o;

Is there a better alternative to doing this ?

But this fix failed to work for IIF(<expression>,<Member>,<Tuple>) and
because in ealier fix we returned a scalar type as a common type between
member and a tuple.
But when these IIF gets resolved they gets resolved to TUPLE_INSTANCE, where
in we compile tuples and not scalars.

To fix this, we are thinking to change the common type between a tuple of
one Member and Tuple to a larger Tuple as above.


        if (type instanceof TupleType) {
            TupleType tupleType = (TupleType) type;
            if (tupleType.elementTypes.length == 1) {
                return new TupleType(new Type[]
            } else {
                return tupleType.computeCommonType(this,conversionCount); //
Currently it is:computeCommonType(tupleType.getValueType, conversionCount);


In TupleType, we create a new tupleType as the commontype for the MemberType
and follow the same logic which is used in case of two tuples.

Is it valid? Or do you think creating different IIF instances for
IIF(Expression, Member, Tuple) and IIF(Expression, Tuple, Member) is a good

We tried MDXs with following IIFs and all are working with the fixes
mentioned above:

IIF(Expression, Member, Tuple)
IIF(Expression, Tuple, Member)
IIF(Expression, Tuple, Tuple) // Tuples of same length
IIF(Expression, Tuple, Tuple) //Tuples of different length
IIF(Expression, Tuple, Tuple) //Tuples with different order of element Types

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.pentaho.org/pipermail/mondrian/attachments/20080208/4dc1fe25/attachment.html 

More information about the Mondrian mailing list