docs: protected List<OrderByElement> getOrderByElements(PlainSelect plainSelect,
                                                        List<SelectItem> autoItems) {
          List<OrderByElement> orderByElements = plainSelect.getOrderByElements();
          ListIterator<OrderByElement> iterator = orderByElements.listIterator();
          OrderByElement orderByElement;
  
          // 非 `*` 且 非 `t.*` 查询列集合
          Map<String, SelectExpressionItem> selectMap = new HashMap<String, SelectExpressionItem>();
          // 别名集合
          Set<String> aliases = new HashSet<String>();
          // 是否包含 `*` 查询列
          boolean allColumns = false;
          // `t.*` 查询列的表名集合
          Set<String> allColumnsTables = new HashSet<String>();
  
          for (SelectItem item : plainSelect.getSelectItems()) {
              if (item instanceof SelectExpressionItem) {
                  SelectExpressionItem expItem = (SelectExpressionItem) item;
                  selectMap.put(expItem.getExpression().toString(), expItem);
  
                  Alias alias = expItem.getAlias();
                  if (alias != null) {
                      aliases.add(alias.getName());
                  }
  
              } else if (item instanceof AllColumns) {
                  allColumns = true;
  
              } else if (item instanceof AllTableColumns) {
                  allColumnsTables.add(((AllTableColumns) item).getTable().getName());
              }
          }
  
          // 开始遍历 OrderByElement 列表
          int aliasNo = 1;
          while (iterator.hasNext()) {
              orderByElement = iterator.next();
              Expression expression = orderByElement.getExpression();
              SelectExpressionItem selectExpressionItem = selectMap.get(expression.toString());
              if (selectExpressionItem != null) { // OrderByElement 在查询列表中
                  Alias alias = selectExpressionItem.getAlias();
                  if (alias != null) { // 查询列含有别名时用查询列别名
                      iterator.set(cloneOrderByElement(orderByElement, alias.getName()));
  
                  } else { // 查询列不包含别名
                      if (expression instanceof Column) {
                          // 查询列为普通列，这时因为列在嵌套查询外时名称中不包含表名，故去除排序列的表名引用
                          // 例（仅为解释此处逻辑，不代表最终分页结果）：
                          // SELECT TEST.A FROM TEST ORDER BY TEST.A
                          // -->
                          // SELECT A FROM (SELECT TEST.A FROM TEST) ORDER BY A
                          ((Column) expression).setTable(null);
  
                      } else {
                          // 查询列不为普通列时（例如函数列）不支持分页
                          // 此种情况比较难预测，简单的增加新列容易产生不可预料的结果
                          // 而为列增加别名是非常简单的，故此要求排序复杂列必须使用别名
                          throw new PageException("列 \"" + expression + "\" 需要定义别名");
                      }
                  }
  
              } else { // OrderByElement 不在查询列表中，需要自动生成一个查询列
                  if (expression instanceof Column) { // OrderByElement 为普通列
                      String table = ((Column) expression).getTable().getName();
                      if (table == null) { // 表名为空
                          if (allColumns ||
                                  (allColumnsTables.size() == 1 && plainSelect.getJoins() == null) ||
                                  aliases.contains(((Column) expression).getColumnName())) {
                              // 包含`*`查询列 或者 只有一个 `t.*`列且为单表查询 或者 其实排序列是一个别名
                              // 此时排序列其实已经包含在查询列表中了，不需做任何操作
                              continue;
                          }
  
                      } else { //表名不为空
                          if (allColumns || allColumnsTables.contains(table)) {
                              // 包含`*`查询列 或者 包含特定的`t.*`列
                              // 此时排序列其实已经包含在查询列表中了，只需去除排序列的表名引
                              ((Column) expression).setTable(null);
                              continue;
                          }
                      }
                  }
  
                  // 将排序列加入查询列中
                  String aliasName = PAGE_COLUMN_ALIAS_PREFIX + aliasNo++;
  
                  SelectExpressionItem item = new SelectExpressionItem();
                  item.setExpression(expression);
                  item.setAlias(new Alias(aliasName));
                  autoItems.add(item);
  
                  iterator.set(cloneOrderByElement(orderByElement, aliasName));
              }
          }
  
          return orderByElements;
      }