Search in sources :

Example 6 with RexProgram

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

the class RelOptUtil method permute.

/**
 * Creates a relational expression which permutes the output fields of a
 * relational expression according to a permutation.
 *
 * <p>Optimizations:</p>
 *
 * <ul>
 * <li>If the relational expression is a
 * {@link org.apache.calcite.rel.logical.LogicalCalc} or
 * {@link org.apache.calcite.rel.logical.LogicalProject} that is already
 * acting as a permutation, combines the new permutation with the old;</li>
 *
 * <li>If the permutation is the identity, returns the original relational
 * expression.</li>
 * </ul>
 *
 * <p>If a permutation is combined with its inverse, these optimizations
 * would combine to remove them both.
 *
 * @param rel         Relational expression
 * @param permutation Permutation to apply to fields
 * @param fieldNames  Field names; if null, or if a particular entry is null,
 *                    the name of the permuted field is used
 * @return relational expression which permutes its input fields
 */
public static RelNode permute(RelNode rel, Permutation permutation, List<String> fieldNames) {
    if (permutation.isIdentity()) {
        return rel;
    }
    if (rel instanceof LogicalCalc) {
        LogicalCalc calc = (LogicalCalc) rel;
        Permutation permutation1 = calc.getProgram().getPermutation();
        if (permutation1 != null) {
            Permutation permutation2 = permutation.product(permutation1);
            return permute(rel, permutation2, null);
        }
    }
    if (rel instanceof LogicalProject) {
        Permutation permutation1 = ((LogicalProject) rel).getPermutation();
        if (permutation1 != null) {
            Permutation permutation2 = permutation.product(permutation1);
            return permute(rel, permutation2, null);
        }
    }
    final List<RelDataType> outputTypeList = new ArrayList<>();
    final List<String> outputNameList = new ArrayList<>();
    final List<RexNode> exprList = new ArrayList<>();
    final List<RexLocalRef> projectRefList = new ArrayList<>();
    final List<RelDataTypeField> fields = rel.getRowType().getFieldList();
    final RelOptCluster cluster = rel.getCluster();
    for (int i = 0; i < permutation.getTargetCount(); i++) {
        int target = permutation.getTarget(i);
        final RelDataTypeField targetField = fields.get(target);
        outputTypeList.add(targetField.getType());
        outputNameList.add(((fieldNames == null) || (fieldNames.size() <= i) || (fieldNames.get(i) == null)) ? targetField.getName() : fieldNames.get(i));
        exprList.add(cluster.getRexBuilder().makeInputRef(fields.get(i).getType(), i));
        final int source = permutation.getSource(i);
        projectRefList.add(new RexLocalRef(source, fields.get(source).getType()));
    }
    final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
    final RexProgram program = new RexProgram(rel.getRowType(), exprList, projectRefList, null, typeFactory.createStructType(outputTypeList, outputNameList));
    return LogicalCalc.create(rel, program);
}
Also used : Permutation(org.apache.calcite.util.Permutation) RexProgram(org.apache.calcite.rex.RexProgram) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RexLocalRef(org.apache.calcite.rex.RexLocalRef) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) LogicalCalc(org.apache.calcite.rel.logical.LogicalCalc) RexNode(org.apache.calcite.rex.RexNode)

Example 7 with RexProgram

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

the class RexProgramTest method testSimplifyCondition2.

/**
 * Tests how the condition is simplified.
 */
@Test
public void testSimplifyCondition2() {
    final RexProgram program = createProg(4).getProgram(false);
    assertThat(program.toString(), is("(expr#0..1=[{inputs}], expr#2=[+($0, 1)], expr#3=[77], " + "expr#4=[+($0, $1)], expr#5=[+($0, 1)], expr#6=[+($0, $t5)], " + "expr#7=[+($t4, $t2)], expr#8=[5], expr#9=[>($t2, $t8)], " + "expr#10=[true], expr#11=[IS NOT NULL($t5)], expr#12=[false], " + "expr#13=[null], expr#14=[CASE($t9, $t10, $t11, $t12, $t13)], " + "expr#15=[NOT($t14)], expr#16=[IS TRUE($t15)], a=[$t7], b=[$t6], " + "$condition=[$t16])"));
    assertThat(program.normalize(rexBuilder, simplify).toString(), is("(expr#0..1=[{inputs}], expr#2=[+($t0, $t1)], expr#3=[1], " + "expr#4=[+($t0, $t3)], expr#5=[+($t2, $t4)], " + "expr#6=[+($t0, $t4)], expr#7=[5], expr#8=[>($t4, $t7)], " + "expr#9=[CAST($t8):BOOLEAN], expr#10=[IS FALSE($t9)], " + "a=[$t5], b=[$t6], $condition=[$t10])"));
}
Also used : RexProgram(org.apache.calcite.rex.RexProgram) Test(org.junit.Test)

