private Expression distributeIfPossible(LogicalExpression expression) {
      if (!isDeterministic(expression)) {
        // Do not distribute boolean expressions if there are any non-deterministic elements
        // TODO: This can be optimized further if non-deterministic elements are not repeated
        return expression;
      }
      List<Set<Expression>> subPredicates =
          getSubPredicates(expression).stream().map(ImmutableSet::copyOf).collect(toList());

      int originalBaseExpressions = subPredicates.stream().mapToInt(Set::size).sum();

      int newBaseExpressions;
      try {
        newBaseExpressions =
            Math.multiplyExact(
                subPredicates.stream().mapToInt(Set::size).reduce(Math::multiplyExact).getAsInt(),
                subPredicates.size());
      } catch (ArithmeticException e) {
        // Integer overflow from multiplication means there are too many expressions
        return expression;
      }

      if (newBaseExpressions > originalBaseExpressions * 2) {
        // Do not distribute boolean expressions if it would create 2x more base expressions
        // (e.g. A, B, C, D from the above example). This is just an arbitrary heuristic to
        // avoid cross product expression explosion.
        return expression;
      }

      Set<List<Expression>> crossProduct = Sets.cartesianProduct(subPredicates);

      return combinePredicates(
          expression.getOperator().flip(),
          crossProduct.stream()
              .map(expressions -> combinePredicates(expression.getOperator(), expressions))
              .collect(toImmutableList()));
    }
Applies the boolean distributive property.

<p>For example: ( A & B ) | ( C & D ) => ( A | C ) & ( A | D ) & ( B | C ) & ( B | D)

<p>Returns the original expression if the expression is non-deterministic or if the
distribution will expand the expression by too much.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/ExtractCommonPredicatesExpressionRewriter.java