Search in sources :

Example 1 with FlinkLogicalTableSourceScan

use of org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalTableSourceScan in project flink by apache.

the class PushWatermarkIntoTableSourceScanAcrossCalcRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    FlinkLogicalWatermarkAssigner watermarkAssigner = call.rel(0);
    FlinkLogicalCalc calc = call.rel(1);
    RexProgram originProgram = calc.getProgram();
    List<RexNode> projectList = originProgram.getProjectList().stream().map(originProgram::expandLocalRef).collect(Collectors.toList());
    // get watermark expression
    RexNode rowTimeColumn = projectList.get(watermarkAssigner.rowtimeFieldIndex());
    RexNode newWatermarkExpr = watermarkAssigner.watermarkExpr().accept(new RexShuttle() {

        @Override
        public RexNode visitInputRef(RexInputRef inputRef) {
            return projectList.get(inputRef.getIndex());
        }
    });
    // push watermark assigner into the scan
    FlinkLogicalTableSourceScan newScan = getNewScan(watermarkAssigner, newWatermarkExpr, call.rel(2), ShortcutUtils.unwrapContext(calc).getTableConfig(), // useWatermarkAssignerRowType
    false);
    FlinkTypeFactory typeFactory = ShortcutUtils.unwrapTypeFactory(calc);
    RexBuilder builder = call.builder().getRexBuilder();
    // cast timestamp/timestamp_ltz type to rowtime type.
    RexNode newRowTimeColumn = builder.makeReinterpretCast(typeFactory.createRowtimeIndicatorType(rowTimeColumn.getType().isNullable(), rowTimeColumn.getType().getSqlTypeName() == SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE), rowTimeColumn, null);
    // build new calc program
    RexProgramBuilder programBuilder = new RexProgramBuilder(newScan.getRowType(), builder);
    List<String> outputFieldNames = originProgram.getOutputRowType().getFieldNames();
    for (int i = 0; i < projectList.size(); i++) {
        if (i == watermarkAssigner.rowtimeFieldIndex()) {
            // replace the origin computed column to keep type consistent
            programBuilder.addProject(newRowTimeColumn, outputFieldNames.get(i));
        } else {
            programBuilder.addProject(projectList.get(i), outputFieldNames.get(i));
        }
    }
    if (originProgram.getCondition() != null) {
        programBuilder.addCondition(originProgram.expandLocalRef(originProgram.getCondition()));
    }
    FlinkLogicalCalc newCalc = FlinkLogicalCalc.create(newScan, programBuilder.getProgram());
    call.transformTo(newCalc);
}
Also used : RexShuttle(org.apache.calcite.rex.RexShuttle) FlinkLogicalCalc(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCalc) RexProgram(org.apache.calcite.rex.RexProgram) FlinkLogicalTableSourceScan(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalTableSourceScan) FlinkLogicalWatermarkAssigner(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalWatermarkAssigner) FlinkTypeFactory(org.apache.flink.table.planner.calcite.FlinkTypeFactory) RexInputRef(org.apache.calcite.rex.RexInputRef) RexBuilder(org.apache.calcite.rex.RexBuilder) RexProgramBuilder(org.apache.calcite.rex.RexProgramBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 2 with FlinkLogicalTableSourceScan

use of org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalTableSourceScan in project flink by apache.

the class PushWatermarkIntoTableSourceScanRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    FlinkLogicalWatermarkAssigner watermarkAssigner = call.rel(0);
    FlinkLogicalTableSourceScan scan = call.rel(1);
    FlinkLogicalTableSourceScan newScan = getNewScan(watermarkAssigner, watermarkAssigner.watermarkExpr(), scan, ShortcutUtils.unwrapContext(scan).getTableConfig(), // useWatermarkAssignerRowType
    true);
    call.transformTo(newScan);
}
Also used : FlinkLogicalTableSourceScan(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalTableSourceScan) FlinkLogicalWatermarkAssigner(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalWatermarkAssigner)

Example 3 with FlinkLogicalTableSourceScan

use of org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalTableSourceScan in project flink by apache.

the class PushFilterInCalcIntoTableSourceScanRule method matches.

@Override
public boolean matches(RelOptRuleCall call) {
    if (!super.matches(call)) {
        return false;
    }
    FlinkLogicalCalc calc = call.rel(0);
    RexProgram originProgram = calc.getProgram();
    if (originProgram.getCondition() == null) {
        return false;
    }
    FlinkLogicalTableSourceScan scan = call.rel(1);
    TableSourceTable tableSourceTable = scan.getTable().unwrap(TableSourceTable.class);
    // we can not push filter twice
    return canPushdownFilter(tableSourceTable);
}
Also used : FlinkLogicalCalc(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCalc) RexProgram(org.apache.calcite.rex.RexProgram) FlinkLogicalTableSourceScan(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalTableSourceScan) TableSourceTable(org.apache.flink.table.planner.plan.schema.TableSourceTable)

