public static boolean treeEqual(
      Node left, Node right, BiFunction<Node, Node, Boolean> subtreeComparator) {
    Boolean equal = subtreeComparator.apply(left, right);

    if (equal != null) {
      return equal;
    }

    List<? extends Node> leftChildren = left.getChildren();
    List<? extends Node> rightChildren = right.getChildren();

    if (leftChildren.size() != rightChildren.size()) {
      return false;
    }

    for (int i = 0; i < leftChildren.size(); i++) {
      if (!treeEqual(leftChildren.get(i), rightChildren.get(i), subtreeComparator)) {
        return false;
      }
    }

    return true;
  }
Compares two AST trees recursively by applying the provided comparator to each pair of nodes.

<p>The comparator can perform a hybrid shallow/deep comparison. If it returns true or false,
the nodes and any subtrees are considered equal or different, respectively. If it returns null,
the nodes are considered shallowly-equal and their children will be compared recursively.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/AstUtil.java