Search in sources :

Example 1 with RexProgramBuilder

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

the class JaninoRexCompiler method compile.

public Scalar compile(List<RexNode> nodes, RelDataType inputRowType) {
    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 context_ = Expressions.parameter(Context.class, "context");
    final ParameterExpression outputValues_ = Expressions.parameter(Object[].class, "outputValues");
    final JavaTypeFactoryImpl javaTypeFactory = new JavaTypeFactoryImpl(rexBuilder.getTypeFactory().getTypeSystem());
    // public void execute(Context, Object[] outputValues)
    final RexToLixTranslator.InputGetter inputGetter = new RexToLixTranslator.InputGetterImpl(ImmutableList.of(Pair.<Expression, PhysType>of(Expressions.field(context_, BuiltInMethod.CONTEXT_VALUES.field), PhysTypeImpl.of(javaTypeFactory, inputRowType, JavaRowFormat.ARRAY, false))));
    final Function1<String, RexToLixTranslator.InputGetter> correlates = new Function1<String, RexToLixTranslator.InputGetter>() {

        public RexToLixTranslator.InputGetter apply(String a0) {
            throw new UnsupportedOperationException();
        }
    };
    final Expression root = Expressions.field(context_, BuiltInMethod.CONTEXT_ROOT.field);
    final List<Expression> list = RexToLixTranslator.translateProjects(program, javaTypeFactory, builder, null, root, inputGetter, correlates);
    for (int i = 0; i < list.size(); i++) {
        builder.add(Expressions.statement(Expressions.assign(Expressions.arrayIndex(outputValues_, Expressions.constant(i)), list.get(i))));
    }
    return baz(context_, outputValues_, builder.toBlock());
}
Also used : RexProgram(org.apache.calcite.rex.RexProgram) Function1(org.apache.calcite.linq4j.function.Function1) PhysType(org.apache.calcite.adapter.enumerable.PhysType) Expression(org.apache.calcite.linq4j.tree.Expression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) JavaTypeFactoryImpl(org.apache.calcite.jdbc.JavaTypeFactoryImpl) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) 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)

Example 2 with RexProgramBuilder

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

the class JoinProjectTransposeRule method onMatch.

// ~ Methods ----------------------------------------------------------------
// implement RelOptRule
public void onMatch(RelOptRuleCall call) {
    Join joinRel = call.rel(0);
    JoinRelType joinType = joinRel.getJoinType();
    Project leftProj;
    Project rightProj;
    RelNode leftJoinChild;
    RelNode rightJoinChild;
    // 2) input's projection doesn't generate nulls
    if (hasLeftChild(call) && (includeOuter || !joinType.generatesNullsOnLeft())) {
        leftProj = call.rel(1);
        leftJoinChild = getProjectChild(call, leftProj, true);
    } else {
        leftProj = null;
        leftJoinChild = call.rel(1);
    }
    if (hasRightChild(call) && (includeOuter || !joinType.generatesNullsOnRight())) {
        rightProj = getRightChild(call);
        rightJoinChild = getProjectChild(call, rightProj, false);
    } else {
        rightProj = null;
        rightJoinChild = joinRel.getRight();
    }
    if ((leftProj == null) && (rightProj == null)) {
        return;
    }
    // Construct two RexPrograms and combine them.  The bottom program
    // is a join of the projection expressions from the left and/or
    // right projects that feed into the join.  The top program contains
    // the join condition.
    // Create a row type representing a concatenation of the inputs
    // underneath the projects that feed into the join.  This is the input
    // into the bottom RexProgram.  Note that the join type is an inner
    // join because the inputs haven't actually been joined yet.
    RelDataType joinChildrenRowType = SqlValidatorUtil.deriveJoinRowType(leftJoinChild.getRowType(), rightJoinChild.getRowType(), JoinRelType.INNER, joinRel.getCluster().getTypeFactory(), null, Collections.<RelDataTypeField>emptyList());
    // Create projection expressions, combining the projection expressions
    // from the projects that feed into the join.  For the RHS projection
    // expressions, shift them to the right by the number of fields on
    // the LHS.  If the join input was not a projection, simply create
    // references to the inputs.
    int nProjExprs = joinRel.getRowType().getFieldCount();
    final List<Pair<RexNode, String>> projects = new ArrayList<>();
    final RexBuilder rexBuilder = joinRel.getCluster().getRexBuilder();
    createProjectExprs(leftProj, leftJoinChild, 0, rexBuilder, joinChildrenRowType.getFieldList(), projects);
    List<RelDataTypeField> leftFields = leftJoinChild.getRowType().getFieldList();
    int nFieldsLeft = leftFields.size();
    createProjectExprs(rightProj, rightJoinChild, nFieldsLeft, rexBuilder, joinChildrenRowType.getFieldList(), projects);
    final List<RelDataType> projTypes = new ArrayList<>();
    for (int i = 0; i < nProjExprs; i++) {
        projTypes.add(projects.get(i).left.getType());
    }
    RelDataType projRowType = rexBuilder.getTypeFactory().createStructType(projTypes, Pair.right(projects));
    // create the RexPrograms and merge them
    RexProgram bottomProgram = RexProgram.create(joinChildrenRowType, Pair.left(projects), null, projRowType, rexBuilder);
    RexProgramBuilder topProgramBuilder = new RexProgramBuilder(projRowType, rexBuilder);
    topProgramBuilder.addIdentity();
    topProgramBuilder.addCondition(joinRel.getCondition());
    RexProgram topProgram = topProgramBuilder.getProgram();
    RexProgram mergedProgram = RexProgramBuilder.mergePrograms(topProgram, bottomProgram, rexBuilder);
    // expand out the join condition and construct a new LogicalJoin that
    // directly references the join children without the intervening
    // ProjectRels
    RexNode newCondition = mergedProgram.expandLocalRef(mergedProgram.getCondition());
    Join newJoinRel = joinRel.copy(joinRel.getTraitSet(), newCondition, leftJoinChild, rightJoinChild, joinRel.getJoinType(), joinRel.isSemiJoinDone());
    // expand out the new projection expressions; if the join is an
    // outer join, modify the expressions to reference the join output
    final List<RexNode> newProjExprs = new ArrayList<>();
    List<RexLocalRef> projList = mergedProgram.getProjectList();
    List<RelDataTypeField> newJoinFields = newJoinRel.getRowType().getFieldList();
    int nJoinFields = newJoinFields.size();
    int[] adjustments = new int[nJoinFields];
    for (int i = 0; i < nProjExprs; i++) {
        RexNode newExpr = mergedProgram.expandLocalRef(projList.get(i));
        if (joinType != JoinRelType.INNER) {
            newExpr = newExpr.accept(new RelOptUtil.RexInputConverter(rexBuilder, joinChildrenRowType.getFieldList(), newJoinFields, adjustments));
        }
        newProjExprs.add(newExpr);
    }
    // finally, create the projection on top of the join
    final RelBuilder relBuilder = call.builder();
    relBuilder.push(newJoinRel);
    relBuilder.project(newProjExprs, joinRel.getRowType().getFieldNames());
    // projection to fix differences wrt nullability of fields
    if (joinType != JoinRelType.INNER) {
        relBuilder.convert(joinRel.getRowType(), false);
    }
    call.transformTo(relBuilder.build());
}
Also used : RelBuilder(org.apache.calcite.tools.RelBuilder) RexProgram(org.apache.calcite.rex.RexProgram) ArrayList(java.util.ArrayList) Join(org.apache.calcite.rel.core.Join) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) RelDataType(org.apache.calcite.rel.type.RelDataType) JoinRelType(org.apache.calcite.rel.core.JoinRelType) Project(org.apache.calcite.rel.core.Project) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RexBuilder(org.apache.calcite.rex.RexBuilder) RexLocalRef(org.apache.calcite.rex.RexLocalRef) RexProgramBuilder(org.apache.calcite.rex.RexProgramBuilder) Pair(org.apache.calcite.util.Pair) RexNode(org.apache.calcite.rex.RexNode)

