fe/src/main/java/com/cloudera/impala/analysis/AggregateInfo.java
/**
   * Create aggregate info for select block containing aggregate exprs with
   * DISTINCT clause.
   * This creates:
   * - aggTupleDesc
   * - a complete secondPhaseDistinctAggInfo
   * - mergeAggInfo
   *
   * At the moment, we require that all distinct aggregate
   * functions be applied to the same set of exprs (ie, we can't do something
   * like SELECT COUNT(DISTINCT id), COUNT(DISTINCT address)).
   * Aggregation happens in two successive phases:
   * - the first phase aggregates by all grouping exprs plus all parameter exprs
   *   of DISTINCT aggregate functions
   *
   * Example:
   *   SELECT a, COUNT(DISTINCT b, c), MIN(d), COUNT(*) FROM T GROUP BY a
   * - 1st phase grouping exprs: a, b, c
   * - 1st phase agg exprs: MIN(d), COUNT(*)
   * - 2nd phase grouping exprs: a
   * - 2nd phase agg exprs: COUNT(*), MIN(<MIN(d) from 1st phase>),
   *     SUM(<COUNT(*) from 1st phase>)
   *
   * TODO: expand implementation to cover the general case; this will require
   * a different execution strategy
   */
Create aggregate info for select block containing aggregate exprs with
DISTINCT clause.
This creates:
- aggTupleDesc
- a complete secondPhaseDistinctAggInfo
- mergeAggInfo

At the moment, we require that all distinct aggregate
functions be applied to the same set of exprs , COUNT(DISTINCT address)).
Aggregation happens in two successive phases:
- the first phase aggregates by all grouping exprs plus all parameter exprs
of DISTINCT aggregate functions



expand implementation to cover the general case; this will require
a different execution strategy
Create aggregate info for select block containing aggregate exprs with DISTINCT clause . This creates : - aggTupleDesc - a complete secondPhaseDistinctAggInfo - mergeAggInfo At the moment we require that all distinct aggregate functions be applied to the same set of exprs COUNT ( DISTINCT address )) . Aggregation happens in two successive phases : - the first phase aggregates by all grouping exprs plus all parameter exprs of DISTINCT aggregate functions expand implementation to cover the general case ; this will require a different execution strategy
private void createDistinctAggInfo(
      ArrayList<Expr> origGroupingExprs,
      ArrayList<FunctionCallExpr> distinctAggExprs, Analyzer analyzer)
      throws AnalysisException, InternalException, AuthorizationException {
    Preconditions.checkState(!distinctAggExprs.isEmpty());
    ArrayList<Expr> expr0Children = Lists.newArrayList();
    for (Expr expr: distinctAggExprs.get(0).getChildren()) {
      expr0Children.add(expr.ignoreImplicitCast());
    }
    for (int i = 1; i < distinctAggExprs.size(); ++i) {
      ArrayList<Expr> exprIChildren = Lists.newArrayList();
      for (Expr expr: distinctAggExprs.get(i).getChildren()) {
        exprIChildren.add(expr.ignoreImplicitCast());
      }
      if (!Expr.equalLists(expr0Children, exprIChildren)) {
        throw new AnalysisException(
            "all DISTINCT aggregate functions need to have the same set of "
            + "parameters as " + distinctAggExprs.get(0).toSql()
            + "; deviating function: " + distinctAggExprs.get(i).toSql());
      }
    }
    isDistinctAgg_ = true;
    groupingExprs_.addAll(distinctAggExprs.get(0).getChildren());
    aggregateExprs_.removeAll(distinctAggExprs);
    aggTupleDesc_ = createAggTupleDesc(analyzer);
    createMergeAggInfo(analyzer);
    createSecondPhaseDistinctAggInfo(origGroupingExprs, distinctAggExprs, analyzer);
  }
private void createDistinctAggInfo ( ArrayList < Expr > origGroupingExprs , ArrayList < FunctionCallExpr > distinctAggExprs , Analyzer analyzer ) throws AnalysisException , InternalException , AuthorizationException { Preconditions . checkState ( ! distinctAggExprs . isEmpty ( ) ) ; ArrayList < Expr > expr0Children = Lists . newArrayList ( ) ; for ( Expr expr : distinctAggExprs . get ( 0 ) . getChildren ( ) ) { expr0Children . add ( expr . ignoreImplicitCast ( ) ) ; } for ( int i = 1 ; i < distinctAggExprs . size ( ) ; ++ i ) { ArrayList < Expr > exprIChildren = Lists . newArrayList ( ) ; for ( Expr expr : distinctAggExprs . get ( i ) . getChildren ( ) ) { exprIChildren . add ( expr . ignoreImplicitCast ( ) ) ; } if ( ! Expr . equalLists ( expr0Children , exprIChildren ) ) { throw new AnalysisException ( "all DISTINCT aggregate functions need to have the same set of " + "parameters as " + distinctAggExprs . get ( 0 ) . toSql ( ) + "; deviating function: " + distinctAggExprs . get ( i ) . toSql ( ) ) ; } } isDistinctAgg_ = true ; groupingExprs_ . addAll ( distinctAggExprs . get ( 0 ) . getChildren ( ) ) ; aggregateExprs_ . removeAll ( distinctAggExprs ) ; aggTupleDesc_ = createAggTupleDesc ( analyzer ) ; createMergeAggInfo ( analyzer ) ; createSecondPhaseDistinctAggInfo ( origGroupingExprs , distinctAggExprs , analyzer ) ; }
Create aggregate info for select block containing aggregate exprs with
 DISTINCT clause.
Create aggregate info for select block containing aggregate exprs with DISTINCT clause .
// make sure that all DISTINCT params are the same; // ignore top-level implicit casts in the comparison, we might have inserted // those during analysis // add DISTINCT parameters to grouping exprs // remove DISTINCT aggregate functions from aggExprs