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

Julian Hyde jhyde at pentaho.org
Tue Feb 5 19:18:54 EST 2008

A version of Iif that takes arguments of the form Iif(<Boolean>, <Tuple>,
<Tuple>) is the right approach. You are noticing that a <Tuple> can
implicitly be converted into a <Scalar>, and therefore any call to that form
of Iif should also match a call to Iif(<Boolean>, <Scalar>, <Scalar>) but
that conversion comes at a cost of increasing conversionCount, and therefore
the validator should prefer the former form.
Maybe you need to make sure that the implicit conversion from Tuple to
Scalar is incrementing conversionCount.
Also, you will need to change the rules so that given two tuple types (A, B)
and (A, B, C) the common type is (A, B, C). More generally the common type
for (A, B) and (B, C) is (A, B, C). You get the idea.
Why is this valid? Because the expression ([Gender].[F]) is equivalent to
([Gender].[F], [Measures].CurrentMember) -- it always returns the same
result -- and therefore you can safely broaden a tuple type.


From: mondrian-bounces at pentaho.org [mailto:mondrian-bounces at pentaho.org] On
Behalf Of Harun Pathan
Sent: Tuesday, February 05, 2008 3:21 AM
To: mondrian at pentaho.org
Subject: [Mondrian] When iif has tupletypes with unequal lengths
asarguments, we get an exception

Hi Julian,
Sorry for creating a new post, I did not receive your reply in my mailbox.
Thanks for the quick review on the solution we came up with.
We totally agree that we need to put in the best solution to the problem and
not the one that works.After more detailed analysis we found that it is a
lot more 
involved and it would be extremely helpful if we could get your insight on
the points mentioned below.


MEMBER [Gender].agg
AS 'IIF(Measures.currentMember is [Measures].[Unit Sales], ([Store].[All
Stores],[Gender].[All Gender],measures.[unit sales]),
([Store].[All Stores],[Gender].[All Gender]) )', SOLVE_ORDER = 4
SELECT {[Measures].[unit sales]} ON 0,
{{[Gender].[Gender].MEMBERS},{([Gender].agg)}} on 1 FROM sales

In the above MDX the common return type in the iif is a TupleType.
In the first tuple we have a measure and hence we know that the tuple
evaluates to a numeric value and we can compile it to yield a scalar result
in the IIF.
In the second tuple we dont know the return type while the iif is getting

When the iif is resolved it gets resolved to 

1) IIF(boolean,Numeric expression,Numeric expression) currently

We tried adding a new IIF(boolean,Tuple,Tuple) definition 

static final FunDefBase TUPLE_INSTANCE =
        new IifFunDef(
            "Returns one of two numeric values determined by a logical
            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};

but we end up resolving to two IIF definitions ( Numeric Instance and Tuple
Instance ) and hence errors out.

Would it be right to create a commontype between the two tuples as
TupleType(MemberType,MemberType ,ScalarType) wherein we assume that the
common types for the 
extra parameters in the larger tuple are scalar types.But this still leaves
us with the issue of two IIFs getting resolved.
We tried commenting out the numeric one and it works.

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

More information about the Mondrian mailing list