Source:
<code>protected void apply(RelOptRuleCall call, Project project, TableScan scan) { final RelOptTable table = scan.getTable(); assert table.unwrap(ProjectableFilterableTable.class) != null; final List<Integer> selectedColumns = new ArrayList<>(); project.getProjects().forEach(proj -> { proj.accept(new RexVisitorImpl<Void>(true) { public Void visitInputRef(RexInputRef inputRef) { if (!selectedColumns.contains(inputRef.getIndex())) { selectedColumns.add(inputRef.getIndex()); } return null; } }); <START> }); <END> final List<RexNode> filtersPushDown; final List<Integer> projectsPushDown; if (scan instanceof Bindables.BindableTableScan) { final Bindables.BindableTableScan bindableScan = (Bindables.BindableTableScan) scan; filtersPushDown = bindableScan.filters; projectsPushDown = selectedColumns.stream() .map(col -> bindableScan.projects.get(col)).collect(Collectors.toList()); } else { filtersPushDown = ImmutableList.of(); projectsPushDown = selectedColumns; } Bindables.BindableTableScan newScan = Bindables.BindableTableScan.create( scan.getCluster(), scan.getTable(), filtersPushDown, projectsPushDown); final List<RexNode> newProjectRexNodes = new RexShuttle() { @Override public RexNode visitInputRef(RexInputRef inputRef) { int newIdx = selectedColumns.indexOf(inputRef.getIndex()); assert newIdx != -1; return new RexInputRef(newIdx, inputRef.getType()); } }.apply(project.getProjects()); if (RexUtil.isIdentity(newProjectRexNodes, newScan.getRowType())) { call.transformTo(newScan); } else { call.transformTo( call.builder().push(newScan).project(newProjectRexNodes).build()); } }</code><technical_language>InputFinder here? is bit set instead of int list</technical_language>

Target:
protected void apply(RelOptRuleCall call, Project project, TableScan scan) { final RelOptTable table = scan.getTable(); assert table.unwrap(ProjectableFilterableTable.class) != null; final List<Integer> selectedColumns = new ArrayList<>(); project.getProjects().forEach(proj -> { proj.accept(new RexVisitorImpl<Void>(true) { public Void visitInputRef(RexInputRef inputRef) { if (!selectedColumns.contains(inputRef.getIndex())) { selectedColumns.add(inputRef.getIndex()); } return null; } }); }); final List<RexNode> filtersPushDown; final List<Integer> projectsPushDown; if (scan instanceof Bindables.BindableTableScan) { final Bindables.BindableTableScan bindableScan = (Bindables.BindableTableScan) scan; filtersPushDown = bindableScan.filters; projectsPushDown = selectedColumns.stream() .map(col -> bindableScan.projects.get(col)) .collect(Collectors.toList()); } else { filtersPushDown = ImmutableList.of(); projectsPushDown = selectedColumns; } Bindables.BindableTableScan newScan = Bindables.BindableTableScan.create( scan.getCluster(), scan.getTable(), filtersPushDown, projectsPushDown); Mapping mapping = Mappings.target(selectedColumns, scan.getRowType().getFieldCount()); final List<RexNode> newProjectRexNodes = ImmutableList.copyOf(RexUtil.apply(mapping, project.getProjects())); if (RexUtil.isIdentity(newProjectRexNodes, newScan.getRowType())) { call.transformTo(newScan); } else { call.transformTo( call.builder() .push(newScan) .project(newProjectRexNodes) .build()); } }