docs: private AbstractExpression parseWindowedAggregationExpression(VoltXMLElement exprNode) {
          int id = Integer.parseInt(exprNode.attributes.get("id"));
          String optypeName = exprNode.attributes.get("optype");
          ExpressionType optype = ExpressionType.get(optypeName);
          if (optype == ExpressionType.INVALID) {
              throw new PlanningErrorException("Undefined windowed function call " + optypeName);
          }
  
          // If this is not in the display column list, and the id is not the id of
          // the windowed expression, then this is an error.
          if (!m_parsingInDisplayColumns) {
              if (m_windowFunctionExpressions.size() > 0) {
                  WindowFunctionExpression we = m_windowFunctionExpressions.get(0);
                  if (we.getXMLID() == id) {
                      // This is the same as a windowed expression we saw in the
                      // display list.  This can happen if we see an alias for
                      // a display list element in the order by expressions.  If
                      // this happens we just want to return the TVE we squirreled
                      // away in the windowed expression.
                      return we.getDisplayListExpression();
                  }
              }
              throw new PlanningErrorException("Windowed function call expressions can only appear in the selection list of a query or subquery.");
          }
          // Parse individual aggregate expressions
          List<AbstractExpression> partitionbyExprs = new ArrayList<>();
          List<AbstractExpression> orderbyExprs = new ArrayList<>();
          List<SortDirectionType>  orderbyDirs  = new ArrayList<>();
          List<AbstractExpression> aggParams    = new ArrayList<>();
  
          for (VoltXMLElement childEle : exprNode.children) {
              if (childEle.name.equals("winspec")) {
                  for (VoltXMLElement ele : childEle.children) {
                      if (ele.name.equals("partitionbyList")) {
                          for (VoltXMLElement childNode : ele.children) {
                              AbstractExpression expr = parseExpressionNode(childNode);
                              if (expr.hasSubquerySubexpression()) {
                                  throw new PlanningErrorException(
                                          "SQL window functions cannot be partitioned by subquery expression arguments.");
                              }
                              ExpressionUtil.finalizeValueTypes(expr);
                              partitionbyExprs.add(expr);
                          }
                      }
                      else if (ele.name.equals("orderbyList")) {
                          for (VoltXMLElement childNode : ele.children) {
                              SortDirectionType sortDir =
                                      Boolean.valueOf(childNode.attributes.get("descending")) ?
                                      SortDirectionType.DESC :
                                      SortDirectionType.ASC;
  
                              AbstractExpression expr = parseExpressionNode(childNode.children.get(0));
                              if (expr.hasSubquerySubexpression()) {
                                  throw new PlanningErrorException(
                                          "SQL window functions cannot be ordered by subquery expression arguments.");
                              }
                              ExpressionUtil.finalizeValueTypes(expr);
                              orderbyExprs.add(expr);
                              orderbyDirs.add(sortDir);
                          }
                      }
                  }
              }
              else {
                  AbstractExpression aggParam = parseExpressionNode(childEle);
                  if (aggParam != null) {
                      aggParam.finalizeValueTypes();
                      aggParams.add(aggParam);
                  }
              }
          }
  
          String alias = WINDOWED_AGGREGATE_COLUMN_NAME;
          if (exprNode.attributes.containsKey("alias")) {
              alias = exprNode.attributes.get("alias");
          }
          WindowFunctionExpression rankExpr = new WindowFunctionExpression(optype,
                                                               partitionbyExprs,
                                                               orderbyExprs,
                                                               orderbyDirs,
                                                               aggParams,
                                                               id);
          ExpressionUtil.finalizeValueTypes(rankExpr);
          // Only offset 0 is useful.  But we keep the index anyway.
          int offset = m_windowFunctionExpressions.size();
          m_windowFunctionExpressions.add(rankExpr);
          TupleValueExpression tve = new TupleValueExpression(
                  TEMP_TABLE_NAME, TEMP_TABLE_NAME,
                  alias, alias,
                  rankExpr, offset);
          // This tve does not ever need a differentiator.
          tve.setNeedsNoDifferentiation();
          rankExpr.setDisplayListExpression(tve);
          return tve;
      }