Search in sources :

Example 26 with Expression

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

the class EnumerableRelImplementor method classDecl.

private ClassDeclaration classDecl(JavaTypeFactoryImpl.SyntheticRecordType type) {
    ClassDeclaration classDeclaration = Expressions.classDecl(Modifier.PUBLIC | Modifier.STATIC, type.getName(), null, ImmutableList.<Type>of(Serializable.class), new ArrayList<MemberDeclaration>());
    // ...
    for (Types.RecordField field : type.getRecordFields()) {
        classDeclaration.memberDeclarations.add(Expressions.fieldDecl(field.getModifiers(), Expressions.parameter(field.getType(), field.getName()), null));
    }
    // Constructor:
    // Foo(T0 f0, ...) { this.f0 = f0; ... }
    final BlockBuilder blockBuilder = new BlockBuilder();
    final List<ParameterExpression> parameters = new ArrayList<>();
    final ParameterExpression thisParameter = Expressions.parameter(type, "this");
    // Here a constructor without parameter is used because the generated
    // code could cause error if number of fields is too large.
    classDeclaration.memberDeclarations.add(Expressions.constructorDecl(Modifier.PUBLIC, type, parameters, blockBuilder.toBlock()));
    // equals method():
    // public boolean equals(Object o) {
    // if (this == o) return true;
    // if (!(o instanceof MyClass)) return false;
    // final MyClass that = (MyClass) o;
    // return this.f0 == that.f0
    // && equal(this.f1, that.f1)
    // ...
    // }
    final BlockBuilder blockBuilder2 = new BlockBuilder();
    final ParameterExpression thatParameter = Expressions.parameter(type, "that");
    final ParameterExpression oParameter = Expressions.parameter(Object.class, "o");
    blockBuilder2.add(Expressions.ifThen(Expressions.equal(thisParameter, oParameter), Expressions.return_(null, Expressions.constant(true))));
    blockBuilder2.add(Expressions.ifThen(Expressions.not(Expressions.typeIs(oParameter, type)), Expressions.return_(null, Expressions.constant(false))));
    blockBuilder2.add(Expressions.declare(Modifier.FINAL, thatParameter, Expressions.convert_(oParameter, type)));
    final List<Expression> conditions = new ArrayList<>();
    for (Types.RecordField field : type.getRecordFields()) {
        conditions.add(Primitive.is(field.getType()) ? Expressions.equal(Expressions.field(thisParameter, field.getName()), Expressions.field(thatParameter, field.getName())) : Expressions.call(BuiltInMethod.OBJECTS_EQUAL.method, Expressions.field(thisParameter, field.getName()), Expressions.field(thatParameter, field.getName())));
    }
    blockBuilder2.add(Expressions.return_(null, Expressions.foldAnd(conditions)));
    classDeclaration.memberDeclarations.add(Expressions.methodDecl(Modifier.PUBLIC, boolean.class, "equals", Collections.singletonList(oParameter), blockBuilder2.toBlock()));
    // hashCode method:
    // public int hashCode() {
    // int h = 0;
    // h = hash(h, f0);
    // ...
    // return h;
    // }
    final BlockBuilder blockBuilder3 = new BlockBuilder();
    final ParameterExpression hParameter = Expressions.parameter(int.class, "h");
    final ConstantExpression constantZero = Expressions.constant(0);
    blockBuilder3.add(Expressions.declare(0, hParameter, constantZero));
    for (Types.RecordField field : type.getRecordFields()) {
        final Method method = BuiltInMethod.HASH.method;
        blockBuilder3.add(Expressions.statement(Expressions.assign(hParameter, Expressions.call(method.getDeclaringClass(), method.getName(), ImmutableList.of(hParameter, Expressions.field(thisParameter, field))))));
    }
    blockBuilder3.add(Expressions.return_(null, hParameter));
    classDeclaration.memberDeclarations.add(Expressions.methodDecl(Modifier.PUBLIC, int.class, "hashCode", Collections.<ParameterExpression>emptyList(), blockBuilder3.toBlock()));
    // compareTo method:
    // public int compareTo(MyClass that) {
    // int c;
    // c = compare(this.f0, that.f0);
    // if (c != 0) return c;
    // ...
    // return 0;
    // }
    final BlockBuilder blockBuilder4 = new BlockBuilder();
    final ParameterExpression cParameter = Expressions.parameter(int.class, "c");
    final int mod = type.getRecordFields().size() == 1 ? Modifier.FINAL : 0;
    blockBuilder4.add(Expressions.declare(mod, cParameter, null));
    final ConditionalStatement conditionalStatement = Expressions.ifThen(Expressions.notEqual(cParameter, constantZero), Expressions.return_(null, cParameter));
    for (Types.RecordField field : type.getRecordFields()) {
        MethodCallExpression compareCall;
        try {
            final Method method = (field.nullable() ? BuiltInMethod.COMPARE_NULLS_LAST : BuiltInMethod.COMPARE).method;
            compareCall = Expressions.call(method.getDeclaringClass(), method.getName(), Expressions.field(thisParameter, field), Expressions.field(thatParameter, field));
        } catch (RuntimeException e) {
            if (e.getCause() instanceof NoSuchMethodException) {
                // In those cases it is fine if we skip the problematic fields.
                continue;
            }
            throw e;
        }
        blockBuilder4.add(Expressions.statement(Expressions.assign(cParameter, compareCall)));
        blockBuilder4.add(conditionalStatement);
    }
    blockBuilder4.add(Expressions.return_(null, constantZero));
    classDeclaration.memberDeclarations.add(Expressions.methodDecl(Modifier.PUBLIC, int.class, "compareTo", Collections.singletonList(thatParameter), blockBuilder4.toBlock()));
    // toString method:
    // public String toString() {
    // return "{f0=" + f0
    // + ", f1=" + f1
    // ...
    // + "}";
    // }
    final BlockBuilder blockBuilder5 = new BlockBuilder();
    Expression expression5 = null;
    for (Types.RecordField field : type.getRecordFields()) {
        if (expression5 == null) {
            expression5 = Expressions.constant("{" + field.getName() + "=");
        } else {
            expression5 = Expressions.add(expression5, Expressions.constant(", " + field.getName() + "="));
        }
        expression5 = Expressions.add(expression5, Expressions.field(thisParameter, field.getName()));
    }
    expression5 = expression5 == null ? Expressions.constant("{}") : Expressions.add(expression5, Expressions.constant("}"));
    blockBuilder5.add(Expressions.return_(null, expression5));
    classDeclaration.memberDeclarations.add(Expressions.methodDecl(Modifier.PUBLIC, String.class, "toString", Collections.<ParameterExpression>emptyList(), blockBuilder5.toBlock()));
    return classDeclaration;
}
Also used : Types(org.apache.calcite.linq4j.tree.Types) Serializable(java.io.Serializable) MemberDeclaration(org.apache.calcite.linq4j.tree.MemberDeclaration) ConstantExpression(org.apache.calcite.linq4j.tree.ConstantExpression) ConditionalStatement(org.apache.calcite.linq4j.tree.ConditionalStatement) ArrayList(java.util.ArrayList) BuiltInMethod(org.apache.calcite.util.BuiltInMethod) Method(java.lang.reflect.Method) ClassDeclaration(org.apache.calcite.linq4j.tree.ClassDeclaration) MethodCallExpression(org.apache.calcite.linq4j.tree.MethodCallExpression) NewArrayExpression(org.apache.calcite.linq4j.tree.NewArrayExpression) Expression(org.apache.calcite.linq4j.tree.Expression) NewExpression(org.apache.calcite.linq4j.tree.NewExpression) MethodCallExpression(org.apache.calcite.linq4j.tree.MethodCallExpression) ConstantExpression(org.apache.calcite.linq4j.tree.ConstantExpression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) BlockBuilder(org.apache.calcite.linq4j.tree.BlockBuilder)

