docs: @Override
      Expression replaceAliasInOrderBy(Expression[] columns, int length) {
  
          // Recurse into sub-expressions.  For example, if
          // this expression is e0 + e1, nodes[0] is e0 and
          // nodes[1] is e1.
          for (int i = 0; i < nodes.length; i++) {
              if (nodes[i] == null) {
                  continue;
              }
              nodes[i] = nodes[i].replaceAliasInOrderBy(columns, length);
          }
          // Now process the node itself.
          switch (opType) {
              case OpTypes.COALESCE :
              case OpTypes.COLUMN : {
                  // Look through all the columns in columns.  These are
                  // the select list, and they may have aliases equal to
                  // the column which we are trying to resolve.  In that
                  // case we really want to use the expression in the
                  // select list.  Note that we only look for aliases here.
                  // Column references which name columns in tables in the
                  // from clause are handled later on.
                  java.util.Set<SelectListAliasResolution> foundNames = new java.util.TreeSet<>();
                  Expression firstFoundExpr = null;
                  for (int i = 0; i < length; i++) {
                      ExpressionColumn ecol = (columns[i] instanceof ExpressionColumn) ? (ExpressionColumn)columns[i] : null;
                      // Ferret out the table name, column name
                      // and alias name from this select column.
                      // If the alias name is null, then use the column name.
                      // This may be null as well.
                      String     selectTableName = null;
                      String     selectTableAlias = null;
                      String     selectColumnName = null;
                      if (ecol != null) {
                          selectTableName = ecol.getTableName();
                          selectTableAlias = ecol.getTableAlias();
                          if (selectTableAlias == null) {
                              selectTableAlias = selectTableName;
                          }
                          selectColumnName = ecol.columnName;
                      }
                      SimpleName selectAliasName = columns[i].alias;
                      String     selectAlias     = selectAliasName == null ? null : selectAliasName.name;
                      if (selectAlias == null) {
                          selectAlias = selectColumnName;
                      }
                      // For VoltDB, schema will always be null.
                      if (schema == null) {
                          // If this reference has no table name, then
                          // just compare the aliases.  If this reference
                          // has a table name this is handled
                          // by the usual lookup rules.
                          if (tableName == null) {
                              if (columnName.equals(selectAlias)) {
                                  foundNames.add(new SelectListAliasResolution(columns[i],
                                                                               selectTableAlias,
                                                                               selectColumnName,
                                                                               selectAlias,
                                                                               i));
                                  if (firstFoundExpr == null) {
                                      firstFoundExpr = columns[i];
                                  }
                              }
                          }
                      }
                  }
                  // If we only got one answer, then we just return it.
                  // If we got more than one, then we print an ambiguous
                  // error message.  If we got no answer, we let HSQL
                  // handle it in the usual way.
                  if (foundNames.size() == 1) {
                      return firstFoundExpr;
                  }
                  if (foundNames.size() > 1) {
                      StringBuffer sb = new StringBuffer();
                      sb.append(String.format("The name \"%s\" in an order by expression is ambiguous.  It's in columns: ", columnName));
                      appendNameList(sb, foundNames, "");
                      sb.append(".");
                      throw new HsqlException(sb.toString(), "", 0);
                  }
              }
              default :
          }
  
          return this;
      }