Search in sources :

Example 56 with Expression

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

the class EnumerableThetaJoin method predicate.

Expression predicate(EnumerableRelImplementor implementor, BlockBuilder builder, PhysType leftPhysType, PhysType rightPhysType, RexNode condition) {
    final ParameterExpression left_ = Expressions.parameter(leftPhysType.getJavaRowType(), "left");
    final ParameterExpression right_ = Expressions.parameter(rightPhysType.getJavaRowType(), "right");
    final RexProgramBuilder program = new RexProgramBuilder(implementor.getTypeFactory().builder().addAll(left.getRowType().getFieldList()).addAll(right.getRowType().getFieldList()).build(), getCluster().getRexBuilder());
    program.addCondition(condition);
    builder.add(Expressions.return_(null, RexToLixTranslator.translateCondition(program.getProgram(), implementor.getTypeFactory(), builder, new RexToLixTranslator.InputGetterImpl(ImmutableList.of(Pair.of((Expression) left_, leftPhysType), Pair.of((Expression) right_, rightPhysType))), implementor.allCorrelateVariables)));
    return Expressions.lambda(Predicate2.class, builder.toBlock(), left_, right_);
}
Also used : Expression(org.apache.calcite.linq4j.tree.Expression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) RexProgramBuilder(org.apache.calcite.rex.RexProgramBuilder)

Example 57 with Expression

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

the class EnumerableUnion method implement.

public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
    final BlockBuilder builder = new BlockBuilder();
    Expression unionExp = null;
    for (Ord<RelNode> ord : Ord.zip(inputs)) {
        EnumerableRel input = (EnumerableRel) ord.e;
        final Result result = implementor.visitChild(this, ord.i, input, pref);
        Expression childExp = builder.append("child" + ord.i, result.block);
        if (unionExp == null) {
            unionExp = childExp;
        } else {
            unionExp = all ? Expressions.call(unionExp, BuiltInMethod.CONCAT.method, childExp) : Expressions.call(unionExp, BuiltInMethod.UNION.method, Expressions.list(childExp).appendIfNotNull(result.physType.comparer()));
        }
    }
    builder.add(unionExp);
    final PhysType physType = PhysTypeImpl.of(implementor.getTypeFactory(), getRowType(), pref.prefer(JavaRowFormat.CUSTOM));
    return implementor.result(physType, builder.toBlock());
}
Also used : RelNode(org.apache.calcite.rel.RelNode) Expression(org.apache.calcite.linq4j.tree.Expression) BlockBuilder(org.apache.calcite.linq4j.tree.BlockBuilder)

Example 58 with Expression

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

the class EnumerableValues method implement.

public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
    /*
          return Linq4j.asEnumerable(
              new Object[][] {
                  new Object[] {1, 2},
                  new Object[] {3, 4}
              });
*/
    final JavaTypeFactory typeFactory = (JavaTypeFactory) getCluster().getTypeFactory();
    final BlockBuilder builder = new BlockBuilder();
    final PhysType physType = PhysTypeImpl.of(implementor.getTypeFactory(), getRowType(), pref.preferCustom());
    final Type rowClass = physType.getJavaRowType();
    final List<Expression> expressions = new ArrayList<Expression>();
    final List<RelDataTypeField> fields = rowType.getFieldList();
    for (List<RexLiteral> tuple : tuples) {
        final List<Expression> literals = new ArrayList<Expression>();
        for (Pair<RelDataTypeField, RexLiteral> pair : Pair.zip(fields, tuple)) {
            literals.add(RexToLixTranslator.translateLiteral(pair.right, pair.left.getType(), typeFactory, RexImpTable.NullAs.NULL));
        }
        expressions.add(physType.record(literals));
    }
    builder.add(Expressions.return_(null, Expressions.call(BuiltInMethod.AS_ENUMERABLE.method, Expressions.newArrayInit(Primitive.box(rowClass), expressions))));
    return implementor.result(physType, builder.toBlock());
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) RelDataType(org.apache.calcite.rel.type.RelDataType) Type(java.lang.reflect.Type) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) Expression(org.apache.calcite.linq4j.tree.Expression) JavaTypeFactory(org.apache.calcite.adapter.java.JavaTypeFactory) ArrayList(java.util.ArrayList) BlockBuilder(org.apache.calcite.linq4j.tree.BlockBuilder)

