Here are the olap4j items, and my commentary on them.
I've mentioned various API changes we can make for olap4j-1.1. (We can't make any API changes in a patch release.) olap4j-1.1 is probably 6-9 months away, so I've proposed a short-term fix for each problem.
Benny, All of the proposed fixes are just proposals. I need you to say "Yes, your proposal will solve my problem" before I do anything.
> 5. Add support for annotations
We could add add a method to org.olap4j.metadata.MetadataElement:
Map<String, Annotation> getAnnotationMap();
But then I think someone would soon need some other piece of metadata on, say, Member or Level, that is not an annotation. So I propose that we make MetadataElement extend java.sql.Wrapper. Then you can do this:
mondrian.olap.Annotated annotated =
System.out.println("annotation is " + annotated.get("foo"));
I have logged olap4j case 3473025, "Make MetadataElement extend java.sql.Wrapper". Targeted for olap4j-1.1.
Short-term. Add method "Map<String, Object> XmlaHandler.XmlaExtra.getAnnotationMap(MetadataElement)".
> 6. No format string on StandardMemberProperty
> 15. Need access to mondrian.olap.Property.FORMAT_EXP from within a Cell and
> Passed through to Excel for formatting. Used to determine if a measure is
> percentage based.
Members don't have format strings. You can give an expression for the cell's FORMAT_STRING when you define a calc member (just as you give an expression for the cell's value), but it is only applied to cells.
I see why you want to see the formula. Would it help if we added a new member property, FORMAT_STRING_FORMULA, that returns the unevaluated MDX formula?
But note that if there is a calc member on another axis with a higher solve order and its own FORMAT_STRING, it might supersede the format string of your member. It probably wouldn't happen in queries generated by Analyzer, but it might happen in user-written queries.
> 7. Need to differentiate between level member properties vs level system properties
Can you be more specific? Do you have a Property object in-hand, or just its name?
Note the method "Set<TypeFlag> org.olap4j.metadata.Property.getType()".
> 8. Need to know if a level is a parent-child level
Short-term, use "boolean XmlaHandler.XmlaExtra.isHierarchyParentChild(Hierarchy hierarchy)".
We will add Hierarchy.isParentChild() in olap4j 1.1. (See olap4j bug #3473039, "Add method 'boolean Hierarchy.isParentChild'".)
> 9. Need to know if a dimension is measure dimension
boolean isMeasures =
dimension.getDimensionType() == Dimension.Type.MEASURE;
> 10. Does level.getMembers include calculated members
No, it does not.
> The Java doc should state this clearly.
Agreed. Will fix.
By the way, to get calculated members, execute a query. For example,
with member [Measures].[Zero] as 0
select AddCalculatedMembers([Time].[Month].Members) on 0
The [Measures].[Zero] saves Mondrian the effort of retrieving cell values.
> 11. Expose getParentLevel and getChildLevel on Level
Write your own functions for this:
static Level getParentLevel(Level level)
return level.getDepth() > 0
? level.getHierarchy().getLevels().get(level.getDepth() - 1)
static Level getChildLevel(Level level)
return level.getDepth() < level.getHierarchy().getLevels().size() - 1
? level.getHierarchy().getLevels().get(level.getDepth() + 1)
> 12. How to tell if a cell is drillable?
> Need to know if a cell is drillable before calling cell.drillThrough.
We will add cell property "ACTION_TYPE". You will have to ask for it in the CELL PROPERTIES clause of the query. The result is an integer bitmask. Bit MDACTION_TYPE_DRILLTHROUGH (0x100), will be set if you can drill through.
> 13. Need to know total drill count
This is difficult to support. I don't want an XMLA provider to have to calculate this for every cell before it sends the result back.
> 14. Why does calculated measure member type not return Measure.Type.MEASURE?
> XMLA spec behavior seems weird here. MDMEMBER_TYPE_FORMULA takes precedence
> over MDMEMBER_TYPE_MEASURE. For example, if there is a formula (calculated)
> member on the Measures dimension, it is listed as MDMEMBER_TYPE_FORMULA.
> Analyzer can work around this by checking the measure hierarchy name
> explicity. Maybe we should add an isMeasure method to Member.
You can easily find out whether a member is a measure:
member.getDimension().getDimensionType() == Dimension.Type.MEASURES
> 16. Member.getPropertyFormattedValue requires a Property instance to lookup a
> value. To lookup a schema defined member property, the caller is forced to
> create a dummy class with the name of the property.
> Add a helper util class in olap4j for this?
I agree it's a bit tricky. It's not obvious where to get the necessary Property object to do the lookup, if the Property is not a standard one.
The getPropertyFormattedValue and getPropertyValue methods should just take a String parameter. I got a bit confused when defining the API, because each position on a cellset axis can contain multiple members, therefore property names are not necessarily unique. But they are unique for a given member.
Short-term, carry on using your workaround (creating your own class that implements Property, with the name you choose).
For olap4j-1.1, I propose to change the type of these methods' parameters.
> 17. OlapException needs to pass through the underlying
> ResourceLimitExceededException, QueryTimeoutException and
> Extend OlapException to include the underlying exception name. Analyzer uses
> this to give more user friendly error messages or to undo the last report
How about if we make sure that OlapException.getSQLState() returns something useful in those cases?