Search in sources :

Example 11 with Expression

use of org.apache.calcite.linq4j.tree.Expression in project calcite by apache.

the class OptimizerTest method testConditionalIfBoolFalseTrue.

@Test
public void testConditionalIfBoolFalseTrue() {
    // if (bool) {1} else if (false) {2} if (true) {4} else {5}
    Expression bool = Expressions.parameter(boolean.class, "bool");
    assertEquals("{\n" + "  if (bool) {\n" + "    return 1;\n" + "  } else {\n" + "    return 4;\n" + "  }\n" + "}\n", optimize(Expressions.ifThenElse(bool, Expressions.return_(null, ONE), FALSE, Expressions.return_(null, TWO), TRUE, Expressions.return_(null, FOUR), Expressions.return_(null, Expressions.constant(5)))));
}
Also used : ConstantExpression(org.apache.calcite.linq4j.tree.ConstantExpression) Expression(org.apache.calcite.linq4j.tree.Expression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) Test(org.junit.Test)

Example 12 with Expression

use of org.apache.calcite.linq4j.tree.Expression in project calcite by apache.

the class OptimizerTest method testConditionalIfBoolTrueElse.

@Test
public void testConditionalIfBoolTrueElse() {
    // if (bool) {return 1} else if (true) {return 2} else {return 3}
    Expression bool = Expressions.parameter(boolean.class, "bool");
    assertEquals("{\n" + "  if (bool) {\n" + "    return 1;\n" + "  } else {\n" + "    return 2;\n" + "  }\n" + "}\n", optimize(Expressions.ifThenElse(bool, Expressions.return_(null, ONE), TRUE, Expressions.return_(null, TWO), Expressions.return_(null, THREE))));
}
Also used : ConstantExpression(org.apache.calcite.linq4j.tree.ConstantExpression) Expression(org.apache.calcite.linq4j.tree.Expression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) Test(org.junit.Test)

Example 13 with Expression

use of org.apache.calcite.linq4j.tree.Expression in project calcite by apache.

the class PhysTypeImpl method generateComparator.

public Expression generateComparator(RelCollation collation) {
    // int c;
    // c = Utilities.compare(v0, v1);
    // if (c != 0) return c; // or -c if descending
    // ...
    // return 0;
    BlockBuilder body = new BlockBuilder();
    final Type javaRowClass = Primitive.box(this.javaRowClass);
    final ParameterExpression parameterV0 = Expressions.parameter(javaRowClass, "v0");
    final ParameterExpression parameterV1 = Expressions.parameter(javaRowClass, "v1");
    final ParameterExpression parameterC = Expressions.parameter(int.class, "c");
    final int mod = collation.getFieldCollations().size() == 1 ? Modifier.FINAL : 0;
    body.add(Expressions.declare(mod, parameterC, null));
    for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
        final int index = fieldCollation.getFieldIndex();
        Expression arg0 = fieldReference(parameterV0, index);
        Expression arg1 = fieldReference(parameterV1, index);
        switch(Primitive.flavor(fieldClass(index))) {
            case OBJECT:
                arg0 = Types.castIfNecessary(Comparable.class, arg0);
                arg1 = Types.castIfNecessary(Comparable.class, arg1);
        }
        final boolean nullsFirst = fieldCollation.nullDirection == RelFieldCollation.NullDirection.FIRST;
        final boolean descending = fieldCollation.getDirection() == RelFieldCollation.Direction.DESCENDING;
        body.add(Expressions.statement(Expressions.assign(parameterC, Expressions.call(Utilities.class, fieldNullable(index) ? (nullsFirst != descending ? "compareNullsFirst" : "compareNullsLast") : "compare", arg0, arg1))));
        body.add(Expressions.ifThen(Expressions.notEqual(parameterC, Expressions.constant(0)), Expressions.return_(null, descending ? Expressions.negate(parameterC) : parameterC)));
    }
    body.add(Expressions.return_(null, Expressions.constant(0)));
    final List<MemberDeclaration> memberDeclarations = Expressions.<MemberDeclaration>list(Expressions.methodDecl(Modifier.PUBLIC, int.class, "compare", ImmutableList.of(parameterV0, parameterV1), body.toBlock()));
    if (EnumerableRules.BRIDGE_METHODS) {
        final ParameterExpression parameterO0 = Expressions.parameter(Object.class, "o0");
        final ParameterExpression parameterO1 = Expressions.parameter(Object.class, "o1");
        BlockBuilder bridgeBody = new BlockBuilder();
        bridgeBody.add(Expressions.return_(null, Expressions.call(Expressions.parameter(Comparable.class, "this"), BuiltInMethod.COMPARATOR_COMPARE.method, Expressions.convert_(parameterO0, javaRowClass), Expressions.convert_(parameterO1, javaRowClass))));
        memberDeclarations.add(overridingMethodDecl(BuiltInMethod.COMPARATOR_COMPARE.method, ImmutableList.of(parameterO0, parameterO1), bridgeBody.toBlock()));
    }
    return Expressions.new_(Comparator.class, Collections.<Expression>emptyList(), memberDeclarations);
}
Also used : RelDataType(org.apache.calcite.rel.type.RelDataType) Type(java.lang.reflect.Type) Utilities(org.apache.calcite.runtime.Utilities) Expression(org.apache.calcite.linq4j.tree.Expression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) MemberDeclaration(org.apache.calcite.linq4j.tree.MemberDeclaration) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) BlockBuilder(org.apache.calcite.linq4j.tree.BlockBuilder)

