Пример #1
0
func unflatten(datum types.Datum, tp *types.FieldType) (types.Datum, error) {
	if datum.IsNull() {
		return datum, nil
	}
	switch tp.Tp {
	case mysql.TypeFloat:
		datum.SetFloat32(float32(datum.GetFloat64()))
		return datum, nil
	case mysql.TypeTiny, mysql.TypeShort, mysql.TypeYear, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong,
		mysql.TypeDouble, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeBlob, mysql.TypeLongBlob,
		mysql.TypeVarchar, mysql.TypeString:
		return datum, nil
	case mysql.TypeDate, mysql.TypeDatetime, mysql.TypeTimestamp:
		var t mysql.Time
		t.Type = tp.Tp
		t.Fsp = tp.Decimal
		err := t.Unmarshal(datum.GetBytes())
		if err != nil {
			return datum, errors.Trace(err)
		}
		datum.SetValue(t)
		return datum, nil
	case mysql.TypeDuration:
		dur := mysql.Duration{Duration: time.Duration(datum.GetInt64())}
		datum.SetValue(dur)
		return datum, nil
	case mysql.TypeNewDecimal, mysql.TypeDecimal:
		dec, err := mysql.ParseDecimal(datum.GetString())
		if err != nil {
			return datum, errors.Trace(err)
		}
		if tp.Decimal >= 0 {
			dec = dec.Truncate(int32(tp.Decimal))
		}
		datum.SetValue(dec)
		return datum, nil
	case mysql.TypeEnum:
		enum, err := mysql.ParseEnumValue(tp.Elems, datum.GetUint64())
		if err != nil {
			return datum, errors.Trace(err)
		}
		datum.SetValue(enum)
		return datum, nil
	case mysql.TypeSet:
		set, err := mysql.ParseSetValue(tp.Elems, datum.GetUint64())
		if err != nil {
			return datum, errors.Trace(err)
		}
		datum.SetValue(set)
		return datum, nil
	case mysql.TypeBit:
		bit := mysql.Bit{Value: datum.GetUint64(), Width: tp.Flen}
		datum.SetValue(bit)
		return datum, nil
	}
	log.Error(tp.Tp, datum)
	return datum, nil
}
Пример #2
0
func parseDayInterval(value types.Datum) (int64, error) {
	switch value.Kind() {
	case types.KindString:
		vs := value.GetString()
		s := strings.ToLower(vs)
		if s == "false" {
			return 0, nil
		} else if s == "true" {
			return 1, nil
		}
		value.SetString(reg.FindString(vs))
	}
	return value.ToInt64()
}
Пример #3
0
func coerceArithmetic(a types.Datum) (d types.Datum, err error) {
	switch a.Kind() {
	case types.KindString, types.KindBytes:
		// MySQL will convert string to float for arithmetic operation
		f, err := types.StrToFloat(a.GetString())
		if err != nil {
			return d, errors.Trace(err)
		}
		d.SetFloat64(f)
		return d, errors.Trace(err)
	case types.KindMysqlTime:
		// if time has no precision, return int64
		t := a.GetMysqlTime()
		de := t.ToNumber()
		if t.Fsp == 0 {
			d.SetInt64(de.IntPart())
			return d, nil
		}
		d.SetMysqlDecimal(de)
		return d, nil
	case types.KindMysqlDuration:
		// if duration has no precision, return int64
		du := a.GetMysqlDuration()
		de := du.ToNumber()
		if du.Fsp == 0 {
			d.SetInt64(de.IntPart())
			return d, nil
		}
		d.SetMysqlDecimal(de)
		return d, nil
	case types.KindMysqlHex:
		d.SetFloat64(a.GetMysqlHex().ToNumber())
		return d, nil
	case types.KindMysqlBit:
		d.SetFloat64(a.GetMysqlBit().ToNumber())
		return d, nil
	case types.KindMysqlEnum:
		d.SetFloat64(a.GetMysqlEnum().ToNumber())
		return d, nil
	case types.KindMysqlSet:
		d.SetFloat64(a.GetMysqlSet().ToNumber())
		return d, nil
	default:
		return a, nil
	}
}
Пример #4
0
func convertDateFormat(ctx context.Context, arg types.Datum, b byte) (types.Datum, error) {
	var d types.Datum
	var err error

	switch b {
	case 'b':
		d, err = builtinMonthName([]types.Datum{arg}, ctx)
		if err == nil && !d.IsNull() {
			d.SetString(d.GetString()[:3])
		}
	case 'M':
		d, err = builtinMonthName([]types.Datum{arg}, ctx)
	case 'm':
		d, err = builtinMonth([]types.Datum{arg}, ctx)
		if err == nil && !d.IsNull() {
			d.SetString(fmt.Sprintf("%02d", d.GetInt64()))
		}
	case 'c':
		d, err = builtinMonth([]types.Datum{arg}, ctx)
	case 'D':
		d, err = abbrDayOfMonth(arg, ctx)
	case 'd':
		d, err = builtinDayOfMonth([]types.Datum{arg}, ctx)
		if err == nil && !d.IsNull() {
			d.SetString(fmt.Sprintf("%02d", d.GetInt64()))
		}
	case 'e':
		d, err = builtinDayOfMonth([]types.Datum{arg}, ctx)
	case 'j':
		d, err = builtinDayOfYear([]types.Datum{arg}, ctx)
		if err == nil {
			d.SetString(fmt.Sprintf("%03d", d.GetInt64()))
		}
	case 'H', 'k':
		d, err = builtinHour([]types.Datum{arg}, ctx)
		if err == nil && b == 'H' && !d.IsNull() {
			d.SetString(fmt.Sprintf("%02d", d.GetInt64()))
		}
	case 'h', 'I', 'l':
		d, err = builtinHour([]types.Datum{arg}, ctx)
		if err == nil && !d.IsNull() {
			if d.GetInt64() > 12 {
				d.SetInt64(d.GetInt64() - 12)
			} else if d.GetInt64() == 0 {
				d.SetInt64(12)
			}
			d.SetString(fmt.Sprintf("%02d", d.GetInt64()))
		}
	case 'i':
		d, err = builtinMinute([]types.Datum{arg}, ctx)
		if err == nil && !d.IsNull() {
			d.SetString(fmt.Sprintf("%02d", d.GetInt64()))
		}
	case 'p':
		d, err = builtinHour([]types.Datum{arg}, ctx)
		if err == nil && !d.IsNull() {
			if d.GetInt64() < 12 {
				d.SetString("AM")
				break
			}
			d.SetString("PM")
		}
	case 'r':
		d, err = to12Hour(arg, ctx)
	case 'T':
		d, err = builtinTime([]types.Datum{arg}, ctx)
		if err == nil && !d.IsNull() {
			duration := types.Duration{
				Duration: d.GetMysqlDuration().Duration,
				Fsp:      0}
			d.SetMysqlDuration(duration)
		}
	case 'S', 's':
		d, err = builtinSecond([]types.Datum{arg}, ctx)
		if err == nil && !d.IsNull() {
			d.SetString(fmt.Sprintf("%02d", d.GetInt64()))
		}
	case 'f':
		d, err = builtinMicroSecond([]types.Datum{arg}, ctx)
		if err == nil && !d.IsNull() {
			d.SetString(fmt.Sprintf("%06d", d.GetInt64()))
		}
	case 'U':
		d, err = builtinWeek([]types.Datum{arg, types.NewIntDatum(0)}, ctx)
		if err == nil && !d.IsNull() {
			d.SetString(fmt.Sprintf("%02d", d.GetInt64()))
		}
	case 'u':
		d, err = builtinWeek([]types.Datum{arg, types.NewIntDatum(1)}, ctx)
		if err == nil && !d.IsNull() {
			d.SetString(fmt.Sprintf("%02d", d.GetInt64()))
		}
	case 'V':
		d, err = builtinWeek([]types.Datum{arg, types.NewIntDatum(2)}, ctx)
		if err == nil && !d.IsNull() {
			d.SetString(fmt.Sprintf("%02d", d.GetInt64()))
		}
	case 'v':
		d, err = builtinWeek([]types.Datum{arg, types.NewIntDatum(3)}, ctx)
		if err == nil && !d.IsNull() {
			d.SetString(fmt.Sprintf("%02d", d.GetInt64()))
		}
	case 'a':
		d, err = builtinDayName([]types.Datum{arg}, ctx)
		if err == nil && !d.IsNull() {
			d.SetString(d.GetString()[:3])
		}
	case 'W':
		d, err = builtinDayName([]types.Datum{arg}, ctx)
	case 'w':
		d, err = builtinDayOfWeek([]types.Datum{arg}, ctx)
		if err == nil && !d.IsNull() {
			d.SetInt64(d.GetInt64() - 1)
		}
	case 'X':
		d, err = builtinYearWeek([]types.Datum{arg, types.NewIntDatum(2)}, ctx)
		if err == nil && !d.IsNull() {
			if d.GetInt64() == math.MaxUint32 {
				break
			}
			str := fmt.Sprintf("%04d", d.GetInt64())
			d.SetString(fmt.Sprintf("%04s", str[:4]))
		}
	case 'x':
		d, err = builtinYearWeek([]types.Datum{arg, types.NewIntDatum(3)}, ctx)
		if err == nil && !d.IsNull() {
			if d.GetInt64() == math.MaxUint32 {
				break
			}
			str := fmt.Sprintf("%04d", d.GetInt64())
			d.SetString(fmt.Sprintf("%04s", str[:4]))
		}
	case 'Y':
		d, err = builtinYear([]types.Datum{arg}, ctx)
		if err == nil && !d.IsNull() {
			d.SetString(fmt.Sprintf("%04d", d.GetInt64()))
		}
	case 'y':
		d, err = builtinYear([]types.Datum{arg}, ctx)
		if err == nil && !d.IsNull() {
			str := fmt.Sprintf("%04d", d.GetInt64())
			d.SetString(fmt.Sprintf("%02s", str[2:]))
		}
	default:
		d.SetString(string(b))
	}

	if err == nil && !d.IsNull() {
		d.SetString(fmt.Sprintf("%v", d.GetValue()))
	}
	return d, errors.Trace(err)
}
Пример #5
0
// Unflatten converts a raw datum to a column datum.
func Unflatten(datum types.Datum, ft *types.FieldType, inIndex bool) (types.Datum, error) {
	if datum.IsNull() {
		return datum, nil
	}
	switch ft.Tp {
	case mysql.TypeFloat:
		datum.SetFloat32(float32(datum.GetFloat64()))
		return datum, nil
	case mysql.TypeTiny, mysql.TypeShort, mysql.TypeYear, mysql.TypeInt24,
		mysql.TypeLong, mysql.TypeLonglong, mysql.TypeDouble, mysql.TypeTinyBlob,
		mysql.TypeMediumBlob, mysql.TypeBlob, mysql.TypeLongBlob, mysql.TypeVarchar,
		mysql.TypeString:
		return datum, nil
	case mysql.TypeDate, mysql.TypeDatetime, mysql.TypeTimestamp:
		var t mysql.Time
		t.Type = ft.Tp
		t.Fsp = ft.Decimal
		var err error
		err = t.FromPackedUint(datum.GetUint64())
		if err != nil {
			return datum, errors.Trace(err)
		}
		datum.SetMysqlTime(t)
		return datum, nil
	case mysql.TypeDuration:
		dur := mysql.Duration{Duration: time.Duration(datum.GetInt64())}
		datum.SetValue(dur)
		return datum, nil
	case mysql.TypeNewDecimal:
		if datum.Kind() == types.KindMysqlDecimal {
			if ft.Decimal >= 0 {
				dec := datum.GetMysqlDecimal().Truncate(int32(ft.Decimal))
				datum.SetMysqlDecimal(dec)
			}
			return datum, nil
		}
		dec, err := mysql.ParseDecimal(datum.GetString())
		if err != nil {
			return datum, errors.Trace(err)
		}
		if ft.Decimal >= 0 {
			dec = dec.Truncate(int32(ft.Decimal))
		}
		datum.SetValue(dec)
		return datum, nil
	case mysql.TypeEnum:
		enum, err := mysql.ParseEnumValue(ft.Elems, datum.GetUint64())
		if err != nil {
			return datum, errors.Trace(err)
		}
		datum.SetValue(enum)
		return datum, nil
	case mysql.TypeSet:
		set, err := mysql.ParseSetValue(ft.Elems, datum.GetUint64())
		if err != nil {
			return datum, errors.Trace(err)
		}
		datum.SetValue(set)
		return datum, nil
	case mysql.TypeBit:
		bit := mysql.Bit{Value: datum.GetUint64(), Width: ft.Flen}
		datum.SetValue(bit)
		return datum, nil
	}
	return datum, nil
}