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

Julian Hyde jhyde at pentaho.com
Tue Aug 4 01:49:05 EDT 2009

By coincidence, I had remembered that you had received a ClassCastException,
and there was something to do with a calculated set, and I was investigating
as you filed the bug.
Mondrian implements MDX sets as both java.util.List and java.util.Iterable
internally. It is not safe for the author of a UDF to assume that if the
argument is an MDX set then Argument.evaluate will return a List, as you did
in your Reverse UDF. I added new methods Argument.evaluateList and
Argument.evaluateIter. The author of the UDF must call one of these.
See further comments in the bug:
Note that this is fixed on the 3.1 branch.


From: Eric McDermid [mailto:mcdermid at stonecreek.com] 
Sent: Monday, August 03, 2009 8:31 PM
To: jhyde at pentaho.com
Cc: Mondrian developer mailing list
Subject: Re: [Mondrian] Problem moving UDF returning a list from 2.4 to

Thanks for the fix, Julian.

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).
Near as I can tell, the problem only occurs when passing a named set to the

I've created a simple reproduction case that demonstrates the problem, and
created MONDRIAN-589 to track it.

 -- Eric

On Jul 31, 2009, at 9:10 PM, Eric McDermid wrote:

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

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.


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);
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.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.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

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

Mondrian mailing list
Mondrian at pentaho.org

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

More information about the Mondrian mailing list