docs: static public ParsedColInfo fromOrderByXml(AbstractParsedStmt parsedStmt,
              VoltXMLElement orderByXml, ExpressionAdjuster adjuster) {
  
          // make sure everything is kosher
          assert(orderByXml.name.equalsIgnoreCase("orderby"));
  
          // get desc/asc
          String desc = orderByXml.attributes.get("desc");
          boolean descending = (desc != null) && (desc.equalsIgnoreCase("true"));
  
          // get the columnref or other expression inside the orderby node
          VoltXMLElement child = orderByXml.children.get(0);
          assert(child != null);
  
          // create the orderby column
          ParsedColInfo orderCol = new ParsedColInfo();
          orderCol.m_orderBy = true;
          orderCol.m_ascending = !descending;
          AbstractExpression orderExpr = parsedStmt.parseExpressionTree(child);
          assert(orderExpr != null);
          orderCol.m_expression = adjuster.adjust(orderExpr);
  
          // Cases:
          // child could be columnref, in which case it's either a normal column
          // or an expression.
          // The latter could be a case if this column came from a subquery that
          // was optimized out.
          // Just make a ParsedColInfo object for it and the planner will do the
          // right thing later.
          if (orderExpr instanceof TupleValueExpression) {
              TupleValueExpression tve = (TupleValueExpression) orderExpr;
              orderCol.m_columnName = tve.getColumnName();
              orderCol.m_tableName = tve.getTableName();
              orderCol.m_tableAlias = tve.getTableAlias();
              if (orderCol.m_tableAlias == null) {
                  orderCol.m_tableAlias = orderCol.m_tableName;
              }
  
              orderCol.m_alias = tve.getColumnAlias();
          }
          else {
              String alias = child.attributes.get("alias");
              orderCol.m_alias = alias;
              orderCol.m_tableName = AbstractParsedStmt.TEMP_TABLE_NAME;
              orderCol.m_tableAlias = AbstractParsedStmt.TEMP_TABLE_NAME;
              orderCol.m_columnName = "";
              // Replace its expression to TVE after we build the ExpressionIndexMap
  
              if ((child.name.equals("operation") == false) &&
                      (child.name.equals("aggregation") == false) &&
                      (child.name.equals("win_aggregation") == false) &&
                      (child.name.equals("function") == false) &&
                      (child.name.equals("rank") == false) &&
                      (child.name.equals("value") == false) &&
                      (child.name.equals("columnref") == false)) {
                 throw new RuntimeException(
                         "ORDER BY parsed with strange child node type: " +
                         child.name);
              }
          }
  
          return orderCol;
      }