Example 3 with RexProgramBuilder

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

the class FilterCalcMergeRule method onMatch.

// ~ Methods ----------------------------------------------------------------
public void onMatch(RelOptRuleCall call) {
    final LogicalFilter filter = call.rel(0);
    final LogicalCalc calc = call.rel(1);
    // We'll have chance to merge later, when the over is expanded.
    if (calc.getProgram().containsAggs()) {
        return;
    }
    // Create a program containing the filter.
    final RexBuilder rexBuilder = filter.getCluster().getRexBuilder();
    final RexProgramBuilder progBuilder = new RexProgramBuilder(calc.getRowType(), rexBuilder);
    progBuilder.addIdentity();
    progBuilder.addCondition(filter.getCondition());
    RexProgram topProgram = progBuilder.getProgram();
    RexProgram bottomProgram = calc.getProgram();
    // Merge the programs together.
    RexProgram mergedProgram = RexProgramBuilder.mergePrograms(topProgram, bottomProgram, rexBuilder);
    final LogicalCalc newCalc = LogicalCalc.create(calc.getInput(), mergedProgram);
    call.transformTo(newCalc);
}
Also used : RexProgram(org.apache.calcite.rex.RexProgram) LogicalFilter(org.apache.calcite.rel.logical.LogicalFilter) RexBuilder(org.apache.calcite.rex.RexBuilder) LogicalCalc(org.apache.calcite.rel.logical.LogicalCalc) RexProgramBuilder(org.apache.calcite.rex.RexProgramBuilder)

Example 4 with RexProgramBuilder

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

the class FilterMergeRule method createProgram.

/**
 * Creates a RexProgram corresponding to a LogicalFilter
 *
 * @param filterRel the LogicalFilter
 * @return created RexProgram
 */
private RexProgram createProgram(Filter filterRel) {
    RexProgramBuilder programBuilder = new RexProgramBuilder(filterRel.getRowType(), filterRel.getCluster().getRexBuilder());
    programBuilder.addIdentity();
    programBuilder.addCondition(filterRel.getCondition());
    return programBuilder.getProgram();
}
Also used : RexProgramBuilder(org.apache.calcite.rex.RexProgramBuilder)

Example 5 with RexProgramBuilder

use of org.apache.calcite.rex.RexProgramBuilder 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)

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