@Override
  public Operator visitAggregationMergeSort(
      AggregationMergeSortNode node, LocalExecutionPlanContext context) {
    OperatorContext operatorContext =
        context
            .getDriverContext()
            .addOperatorContext(
                context.getNextOperatorId(),
                node.getPlanNodeId(),
                AggregationMergeSortOperator.class.getSimpleName());
    List<TSDataType> dataTypes = getOutputColumnTypes(node, context.getTypeProvider());
    List<Operator> children = dealWithConsumeAllChildrenPipelineBreaker(node, context);

    List<SortItem> sortItemList = node.getMergeOrderParameter().getSortItemList();
    if (!sortItemList.get(0).getSortKey().equalsIgnoreCase("Device")) {
      throw new IllegalArgumentException(
          "Only order by device align by device support AggregationMergeSortNode.");
    }

    boolean timeAscending = true;
    for (SortItem sortItem : sortItemList) {
      if (TIMESTAMP_EXPRESSION_STRING.equalsIgnoreCase(sortItem.getSortKey())
          && (sortItem.getOrdering() == Ordering.DESC)) {
        timeAscending = false;
        break;
      }
    }

    List<Accumulator> accumulators = new ArrayList<>();
    for (Expression expression : node.getSelectExpressions()) {
      if (expression instanceof FunctionExpression) {
        FunctionExpression functionExpression = (FunctionExpression) expression;
        String aggregationName = functionExpression.getFunctionName();
        Accumulator accumulator =
            AccumulatorFactory.createAccumulator(
                aggregationName,
                getAggregationTypeByFuncName(aggregationName),
                Collections.singletonList(
                    context
                        .getTypeProvider()
                        .getTreeModelType(functionExpression.getOutputSymbol())),
                functionExpression.getExpressions(),
                functionExpression.getFunctionAttributes(),
                timeAscending,
                false);
        accumulators.add(accumulator);
      }
    }

    List<Integer> sortItemIndexList = new ArrayList<>(sortItemList.size());
    List<TSDataType> sortItemDataTypeList = new ArrayList<>(sortItemList.size());
    genSortInformation(
        node.getOutputColumnNames(),
        dataTypes,
        sortItemList,
        sortItemIndexList,
        sortItemDataTypeList);
    return new AggregationMergeSortOperator(
        operatorContext,
        children,
        dataTypes,
        accumulators,
        node.isHasGroupBy(),
        getComparator(sortItemList, sortItemIndexList, sortItemDataTypeList));
  }
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