@Override
    public PlanNode visitSort(SortNode node, Context context) {

      PlanNode child = node.getChild().accept(this, context);

      // sort in outer query cannot use StreamSort
      if (!context.canTransform()) {
        node.setChild(child);
        return node;
      }
      context.setCanTransform(false);

      DeviceTableScanNode deviceTableScanNode = context.getTableScanNode();
      Map<Symbol, ColumnSchema> tableColumnSchema =
          analysis.getTableColumnSchema(deviceTableScanNode.getQualifiedObjectName());

      OrderingScheme orderingScheme = node.getOrderingScheme();
      int streamSortIndex = -1;
      for (Symbol orderBy : orderingScheme.getOrderBy()) {
        if (!tableColumnSchema.containsKey(orderBy)
            || tableColumnSchema.get(orderBy).getColumnCategory() == TsTableColumnCategory.FIELD
            || tableColumnSchema.get(orderBy).getColumnCategory() == TsTableColumnCategory.TIME) {
          break;
        } else {
          streamSortIndex++;
        }
      }

      if (streamSortIndex >= 0) {
        boolean orderByAllIdsAndTime =
            isOrderByAllIdsAndTime(tableColumnSchema, orderingScheme, streamSortIndex);

        return new StreamSortNode(
            queryContext.getQueryId().genPlanNodeId(),
            child,
            node.getOrderingScheme(),
            node.isPartial(),
            orderByAllIdsAndTime,
            streamSortIndex);
      }

      return node;
    }
<b>Optimization phase:</b> Logical plan planning.

<p>This optimize rule implement the rules below.
<li>When the sort order is `IDColumns,Time` or `IDColumns,Others` in SortNode, SortNode can be
    transformed to StreamSortNode.
<li>Set value to `orderByAllIdsAndTime`.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/TransformSortToStreamSort.java