Search in sources :

Example 1 with HierarchyType

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;
}
Also used : HierarchyType(mondrian.olap.type.HierarchyType) Type(mondrian.olap.type.Type) HierarchyType(mondrian.olap.type.HierarchyType)

Aggregations

HierarchyType (mondrian.olap.type.HierarchyType)1 Type (mondrian.olap.type.Type)1