private Expression rewrite(
      Expression expression, Predicate<Symbol> symbolScope, boolean allowFullReplacement) {
    Map<Expression, Expression> expressionRemap = new HashMap<>();
    extractSubExpressions(expression).stream()
        .filter(
            allowFullReplacement
                ? subExpression -> true
                : subExpression -> !subExpression.equals(expression))
        .forEach(
            subExpression -> {
              Expression canonical = getScopedCanonical(subExpression, symbolScope);
              if (canonical != null) {
                expressionRemap.putIfAbsent(subExpression, canonical);
              }
            });

    // Perform a naive single-pass traversal to try to rewrite non-compliant portions of the tree.
    // Prefers to replace
    // larger subtrees over smaller subtrees
    // TODO: this rewrite can probably be made more sophisticated
    Expression rewritten = replaceExpression(expression, expressionRemap);
    if (!isScoped(rewritten, symbolScope)) {
      // If the rewritten is still not compliant with the symbol scope, just give up
      return null;
    }
    return rewritten;
  }
Provides a convenience Stream of Expression conjuncts which have not been added to the
inference
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/EqualityInference.java