func (af *avgFunction) calculateResult(ctx *ast.AggEvaluateContext) (d types.Datum) { switch ctx.Value.Kind() { case types.KindFloat64: t := ctx.Value.GetFloat64() / float64(ctx.Count) d.SetValue(t) case types.KindMysqlDecimal: x := ctx.Value.GetMysqlDecimal() y := mysql.NewDecFromInt(ctx.Count) to := new(mysql.MyDecimal) mysql.DecimalDiv(x, y, to, mysql.DivFracIncr) to.Round(to, ctx.Value.Frac()+mysql.DivFracIncr) d.SetMysqlDecimal(to) } return }
func (e *Evaluator) evalAggAvg(v *ast.AggregateFuncExpr) { ctx := v.GetContext() switch ctx.Value.Kind() { case types.KindFloat64: t := ctx.Value.GetFloat64() / float64(ctx.Count) v.SetValue(t) case types.KindMysqlDecimal: x := ctx.Value.GetMysqlDecimal() var y, to mysql.MyDecimal y.FromUint(uint64(ctx.Count)) mysql.DecimalDiv(x, &y, &to, mysql.DivFracIncr) to.Round(&to, ctx.Value.Frac()+mysql.DivFracIncr) v.SetMysqlDecimal(&to) } ctx.Value = *v.GetDatum() }
// GetGroupResult implements AggregationFunction interface. func (af *avgFunction) GetGroupResult(groupKey []byte) (d types.Datum) { ctx := af.getContext(groupKey) switch ctx.Value.Kind() { case types.KindFloat64: t := ctx.Value.GetFloat64() / float64(ctx.Count) d.SetValue(t) case types.KindMysqlDecimal: x := ctx.Value.GetMysqlDecimal() y := mysql.NewDecFromInt(ctx.Count) to := new(mysql.MyDecimal) mysql.DecimalDiv(x, y, to, mysql.DivFracIncr) to.Round(to, ctx.Value.Frac()+mysql.DivFracIncr) d.SetMysqlDecimal(to) } return }
// decimal2RoundUint converts a MyDecimal to an uint64 after rounding. func decimal2RoundUint(x *mysql.MyDecimal) (uint64, error) { roundX := new(mysql.MyDecimal) x.Round(roundX, 0) var ( uintX uint64 err error ) if roundX.IsNegative() { intX, err := roundX.ToInt() if err != nil && err != mysql.ErrTruncated { return 0, errors.Trace(err) } uintX = uint64(intX) } else { uintX, err = roundX.ToUint() if err != nil && err != mysql.ErrTruncated { return 0, errors.Trace(err) } } return uintX, nil }