Example 14 with Expression

use of org.apache.calcite.linq4j.tree.Expression in project calcite by apache.

the class PhysTypeImpl method generateCollationKey.

public Pair<Expression, Expression> generateCollationKey(final List<RelFieldCollation> collations) {
    final Expression selector;
    if (collations.size() == 1) {
        RelFieldCollation collation = collations.get(0);
        ParameterExpression parameter = Expressions.parameter(javaRowClass, "v");
        selector = Expressions.lambda(Function1.class, fieldReference(parameter, collation.getFieldIndex()), parameter);
        return Pair.<Expression, Expression>of(selector, Expressions.call(BuiltInMethod.NULLS_COMPARATOR.method, Expressions.constant(collation.nullDirection == RelFieldCollation.NullDirection.FIRST), Expressions.constant(collation.getDirection() == RelFieldCollation.Direction.DESCENDING)));
    }
    selector = Expressions.call(BuiltInMethod.IDENTITY_SELECTOR.method);
    // int c;
    // c = Utilities.compare(v0, v1);
    // if (c != 0) return c; // or -c if descending
    // ...
    // return 0;
    BlockBuilder body = new BlockBuilder();
    final ParameterExpression parameterV0 = Expressions.parameter(javaRowClass, "v0");
    final ParameterExpression parameterV1 = Expressions.parameter(javaRowClass, "v1");
    final ParameterExpression parameterC = Expressions.parameter(int.class, "c");
    final int mod = collations.size() == 1 ? Modifier.FINAL : 0;
    body.add(Expressions.declare(mod, parameterC, null));
    for (RelFieldCollation collation : collations) {
        final int index = collation.getFieldIndex();
        Expression arg0 = fieldReference(parameterV0, index);
        Expression arg1 = fieldReference(parameterV1, index);
        switch(Primitive.flavor(fieldClass(index))) {
            case OBJECT:
                arg0 = Types.castIfNecessary(Comparable.class, arg0);
                arg1 = Types.castIfNecessary(Comparable.class, arg1);
        }
        final boolean nullsFirst = collation.nullDirection == RelFieldCollation.NullDirection.FIRST;
        final boolean descending = collation.getDirection() == RelFieldCollation.Direction.DESCENDING;
        final Method method = (fieldNullable(index) ? (nullsFirst ^ descending ? BuiltInMethod.COMPARE_NULLS_FIRST : BuiltInMethod.COMPARE_NULLS_LAST) : BuiltInMethod.COMPARE).method;
        body.add(Expressions.statement(Expressions.assign(parameterC, Expressions.call(method.getDeclaringClass(), method.getName(), arg0, arg1))));
        body.add(Expressions.ifThen(Expressions.notEqual(parameterC, Expressions.constant(0)), Expressions.return_(null, descending ? Expressions.negate(parameterC) : parameterC)));
    }
    body.add(Expressions.return_(null, Expressions.constant(0)));
    final List<MemberDeclaration> memberDeclarations = Expressions.<MemberDeclaration>list(Expressions.methodDecl(Modifier.PUBLIC, int.class, "compare", ImmutableList.of(parameterV0, parameterV1), body.toBlock()));
    if (EnumerableRules.BRIDGE_METHODS) {
        final ParameterExpression parameterO0 = Expressions.parameter(Object.class, "o0");
        final ParameterExpression parameterO1 = Expressions.parameter(Object.class, "o1");
        BlockBuilder bridgeBody = new BlockBuilder();
        bridgeBody.add(Expressions.return_(null, Expressions.call(Expressions.parameter(Comparable.class, "this"), BuiltInMethod.COMPARATOR_COMPARE.method, Expressions.convert_(parameterO0, javaRowClass), Expressions.convert_(parameterO1, javaRowClass))));
        memberDeclarations.add(overridingMethodDecl(BuiltInMethod.COMPARATOR_COMPARE.method, ImmutableList.of(parameterO0, parameterO1), bridgeBody.toBlock()));
    }
    return Pair.<Expression, Expression>of(selector, Expressions.new_(Comparator.class, Collections.<Expression>emptyList(), memberDeclarations));
}
Also used : Expression(org.apache.calcite.linq4j.tree.Expression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) MemberDeclaration(org.apache.calcite.linq4j.tree.MemberDeclaration) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) Function1(org.apache.calcite.linq4j.function.Function1) BuiltInMethod(org.apache.calcite.util.BuiltInMethod) Method(java.lang.reflect.Method) BlockBuilder(org.apache.calcite.linq4j.tree.BlockBuilder) Comparator(java.util.Comparator)

