class CompiledAggregateFunction extends AbstractCompiledValue {

  @Override
  public Object evaluate(ExecutionContext context) throws FunctionDomainException,
      TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
    boolean isPRQueryNode = context.getIsPRQueryNode();
    boolean isBucketNode = context.getBucketList() != null;
    switch (this.aggFuncType) {

      case OQLLexerTokenTypes.SUM:
        if (isPRQueryNode) {
          return this.distinctOnly ? new SumDistinctPRQueryNode() : new Sum();
        } else {
          return this.distinctOnly ? (isBucketNode ? new DistinctAggregator() : new SumDistinct())
              : new Sum();
        }

      case OQLLexerTokenTypes.MAX:
        return new MaxMin(true);

      case OQLLexerTokenTypes.MIN:
        return new MaxMin(false);

      case OQLLexerTokenTypes.AVG:
        if (isPRQueryNode) {
          return this.distinctOnly ? new AvgDistinctPRQueryNode() : new AvgPRQueryNode();
        } else {
          return this.distinctOnly ? (isBucketNode ? new DistinctAggregator() : new AvgDistinct())
              : (isBucketNode ? new AvgBucketNode() : new Avg());
        }

      case OQLLexerTokenTypes.COUNT:
        if (isPRQueryNode) {
          return this.distinctOnly ? new CountDistinctPRQueryNode() : new CountPRQueryNode();
        } else {
          return this.distinctOnly ? (isBucketNode ? new DistinctAggregator() : new CountDistinct())
              : new Count();
        }

      default:
        throw new UnsupportedOperationException("Aggregate function not implemented");

    }

  }

  public  CompiledAggregateFunction(CompiledValue expr, int aggFunc);
  public  CompiledAggregateFunction(CompiledValue expr, int aggFunc, boolean distinctOnly);

}