<div class="gmail_quote"><div>Sorry for late reply. We have been working on this issue, and added a new IIF Tuple instance as <br><br> static final FunDefBase TUPLE_INSTANCE =<br> new IifFunDef(<br> "IIf",<br>
"Returns one of two tuples determined by a logical test.",<br> "ftbtt")<br> {<br> public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {<br> final BooleanCalc booleanCalc =<br>
compiler.compileBoolean(call.getArg(0));<br> final Calc calc1 = compiler.compileTuple(call.getArg(1));<br> final Calc calc2 = compiler.compileTuple(call.getArg(2));<br> return new GenericCalc(call) {<br>
public Object evaluate(Evaluator evaluator) {<br> final boolean b =<br> booleanCalc.evaluateBoolean(evaluator);<br> Calc calc = b ? calc1 : calc2;<br>
return calc.evaluate(evaluator);<br> }<br><br> public Calc[] getCalcs() {<br> return new Calc[] {booleanCalc, calc1, calc2};<br> }<br>
};<br> }<br> };<br><br><br>By incrementing conversion count for Numeric and value instance the IIF(<expression>,<Tuple>,<Tuple>) version gets resolved as the best match.<br>
<br>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.<br><br>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 <br>
tuple evaluated by it.<br><br> public Object evaluate(Evaluator evaluator) {<br> final Member[] members = tupleCalc.evaluateTuple(evaluator);<br> if (members == null) {<br> return null;<br> }<br>
for (int i = 0; i < members.length; i++) {<br> savedMembers[i] = evaluator.setContext(members[i]);<br> }<br> final Object o = evaluator.evaluateCurrent();<br><br> //Currently it is just evaluator.setContext(savedMembers[i]);<br>
for (int i = 0; i < members.length; i++) {<br> evaluator.setContext(savedMembers[i]);<br> }<br> return o;<br> }<br><br>Is there a better alternative to doing this ?<br><br>But this fix failed to work for IIF(<expression>,<Member>,<Tuple>) and IIF(<expression>,<Tuple>,<Member>),<br>
because in ealier fix we returned a scalar type as a common type between member and a tuple. <br>But when these IIF gets resolved they gets resolved to TUPLE_INSTANCE, where in we compile tuples and not scalars.<br><br>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.<br>
<br>MemberType:<br><br><br> if (type instanceof TupleType) {<br> TupleType tupleType = (TupleType) type;<br> if (tupleType.elementTypes.length == 1) {<br> return new TupleType(new Type[] {type}).computeCommonType(tupleType,<br>
conversionCount);<br> } else {<br> return tupleType.computeCommonType(this,conversionCount); // Currently it is:computeCommonType(tupleType.getValueType, conversionCount);<br>
}<br> }<br><br><br>TupleType:<br><br>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.<br><br>Is it valid? Or do you think creating different IIF instances for <br>
IIF(Expression, Member, Tuple) and IIF(Expression, Tuple, Member) is a good idea.<br><br><br>We tried MDXs with following IIFs and all are working with the fixes mentioned above:<br><br>IIF(Expression, Member, Tuple)<br>IIF(Expression, Tuple, Member)<br>
IIF(Expression, Tuple, Tuple) // Tuples of same length<br>IIF(Expression, Tuple, Tuple) //Tuples of different length<br>IIF(Expression, Tuple, Tuple) //Tuples with different order of element Types<br><br><br>Harun<br></div>
</div>