<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Thanks for the fix,&nbsp;Julian.</div><div><br></div><div>Running the new code, I do find that i still run into the second issue I mentioned below (args[0] evaluating anonymous Iterable rather than a List). &nbsp;Near&nbsp;as&nbsp;I&nbsp;can&nbsp;tell,&nbsp;the problem only occurs when passing a named set to the UDF.</div><div><br></div><div>I've created a simple reproduction case that demonstrates the problem, and created MONDRIAN-589 to track it.</div><div><br></div><div>&nbsp;-- Eric<br><div><br><div><div>On Jul 31, 2009, at 9:10 PM, Eric McDermid wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Done. &nbsp;Mondrian-588.<div><br></div><div>I've also added some further notes in that description. &nbsp;I experimented this afternoon with changing UdfResolver to return an object that implements AbstractMemberListCalc (rather than just GenericCalc) if the compiler's preferred result type is a list. &nbsp;I'm not sure it's the right answer, and I've yet to run the full test suite on it, but it does get me past the error. &nbsp;</div><div><br></div><div>Unfortunately, when the Reverse UDF is actually executed, "args[0].evaluate(eval)" returns an anonymous Iterable generated from RolapNamedSetEvaluator.evaluateMemberIterable(), rather than a List as used to be the case under 2.4, triggering a class cast exception. &nbsp;This has nothing to do with my workaround; I've seen it prior to the change as well.</div><div><br></div><div>&nbsp;-- Eric</div><div><br><div><div>On Jul 31, 2009, at 7:33 PM, Julian Hyde wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"> <div style="WORD-WRAP: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space"> <div><span class="479463201-01082009"><font color="#000080" size="2" face="Lucida Sans">I'll look into it over the weekend. Can you please log a bug.</font></span></div> <div><span class="479463201-01082009"><font color="#000080" size="2" face="Lucida Sans"></font></span>&nbsp;</div> <div><span class="479463201-01082009"><font color="#000080" size="2" face="Lucida Sans">Julian</font></span></div><br> <blockquote style="BORDER-LEFT: #000080 2px solid; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; MARGIN-RIGHT: 0px" dir="ltr">  <div dir="ltr" lang="en-us" class="OutlookMessageHeader" align="left">  <hr tabindex="-1">  <font size="2" face="Tahoma"><b>From:</b> <a href="mailto:mondrian-bounces@pentaho.org">mondrian-bounces@pentaho.org</a>   [<a href="mailto:mondrian-bounces@pentaho.org">mailto:mondrian-bounces@pentaho.org</a>] <b>On Behalf Of </b>Eric   McDermid<br><b>Sent:</b> Friday, July 31, 2009 10:36 AM<br><b>To:</b> Mondrian   developer mailing list<br><b>Subject:</b> [Mondrian] Problem moving UDF   returning a list from 2.4 to 3.1.1<br></font><br></div>  <div></div>  <div>I'm having some trouble with a UDF returning a List that worked under   2.4, but fails with a parse error under 3.1.1. &nbsp;I'm not sure whether the   problem is a flaw in the UDF or in how the newer version of Mondrian is   attempting to use it. &nbsp;</div>  <div><br></div>  <div>Here's the function, which simply reverses the order of a set:</div>  <div>  <div><br></div>  <div><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">&nbsp;&nbsp;public class ReverseFunction implements   UserDefinedFunction {</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">public Object   execute(Evaluator eval, Argument[] args) {</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">List memberList =   (List) args[0].evaluate(eval);</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">Collections.reverse(memberList);</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">return   memberList;</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">}</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">public String   getDescription() {</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">return "Reverses   the order of a set";</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">}</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">public String   getName() {</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">return   "Reverse";</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">}</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">public Type[]   getParameterTypes() {</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">return new Type[]   {new SetType(MemberType.Unknown)};</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">}</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">public String[]   getReservedWords() {</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">return   null;</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">}</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">public Type   getReturnType(Type[] arg0) {</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">return   arg0[0];</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">}</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">public Syntax   getSyntax() {</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">return   Syntax.Function;</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">}</span></font></div>  <div><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">&nbsp;&nbsp;}</span></font></div>  <div><br></div>  <div>  <div>The stack trace for the underlying cause of the error is here:</div>  <div><br></div>  <div><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">Caused by: mondrian.olap.MondrianException: Mondrian   Error:Internal error: Cannot convert calc to list:   mondrian.olap.fun.UdfResolver$CalcImpl@315d04</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.resource.MondrianResource$_Def0.ex(MondrianResource.java:803)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.olap.Util.newInternal(Util.java:1465)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.calc.impl.AbstractExpCompiler.compileList(AbstractExpCompiler.java:286)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.calc.impl.BetterExpCompiler.compileList(BetterExpCompiler.java:77)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.calc.impl.AbstractExpCompiler.compileList(AbstractExpCompiler.java:260)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.olap.fun.SetFunDef$MemberSetListCalc.createCalc(SetFunDef.java:147)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.olap.fun.SetFunDef$MemberSetListCalc.compileSelf(SetFunDef.java:134)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.olap.fun.SetFunDef$MemberSetListCalc.&lt;init&gt;(SetFunDef.java:120)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.olap.fun.SetFunDef.compileCall(SetFunDef.java:89)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.mdx.ResolvedFunCall.accept(ResolvedFunCall.java:152)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.calc.impl.AbstractExpCompiler.compile(AbstractExpCompiler.java:79)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.calc.impl.AbstractExpCompiler.compileAs(AbstractExpCompiler.java:124)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.calc.impl.AbstractExpCompiler.compileIter(AbstractExpCompiler.java:311)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.olap.QueryAxis.compile(QueryAxis.java:122)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.olap.Query.compile(Query.java:519)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.olap.Query.resolve(Query.java:456)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.olap.Query.&lt;init&gt;(Query.java:231)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.olap.Query.&lt;init&gt;(Query.java:187)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.olap.Parser.makeQuery(Parser.java:870)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.olap.CUP$Parser$actions.CUP$Parser$do_action(Parser.java:1764)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.olap.Parser.do_action(Parser.java:699)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   java_cup.runtime.lr_parser.parse(lr_parser.java:569)</span></font></div>  <div><span style="WHITE-SPACE: pre" class="Apple-tab-span"><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span"></span></font></span><font class="Apple-style-span" size="3"><span style="FONT-SIZE: 11px" class="Apple-style-span">at   mondrian.olap.Parser.parseInternal(Parser.java:772)</span></font></div>  <div><br></div>  <div>The immediate problem is in AbstractExpCompiler.compileList(). &nbsp;It   compiles the expression "Reverse([Requested Dates])", gets a   mondrian.olap.fun.UdfResolver$CalcImpl instance as a result, then complains   because said calc is neither null, a ListCalc, or an IterCalc.</div>  <div><br></div>  <div>UDF documentation seems a little thin, and I've been unable to find an   example of a UDF returning a list in either mondrian/udf or in UdfTest to use   as a reference point.&nbsp;&nbsp;Searching the archive, I do see that Pappyn   Bart asked a somewhat similar question back in 2007, but I didn't see a clear   resolution.</div>  <div><br></div>  <div>Can anyone help me sort this problem out, or failing that at least point   me to an example of a UDF that does successfully return a list that I can   compare against?</div>  <div><br></div>  <div>&nbsp;-- Eric</div>  <div><br></div>  <div><br></div></div></div></blockquote></div> _______________________________________________<br>Mondrian mailing list<br><a href="mailto:Mondrian@pentaho.org">Mondrian@pentaho.org</a><br><a href="http://lists.pentaho.org/mailman/listinfo/mondrian">http://lists.pentaho.org/mailman/listinfo/mondrian</a><br></blockquote></div><br></div></div>_______________________________________________<br>Mondrian mailing list<br><a href="mailto:Mondrian@pentaho.org">Mondrian@pentaho.org</a><br>http://lists.pentaho.org/mailman/listinfo/mondrian<br></blockquote></div><br></div></div></body></html>