[Mondrian] Problem moving UDF returning a list from 2.4 to 3.1.1

Eric McDermid mcdermid at stonecreek.com
Fri Jul 31 23:10:56 EDT 2009


Done.  Mondrian-588.

I've also added some further notes in that description.  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.  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.

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.   
This has nothing to do with my workaround; I've seen it prior to the  
change as well.

  -- Eric

On Jul 31, 2009, at 7:33 PM, Julian Hyde wrote:

> I'll look into it over the weekend. Can you please log a bug.
>
> Julian
>
> From: mondrian-bounces at pentaho.org [mailto:mondrian-bounces at pentaho.org 
> ] On Behalf Of Eric McDermid
> Sent: Friday, July 31, 2009 10:36 AM
> To: Mondrian developer mailing list
> Subject: [Mondrian] Problem moving UDF returning a list from 2.4 to  
> 3.1.1
>
> 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.  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.
>
> Here's the function, which simply reverses the order of a set:
>
>   public class ReverseFunction implements UserDefinedFunction {
> public Object execute(Evaluator eval, Argument[] args) {
> List memberList = (List) args[0].evaluate(eval);
> Collections.reverse(memberList);
> return memberList;
> }
> public String getDescription() {
> return "Reverses the order of a set";
> }
> public String getName() {
> return "Reverse";
> }
> public Type[] getParameterTypes() {
> return new Type[] {new SetType(MemberType.Unknown)};
> }
> public String[] getReservedWords() {
> return null;
> }
> public Type getReturnType(Type[] arg0) {
> return arg0[0];
> }
> public Syntax getSyntax() {
> return Syntax.Function;
> }
>   }
>
> The stack trace for the underlying cause of the error is here:
>
> Caused by: mondrian.olap.MondrianException: Mondrian Error:Internal  
> error: Cannot convert calc to list: mondrian.olap.fun.UdfResolver 
> $CalcImpl at 315d04
> at mondrian.resource.MondrianResource$_Def0.ex(MondrianResource.java: 
> 803)
> at mondrian.olap.Util.newInternal(Util.java:1465)
> at  
> mondrian 
> .calc.impl.AbstractExpCompiler.compileList(AbstractExpCompiler.java: 
> 286)
> at  
> mondrian 
> .calc.impl.BetterExpCompiler.compileList(BetterExpCompiler.java:77)
> at  
> mondrian 
> .calc.impl.AbstractExpCompiler.compileList(AbstractExpCompiler.java: 
> 260)
> at mondrian.olap.fun.SetFunDef 
> $MemberSetListCalc.createCalc(SetFunDef.java:147)
> at mondrian.olap.fun.SetFunDef 
> $MemberSetListCalc.compileSelf(SetFunDef.java:134)
> at mondrian.olap.fun.SetFunDef 
> $MemberSetListCalc.<init>(SetFunDef.java:120)
> at mondrian.olap.fun.SetFunDef.compileCall(SetFunDef.java:89)
> at mondrian.mdx.ResolvedFunCall.accept(ResolvedFunCall.java:152)
> at  
> mondrian 
> .calc.impl.AbstractExpCompiler.compile(AbstractExpCompiler.java:79)
> at  
> mondrian 
> .calc.impl.AbstractExpCompiler.compileAs(AbstractExpCompiler.java:124)
> at  
> mondrian 
> .calc.impl.AbstractExpCompiler.compileIter(AbstractExpCompiler.java: 
> 311)
> at mondrian.olap.QueryAxis.compile(QueryAxis.java:122)
> at mondrian.olap.Query.compile(Query.java:519)
> at mondrian.olap.Query.resolve(Query.java:456)
> at mondrian.olap.Query.<init>(Query.java:231)
> at mondrian.olap.Query.<init>(Query.java:187)
> at mondrian.olap.Parser.makeQuery(Parser.java:870)
> at mondrian.olap.CUP$Parser$actions.CUP$Parser$do_action(Parser.java: 
> 1764)
> at mondrian.olap.Parser.do_action(Parser.java:699)
> at java_cup.runtime.lr_parser.parse(lr_parser.java:569)
> at mondrian.olap.Parser.parseInternal(Parser.java:772)
>
> The immediate problem is in AbstractExpCompiler.compileList().  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.
>
> 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.  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.
>
> 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?
>
>  -- Eric
>
>
> _______________________________________________
> Mondrian mailing list
> Mondrian at pentaho.org
> http://lists.pentaho.org/mailman/listinfo/mondrian

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


More information about the Mondrian mailing list