Example 27 with Expression

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

the class EnumerableSort method implement.

public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
    final BlockBuilder builder = new BlockBuilder();
    final EnumerableRel child = (EnumerableRel) getInput();
    final Result result = implementor.visitChild(this, 0, child, pref);
    final PhysType physType = PhysTypeImpl.of(implementor.getTypeFactory(), getRowType(), result.format);
    Expression childExp = builder.append("child", result.block);
    PhysType inputPhysType = result.physType;
    final Pair<Expression, Expression> pair = inputPhysType.generateCollationKey(collation.getFieldCollations());
    builder.add(Expressions.return_(null, Expressions.call(childExp, BuiltInMethod.ORDER_BY.method, Expressions.list(builder.append("keySelector", pair.left)).appendIfNotNull(builder.appendIfNotNull("comparator", pair.right)))));
    return implementor.result(physType, builder.toBlock());
}
Also used : Expression(org.apache.calcite.linq4j.tree.Expression) BlockBuilder(org.apache.calcite.linq4j.tree.BlockBuilder)

Example 28 with Expression

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

the class EnumUtils method joinSelector.

static Expression joinSelector(JoinRelType joinType, PhysType physType, List<PhysType> inputPhysTypes) {
    // A parameter for each input.
    final List<ParameterExpression> parameters = new ArrayList<>();
    // Generate all fields.
    final List<Expression> expressions = new ArrayList<>();
    final int outputFieldCount = physType.getRowType().getFieldCount();
    for (Ord<PhysType> ord : Ord.zip(inputPhysTypes)) {
        final PhysType inputPhysType = ord.e.makeNullable(joinType.generatesNullsOn(ord.i));
        // If input item is just a primitive, we do not generate specialized
        // primitive apply override since it won't be called anyway
        // Function<T> always operates on boxed arguments
        final ParameterExpression parameter = Expressions.parameter(Primitive.box(inputPhysType.getJavaRowType()), EnumUtils.LEFT_RIGHT.get(ord.i));
        parameters.add(parameter);
        if (expressions.size() == outputFieldCount) {
            // For instance, if semi-join needs to return just the left inputs
            break;
        }
        final int fieldCount = inputPhysType.getRowType().getFieldCount();
        for (int i = 0; i < fieldCount; i++) {
            Expression expression = inputPhysType.fieldReference(parameter, i, physType.getJavaFieldType(expressions.size()));
            if (joinType.generatesNullsOn(ord.i)) {
                expression = Expressions.condition(Expressions.equal(parameter, Expressions.constant(null)), Expressions.constant(null), expression);
            }
            expressions.add(expression);
        }
    }
    return Expressions.lambda(Function2.class, physType.record(expressions), parameters);
}
Also used : Expression(org.apache.calcite.linq4j.tree.Expression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) ArrayList(java.util.ArrayList)

