public static OrderingScheme translateOrderingScheme(
      List<SortItem> items, Function<Expression, Symbol> coercions) {
    List<Symbol> coerced =
        items.stream().map(SortItem::getSortKey).map(coercions).collect(toImmutableList());

    ImmutableList.Builder<Symbol> symbols = ImmutableList.builder();
    Map<Symbol, SortOrder> orders = new HashMap<>();
    for (int i = 0; i < coerced.size(); i++) {
      Symbol symbol = coerced.get(i);
      // for multiple sort items based on the same expression, retain the first one:
      // ORDER BY x DESC, x ASC, y --> ORDER BY x DESC, y
      if (!orders.containsKey(symbol)) {
        symbols.add(symbol);
        orders.put(symbol, OrderingTranslator.sortItemToSortOrder(items.get(i)));
      }
    }

    return new OrderingScheme(symbols.build(), orders);
  }
Creates a projection with any additional coercions by identity of the provided expressions.

@return the new subplan and a mapping of each expression to the symbol representing the
    coercion or an existing symbol if a coercion wasn't needed
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/QueryPlanner.java