Search in sources :

Example 26 with RexProgramBuilder

use of org.apache.calcite.rex.RexProgramBuilder in project calcite by apache.

the class RexProgramTest method createProg.

/**
 * Creates a program, depending on variant:
 *
 * <ol>
 * <li><code>select (x + y) + (x + 1) as a, (x + x) as b from t(x, y)</code>
 * <li><code>select (x + y) + (x + 1) as a, (x + (x + 1)) as b
 * from t(x, y)</code>
 * <li><code>select (x + y) + (x + 1) as a, (x + x) as b from t(x, y)
 * where ((x + y) &gt; 1) and ((x + y) &gt; 1)</code>
 * <li><code>select (x + y) + (x + 1) as a, (x + x) as b from t(x, y)
 * where not case
 *           when x + 1 &gt; 5 then true
 *           when y is null then null
 *           else false
 *           end</code>
 * </ol>
 */
private RexProgramBuilder createProg(int variant) {
    assert variant >= 0 && variant <= 4;
    List<RelDataType> types = Arrays.asList(typeFactory.createSqlType(SqlTypeName.INTEGER), typeFactory.createSqlType(SqlTypeName.INTEGER));
    List<String> names = Arrays.asList("x", "y");
    RelDataType inputRowType = typeFactory.createStructType(types, names);
    final RexProgramBuilder builder = new RexProgramBuilder(inputRowType, rexBuilder);
    // $t0 = x
    // $t1 = y
    // $t2 = $t0 + 1 (i.e. x + 1)
    final RexNode i0 = rexBuilder.makeInputRef(types.get(0), 0);
    final RexLiteral c1 = rexBuilder.makeExactLiteral(BigDecimal.ONE);
    final RexLiteral c5 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(5L));
    RexLocalRef t2 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.PLUS, i0, c1));
    // $t3 = 77 (not used)
    final RexLiteral c77 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(77));
    RexLocalRef t3 = builder.addExpr(c77);
    Util.discard(t3);
    // $t4 = $t0 + $t1 (i.e. x + y)
    final RexNode i1 = rexBuilder.makeInputRef(types.get(1), 1);
    RexLocalRef t4 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.PLUS, i0, i1));
    RexLocalRef t5;
    final RexLocalRef t1;
    switch(variant) {
        case 0:
        case 2:
            // $t5 = $t0 + $t0 (i.e. x + x)
            t5 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.PLUS, i0, i0));
            t1 = null;
            break;
        case 1:
        case 3:
        case 4:
            // $tx = $t0 + 1
            t1 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.PLUS, i0, c1));
            // $t5 = $t0 + $tx (i.e. x + (x + 1))
            t5 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.PLUS, i0, t1));
            break;
        default:
            throw new AssertionError("unexpected variant " + variant);
    }
    // $t6 = $t4 + $t2 (i.e. (x + y) + (x + 1))
    RexLocalRef t6 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.PLUS, t4, t2));
    builder.addProject(t6.getIndex(), "a");
    builder.addProject(t5.getIndex(), "b");
    final RexLocalRef t7;
    final RexLocalRef t8;
    switch(variant) {
        case 2:
            // $t7 = $t4 > $i0 (i.e. (x + y) > 0)
            t7 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN, t4, i0));
            // $t8 = $t7 AND $t7
            t8 = builder.addExpr(and(t7, t7));
            builder.addCondition(t8);
            builder.addCondition(t7);
            break;
        case 3:
        case 4:
            // $t7 = 5
            t7 = builder.addExpr(c5);
            // $t8 = $t2 > $t7 (i.e. (x + 1) > 5)
            t8 = builder.addExpr(gt(t2, t7));
            // $t9 = true
            final RexLocalRef t9 = builder.addExpr(trueLiteral);
            // $t10 = $t1 is not null (i.e. y is not null)
            assert t1 != null;
            final RexLocalRef t10 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, t1));
            // $t11 = false
            final RexLocalRef t11 = builder.addExpr(falseLiteral);
            // $t12 = unknown
            final RexLocalRef t12 = builder.addExpr(unknownLiteral);
            // $t13 = case when $t8 then $t9 when $t10 then $t11 else $t12 end
            final RexLocalRef t13 = builder.addExpr(case_(t8, t9, t10, t11, t12));
            // $t14 = not $t13 (i.e. not case ... end)
            final RexLocalRef t14 = builder.addExpr(not(t13));
            // don't add 't14 is true' - that is implicit
            if (variant == 3) {
                builder.addCondition(t14);
            } else {
                // $t15 = $14 is true
                final RexLocalRef t15 = builder.addExpr(rexBuilder.makeCall(SqlStdOperatorTable.IS_TRUE, t14));
                builder.addCondition(t15);
            }
    }
    return builder;
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) RexLocalRef(org.apache.calcite.rex.RexLocalRef) RelDataType(org.apache.calcite.rel.type.RelDataType) DateString(org.apache.calcite.util.DateString) TimestampWithTimeZoneString(org.apache.calcite.util.TimestampWithTimeZoneString) ByteString(org.apache.calcite.avatica.util.ByteString) TimestampString(org.apache.calcite.util.TimestampString) TimeString(org.apache.calcite.util.TimeString) NlsString(org.apache.calcite.util.NlsString) RexProgramBuilder(org.apache.calcite.rex.RexProgramBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 27 with RexProgramBuilder

use of org.apache.calcite.rex.RexProgramBuilder in project flink by apache.

the class PushFilterPastChangelogNormalizeRule method projectIdentityWithConditions.

/**
 * Returns a {@link StreamPhysicalCalc} with the given {@param conditions} and an identity
 * projection.
 */
private StreamPhysicalCalc projectIdentityWithConditions(RelBuilder relBuilder, RelNode newInput, List<RexNode> conditions) {
    final RexProgramBuilder programBuilder = new RexProgramBuilder(newInput.getRowType(), relBuilder.getRexBuilder());
    programBuilder.addIdentity();
    final RexNode condition = relBuilder.and(conditions);
    if (!condition.isAlwaysTrue()) {
        programBuilder.addCondition(condition);
    }
    final RexProgram newProgram = programBuilder.getProgram();
    return new StreamPhysicalCalc(newInput.getCluster(), newInput.getTraitSet(), newInput, newProgram, newProgram.getOutputRowType());
}
Also used : RexProgram(org.apache.calcite.rex.RexProgram) StreamPhysicalCalc(org.apache.flink.table.planner.plan.nodes.physical.stream.StreamPhysicalCalc) RexProgramBuilder(org.apache.calcite.rex.RexProgramBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 28 with RexProgramBuilder

use of org.apache.calcite.rex.RexProgramBuilder in project flink by apache.

the class PushFilterPastChangelogNormalizeRule method projectWith.

/**
 * Returns a {@link StreamPhysicalCalc} which is a copy of {@param calc}, but with the
 * projections applied from {@param projectFromCalc}.
 */
private StreamPhysicalCalc projectWith(RelBuilder relBuilder, StreamPhysicalCalc projectFromCalc, StreamPhysicalCalc calc) {
    final RexProgramBuilder programBuilder = new RexProgramBuilder(calc.getRowType(), relBuilder.getRexBuilder());
    if (calc.getProgram().getCondition() != null) {
        programBuilder.addCondition(calc.getProgram().expandLocalRef(calc.getProgram().getCondition()));
    }
    for (Pair<RexLocalRef, String> projectRef : projectFromCalc.getProgram().getNamedProjects()) {
        final RexNode project = projectFromCalc.getProgram().expandLocalRef(projectRef.left);
        programBuilder.addProject(project, projectRef.right);
    }
    final RexProgram newProgram = programBuilder.getProgram();
    return (StreamPhysicalCalc) calc.copy(calc.getTraitSet(), calc.getInput(), newProgram);
}
Also used : RexProgram(org.apache.calcite.rex.RexProgram) StreamPhysicalCalc(org.apache.flink.table.planner.plan.nodes.physical.stream.StreamPhysicalCalc) RexLocalRef(org.apache.calcite.rex.RexLocalRef) RexProgramBuilder(org.apache.calcite.rex.RexProgramBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 29 with RexProgramBuilder

use of org.apache.calcite.rex.RexProgramBuilder in project flink by apache.

the class FlinkSemiAntiJoinProjectTransposeRule method adjustCondition.

/**
 * Pulls the project above the semi/anti join and returns the resulting semi/anti join
 * condition. As a result, the semi/anti join condition should be modified such that references
 * to the LHS of a semi/anti join should now reference the children of the project that's on the
 * LHS.
 *
 * @param project LogicalProject on the LHS of the semi/anti join
 * @param join the semi/anti join
 * @return the modified semi/anti join condition
 */
private RexNode adjustCondition(LogicalProject project, Join join) {
    // create two RexPrograms -- the bottom one representing a
    // concatenation of the project and the RHS of the semi/anti join and the
    // top one representing the semi/anti join condition
    RexBuilder rexBuilder = project.getCluster().getRexBuilder();
    RelDataTypeFactory typeFactory = rexBuilder.getTypeFactory();
    RelNode rightChild = join.getRight();
    // for the bottom RexProgram, the input is a concatenation of the
    // child of the project and the RHS of the semi/anti join
    RelDataType bottomInputRowType = SqlValidatorUtil.deriveJoinRowType(project.getInput().getRowType(), rightChild.getRowType(), JoinRelType.INNER, typeFactory, null, join.getSystemFieldList());
    RexProgramBuilder bottomProgramBuilder = new RexProgramBuilder(bottomInputRowType, rexBuilder);
    // of the semi/anti join
    for (Pair<RexNode, String> pair : project.getNamedProjects()) {
        bottomProgramBuilder.addProject(pair.left, pair.right);
    }
    int nLeftFields = project.getInput().getRowType().getFieldCount();
    List<RelDataTypeField> rightFields = rightChild.getRowType().getFieldList();
    int nRightFields = rightFields.size();
    for (int i = 0; i < nRightFields; i++) {
        final RelDataTypeField field = rightFields.get(i);
        RexNode inputRef = rexBuilder.makeInputRef(field.getType(), i + nLeftFields);
        bottomProgramBuilder.addProject(inputRef, field.getName());
    }
    RexProgram bottomProgram = bottomProgramBuilder.getProgram();
    // input rowtype into the top program is the concatenation of the
    // project and the RHS of the semi/anti join
    RelDataType topInputRowType = SqlValidatorUtil.deriveJoinRowType(project.getRowType(), rightChild.getRowType(), JoinRelType.INNER, typeFactory, null, join.getSystemFieldList());
    RexProgramBuilder topProgramBuilder = new RexProgramBuilder(topInputRowType, rexBuilder);
    topProgramBuilder.addIdentity();
    topProgramBuilder.addCondition(join.getCondition());
    RexProgram topProgram = topProgramBuilder.getProgram();
    // merge the programs and expand out the local references to form
    // the new semi/anti join condition; it now references a concatenation of
    // the project's child and the RHS of the semi/anti join
    RexProgram mergedProgram = RexProgramBuilder.mergePrograms(topProgram, bottomProgram, rexBuilder);
    return mergedProgram.expandLocalRef(mergedProgram.getCondition());
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RexProgram(org.apache.calcite.rex.RexProgram) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RexBuilder(org.apache.calcite.rex.RexBuilder) RelDataType(org.apache.calcite.rel.type.RelDataType) RexProgramBuilder(org.apache.calcite.rex.RexProgramBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 30 with RexProgramBuilder

use of org.apache.calcite.rex.RexProgramBuilder in project flink by apache.

the class RelTimeIndicatorConverter method mergeCalcToMaterializeTimeIndicators.

private RelNode mergeCalcToMaterializeTimeIndicators(FlinkLogicalCalc calc, Set<Integer> refIndices) {
    RexProgram program = calc.getProgram();
    RexProgramBuilder newProgramBuilder = new RexProgramBuilder(program.getInputRowType(), rexBuilder);
    for (int idx = 0; idx < program.getNamedProjects().size(); idx++) {
        Pair<RexLocalRef, String> pair = program.getNamedProjects().get(idx);
        RexNode project = program.expandLocalRef(pair.left);
        if (refIndices.contains(idx)) {
            project = materializeTimeIndicators(project);
        }
        newProgramBuilder.addProject(project, pair.right);
    }
    if (program.getCondition() != null) {
        newProgramBuilder.addCondition(program.expandLocalRef(program.getCondition()));
    }
    RexProgram newProgram = newProgramBuilder.getProgram();
    return FlinkLogicalCalc.create(calc.getInput(), newProgram);
}
Also used : RexProgram(org.apache.calcite.rex.RexProgram) RexLocalRef(org.apache.calcite.rex.RexLocalRef) RexProgramBuilder(org.apache.calcite.rex.RexProgramBuilder) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexProgramBuilder (org.apache.calcite.rex.RexProgramBuilder)32 RexProgram (org.apache.calcite.rex.RexProgram)23 RexNode (org.apache.calcite.rex.RexNode)17 RexBuilder (org.apache.calcite.rex.RexBuilder)13 RelNode (org.apache.calcite.rel.RelNode)11 RelDataType (org.apache.calcite.rel.type.RelDataType)11 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)7 RexLocalRef (org.apache.calcite.rex.RexLocalRef)6 ByteString (org.apache.calcite.avatica.util.ByteString)5 LogicalCalc (org.apache.calcite.rel.logical.LogicalCalc)5 DateString (org.apache.calcite.util.DateString)5 NlsString (org.apache.calcite.util.NlsString)5 TimeString (org.apache.calcite.util.TimeString)5 TimestampString (org.apache.calcite.util.TimestampString)5 TimestampWithTimeZoneString (org.apache.calcite.util.TimestampWithTimeZoneString)5 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)4 RexInputRef (org.apache.calcite.rex.RexInputRef)4 FlinkLogicalCalc (org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCalc)4 Test (org.junit.Test)4 ArrayList (java.util.ArrayList)3