private List<Expression> analyzeOrderBy(
        Node node, List<SortItem> sortItems, Scope orderByScope) {
      ImmutableList.Builder<Expression> orderByFieldsBuilder = ImmutableList.builder();

      for (SortItem item : sortItems) {
        Expression expression = item.getSortKey();

        if (expression instanceof LongLiteral) {
          // this is an ordinal in the output tuple

          long ordinal = ((LongLiteral) expression).getParsedValue();
          if (ordinal < 1 || ordinal > orderByScope.getRelationType().getVisibleFieldCount()) {
            throw new SemanticException(
                String.format("ORDER BY position %s is not in select list", ordinal));
          }

          expression = new FieldReference(toIntExact(ordinal - 1));
        }

        ExpressionAnalysis expressionAnalysis =
            ExpressionAnalyzer.analyzeExpression(
                metadata,
                queryContext,
                sessionContext,
                statementAnalyzerFactory,
                accessControl,
                orderByScope,
                analysis,
                expression,
                WarningCollector.NOOP,
                correlationSupport);
        analysis.recordSubqueries(node, expressionAnalysis);

        Type type = analysis.getType(expression);
        if (!type.isOrderable()) {
          throw new SemanticException(
              String.format(
                  "Type %s is not orderable, and therefore cannot be used in ORDER BY: %s",
                  type, expression));
        }

        orderByFieldsBuilder.add(expression);
      }

      return orderByFieldsBuilder.build();
    }
Check if there is Columns function in expression, and verify they are same if there are multi
Column functions.

@param expression input expression
@return if there is Columns function in expression
@throws SemanticException if there are multi Columns functions but different
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java