Example 8 with RexProgram

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

the class ReduceDecimalsRule method onMatch.

// implement RelOptRule
public void onMatch(RelOptRuleCall call) {
    LogicalCalc calc = call.rel(0);
    // Expand decimals in every expression in this program. If no
    // expression changes, don't apply the rule.
    final RexProgram program = calc.getProgram();
    if (!RexUtil.requiresDecimalExpansion(program, true)) {
        return;
    }
    final RexBuilder rexBuilder = calc.getCluster().getRexBuilder();
    final RexShuttle shuttle = new DecimalShuttle(rexBuilder);
    RexProgramBuilder programBuilder = RexProgramBuilder.create(rexBuilder, calc.getInput().getRowType(), program.getExprList(), program.getProjectList(), program.getCondition(), program.getOutputRowType(), shuttle, true);
    final RexProgram newProgram = programBuilder.getProgram();
    LogicalCalc newCalc = LogicalCalc.create(calc.getInput(), newProgram);
    call.transformTo(newCalc);
}
Also used : RexShuttle(org.apache.calcite.rex.RexShuttle) RexProgram(org.apache.calcite.rex.RexProgram) RexBuilder(org.apache.calcite.rex.RexBuilder) LogicalCalc(org.apache.calcite.rel.logical.LogicalCalc) RexProgramBuilder(org.apache.calcite.rex.RexProgramBuilder)

Example 9 with RexProgram

use of org.apache.calcite.rex.RexProgram in project drill by axbaretto.

the class DrillMergeFilterRule method onMatch.

