private List<TSDataType> getInputColumnTypesUseTemplate(PlanNode node) {
    // Only templated device + filter situation can invoke this method,
    // the children of FilterNode/TransformNode can be TimeJoinNode, ScanNode, any others?
    List<TSDataType> dataTypes = new ArrayList<>();
    for (PlanNode child : node.getChildren()) {
      if (child instanceof SeriesScanNode) {
        dataTypes.add(((SeriesScanNode) child).getSeriesPath().getSeriesType());
      } else if (child instanceof AlignedSeriesScanNode) {
        AlignedSeriesScanNode alignedSeriesScanNode = (AlignedSeriesScanNode) child;
        alignedSeriesScanNode
            .getAlignedPath()
            .getSchemaList()
            .forEach(c -> dataTypes.add(c.getType()));
      } else {
        dataTypes.addAll(getInputColumnTypesUseTemplate(child));
      }
    }
    return dataTypes;
  }
This Visitor is responsible for transferring PlanNode Tree to Operator Tree.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java