Menu

MDX -> Query Model

2008-06-06
2012-10-08
  • Luiz Felipe Gomes

    Is there anyway in olap4j to parse a MDX string to query model?
    The goal is to reconstruct the MDX string via objects, like hierarchies, axis, where, etc.

    The SelectNode class seems to have this description, but I can't parse a MDX string directly to it.

    I'd be very glad if there's this resource on olap4j.

    Thanks for any reply.

     
    • Luc Boudreau

      Luc Boudreau - 2009-08-04

      I cannot understand your question. Can you provide examples of what you are trying to achieve?

       
    • Julian Hyde

      Julian Hyde - 2008-06-07

      The olap4j parser creates a parse tree consisting of parse tree nodes SelectNode et cetera. And every parse tree node can convert itself to MDX.

      I see the logical query model as a layer of abstraction on top of that. First thing to understand is that the query model is very immature; I don't know whether we've found the right way to represent queries yet. I want to encourage people who are building user interfaces - halogen included - to contribute to the query model.

      And the important point for this thread is that each component of the query model needs to be able to convert itself to AND FROM mdx. Or equivalently, to an from a parse tree. That is, a construct needs to be able to recognize itself in a parse tree. This is quite hard to do, given that people can write MDX by hand. I would like to hear proposals from developers for how to do that; maybe a chain of responsibility pattern, where the various known query constructs each look for themselves. But it's important that we get the conversion to and from MDX parse trees working, so that we can freely add query constructs.

      Julian

       
    • Luiz Felipe Gomes

      My suggestion would be that every component needed to build a org.olap4j.mdx.SelectNode or org.olap4j.query.Query and its subcomponents (not subclasses), should be able to get back through getComponentXYZ method in the appropriate class that was needed to construct it. This makes the abstraction very simple to the programmer.

      For instance:
      In the example shown here http://olap4j.svn.sourceforge.net/viewvc/olap4j/trunk/doc/olap4j_fs.html#MDX_query_model,

      <SNIP>
      new AxisNode(
      false,
      new CallNode(
      "{}",
      Syntax.Braces,
      new IdentifierNode(
      new IdentifierNode.Segment("Measures"),
      </SNIP>

      The AxisNode class should have a method getCallNode, but it doesn't have. The CallNode class should have a method getIdentifierNode but it also doesn't have, and so on. I guess it you've got the idea.

      In addition, each of these classes should be able to pass itself to a String class. This string is built and not just returned. I mean, when I call the SelectNode.toString (or something like this) method, it should get the list of axis and generate the result on runtime calling its subcomponents, not just return the value of a attribute. The same thing to all components needed to build a query. So, a Dimension can get it's Members and Hierarchies and generate its Strings to pass it to the Axis class when some object requested the string related with this Axis.
      If I want move some dimension to another axis, I just remove it from the Axis list that it is associated and add it to the another Axis object representing the another class.

      That's my point and how I'd do it.

      It helped you somwhat or nothing you already did know?

      Best regards,
      Luiz Felipe.

       
    • Luiz Felipe Gomes

      By the way, what's the conceptual difference between org.olap4j.mdx.SelectNode and org.olap4j.query.Query classes?

      Thanks for any advance,
      Luiz Felipe.

       
      • Julian Hyde

        Julian Hyde - 2008-08-05

        > By the way, what's the conceptual difference between
        > org.olap4j.mdx.SelectNode and org.olap4j.query.Query classes?

        One is physical, the other is logical.

        The org.olap4j.mdx package (in particular subclasses of org.olap4j.mdx.ParseTreeNode, including SelectNode) represent a parsed MDX statement. It is complete in olap4j 0.9 onwards, and fully supported by a parser.

        It is documented in section 2.4 of the spec, http://olap4j.svn.sourceforge.net/viewvc/olap4j/trunk/doc/olap4j_fs.html#MDX_query_model .

        The org.olap4j.query package is intended to be a logical query model. Not as closely tied to the MDX language, and closer to the kinds of operations that an end user would perform while building a query. Still very experimental in olap4j 0.9; all of the classes in that package, including org.olap4j.query.Query, are likely to change significantly.

        By the way, the transform package org.olap4j.transform is closely related to the query package. It too is experimental.

        Transform and query are documented (somewhat) in section 2.8, http://olap4j.svn.sourceforge.net/viewvc/olap4j/trunk/doc/olap4j_fs.html#Transform .

        My recommendations are:

        Julian

         
    • Luiz Felipe Gomes

      One suggestion to MDX parser package is to include a class org.olap4j.mdx.SetExpression with a method called getSubSets.
      The code I've found on the test package to get the IdentifierNodes doesn't deal correctly with sets when it have subsets.

      What do you think?

       
    • shyam s

      shyam s - 2009-08-04

      By using the below code snippet i am able to prepare query.. but if i add more than 2 dimensions at a time i need to get functions dynamically based on Dimesions like Jpivot.
      Please can u help how this query can be transformed to queries like jpivot if we add more than 2 dimensions or measures?

      query.getAxisList().add(
      new AxisNode(
      null,
      false,
      Axis.COLUMNS,
      new ArrayList<IdentifierNode>(),
      new CallNode(
      null,
      "{}",
      Syntax.Braces,
      new IdentifierNode(
      new Segment("TouchDate"),
      new Segment("Total")
      ),
      new IdentifierNode(
      new Segment("BlastDate"),
      new Segment("Total")
      ),
      new IdentifierNode(
      new Segment("ProfileAddedDate"),
      new Segment("Total")
      ))));

       

Log in to post a comment.