Example 59 with Expression

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

the class EnumerableAggregate 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);
    Expression childExp = builder.append("child", result.block);
    final PhysType physType = PhysTypeImpl.of(typeFactory, getRowType(), pref.preferCustom());
    // final Enumerable<Employee> child = <<child adapter>>;
    // Function1<Employee, Integer> keySelector =
    // new Function1<Employee, Integer>() {
    // public Integer apply(Employee a0) {
    // return a0.deptno;
    // }
    // };
    // Function1<Employee, Object[]> accumulatorInitializer =
    // new Function1<Employee, Object[]>() {
    // public Object[] apply(Employee a0) {
    // return new Object[] {0, 0};
    // }
    // };
    // Function2<Object[], Employee, Object[]> accumulatorAdder =
    // new Function2<Object[], Employee, Object[]>() {
    // public Object[] apply(Object[] a1, Employee a0) {
    // a1[0] = ((Integer) a1[0]) + 1;
    // a1[1] = ((Integer) a1[1]) + a0.salary;
    // return a1;
    // }
    // };
    // Function2<Integer, Object[], Object[]> resultSelector =
    // new Function2<Integer, Object[], Object[]>() {
    // public Object[] apply(Integer a0, Object[] a1) {
    // return new Object[] { a0, a1[0], a1[1] };
    // }
    // };
    // return childEnumerable
    // .groupBy(
    // keySelector, accumulatorInitializer, accumulatorAdder,
    // resultSelector);
    // 
    // or, if key has 0 columns,
    // 
    // return childEnumerable
    // .aggregate(
    // accumulatorInitializer.apply(),
    // accumulatorAdder,
    // resultSelector);
    // 
    // with a slightly different resultSelector; or if there are no aggregate
    // functions
    // 
    // final Enumerable<Employee> child = <<child adapter>>;
    // Function1<Employee, Integer> keySelector =
    // new Function1<Employee, Integer>() {
    // public Integer apply(Employee a0) {
    // return a0.deptno;
    // }
    // };
    // EqualityComparer<Employee> equalityComparer =
    // new EqualityComparer<Employee>() {
    // boolean equal(Employee a0, Employee a1) {
    // return a0.deptno;
    // }
    // };
    // return child
    // .distinct(equalityComparer);
    final PhysType inputPhysType = result.physType;
    ParameterExpression parameter = Expressions.parameter(inputPhysType.getJavaRowType(), "a0");
    final PhysType keyPhysType = inputPhysType.project(groupSet.asList(), getGroupType() != Group.SIMPLE, JavaRowFormat.LIST);
    final int groupCount = getGroupCount();
    final List<AggImpState> aggs = new ArrayList<>(aggCalls.size());
    for (Ord<AggregateCall> call : Ord.zip(aggCalls)) {
        aggs.add(new AggImpState(call.i, call.e, false));
    }
    // Function0<Object[]> accumulatorInitializer =
    // new Function0<Object[]>() {
    // public Object[] apply() {
    // return new Object[] {0, 0};
    // }
    // };
    final List<Expression> initExpressions = new ArrayList<>();
    final BlockBuilder initBlock = new BlockBuilder();
    final List<Type> aggStateTypes = new ArrayList<>();
    for (final AggImpState agg : aggs) {
        agg.context = new AggContextImpl(agg, typeFactory);
        final List<Type> state = agg.implementor.getStateType(agg.context);
        if (state.isEmpty()) {
            agg.state = ImmutableList.of();
            continue;
        }
        aggStateTypes.addAll(state);
        final List<Expression> decls = new ArrayList<>(state.size());
        for (int i = 0; i < state.size(); i++) {
            String aggName = "a" + agg.aggIdx;
            if (CalcitePrepareImpl.DEBUG) {
                aggName = Util.toJavaId(agg.call.getAggregation().getName(), 0).substring("ID$0$".length()) + aggName;
            }
            Type type = state.get(i);
            ParameterExpression pe = Expressions.parameter(type, initBlock.newName(aggName + "s" + i));
            initBlock.add(Expressions.declare(0, pe, null));
            decls.add(pe);
        }
        agg.state = decls;
        initExpressions.addAll(decls);
        agg.implementor.implementReset(agg.context, new AggResultContextImpl(initBlock, agg.call, decls, null, null));
    }
    final PhysType accPhysType = PhysTypeImpl.of(typeFactory, typeFactory.createSyntheticType(aggStateTypes));
    if (accPhysType.getJavaRowType() instanceof JavaTypeFactoryImpl.SyntheticRecordType) {
        // We have to initialize the SyntheticRecordType instance this way, to avoid using
        // class constructor with too many parameters.
        JavaTypeFactoryImpl.SyntheticRecordType synType = (JavaTypeFactoryImpl.SyntheticRecordType) accPhysType.getJavaRowType();
        final ParameterExpression record0_ = Expressions.parameter(accPhysType.getJavaRowType(), "record0");
        initBlock.add(Expressions.declare(0, record0_, null));
        initBlock.add(Expressions.statement(Expressions.assign(record0_, Expressions.new_(accPhysType.getJavaRowType()))));
        List<Types.RecordField> fieldList = synType.getRecordFields();
        for (int i = 0; i < initExpressions.size(); i++) {
            Expression right = initExpressions.get(i);
            initBlock.add(Expressions.statement(Expressions.assign(Expressions.field(record0_, fieldList.get(i)), right)));
        }
        initBlock.add(record0_);
    } else {
        initBlock.add(accPhysType.record(initExpressions));
    }
    final Expression accumulatorInitializer = builder.append("accumulatorInitializer", Expressions.lambda(Function0.class, initBlock.toBlock()));
    // Function2<Object[], Employee, Object[]> accumulatorAdder =
    // new Function2<Object[], Employee, Object[]>() {
    // public Object[] apply(Object[] acc, Employee in) {
    // acc[0] = ((Integer) acc[0]) + 1;
    // acc[1] = ((Integer) acc[1]) + in.salary;
    // return acc;
    // }
    // };
    final BlockBuilder builder2 = new BlockBuilder();
    final ParameterExpression inParameter = Expressions.parameter(inputPhysType.getJavaRowType(), "in");
    final ParameterExpression acc_ = Expressions.parameter(accPhysType.getJavaRowType(), "acc");
    for (int i = 0, stateOffset = 0; i < aggs.size(); i++) {
        final AggImpState agg = aggs.get(i);
        final int stateSize = agg.state.size();
        final List<Expression> accumulator = new ArrayList<>(stateSize);
        for (int j = 0; j < stateSize; j++) {
            accumulator.add(accPhysType.fieldReference(acc_, j + stateOffset));
        }
        agg.state = accumulator;
        stateOffset += stateSize;
        AggAddContext addContext = new AggAddContextImpl(builder2, accumulator) {

            public List<RexNode> rexArguments() {
                List<RelDataTypeField> inputTypes = inputPhysType.getRowType().getFieldList();
                List<RexNode> args = new ArrayList<>();
                for (int index : agg.call.getArgList()) {
                    args.add(RexInputRef.of(index, inputTypes));
                }
                return args;
            }

            public RexNode rexFilterArgument() {
                return agg.call.filterArg < 0 ? null : RexInputRef.of(agg.call.filterArg, inputPhysType.getRowType());
            }

            public RexToLixTranslator rowTranslator() {
                return RexToLixTranslator.forAggregation(typeFactory, currentBlock(), new RexToLixTranslator.InputGetterImpl(Collections.singletonList(Pair.of((Expression) inParameter, inputPhysType)))).setNullable(currentNullables());
            }
        };
        agg.implementor.implementAdd(agg.context, addContext);
    }
    builder2.add(acc_);
    final Expression accumulatorAdder = builder.append("accumulatorAdder", Expressions.lambda(Function2.class, builder2.toBlock(), acc_, inParameter));
    // Function2<Integer, Object[], Object[]> resultSelector =
    // new Function2<Integer, Object[], Object[]>() {
    // public Object[] apply(Integer key, Object[] acc) {
    // return new Object[] { key, acc[0], acc[1] };
    // }
    // };
    final BlockBuilder resultBlock = new BlockBuilder();
    final List<Expression> results = Expressions.list();
    final ParameterExpression key_;
    if (groupCount == 0) {
        key_ = null;
    } else {
        final Type keyType = keyPhysType.getJavaRowType();
        key_ = Expressions.parameter(keyType, "key");
        for (int j = 0; j < groupCount; j++) {
            final Expression ref = keyPhysType.fieldReference(key_, j);
            if (getGroupType() == Group.SIMPLE) {
                results.add(ref);
            } else {
                results.add(Expressions.condition(keyPhysType.fieldReference(key_, groupCount + j), Expressions.constant(null), Expressions.box(ref)));
            }
        }
    }
    for (final AggImpState agg : aggs) {
        results.add(agg.implementor.implementResult(agg.context, new AggResultContextImpl(resultBlock, agg.call, agg.state, key_, keyPhysType)));
    }
    resultBlock.add(physType.record(results));
    if (getGroupType() != Group.SIMPLE) {
        final List<Expression> list = Lists.newArrayList();
        for (ImmutableBitSet set : groupSets) {
            list.add(inputPhysType.generateSelector(parameter, groupSet.asList(), set.asList(), keyPhysType.getFormat()));
        }
        final Expression keySelectors_ = builder.append("keySelectors", Expressions.call(BuiltInMethod.ARRAYS_AS_LIST.method, list));
        final Expression resultSelector = builder.append("resultSelector", Expressions.lambda(Function2.class, resultBlock.toBlock(), key_, acc_));
        builder.add(Expressions.return_(null, Expressions.call(BuiltInMethod.GROUP_BY_MULTIPLE.method, Expressions.list(childExp, keySelectors_, accumulatorInitializer, accumulatorAdder, resultSelector).appendIfNotNull(keyPhysType.comparer()))));
    } else if (groupCount == 0) {
        final Expression resultSelector = builder.append("resultSelector", Expressions.lambda(Function1.class, resultBlock.toBlock(), acc_));
        builder.add(Expressions.return_(null, Expressions.call(BuiltInMethod.SINGLETON_ENUMERABLE.method, Expressions.call(childExp, BuiltInMethod.AGGREGATE.method, Expressions.call(accumulatorInitializer, "apply"), accumulatorAdder, resultSelector))));
    } else if (aggCalls.isEmpty() && groupSet.equals(ImmutableBitSet.range(child.getRowType().getFieldCount()))) {
        builder.add(Expressions.return_(null, Expressions.call(inputPhysType.convertTo(childExp, physType), BuiltInMethod.DISTINCT.method, Expressions.<Expression>list().appendIfNotNull(physType.comparer()))));
    } else {
        final Expression keySelector_ = builder.append("keySelector", inputPhysType.generateSelector(parameter, groupSet.asList(), keyPhysType.getFormat()));
        final Expression resultSelector_ = builder.append("resultSelector", Expressions.lambda(Function2.class, resultBlock.toBlock(), key_, acc_));
        builder.add(Expressions.return_(null, Expressions.call(childExp, BuiltInMethod.GROUP_BY2.method, Expressions.list(keySelector_, accumulatorInitializer, accumulatorAdder, resultSelector_).appendIfNotNull(keyPhysType.comparer()))));
    }
    return implementor.result(physType, builder.toBlock());
}
Also used : ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ArrayList(java.util.ArrayList) JavaTypeFactoryImpl(org.apache.calcite.jdbc.JavaTypeFactoryImpl) JavaTypeFactory(org.apache.calcite.adapter.java.JavaTypeFactory) BlockBuilder(org.apache.calcite.linq4j.tree.BlockBuilder) Function0(org.apache.calcite.linq4j.function.Function0) Function2(org.apache.calcite.linq4j.function.Function2) AggregateCall(org.apache.calcite.rel.core.AggregateCall) AggAddContextImpl(org.apache.calcite.adapter.enumerable.impl.AggAddContextImpl) RelDataType(org.apache.calcite.rel.type.RelDataType) Type(java.lang.reflect.Type) AggResultContextImpl(org.apache.calcite.adapter.enumerable.impl.AggResultContextImpl) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) Expression(org.apache.calcite.linq4j.tree.Expression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) RexNode(org.apache.calcite.rex.RexNode)

