private void doPhase1GetAllAggregations(ASTNode expressionTree, QB qb,
                                          Map<String, ASTNode> aggregations, List<ASTNode> wdwFns,
                                          ASTNode wndParent) throws SemanticException {
    int exprTokenType = expressionTree.getToken().getType();
    if(exprTokenType == HiveParser.TOK_SUBQUERY_EXPR) {
      //since now we have scalar subqueries we can get subquery expression in having
      // we don't want to include aggregate from within subquery
      qb.addSubqExprAlias(expressionTree, this);
      return;
    }

    boolean parentIsWindowSpec = wndParent != null;

    if (exprTokenType == HiveParser.TOK_FUNCTION
        || exprTokenType == HiveParser.TOK_FUNCTIONDI
        || exprTokenType == HiveParser.TOK_FUNCTIONSTAR) {
      assert (expressionTree.getChildCount() != 0);
      Tree lastChild = expressionTree.getChild(expressionTree.getChildCount() - 1);
      if (lastChild.getType() == HiveParser.TOK_WINDOWSPEC) {
        // If it is a windowing spec, we include it in the list
        // Further, we will examine its children AST nodes to check whether
        // there are aggregation functions within
        wdwFns.add(expressionTree);
        for(Node child : expressionTree.getChildren()) {
          doPhase1GetAllAggregations((ASTNode) child, qb, aggregations, wdwFns, expressionTree);
        }
        return;
      } else if (lastChild.getType() == HiveParser.TOK_WITHIN_GROUP) {
        transformWithinGroup(expressionTree, lastChild);
      }
      if (expressionTree.getChild(0).getType() == HiveParser.Identifier) {
        String functionName = unescapeIdentifier(expressionTree.getChild(0)
            .getText());
        // Validate the function name
        if (FunctionRegistry.getFunctionInfo(functionName) == null) {
          throw new SemanticException(ErrorMsg.INVALID_FUNCTION.getMsg(functionName));
        }
        if(FunctionRegistry.impliesOrder(functionName) && !parentIsWindowSpec) {
          throw new SemanticException(ErrorMsg.MISSING_OVER_CLAUSE.getMsg(functionName));
        }
        if (FunctionRegistry.getGenericUDAFResolver(functionName) != null) {
          if(containsLeadLagUDF(expressionTree) && !parentIsWindowSpec) {
            throw new SemanticException(ErrorMsg.MISSING_OVER_CLAUSE.getMsg(functionName));
          }
          aggregations.put(expressionTree.toStringTree(), expressionTree);
          FunctionInfo fi = FunctionRegistry.getFunctionInfo(functionName);
          if (!fi.isNative()) {
            unparseTranslator.addIdentifierTranslation((ASTNode) expressionTree
                .getChild(0));
          }
          return;
        }
      }
    }
    for (int i = 0; i < expressionTree.getChildCount(); i++) {
      doPhase1GetAllAggregations((ASTNode) expressionTree.getChild(i), qb,
          aggregations, wdwFns, wndParent);
    }
  }
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