Beispiel #1
0
// 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
}
Beispiel #2
0
// 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())
	}
}
Beispiel #3
0
// 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
}