Example 60 with Expression

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

the class EnumerableRelImplementor method implementRoot.

public ClassDeclaration implementRoot(EnumerableRel rootRel, EnumerableRel.Prefer prefer) {
    EnumerableRel.Result result = rootRel.implement(this, prefer);
    switch(prefer) {
        case ARRAY:
            if (result.physType.getFormat() == JavaRowFormat.ARRAY && rootRel.getRowType().getFieldCount() == 1) {
                BlockBuilder bb = new BlockBuilder();
                Expression e = null;
                for (Statement statement : result.block.statements) {
                    if (statement instanceof GotoStatement) {
                        e = bb.append("v", ((GotoStatement) statement).expression);
                    } else {
                        bb.add(statement);
                    }
                }
                if (e != null) {
                    bb.add(Expressions.return_(null, Expressions.call(null, BuiltInMethod.SLICE0.method, e)));
                }
                result = new EnumerableRel.Result(bb.toBlock(), result.physType, JavaRowFormat.SCALAR);
            }
    }
    final List<MemberDeclaration> memberDeclarations = new ArrayList<>();
    new TypeRegistrar(memberDeclarations).go(result);
    // The following is a workaround to
    // http://jira.codehaus.org/browse/JANINO-169. Otherwise we'd remove the
    // member variable, rename the "root0" parameter as "root", and reference it
    // directly from inner classes.
    final ParameterExpression root0_ = Expressions.parameter(Modifier.FINAL, DataContext.class, "root0");
    // This creates the following code
    // final Integer v1stashed = (Integer) root.get("v1stashed")
    // It is convenient for passing non-literal "compile-time" constants
    final Collection<Statement> stashed = Collections2.transform(stashedParameters.values(), new Function<ParameterExpression, Statement>() {

        public Statement apply(ParameterExpression input) {
            return Expressions.declare(Modifier.FINAL, input, Expressions.convert_(Expressions.call(DataContext.ROOT, BuiltInMethod.DATA_CONTEXT_GET.method, Expressions.constant(input.name)), input.type));
        }
    });
    final BlockStatement block = Expressions.block(Iterables.concat(ImmutableList.of(Expressions.statement(Expressions.assign(DataContext.ROOT, root0_))), stashed, result.block.statements));
    memberDeclarations.add(Expressions.fieldDecl(0, DataContext.ROOT, null));
    memberDeclarations.add(Expressions.methodDecl(Modifier.PUBLIC, Enumerable.class, BuiltInMethod.BINDABLE_BIND.method.getName(), Expressions.list(root0_), block));
    memberDeclarations.add(Expressions.methodDecl(Modifier.PUBLIC, Class.class, BuiltInMethod.TYPED_GET_ELEMENT_TYPE.method.getName(), Collections.<ParameterExpression>emptyList(), Blocks.toFunctionBlock(Expressions.return_(null, Expressions.constant(result.physType.getJavaRowType())))));
    return Expressions.classDecl(Modifier.PUBLIC, "Baz", null, Collections.<Type>singletonList(Bindable.class), memberDeclarations);
}
Also used : GotoStatement(org.apache.calcite.linq4j.tree.GotoStatement) Statement(org.apache.calcite.linq4j.tree.Statement) BlockStatement(org.apache.calcite.linq4j.tree.BlockStatement) ConditionalStatement(org.apache.calcite.linq4j.tree.ConditionalStatement) MemberDeclaration(org.apache.calcite.linq4j.tree.MemberDeclaration) ArrayList(java.util.ArrayList) Bindable(org.apache.calcite.runtime.Bindable) BlockStatement(org.apache.calcite.linq4j.tree.BlockStatement) GotoStatement(org.apache.calcite.linq4j.tree.GotoStatement) 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) Enumerable(org.apache.calcite.linq4j.Enumerable) 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