@Override
  public Operator visitFilter(FilterNode node, LocalExecutionPlanContext context) {
    if (context.isBuildPlanUseTemplate() && node.isFromWhere()) {
      TemplatedInfo templatedInfo = context.getTemplatedInfo();
      return constructFilterOperator(
          node.getPredicate(),
          generateOnlyChildOperator(node, context),
          templatedInfo.getProjectExpressions(),
          templatedInfo.getDataTypes(),
          templatedInfo.getFilterLayoutMap(),
          templatedInfo.isKeepNull(),
          node.getPlanNodeId(),
          templatedInfo.getScanOrder(),
          context);
    }

    // 1. not use template
    // 2. use template but the FilterNode is not generated by FilterNode
    // the inputDataTypes should be generated by the outputColumns of children
    return constructFilterOperator(
        node.getPredicate(),
        generateOnlyChildOperator(node, context),
        node.getOutputExpressions(),
        node.getChildren().stream()
            .map(PlanNode::getOutputColumnNames)
            .flatMap(List::stream)
            .map(context.getTypeProvider()::getTreeModelType)
            .collect(Collectors.toList()),
        makeLayout(node),
        node.isKeepNull(),
        node.getPlanNodeId(),
        node.getScanOrder(),
        context);
  }
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