Example 4 with FlinkLogicalTableSourceScan

use of org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalTableSourceScan in project flink by apache.

the class PushFilterInCalcIntoTableSourceScanRule method pushFilterIntoScan.

private void pushFilterIntoScan(RelOptRuleCall call, Calc calc, FlinkLogicalTableSourceScan scan, FlinkPreparingTableBase relOptTable) {
    RexProgram originProgram = calc.getProgram();
    RelBuilder relBuilder = call.builder();
    Tuple2<RexNode[], RexNode[]> extractedPredicates = extractPredicates(originProgram.getInputRowType().getFieldNames().toArray(new String[0]), originProgram.expandLocalRef(originProgram.getCondition()), scan, relBuilder.getRexBuilder());
    RexNode[] convertiblePredicates = extractedPredicates._1;
    RexNode[] unconvertedPredicates = extractedPredicates._2;
    if (convertiblePredicates.length == 0) {
        // no condition can be translated to expression
        return;
    }
    Tuple2<SupportsFilterPushDown.Result, TableSourceTable> pushdownResultWithScan = resolveFiltersAndCreateTableSourceTable(convertiblePredicates, relOptTable.unwrap(TableSourceTable.class), scan, relBuilder);
    SupportsFilterPushDown.Result result = pushdownResultWithScan._1;
    TableSourceTable tableSourceTable = pushdownResultWithScan._2;
    FlinkLogicalTableSourceScan newScan = FlinkLogicalTableSourceScan.create(scan.getCluster(), scan.getHints(), tableSourceTable);
    // build new calc program
    RexProgramBuilder programBuilder = RexProgramBuilder.forProgram(originProgram, call.builder().getRexBuilder(), true);
    programBuilder.clearCondition();
    if (!result.getRemainingFilters().isEmpty() || unconvertedPredicates.length != 0) {
        RexNode remainingCondition = createRemainingCondition(relBuilder, result.getRemainingFilters(), unconvertedPredicates);
        RexNode simplifiedRemainingCondition = FlinkRexUtil.simplify(relBuilder.getRexBuilder(), remainingCondition, calc.getCluster().getPlanner().getExecutor());
        programBuilder.addCondition(simplifiedRemainingCondition);
    }
    RexProgram program = programBuilder.getProgram();
    if (program.isTrivial()) {
        call.transformTo(newScan);
    } else {
        FlinkLogicalCalc newCalc = FlinkLogicalCalc.create(newScan, program);
        call.transformTo(newCalc);
    }
}
Also used : RelBuilder(org.apache.calcite.tools.RelBuilder) FlinkLogicalCalc(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCalc) RexProgram(org.apache.calcite.rex.RexProgram) FlinkLogicalTableSourceScan(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalTableSourceScan) SupportsFilterPushDown(org.apache.flink.table.connector.source.abilities.SupportsFilterPushDown) TableSourceTable(org.apache.flink.table.planner.plan.schema.TableSourceTable) RexProgramBuilder(org.apache.calcite.rex.RexProgramBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 5 with FlinkLogicalTableSourceScan

use of org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalTableSourceScan in project flink by apache.

the class PushFilterInCalcIntoTableSourceScanRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    FlinkLogicalCalc calc = call.rel(0);
    FlinkLogicalTableSourceScan scan = call.rel(1);
    TableSourceTable table = scan.getTable().unwrap(TableSourceTable.class);
    pushFilterIntoScan(call, calc, scan, table);
}
Also used : FlinkLogicalCalc(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCalc) FlinkLogicalTableSourceScan(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalTableSourceScan) TableSourceTable(org.apache.flink.table.planner.plan.schema.TableSourceTable)

Aggregations

FlinkLogicalTableSourceScan (org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalTableSourceScan)6 FlinkLogicalCalc (org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCalc)4 TableSourceTable (org.apache.flink.table.planner.plan.schema.TableSourceTable)4 RexProgram (org.apache.calcite.rex.RexProgram)3 RexNode (org.apache.calcite.rex.RexNode)2 RexProgramBuilder (org.apache.calcite.rex.RexProgramBuilder)2 FlinkLogicalWatermarkAssigner (org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalWatermarkAssigner)2 Sort (org.apache.calcite.rel.core.Sort)1 RexBuilder (org.apache.calcite.rex.RexBuilder)1 RexInputRef (org.apache.calcite.rex.RexInputRef)1 RexShuttle (org.apache.calcite.rex.RexShuttle)1 RelBuilder (org.apache.calcite.tools.RelBuilder)1 SupportsFilterPushDown (org.apache.flink.table.connector.source.abilities.SupportsFilterPushDown)1 FlinkTypeFactory (org.apache.flink.table.planner.calcite.FlinkTypeFactory)1 FlinkLogicalSort (org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalSort)1