Example 15 with Expression

use of org.apache.calcite.linq4j.tree.Expression in project calcite by apache.

the class RexImpTable method createImplementor.

public static CallImplementor createImplementor(final NotNullImplementor implementor, final NullPolicy nullPolicy, final boolean harmonize) {
    switch(nullPolicy) {
        case ANY:
        case STRICT:
        case SEMI_STRICT:
            return new CallImplementor() {

                public Expression implement(RexToLixTranslator translator, RexCall call, NullAs nullAs) {
                    return implementNullSemantics0(translator, call, nullAs, nullPolicy, harmonize, implementor);
                }
            };
        case AND:
            // : Boolean.FALSE;
            return new CallImplementor() {

                public Expression implement(RexToLixTranslator translator, RexCall call, NullAs nullAs) {
                    assert call.getOperator() == AND : "AND null semantics is supported only for AND operator. Actual operator is " + String.valueOf(call.getOperator());
                    final RexCall call2 = call2(false, translator, call);
                    switch(nullAs) {
                        // Just foldAnd
                        case NOT_POSSIBLE:
                        case TRUE:
                        // thus if we convert nulls to true then no harm is made
                        case FALSE:
                            // AND call should return false iff has FALSEs or has NULLs,
                            // thus if we convert nulls to false, no harm is made
                            final List<Expression> expressions = translator.translateList(call2.getOperands(), nullAs);
                            return Expressions.foldAnd(expressions);
                        case NULL:
                        case IS_NULL:
                        case IS_NOT_NULL:
                            final List<Expression> nullAsTrue = translator.translateList(call2.getOperands(), NullAs.TRUE);
                            final List<Expression> nullAsIsNull = translator.translateList(call2.getOperands(), NullAs.IS_NULL);
                            Expression hasFalse = Expressions.not(Expressions.foldAnd(nullAsTrue));
                            Expression hasNull = Expressions.foldOr(nullAsIsNull);
                            Expression result = nullAs.handle(Expressions.condition(hasFalse, BOXED_FALSE_EXPR, Expressions.condition(hasNull, NULL_EXPR, BOXED_TRUE_EXPR)));
                            return result;
                        default:
                            throw new IllegalArgumentException("Unknown nullAs when implementing AND: " + nullAs);
                    }
                }
            };
        case OR:
            // : Boolean.TRUE;
            return new CallImplementor() {

                public Expression implement(RexToLixTranslator translator, RexCall call, final NullAs nullAs) {
                    assert call.getOperator() == OR : "OR null semantics is supported only for OR operator. Actual operator is " + String.valueOf(call.getOperator());
                    final RexCall call2 = call2(harmonize, translator, call);
                    switch(nullAs) {
                        // Just foldOr
                        case NOT_POSSIBLE:
                        case TRUE:
                        // thus we convert nulls to TRUE and foldOr
                        case FALSE:
                            // This should return true iff has TRUE arguments,
                            // thus we convert nulls to FALSE and foldOr
                            final List<Expression> expressions = translator.translateList(call2.getOperands(), nullAs);
                            return Expressions.foldOr(expressions);
                        case NULL:
                        case IS_NULL:
                        case IS_NOT_NULL:
                            final List<Expression> nullAsFalse = translator.translateList(call2.getOperands(), NullAs.FALSE);
                            final List<Expression> nullAsIsNull = translator.translateList(call2.getOperands(), NullAs.IS_NULL);
                            Expression hasTrue = Expressions.foldOr(nullAsFalse);
                            Expression hasNull = Expressions.foldOr(nullAsIsNull);
                            Expression result = nullAs.handle(Expressions.condition(hasTrue, BOXED_TRUE_EXPR, Expressions.condition(hasNull, NULL_EXPR, BOXED_FALSE_EXPR)));
                            return result;
                        default:
                            throw new IllegalArgumentException("Unknown nullAs when implementing OR: " + nullAs);
                    }
                }
            };
        case NOT:
            // else false.
            return new CallImplementor() {

                public Expression implement(RexToLixTranslator translator, RexCall call, NullAs nullAs) {
                    switch(nullAs) {
                        case NULL:
                            return Expressions.call(BuiltInMethod.NOT.method, translator.translateList(call.getOperands(), nullAs));
                        default:
                            return Expressions.not(translator.translate(call.getOperands().get(0), negate(nullAs)));
                    }
                }

                private NullAs negate(NullAs nullAs) {
                    switch(nullAs) {
                        case FALSE:
                            return NullAs.TRUE;
                        case TRUE:
                            return NullAs.FALSE;
                        default:
                            return nullAs;
                    }
                }
            };
        case NONE:
            return new CallImplementor() {

                public Expression implement(RexToLixTranslator translator, RexCall call, NullAs nullAs) {
                    final RexCall call2 = call2(false, translator, call);
                    return implementCall(translator, call2, implementor, nullAs);
                }
            };
        default:
            throw new AssertionError(nullPolicy);
    }
}
Also used : RexCall(org.apache.calcite.rex.RexCall) UnaryExpression(org.apache.calcite.linq4j.tree.UnaryExpression) ConstantExpression(org.apache.calcite.linq4j.tree.ConstantExpression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) Expression(org.apache.calcite.linq4j.tree.Expression) MemberExpression(org.apache.calcite.linq4j.tree.MemberExpression)

