<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
<META content="MSHTML 6.00.5730.11" name=GENERATOR></HEAD>
<BODY>
<DIV><SPAN class=421330213-18042007><FONT face=Arial size=2>Since the
introduction of ITERABLE into mondrian, I have a user defined function that is
broken under some </FONT></SPAN><SPAN class=421330213-18042007><FONT face=Arial
size=2>circumstances.</FONT></SPAN></DIV>
<DIV><SPAN class=421330213-18042007><FONT face=Arial
size=2></FONT></SPAN> </DIV>
<DIV><SPAN class=421330213-18042007><FONT face=Arial size=2>I have a user
defined function, implementing an Iif() statement that accepts Sets. The
return type is SetType(null).</FONT></SPAN></DIV>
<DIV><SPAN class=421330213-18042007><FONT face=Arial
size=2></FONT></SPAN> </DIV>
<DIV><SPAN class=421330213-18042007><FONT face=Arial size=2>But when using this
function in a crossjoin, it fails with a ResultStyleException, since UdfResolver
and the underlying </FONT></SPAN><SPAN class=421330213-18042007><FONT face=Arial
size=2>AbstractCalc.getResultStyle() always returns VALUE.</FONT></SPAN></DIV>
<DIV><SPAN class=421330213-18042007><FONT face=Arial
size=2></FONT></SPAN> </DIV>
<DIV><SPAN class=421330213-18042007><FONT face=Arial size=2>Besides this
problem, there is another one with user defined functions, regardless of the
return type returned by getReturnType(), </FONT></SPAN><SPAN
class=421330213-18042007><FONT face=Arial size=2>mondrian
(FunDefBase.guessResultType) always looks to the first argument of the udf to
determine the result type. So it is not possible to defined
</FONT></SPAN><SPAN class=421330213-18042007><FONT face=Arial size=2>a Iif()
function with first argument the logical expression, and then the two set
arguments, since mondrian will assume that the UDF will </FONT></SPAN><SPAN
class=421330213-18042007><FONT face=Arial size=2>return a logical
expression.</FONT></SPAN></DIV>
<DIV><SPAN class=421330213-18042007><FONT face=Arial
size=2></FONT></SPAN> </DIV>
<DIV><SPAN class=421330213-18042007><FONT face=Arial size=2>The is a snapshot of
my UDF :</FONT></SPAN></DIV>
<DIV><SPAN class=421330213-18042007><FONT face=Arial
size=2></FONT></SPAN> </DIV>
<DIV><SPAN class=421330213-18042007><FONT face="Courier New" size=2>public class
VDWIIfSet implements UserDefinedFunction {<BR> // public
constructor<BR> public VDWIIfSet() {<BR>
}<BR> <BR> public String getName()
{<BR> return
"VDWIIfSet";<BR> }</FONT></SPAN></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><SPAN class=421330213-18042007><FONT face="Courier New"
size=2> public String getDescription()
{<BR> // ahh, logical expression must
not be the first since <BR> //
FunDefBase.guessResultType always looks at the first
argument<BR> // to guest the result
type<BR> return
"VDWIIfSet(<Set1>, <Set2>,<Logical
Expression>)";<BR> }</FONT></SPAN></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><SPAN class=421330213-18042007><FONT face="Courier New"
size=2> public Syntax getSyntax()
{<BR> return
Syntax.Function;<BR> }</FONT></SPAN></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><SPAN class=421330213-18042007><FONT face="Courier New"
size=2> public Type getReturnType(Type[] parameterTypes)
{<BR> return new
SetType(null);<BR> }</FONT></SPAN></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><SPAN class=421330213-18042007><FONT face="Courier New"
size=2> public Type[] getParameterTypes()
{<BR> return new Type[] {new
SetType(null),<BR>
new
SetType(null),<BR>
new BooleanType()};<BR> }</FONT></SPAN></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><SPAN class=421330213-18042007><FONT face="Courier New"
size=2> public Object execute(Evaluator evaluator, Argument[]
arguments) {<BR> Object list1 =
arguments[0].evaluate(evaluator);<BR>
Object list2 =
arguments[1].evaluate(evaluator);
</FONT></SPAN></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><SPAN class=421330213-18042007><FONT face="Courier New"
size=2> Boolean expression =
(Boolean)arguments[2].evaluate(evaluator);
<BR>
<BR> if (expression)
{<BR> return
list1;<BR> } else
{<BR> return
list2;<BR> }<BR>
}</FONT></SPAN></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><SPAN class=421330213-18042007><FONT face="Courier New"
size=2> public String[] getReservedWords()
{<BR> return
null;<BR> }<BR>}</FONT></SPAN></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV align=left><SPAN class=421330213-18042007><FONT face=Arial
size=2>Bart</FONT></SPAN></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV></BODY></HTML>