code: func (a *AggFuncDesc) GetAggFunc(ctx sessionctx.Context) Aggregation {
  	aggFunc := aggFunction{AggFuncDesc: a}
  	switch a.Name {
  	case ast.AggFuncSum:
  		return &sumFunction{aggFunction: aggFunc}
  	case ast.AggFuncCount:
  		return &countFunction{aggFunction: aggFunc}
  	case ast.AggFuncAvg:
  		return &avgFunction{aggFunction: aggFunc}
  	case ast.AggFuncGroupConcat:
  		var s string
  		var err error
  		var maxLen uint64
  		s, err = variable.GetSessionSystemVar(ctx.GetSessionVars(), variable.GroupConcatMaxLen)
  		if err != nil {
  			panic(fmt.Sprintf("Error happened when GetAggFunc: no system variable named '%s'", variable.GroupConcatMaxLen))
  		}
  		maxLen, err = strconv.ParseUint(s, 10, 64)
  		if err != nil {
  			panic(fmt.Sprintf("Error happened when GetAggFunc: illegal value for system variable named '%s'", variable.GroupConcatMaxLen))
  		}
  		return &concatFunction{aggFunction: aggFunc, maxLen: maxLen}
  	case ast.AggFuncMax:
  		return &maxMinFunction{aggFunction: aggFunc, isMax: true}
  	case ast.AggFuncMin:
  		return &maxMinFunction{aggFunction: aggFunc, isMax: false}
  	case ast.AggFuncFirstRow:
  		return &firstRowFunction{aggFunction: aggFunc}
  	case ast.AggFuncBitOr:
  		return &bitOrFunction{aggFunction: aggFunc}
  	case ast.AggFuncBitXor:
  		return &bitXorFunction{aggFunction: aggFunc}
  	case ast.AggFuncBitAnd:
  		return &bitAndFunction{aggFunction: aggFunc}
  	default:
  		panic("unsupported agg function")
  	}
  }
docs: // GetAggFunc gets an evaluator according to the aggregation function signature.