Search in sources :

Example 1 with Type

use of mondrian.olap.type.Type in project mondrian by pentaho.

the class SqlConstraintUtilsTest method testIsSupportedExpressionForCalculatedMember.

// ~ Test methods ----------------------------------------------------------
public void testIsSupportedExpressionForCalculatedMember() {
    Assert.assertEquals("null expression", false, SqlConstraintUtils.isSupportedExpressionForCalculatedMember(null));
    Exp memberExpr = new MemberExpr(Mockito.mock(Member.class));
    Assert.assertEquals("MemberExpr", true, SqlConstraintUtils.isSupportedExpressionForCalculatedMember(memberExpr));
    Exp nullFunDefExpr = new ResolvedFunCall(new NullFunDef(), new Exp[] {}, new NullType());
    Assert.assertEquals("ResolvedFunCall-NullFunDef", false, SqlConstraintUtils.isSupportedExpressionForCalculatedMember(nullFunDefExpr));
    // ResolvedFunCall arguments
    final Exp argUnsupported = new ResolvedFunCall(new NullFunDef(), new Exp[] {}, new NullType());
    final Exp argSupported = new MemberExpr(Mockito.mock(Member.class));
    Assert.assertEquals(false, SqlConstraintUtils.isSupportedExpressionForCalculatedMember(argUnsupported));
    Assert.assertEquals(true, SqlConstraintUtils.isSupportedExpressionForCalculatedMember(argSupported));
    final Exp[] noArgs = new Exp[] {};
    final Exp[] args1Unsupported = new Exp[] { argUnsupported };
    final Exp[] args1Supported = new Exp[] { argSupported };
    final Exp[] args2Different = new Exp[] { argUnsupported, argSupported };
    final ParenthesesFunDef parenthesesFunDef = new ParenthesesFunDef(Category.Member);
    Type parenthesesReturnType = new DecimalType(1, 1);
    Exp parenthesesExpr = new ResolvedFunCall(parenthesesFunDef, noArgs, parenthesesReturnType);
    Assert.assertEquals("ResolvedFunCall-Parentheses()", true, SqlConstraintUtils.isSupportedExpressionForCalculatedMember(parenthesesExpr));
    parenthesesExpr = new ResolvedFunCall(parenthesesFunDef, args1Unsupported, parenthesesReturnType);
    Assert.assertEquals("ResolvedFunCall-Parentheses(N)", false, SqlConstraintUtils.isSupportedExpressionForCalculatedMember(parenthesesExpr));
    parenthesesExpr = new ResolvedFunCall(parenthesesFunDef, args1Supported, parenthesesReturnType);
    Assert.assertEquals("ResolvedFunCall-Parentheses(Y)", true, SqlConstraintUtils.isSupportedExpressionForCalculatedMember(parenthesesExpr));
    parenthesesExpr = new ResolvedFunCall(parenthesesFunDef, args2Different, parenthesesReturnType);
    Assert.assertEquals("ResolvedFunCall-Parentheses(N,Y)", true, SqlConstraintUtils.isSupportedExpressionForCalculatedMember(parenthesesExpr));
    FunDef dummy = Mockito.mock(FunDef.class);
    Mockito.doReturn(Syntax.Function).when(dummy).getSyntax();
    Mockito.doReturn("dummy").when(dummy).getName();
    FunDef aggregateFunDef = new AggregateFunDef(dummy);
    Type aggregateReturnType = new DecimalType(1, 1);
    Exp aggregateExpr = new ResolvedFunCall(aggregateFunDef, noArgs, aggregateReturnType);
    Assert.assertEquals("ResolvedFunCall-Aggregate()", true, SqlConstraintUtils.isSupportedExpressionForCalculatedMember(aggregateExpr));
    aggregateExpr = new ResolvedFunCall(aggregateFunDef, args1Unsupported, aggregateReturnType);
    Assert.assertEquals("ResolvedFunCall-Aggregate(N)", true, SqlConstraintUtils.isSupportedExpressionForCalculatedMember(aggregateExpr));
    aggregateExpr = new ResolvedFunCall(aggregateFunDef, args1Supported, aggregateReturnType);
    Assert.assertEquals("ResolvedFunCall-Aggregate(Y)", true, SqlConstraintUtils.isSupportedExpressionForCalculatedMember(aggregateExpr));
    aggregateExpr = new ResolvedFunCall(aggregateFunDef, args2Different, aggregateReturnType);
    Assert.assertEquals("ResolvedFunCall-Aggregate(N,Y)", true, SqlConstraintUtils.isSupportedExpressionForCalculatedMember(aggregateExpr));
}
Also used : FunDef(mondrian.olap.FunDef) ParenthesesFunDef(mondrian.olap.fun.ParenthesesFunDef) AggregateFunDef(mondrian.olap.fun.AggregateFunDef) NullFunDef(mondrian.olap.fun.CrossJoinTest.NullFunDef) NullType(mondrian.olap.type.NullType) DecimalType(mondrian.olap.type.DecimalType) TupleType(mondrian.olap.type.TupleType) Type(mondrian.olap.type.Type) NullFunDef(mondrian.olap.fun.CrossJoinTest.NullFunDef) MemberExpr(mondrian.mdx.MemberExpr) ParenthesesFunDef(mondrian.olap.fun.ParenthesesFunDef) DecimalType(mondrian.olap.type.DecimalType) ResolvedFunCall(mondrian.mdx.ResolvedFunCall) AggregateFunDef(mondrian.olap.fun.AggregateFunDef) NullType(mondrian.olap.type.NullType) Exp(mondrian.olap.Exp) Member(mondrian.olap.Member) TestMember(mondrian.olap.fun.TestMember)

