PDA

View Full Version : [Mondrian] RE: olap4j POC



Julian Hyde
05-21-2007, 08:52 PM
James Dixon wrote:


I have started on a proof-of-concept for the olap4j model layer. I have
an abstract olap4j layer with a Mondrian-specific implementation.


I have cubes, dimensions, members, results etc working but I'm having
problems with the Mondrian implementation of .Children and .Siblings
etc.


I am not getting errors when I create the QueryAxis or when I run the
query but I don't get the results I am expecting. For [Markets].[All
Markets].[EMEA].Children I get 'France' as the only result and when I
try siblings I only get the original member. Cn you see anything wrong
with this run of code.


Exp exp = new MemberExpr( member );
Exp exps[] = { exp };
Syntax syntax = Syntax.Property;
Validator validator =
Util.createSimpleValidator(BuiltinFunTable.instance());
FunDef fun = BuiltinFunTable.instance().getDef( exps, validator,
"Children", syntax );
Type type = getMemberType( member );
type = new SetType( type );
return new ResolvedFunCall( fun, exps, type );


I tried to write something similar and I ended up with


public void testFoo() {
final TestContext testContext = getTestContext();

final Connection connection = testContext.getConnection();
final Cube salesCube =
connection.getSchema().lookupCube("Sales", true);
final SchemaReader schemaReader =
salesCube.getSchemaReader(null);
final Member member = schemaReader.getMemberByUniqueName(
new String[]{"Time", "1997", "Q1"}, true);

Exp exp = new MemberExpr( member );
Exp exps[] = { exp };
Syntax syntax = Syntax.Property;
Validator validator =
Util.createSimpleValidator(BuiltinFunTable.instance());
FunDef fun = BuiltinFunTable.instance().getDef( exps, validator,
"Children", syntax );
Type type = exp.getType();
type = new SetType( type );
Util.discard(new ResolvedFunCall( fun, exps, type ));
}

I didn't get any errors, so far so good. But to execute it you need a
Query object. Thus:


public void testFoo() {
final TestContext testContext = getTestContext();

final Connection connection = testContext.getConnection();
final Cube salesCube =
connection.getSchema().lookupCube("Sales", true);
final SchemaReader schemaReader =
salesCube.getSchemaReader(null);
final Member member = schemaReader.getMemberByUniqueName(
new String[]{"Time", "1997", "Q1"}, true);

Exp exp = new MemberExpr( member );
Exp exps[] = { exp };
Syntax syntax = Syntax.Property;
Validator validator =
Util.createSimpleValidator(BuiltinFunTable.instance());
FunDef fun = BuiltinFunTable.instance().getDef( exps, validator,
"Children", syntax );
final Exp call = fun.createCall(validator, exps);

final QueryAxis[] queryAxes = new QueryAxis[] {
new QueryAxis(
false, call, AxisOrdinal.COLUMNS,
QueryAxis.SubtotalVisibility.Undefined)
};
final Query query =
new Query(
connection, salesCube, new Formula[0], queryAxes, null,
new QueryPart[0], new Parameter[0], false);
final Result result = connection.execute(query);
final String s = TestContext.toString(result);
System.out.println(s);
}

Note that FunCall.createCall creates an UnresolvedFunCall, which gets
converted to a ResolvedFunCall after validation, and the bonus is that
the right type gets assigned.

I've never tried to compile & run an expression without having a query
around. It may be theoretically possible, but I think the RolapEvaluator
needs one, and probably several other crucial places.

Besides, a lot of stuff happens automatically when you create a query:
Query.resolve() happens from the Query constructor; and compilation
happens when you call Connection.execute(Query).

I ran it and got a sensible looking result:

Axis #0:
{}
Axis #1:
{[Time].[1997].[Q1].[1]}
{[Time].[1997].[Q1].[2]}
{[Time].[1997].[Q1].[3]}
Row #0: 21,628
Row #0: 20,957
Row #0: 23,706

Cc-ing other developers in case anyone else wants to try this at home.

Julian


_______________________________________________
Mondrian mailing list
Mondrian (AT) pentaho (DOT) org
http://lists.pentaho.org/mailman/listinfo/mondrian