// ~ Methods ----------------------------------------------------------------
// implement RelOptRule
public void onMatch(RelOptRuleCall call) {
    Filter topFilter = call.rel(0);
    Filter bottomFilter = call.rel(1);
    // use RexPrograms to merge the two FilterRels into a single program
    // so we can convert the two FilterRel conditions to directly
    // reference the bottom FilterRel's child
    RexBuilder rexBuilder = topFilter.getCluster().getRexBuilder();
    RexProgram bottomProgram = createProgram(bottomFilter);
    RexProgram topProgram = createProgram(topFilter);
    RexProgram mergedProgram = RexProgramBuilder.mergePrograms(topProgram, bottomProgram, rexBuilder);
    RexNode newCondition = mergedProgram.expandLocalRef(mergedProgram.getCondition());
    // if(!RexUtil.isFlat(newCondition)){
    // RexCall newCall = (RexCall) newCondition;
    // newCondition = rexBuilder.makeFlatCall( newCall.getOperator(), newCall.getOperands());
    // }
    Filter newFilterRel = (Filter) filterFactory.createFilter(bottomFilter.getInput(), RexUtil.flatten(rexBuilder, newCondition));
    call.transformTo(newFilterRel);
}
Also used : Filter(org.apache.calcite.rel.core.Filter) RexProgram(org.apache.calcite.rex.RexProgram) RexBuilder(org.apache.calcite.rex.RexBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 10 with RexProgram

use of org.apache.calcite.rex.RexProgram in project samza by apache.

the class RexToJavaCompiler method compile.

/**
 * Compiles a relational expression to a instance of {@link Expression}
 *
 * for e.g.
 *    Query : select id from profile
 *      where profile table has relational schema with id(NUMBER) and name(VARCHAR) columns.
 *    This query will result in the following relational plan
 *      LogicalProject(id=[$1])
 *        LogicalTableScan(table=[[profile]])
 *
 *    And the corresponding expressions are
 *       inputs : EnumerableTableScan (Which is the output of LogicalTableScan)
 *       nodes : [$1] Which essentially means take pick the first column from the input
 *
 *    This function converts the LogicalProject expression "[$1]" with input RexNode which is an output of TableScan
 *    to a java code that implements the interface {@link Expression}
 *
 * @param inputs Input relations/time-varying relations for this row expression
 * @param nodes relational expressions that needs to be converted to java code.
 * @return compiled expression of type {@link org.apache.samza.sql.data.Expression}
 */
public org.apache.samza.sql.data.Expression compile(List<RelNode> inputs, List<RexNode> nodes) {
    /*
     *  In case there are multiple input relations, we build a single input row type combining types of all the inputs.
     */
    final RelDataTypeFactory.FieldInfoBuilder fieldBuilder = rexBuilder.getTypeFactory().builder();
    for (RelNode input : inputs) {
        fieldBuilder.addAll(input.getRowType().getFieldList());
    }
    final RelDataType inputRowType = fieldBuilder.build();
    final RexProgramBuilder programBuilder = new RexProgramBuilder(inputRowType, rexBuilder);
    for (RexNode node : nodes) {
        programBuilder.addProject(node, null);
    }
    final RexProgram program = programBuilder.getProgram();
    final BlockBuilder builder = new BlockBuilder();
    final ParameterExpression sqlContext = Expressions.parameter(SamzaSqlExecutionContext.class, "sqlContext");
    final ParameterExpression context = Expressions.parameter(Context.class, "context");
    final ParameterExpression root = DataContext.ROOT;
    final ParameterExpression inputValues = Expressions.parameter(Object[].class, "inputValues");
    final ParameterExpression outputValues = Expressions.parameter(Object[].class, "outputValues");
    final JavaTypeFactoryImpl javaTypeFactory = new SamzaSqlJavaTypeFactoryImpl(rexBuilder.getTypeFactory().getTypeSystem());
    // public void execute(Object[] inputValues, Object[] outputValues)
    final RexToLixTranslator.InputGetter inputGetter = new RexToLixTranslator.InputGetterImpl(ImmutableList.of(Pair.of(Expressions.variable(Object[].class, "inputValues"), PhysTypeImpl.of(javaTypeFactory, inputRowType, JavaRowFormat.ARRAY, false))));
    final List<org.apache.calcite.linq4j.tree.Expression> list = RexToLixTranslator.translateProjects(program, javaTypeFactory, SqlConformanceEnum.DEFAULT, builder, null, DataContext.ROOT, inputGetter, null);
    for (int i = 0; i < list.size(); i++) {
        builder.add(Expressions.statement(Expressions.assign(Expressions.arrayIndex(outputValues, Expressions.constant(i)), list.get(i))));
    }
    return createSamzaExpressionFromCalcite(sqlContext, context, root, inputValues, outputValues, builder.toBlock());
}
Also used : RexProgram(org.apache.calcite.rex.RexProgram) RelDataType(org.apache.calcite.rel.type.RelDataType) RelNode(org.apache.calcite.rel.RelNode) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) JavaTypeFactoryImpl(org.apache.calcite.jdbc.JavaTypeFactoryImpl) SamzaSqlJavaTypeFactoryImpl(org.apache.samza.sql.interfaces.SamzaSqlJavaTypeFactoryImpl) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RexToLixTranslator(org.apache.calcite.adapter.enumerable.RexToLixTranslator) RexProgramBuilder(org.apache.calcite.rex.RexProgramBuilder) RexNode(org.apache.calcite.rex.RexNode) BlockBuilder(org.apache.calcite.linq4j.tree.BlockBuilder) SamzaSqlJavaTypeFactoryImpl(org.apache.samza.sql.interfaces.SamzaSqlJavaTypeFactoryImpl)

Aggregations

RexProgram (org.apache.calcite.rex.RexProgram)46 RexNode (org.apache.calcite.rex.RexNode)29 RexProgramBuilder (org.apache.calcite.rex.RexProgramBuilder)26 RexBuilder (org.apache.calcite.rex.RexBuilder)21 RelNode (org.apache.calcite.rel.RelNode)17 RelDataType (org.apache.calcite.rel.type.RelDataType)13 ArrayList (java.util.ArrayList)12 RexLocalRef (org.apache.calcite.rex.RexLocalRef)12 LogicalCalc (org.apache.calcite.rel.logical.LogicalCalc)11 FlinkLogicalCalc (org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCalc)10 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)9 List (java.util.List)7 RexInputRef (org.apache.calcite.rex.RexInputRef)7 Collectors (java.util.stream.Collectors)5 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)5 RexCall (org.apache.calcite.rex.RexCall)5 RexShuttle (org.apache.calcite.rex.RexShuttle)5 Collections (java.util.Collections)4 RelOptUtil (org.apache.calcite.plan.RelOptUtil)4 FlinkLogicalCorrelate (org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCorrelate)4