Aggregations

Expression (org.apache.calcite.linq4j.tree.Expression)91 ParameterExpression (org.apache.calcite.linq4j.tree.ParameterExpression)64 BlockBuilder (org.apache.calcite.linq4j.tree.BlockBuilder)56 ArrayList (java.util.ArrayList)22 MethodCallExpression (org.apache.calcite.linq4j.tree.MethodCallExpression)19 RelDataType (org.apache.calcite.rel.type.RelDataType)19 ConstantExpression (org.apache.calcite.linq4j.tree.ConstantExpression)16 Test (org.junit.Test)16 Type (java.lang.reflect.Type)11 PhysType (org.apache.calcite.adapter.enumerable.PhysType)11 UnaryExpression (org.apache.calcite.linq4j.tree.UnaryExpression)11 RexNode (org.apache.calcite.rex.RexNode)10 JavaTypeFactory (org.apache.calcite.adapter.java.JavaTypeFactory)9 BinaryExpression (org.apache.calcite.linq4j.tree.BinaryExpression)8 BlockStatement (org.apache.calcite.linq4j.tree.BlockStatement)8 NewExpression (org.apache.calcite.linq4j.tree.NewExpression)8 FunctionExpression (org.apache.calcite.linq4j.tree.FunctionExpression)7 MemberDeclaration (org.apache.calcite.linq4j.tree.MemberDeclaration)7 ImmutableList (com.google.common.collect.ImmutableList)5 List (java.util.List)5