Example 29 with Expression

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

the class EnumerableCalc method implement.

public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
    final JavaTypeFactory typeFactory = implementor.getTypeFactory();
    final BlockBuilder builder = new BlockBuilder();
    final EnumerableRel child = (EnumerableRel) getInput();
    final Result result = implementor.visitChild(this, 0, child, pref);
    final PhysType physType = PhysTypeImpl.of(typeFactory, getRowType(), pref.prefer(result.format));
    // final Enumerable<Employee> inputEnumerable = <<child adapter>>;
    // return new Enumerable<IntString>() {
    // Enumerator<IntString> enumerator() {
    // return new Enumerator<IntString>() {
    // public void reset() {
    // ...
    Type outputJavaType = physType.getJavaRowType();
    final Type enumeratorType = Types.of(Enumerator.class, outputJavaType);
    Type inputJavaType = result.physType.getJavaRowType();
    ParameterExpression inputEnumerator = Expressions.parameter(Types.of(Enumerator.class, inputJavaType), "inputEnumerator");
    Expression input = RexToLixTranslator.convert(Expressions.call(inputEnumerator, BuiltInMethod.ENUMERATOR_CURRENT.method), inputJavaType);
    final RexBuilder rexBuilder = getCluster().getRexBuilder();
    final RelMetadataQuery mq = RelMetadataQuery.instance();
    final RelOptPredicateList predicates = mq.getPulledUpPredicates(child);
    final RexSimplify simplify = new RexSimplify(rexBuilder, predicates, false, RexUtil.EXECUTOR);
    final RexProgram program = this.program.normalize(rexBuilder, simplify);
    BlockStatement moveNextBody;
    if (program.getCondition() == null) {
        moveNextBody = Blocks.toFunctionBlock(Expressions.call(inputEnumerator, BuiltInMethod.ENUMERATOR_MOVE_NEXT.method));
    } else {
        final BlockBuilder builder2 = new BlockBuilder();
        Expression condition = RexToLixTranslator.translateCondition(program, typeFactory, builder2, new RexToLixTranslator.InputGetterImpl(Collections.singletonList(Pair.of(input, result.physType))), implementor.allCorrelateVariables);
        builder2.add(Expressions.ifThen(condition, Expressions.return_(null, Expressions.constant(true))));
        moveNextBody = Expressions.block(Expressions.while_(Expressions.call(inputEnumerator, BuiltInMethod.ENUMERATOR_MOVE_NEXT.method), builder2.toBlock()), Expressions.return_(null, Expressions.constant(false)));
    }
    final BlockBuilder builder3 = new BlockBuilder();
    List<Expression> expressions = RexToLixTranslator.translateProjects(program, typeFactory, builder3, physType, DataContext.ROOT, new RexToLixTranslator.InputGetterImpl(Collections.singletonList(Pair.of(input, result.physType))), implementor.allCorrelateVariables);
    builder3.add(Expressions.return_(null, physType.record(expressions)));
    BlockStatement currentBody = builder3.toBlock();
    final Expression inputEnumerable = builder.append("inputEnumerable", result.block, false);
    final Expression body = Expressions.new_(enumeratorType, NO_EXPRS, Expressions.list(Expressions.fieldDecl(Modifier.PUBLIC | Modifier.FINAL, inputEnumerator, Expressions.call(inputEnumerable, BuiltInMethod.ENUMERABLE_ENUMERATOR.method)), EnumUtils.overridingMethodDecl(BuiltInMethod.ENUMERATOR_RESET.method, NO_PARAMS, Blocks.toFunctionBlock(Expressions.call(inputEnumerator, BuiltInMethod.ENUMERATOR_RESET.method))), EnumUtils.overridingMethodDecl(BuiltInMethod.ENUMERATOR_MOVE_NEXT.method, NO_PARAMS, moveNextBody), EnumUtils.overridingMethodDecl(BuiltInMethod.ENUMERATOR_CLOSE.method, NO_PARAMS, Blocks.toFunctionBlock(Expressions.call(inputEnumerator, BuiltInMethod.ENUMERATOR_CLOSE.method))), Expressions.methodDecl(Modifier.PUBLIC, BRIDGE_METHODS ? Object.class : outputJavaType, "current", NO_PARAMS, currentBody)));
    builder.add(Expressions.return_(null, Expressions.new_(BuiltInMethod.ABSTRACT_ENUMERABLE_CTOR.constructor, // Collections.singletonList(inputRowType),
    NO_EXPRS, ImmutableList.<MemberDeclaration>of(Expressions.methodDecl(Modifier.PUBLIC, enumeratorType, BuiltInMethod.ENUMERABLE_ENUMERATOR.method.getName(), NO_PARAMS, Blocks.toFunctionBlock(body))))));
    return implementor.result(physType, builder.toBlock());
}
Also used : RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) RexProgram(org.apache.calcite.rex.RexProgram) BlockStatement(org.apache.calcite.linq4j.tree.BlockStatement) Type(java.lang.reflect.Type) Enumerator(org.apache.calcite.linq4j.Enumerator) Expression(org.apache.calcite.linq4j.tree.Expression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) RexSimplify(org.apache.calcite.rex.RexSimplify) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) JavaTypeFactory(org.apache.calcite.adapter.java.JavaTypeFactory) RexBuilder(org.apache.calcite.rex.RexBuilder) BlockBuilder(org.apache.calcite.linq4j.tree.BlockBuilder)

Example 30 with Expression

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

the class EnumerableCollect method implement.

public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
    final BlockBuilder builder = new BlockBuilder();
    final EnumerableRel child = (EnumerableRel) getInput();
    final Result result = implementor.visitChild(this, 0, child, Prefer.ARRAY);
    final PhysType physType = PhysTypeImpl.of(implementor.getTypeFactory(), getRowType(), JavaRowFormat.LIST);
    // final Enumerable<Employee> child = <<child adapter>>;
    // final List<Employee> list = child.toList();
    Expression child_ = builder.append("child", result.block);
    Expression list_ = builder.append("list", Expressions.call(child_, BuiltInMethod.ENUMERABLE_TO_LIST.method));
    builder.add(Expressions.return_(null, Expressions.call(BuiltInMethod.SINGLETON_ENUMERABLE.method, list_)));
    return implementor.result(physType, builder.toBlock());
}
Also used : Expression(org.apache.calcite.linq4j.tree.Expression) BlockBuilder(org.apache.calcite.linq4j.tree.BlockBuilder)

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