use of mondrian.olap.type.HierarchyType in project mondrian by pentaho.
the class CrossJoinArgFactory method checkFilterPredicateInIs.
/**
* Check whether the predicate is an IN or IS predicate and can be
* natively evaluated.
*
* @return the array of CrossJoinArg containing the predicate.
*/
private CrossJoinArg[] checkFilterPredicateInIs(RolapEvaluator evaluator, ResolvedFunCall predicateCall, boolean exclude) {
final boolean useIs;
if (predicateCall.getFunName().equals("IS")) {
useIs = true;
} else if (predicateCall.getFunName().equals("IN")) {
useIs = false;
} else {
// This predicate can not be natively evaluated.
return null;
}
Exp[] predArgs = predicateCall.getArgs();
if (predArgs.length != 2) {
return null;
}
// or Ancestor of those functions.
if (!(predArgs[0] instanceof ResolvedFunCall)) {
return null;
}
ResolvedFunCall predFirstArgCall = (ResolvedFunCall) predArgs[0];
if (predFirstArgCall.getFunDef().getName().equals("Ancestor")) {
Exp[] ancestorArgs = predFirstArgCall.getArgs();
if (!(ancestorArgs[0] instanceof ResolvedFunCall)) {
return null;
}
predFirstArgCall = (ResolvedFunCall) ancestorArgs[0];
}
// Now check that predFirstArgCall is a CurrentMember function that
// refers to the dimension being filtered
FunDef predFirstArgFun = predFirstArgCall.getFunDef();
if (!predFirstArgFun.getName().equals("CurrentMember")) {
return null;
}
Exp currentMemberArg = predFirstArgCall.getArg(0);
Type currentMemberArgType = currentMemberArg.getType();
// Input to CurremntMember should be either Dimension or Hierarchy type.
if (!(currentMemberArgType instanceof mondrian.olap.type.DimensionType || currentMemberArgType instanceof HierarchyType)) {
return null;
}
// It is not necessary to check currentMemberArg comes from the same
// dimension as one of the filterCJArgs, because query parser makes sure
// that currentMember always references dimensions in context.
// Check that predArgs[1] can be expressed as an MemberListCrossJoinArg.
Exp predSecondArg = predArgs[1];
Exp[] predSecondArgList;
FunDef predSecondArgFun;
CrossJoinArg[] predCJArgs;
if (useIs) {
// IS operator
if (!(predSecondArg instanceof MemberExpr)) {
return null;
}
// IS predicate only contains one member
// Make it into a list to be uniform with IN predicate.
predSecondArgFun = null;
predSecondArgList = new Exp[] { predSecondArg };
} else {
// IN operator
if (predSecondArg instanceof NamedSetExpr) {
NamedSet namedSet = ((NamedSetExpr) predSecondArg).getNamedSet();
predSecondArg = namedSet.getExp();
}
if (!(predSecondArg instanceof ResolvedFunCall)) {
return null;
}
ResolvedFunCall predSecondArgCall = (ResolvedFunCall) predSecondArg;
predSecondArgFun = predSecondArgCall.getFunDef();
predSecondArgList = predSecondArgCall.getArgs();
}
predCJArgs = checkEnumeration(evaluator, predSecondArgFun, predSecondArgList, exclude);
return predCJArgs;
}
Aggregations