private static List<RexNode> extractCommonOperands(RexBuilder rexBuilder, RelNode input,
      RexNode condition, int maxCNFNodeCount) {
    assert condition.getKind() == SqlKind.OR;
    Multimap<String, RexNode> reductionCondition = LinkedHashMultimap.create();

    // Data structure to control whether a certain reference is present in every
    // operand
    Set<String> refsInAllOperands = null;

    // 1. We extract the information necessary to create the predicate for the
    // new filter; currently we support comparison functions, in and between
    ImmutableList<RexNode> operands = RexUtil.flattenOr(((RexCall) condition).getOperands());
    for (int i = 0; i < operands.size(); i++) {
      final RexNode operand = operands.get(i);

      final RexNode operandCNF = RexUtil.toCnf(rexBuilder, maxCNFNodeCount, operand);
      final List<RexNode> conjunctions = RelOptUtil.conjunctions(operandCNF);

      Set<String> refsInCurrentOperand = Sets.newHashSet();
      for (RexNode conjunction : conjunctions) {
        // We do not know what it is, we bail out for safety
        if (!(conjunction instanceof RexCall) || !HiveCalciteUtil.isDeterministic(conjunction)) {
          return Collections.emptyList();
        }
        RexCall conjCall = (RexCall) conjunction;
        Set<Integer> refs = HiveCalciteUtil.getInputRefs(conjCall);
        if (refs.size() != 1) {
          // We do not know what it is, we bail out for safety
          return Collections.emptyList();
        }
        RexNode ref = rexBuilder.makeInputRef(input, refs.iterator().next());
        String stringRef = ref.toString();
        reductionCondition.put(stringRef, conjCall);
        refsInCurrentOperand.add(stringRef);
      }

      // Updates the references that are present in every operand up till now
      if (i == 0) {
        refsInAllOperands = refsInCurrentOperand;
      } else {
        refsInAllOperands = Sets.intersection(refsInAllOperands, refsInCurrentOperand);
      }
      // If we did not add any factor or there are no common factors, we can
      // bail out
      if (refsInAllOperands.isEmpty()) {
        return Collections.emptyList();
      }
    }

    // 2. We gather the common factors and return them
    List<RexNode> commonOperands = new ArrayList<>();
    for (String ref : refsInAllOperands) {
      commonOperands
          .add(RexUtil.composeDisjunction(rexBuilder, reductionCondition.get(ref), false));
    }
    return commonOperands;
  }
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