public void onMatch(RelOptRuleCall call) {
    final Filter filter = call.rel(0);
    final HiveTableFunctionScan tfs = call.rel(1);
    final RelBuilder builder = call.builder();

    final List<RexNode> newPartKeyFilterConditions = new ArrayList<>();
    final List<RexNode> unpushedFilterConditions = new ArrayList<>();

    // Check for each individual 'and' condition so that we can push partial
    // expressions through.
    for (RexNode ce : RelOptUtil.conjunctions(filter.getCondition())) {
      // We can only push if all the InputRef pointers are referencing the
      // input RelNode to the TableFunctionScan
      if (canBePushed(HiveCalciteUtil.getInputRefs(ce), tfs)) {
        newPartKeyFilterConditions.add(ce);
      } else {
        unpushedFilterConditions.add(ce);
      }
    }

    // The "matches" check should guarantee there's something to push.
    final RexNode filterCondToPushBelowProj = RexUtil.composeConjunction(
        filter.getCluster().getRexBuilder(), newPartKeyFilterConditions, true);

    builder.push(tfs.getInput(0)).filter(filterCondToPushBelowProj);

    // If there are conditions that cannot be pushed through, generate the RexNode
    final RexNode unpushedFilCondAboveProj = unpushedFilterConditions.isEmpty()
        ? null
        : RexUtil.composeConjunction(filter.getCluster().getRexBuilder(),
            unpushedFilterConditions, true);

    // Generate the new TableFunctionScanNode with the Filter InputRel
    final RelNode tableFunctionScanNode = tfs.copy(tfs.getTraitSet(),
        ImmutableList.of(builder.build()), tfs.getCall(), tfs.getElementType(),
        tfs.getRowType(), tfs.getColumnMappings());

    builder.clear();
    builder.push(tableFunctionScanNode);

    if (unpushedFilCondAboveProj != null) {
      builder.filter(unpushedFilCondAboveProj);
    }

    call.transformTo(builder.build());
  }
Rule to transpose Filter and TableFunctionScan RelNodes

We cannot use Calcite's FilterTableFunctionTransposeRule because that rule
uses LogicalFilter and LogicalTableFunctionScan.  We should remove this
class when CALCITE-5985 is fixed (and remove the CALCITE_5985_FIXED entry
in Bug.java)
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveFilterTableFunctionTransposeRule.java