// 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 }
// ToInt64 converts to a int64. func (d *Datum) ToInt64() (int64, error) { tp := mysql.TypeLonglong lowerBound := signedLowerBound[tp] upperBound := signedUpperBound[tp] switch d.Kind() { case KindInt64: return convertIntToInt(d.GetInt64(), lowerBound, upperBound, tp) case KindUint64: return convertUintToInt(d.GetUint64(), upperBound, tp) case KindFloat32: return convertFloatToInt(float64(d.GetFloat32()), lowerBound, upperBound, tp) case KindFloat64: return convertFloatToInt(d.GetFloat64(), lowerBound, upperBound, tp) case KindString: s := d.GetString() fval, err := StrToFloat(s) if err != nil { return 0, errors.Trace(err) } return convertFloatToInt(fval, lowerBound, upperBound, tp) case KindBytes: s := string(d.GetBytes()) fval, err := StrToFloat(s) if err != nil { return 0, errors.Trace(err) } return convertFloatToInt(fval, lowerBound, upperBound, tp) case KindMysqlTime: // 2011-11-10 11:11:11.999999 -> 20111110111112 dec := d.GetMysqlTime().ToNumber() dec.Round(dec, 0) ival, err := dec.ToInt() ival, err2 := convertIntToInt(ival, lowerBound, upperBound, tp) if err == nil { err = err2 } return ival, err case KindMysqlDuration: // 11:11:11.999999 -> 111112 dec := d.GetMysqlDuration().ToNumber() dec.Round(dec, 0) ival, err := dec.ToInt() ival, err2 := convertIntToInt(ival, lowerBound, upperBound, tp) if err == nil { err = err2 } return ival, err case KindMysqlDecimal: var to mysql.MyDecimal d.GetMysqlDecimal().Round(&to, 0) ival, err := to.ToInt() ival, err2 := convertIntToInt(ival, lowerBound, upperBound, tp) if err == nil { err = err2 } return ival, err case KindMysqlHex: fval := d.GetMysqlHex().ToNumber() return convertFloatToInt(fval, lowerBound, upperBound, tp) case KindMysqlBit: fval := d.GetMysqlBit().ToNumber() return convertFloatToInt(fval, lowerBound, upperBound, tp) case KindMysqlEnum: fval := d.GetMysqlEnum().ToNumber() return convertFloatToInt(fval, lowerBound, upperBound, tp) case KindMysqlSet: fval := d.GetMysqlSet().ToNumber() return convertFloatToInt(fval, lowerBound, upperBound, tp) default: return 0, errors.Errorf("cannot convert %v(type %T) to int64", d.GetValue(), d.GetValue()) } }
// ComputeIntDiv computes the result of a / b, both a and b are integer. func ComputeIntDiv(a, b Datum) (d Datum, err error) { switch a.Kind() { case KindInt64: x := a.GetInt64() switch b.Kind() { case KindInt64: y := b.GetInt64() if y == 0 { return d, nil } r, err1 := DivInt64(x, y) d.SetInt64(r) return d, errors.Trace(err1) case KindUint64: y := b.GetUint64() if y == 0 { return d, nil } r, err1 := DivIntWithUint(x, y) d.SetUint64(r) return d, errors.Trace(err1) } case KindUint64: x := a.GetUint64() switch b.Kind() { case KindInt64: y := b.GetInt64() if y == 0 { return d, nil } r, err1 := DivUintWithInt(x, y) d.SetUint64(r) return d, errors.Trace(err1) case KindUint64: y := b.GetUint64() if y == 0 { return d, nil } d.SetUint64(x / y) return d, nil } } // If either is not integer, use decimal to calculate x, err := a.ToDecimal() if err != nil { return d, errors.Trace(err) } y, err := b.ToDecimal() if err != nil { return d, errors.Trace(err) } to := new(mysql.MyDecimal) err = mysql.DecimalDiv(x, y, to, mysql.DivFracIncr) if err == mysql.ErrDivByZero { return d, nil } iVal, err1 := to.ToInt() if err == nil { err = err1 } d.SetInt64(iVal) return d, nil }