List<PlanMatchingState> shapeMatches(PlanNode node) {
    ImmutableList.Builder<PlanMatchingState> states = ImmutableList.builder();
    if (anyTree) {
      int sourcesCount = node.getChildren().size();
      if (sourcesCount > 1) {
        states.add(new PlanMatchingState(nCopies(sourcesCount, this)));
      } else {
        states.add(new PlanMatchingState(ImmutableList.of(this)));
      }
    }
    if (node instanceof GroupReference) {
      if (sourcePatterns.isEmpty() && shapeMatchesMatchers(node)) {
        states.add(new PlanMatchingState(ImmutableList.of()));
      }
    } else if (node.getChildren().size() == sourcePatterns.size() && shapeMatchesMatchers(node)) {
      states.add(new PlanMatchingState(sourcePatterns));
    }
    return states.build();
  }
Matches to any tree of nodes with children matching to given source matchers.
anyTree(tableScan("nation")) - will match to any plan which all leafs contain any node
containing table scan from nation table.

<p>Note: anyTree does not match zero nodes. E.g. output(anyTree(tableScan)) will NOT match
TableScan node followed by OutputNode.
iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/PlanMatchPattern.java