use of mondrian.olap.type.MemberType in project mondrian by pentaho.
the class CrossJoinTest method getResolvedFunCall.
protected ResolvedFunCall getResolvedFunCall() {
FunDef funDef = new TestFunDef();
Exp[] args = new Exp[0];
Type returnType = new SetType(new TupleType(new Type[] { new MemberType(null, null, null, null), new MemberType(null, null, null, null) }));
return new ResolvedFunCall(funDef, args, returnType);
}
use of mondrian.olap.type.MemberType in project mondrian by pentaho.
the class FunUtil method makeNullTuple.
public static Member[] makeNullTuple(final TupleType tupleType) {
final Type[] elementTypes = tupleType.elementTypes;
Member[] members = new Member[elementTypes.length];
for (int i = 0; i < elementTypes.length; i++) {
MemberType type = (MemberType) elementTypes[i];
members[i] = makeNullMember(type);
}
return members;
}
use of mondrian.olap.type.MemberType in project mondrian by pentaho.
the class CrossJoinFunDef method getResultType.
public Type getResultType(Validator validator, Exp[] args) {
// CROSSJOIN(<Set1>,<Set2>) has type [Hie1] x [Hie2].
List<MemberType> list = new ArrayList<MemberType>();
for (Exp arg : args) {
final Type type = arg.getType();
if (type instanceof SetType) {
addTypes(type, list);
} else if (getName().equals("*")) {
// The "*" form of CrossJoin is lenient: args can be either
// members/tuples or sets.
addTypes(type, list);
} else {
throw Util.newInternal("arg to crossjoin must be a set");
}
}
final MemberType[] types = list.toArray(new MemberType[list.size()]);
TupleType.checkHierarchies(types);
final TupleType tupleType = new TupleType(types);
return new SetType(tupleType);
}
use of mondrian.olap.type.MemberType in project mondrian by pentaho.
the class CrossJoinFunDef method addTypes.
/**
* Adds a type to a list of types. If type is a {@link TupleType}, does so recursively.
*
* @param type
* Type to add to list
* @param list
* List of types to add to
*/
private static void addTypes(final Type type, List<MemberType> list) {
if (type instanceof SetType) {
SetType setType = (SetType) type;
addTypes(setType.getElementType(), list);
} else if (type instanceof TupleType) {
TupleType tupleType = (TupleType) type;
for (Type elementType : tupleType.elementTypes) {
addTypes(elementType, list);
}
} else if (type instanceof MemberType) {
list.add((MemberType) type);
} else {
throw Util.newInternal("Unexpected type: " + type);
}
}
use of mondrian.olap.type.MemberType in project mondrian by pentaho.
the class DescendantsFunDef method compileCall.
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final Type type0 = call.getArg(0).getType();
if (type0 instanceof SetType) {
final SetType setType = (SetType) type0;
if (setType.getElementType() instanceof TupleType) {
throw MondrianResource.instance().DescendantsAppliedToSetOfTuples.ex();
}
MemberType memberType = (MemberType) setType.getElementType();
final Hierarchy hierarchy = memberType.getHierarchy();
if (hierarchy == null) {
throw MondrianResource.instance().CannotDeduceTypeOfSet.ex();
}
// Convert
// Descendants(<set>, <args>)
// into
// Generate(<set>, Descendants(<dimension>.CurrentMember, <args>))
Exp[] descendantsArgs = call.getArgs().clone();
descendantsArgs[0] = new UnresolvedFunCall("CurrentMember", Syntax.Property, new Exp[] { new HierarchyExpr(hierarchy) });
final ResolvedFunCall generateCall = (ResolvedFunCall) compiler.getValidator().validate(new UnresolvedFunCall("Generate", new Exp[] { call.getArg(0), new UnresolvedFunCall("Descendants", descendantsArgs) }), false);
return generateCall.accept(compiler);
}
final MemberCalc memberCalc = compiler.compileMember(call.getArg(0));
Flag flag = Flag.SELF;
if (call.getArgCount() == 1) {
flag = Flag.SELF_BEFORE_AFTER;
}
final boolean depthSpecified = call.getArgCount() >= 2 && call.getArg(1).getType() instanceof NumericType;
final boolean depthEmpty = call.getArgCount() >= 2 && call.getArg(1).getType() instanceof EmptyType;
if (call.getArgCount() >= 3) {
flag = FunUtil.getLiteralArg(call, 2, Flag.SELF, Flag.class);
}
if (call.getArgCount() >= 2 && depthEmpty) {
if (flag != Flag.LEAVES) {
throw Util.newError("depth must be specified unless DESC_FLAG is LEAVES");
}
}
if ((depthSpecified || depthEmpty) && flag.leaves) {
final IntegerCalc depthCalc = depthSpecified ? compiler.compileInteger(call.getArg(1)) : null;
return new AbstractListCalc(call, new Calc[] { memberCalc, depthCalc }) {
public TupleList evaluateList(Evaluator evaluator) {
final Member member = memberCalc.evaluateMember(evaluator);
List<Member> result = new ArrayList<Member>();
int depth = -1;
if (depthCalc != null) {
depth = depthCalc.evaluateInteger(evaluator);
if (depth < 0) {
// no limit
depth = -1;
}
}
final SchemaReader schemaReader = evaluator.getSchemaReader();
descendantsLeavesByDepth(member, result, schemaReader, depth);
hierarchizeMemberList(result, false);
return new UnaryTupleList(result);
}
};
} else if (depthSpecified) {
final IntegerCalc depthCalc = compiler.compileInteger(call.getArg(1));
final Flag flag1 = flag;
return new AbstractListCalc(call, new Calc[] { memberCalc, depthCalc }) {
public TupleList evaluateList(Evaluator evaluator) {
final Member member = memberCalc.evaluateMember(evaluator);
List<Member> result = new ArrayList<Member>();
final int depth = depthCalc.evaluateInteger(evaluator);
final SchemaReader schemaReader = evaluator.getSchemaReader();
descendantsByDepth(member, result, schemaReader, depth, flag1.before, flag1.self, flag1.after, evaluator);
hierarchizeMemberList(result, false);
return new UnaryTupleList(result);
}
};
} else {
final LevelCalc levelCalc = call.getArgCount() > 1 ? compiler.compileLevel(call.getArg(1)) : null;
final Flag flag2 = flag;
return new AbstractListCalc(call, new Calc[] { memberCalc, levelCalc }) {
public TupleList evaluateList(Evaluator evaluator) {
final Evaluator context = evaluator.isNonEmpty() ? evaluator : null;
final Member member = memberCalc.evaluateMember(evaluator);
List<Member> result = new ArrayList<Member>();
final SchemaReader schemaReader = evaluator.getSchemaReader();
final Level level = levelCalc != null ? levelCalc.evaluateLevel(evaluator) : member.getLevel();
descendantsByLevel(schemaReader, member, level, result, flag2.before, flag2.self, flag2.after, flag2.leaves, context);
hierarchizeMemberList(result, false);
return new UnaryTupleList(result);
}
};
}
}
Aggregations