private void transformWithinGroup(ASTNode expressionTree, Tree withinGroupNode) throws SemanticException {
    if (isCBOExecuted()) {
      return;
    }

    Tree functionNameNode = expressionTree.getChild(0);
    if (!FunctionRegistry.isOrderedAggregate(functionNameNode.getText())) {
      throw new SemanticException(ErrorMsg.WITHIN_GROUP_NOT_ALLOWED, functionNameNode.getText());
    }

    List<Tree> parameters = new ArrayList<>(expressionTree.getChildCount() - 2);
    for (int i = 1; i < expressionTree.getChildCount() - 1; ++i) {
      parameters.add(expressionTree.getChild(i));
    }
    while (expressionTree.getChildCount() > 1) {
      expressionTree.deleteChild(1);
    }

    Tree orderByNode = withinGroupNode.getChild(0);
    if (parameters.size() != orderByNode.getChildCount()) {
      throw new SemanticException(ErrorMsg.WITHIN_GROUP_PARAMETER_MISMATCH,
              Integer.toString(parameters.size()), Integer.toString(orderByNode.getChildCount()));
    }

    for (int i = 0; i < orderByNode.getChildCount(); ++i) {
      expressionTree.addChild(parameters.get(i));
      Tree tabSortColNameNode = orderByNode.getChild(i);
      Tree nullsNode = tabSortColNameNode.getChild(0);
      ASTNode sortKey = (ASTNode) tabSortColNameNode.getChild(0).getChild(0);
      expressionTree.addChild(sortKey);
      expressionTree.addChild(ASTBuilder.createAST(HiveParser.NumberLiteral,
              Integer.toString(DirectionUtils.tokenToCode(tabSortColNameNode.getType()))));
      expressionTree.addChild(ASTBuilder.createAST(HiveParser.NumberLiteral,
              Integer.toString(NullOrdering.fromToken(nullsNode.getType()).getCode())));
    }
  }
DFS-scan the expressionTree to find all aggregation subtrees and put them
in aggregations.

@param expressionTree
@param aggregations
         the key to the HashTable is the toStringTree() representation of
         the aggregation subtree.
@throws SemanticException
ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java