Example 2 with Type

use of mondrian.olap.type.Type in project mondrian by pentaho.

the class ValidatorImpl method validate.

public Exp validate(Exp exp, boolean scalar) {
    Exp resolved;
    try {
        resolved = (Exp) resolvedNodes.get(exp);
    } catch (ClassCastException e) {
        // not occur for any query, valid or invalid.
        throw Util.newInternal(e, "Infinite recursion encountered while validating '" + Util.unparse(exp) + "'");
    }
    if (resolved == null) {
        try {
            stack.push((QueryPart) exp);
            // To prevent recursion, put in a placeholder while we're
            // resolving.
            resolvedNodes.put((QueryPart) exp, placeHolder);
            resolved = exp.accept(this);
            Util.assertTrue(resolved != null);
            resolvedNodes.put((QueryPart) exp, (QueryPart) resolved);
        } finally {
            stack.pop();
        }
    }
    if (scalar) {
        final Type type = resolved.getType();
        if (!TypeUtil.canEvaluate(type)) {
            String exprString = Util.unparse(resolved);
            throw MondrianResource.instance().MdxMemberExpIsSet.ex(exprString);
        }
    }
    return resolved;
}
Also used : Type(mondrian.olap.type.Type)

Example 3 with Type

use of mondrian.olap.type.Type in project mondrian by pentaho.

the class AncestorFunDef method compileCall.

public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
    final MemberCalc memberCalc = compiler.compileMember(call.getArg(0));
    final Type type1 = call.getArg(1).getType();
    if (type1 instanceof LevelType) {
        final LevelCalc levelCalc = compiler.compileLevel(call.getArg(1));
        return new AbstractMemberCalc(call, new Calc[] { memberCalc, levelCalc }) {

            public Member evaluateMember(Evaluator evaluator) {
                Level level = levelCalc.evaluateLevel(evaluator);
                Member member = memberCalc.evaluateMember(evaluator);
                int distance = member.getLevel().getDepth() - level.getDepth();
                return ancestor(evaluator, member, distance, level);
            }
        };
    } else {
        final IntegerCalc distanceCalc = compiler.compileInteger(call.getArg(1));
        return new AbstractMemberCalc(call, new Calc[] { memberCalc, distanceCalc }) {

            public Member evaluateMember(Evaluator evaluator) {
                int distance = distanceCalc.evaluateInteger(evaluator);
                Member member = memberCalc.evaluateMember(evaluator);
                return ancestor(evaluator, member, distance, null);
            }
        };
    }
}
Also used : Type(mondrian.olap.type.Type) LevelType(mondrian.olap.type.LevelType) LevelType(mondrian.olap.type.LevelType) AbstractMemberCalc(mondrian.calc.impl.AbstractMemberCalc) AbstractMemberCalc(mondrian.calc.impl.AbstractMemberCalc)

Example 4 with Type

use of mondrian.olap.type.Type in project mondrian by pentaho.

the class GlobalFunTable method validateFunction.

/**
 * Throws an error if a user-defined function does not adhere to the
 * API.
 *
 * @param udf User defined function
 */
private void validateFunction(final UserDefinedFunction udf) {
    // Check that the name is not null or empty.
    final String udfName = udf.getName();
    if (udfName == null || udfName.equals("")) {
        throw Util.newInternal("User-defined function defined by class '" + udf.getClass() + "' has empty name");
    }
    // It's OK for the description to be null.
    // final String description = udf.getDescription();
    final Type[] parameterTypes = udf.getParameterTypes();
    for (int i = 0; i < parameterTypes.length; i++) {
        Type parameterType = parameterTypes[i];
        if (parameterType == null) {
            throw Util.newInternal("Invalid user-defined function '" + udfName + "': parameter type #" + i + " is null");
        }
    }
    // It's OK for the reserved words to be null or empty.
    // final String[] reservedWords = udf.getReservedWords();
    // Test that the function returns a sensible type when given the FORMAL
    // types. It may still fail when we give it the ACTUAL types, but it's
    // impossible to check that now.
    final Type returnType = udf.getReturnType(parameterTypes);
    if (returnType == null) {
        throw Util.newInternal("Invalid user-defined function '" + udfName + "': return type is null");
    }
    final Syntax syntax = udf.getSyntax();
    if (syntax == null) {
        throw Util.newInternal("Invalid user-defined function '" + udfName + "': syntax is null");
    }
}
Also used : Type(mondrian.olap.type.Type)

Example 5 with Type

use of mondrian.olap.type.Type 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

Type (mondrian.olap.type.Type)15 ResolvedFunCall (mondrian.mdx.ResolvedFunCall)5 Exp (mondrian.olap.Exp)4 Member (mondrian.olap.Member)4 NullType (mondrian.olap.type.NullType)4 TupleType (mondrian.olap.type.TupleType)4 MemberExpr (mondrian.mdx.MemberExpr)3 FunDef (mondrian.olap.FunDef)3 AggregateFunDef (mondrian.olap.fun.AggregateFunDef)3 NullFunDef (mondrian.olap.fun.CrossJoinTest.NullFunDef)3 ParenthesesFunDef (mondrian.olap.fun.ParenthesesFunDef)3 TestMember (mondrian.olap.fun.TestMember)3 DecimalType (mondrian.olap.type.DecimalType)3 LevelType (mondrian.olap.type.LevelType)3 AbstractListCalc (mondrian.calc.impl.AbstractListCalc)2 PrintWriter (java.io.PrintWriter)1 ArrayList (java.util.ArrayList)1 Calc (mondrian.calc.Calc)1 IterCalc (mondrian.calc.IterCalc)1 TupleIterable (mondrian.calc.TupleIterable)1