@Override
  public boolean matches(RelOptRuleCall call) {
    final Filter filter = call.rel(0);
    final RelNode filterChild = call.rel(1);

    // If the filter is already on top of a TableScan,
    // we can bail out
    if (filterChild instanceof TableScan) {
      return false;
    }

    HiveRulesRegistry registry = call.getPlanner().getContext().unwrap(HiveRulesRegistry.class);

    // If this operator has been visited already by the rule,
    // we do not need to apply the optimization
    if (registry != null && registry.getVisited(this).contains(filter)) {
      return false;
    }

    return true;
  }
A rule that splits a {@code Filter} operator into two, deterministic and non-deterministic, to facilitate push down
 of the latter by other rules.
 It is a reduction rule cause along with splitting it needs to reduce some of the new conditions to ensure that it
 can reach a fix point.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HivePreFilteringRule.java