func dumpTextValue(mysqlType uint8, value types.Datum) ([]byte, error) { switch value.Kind() { case types.KindInt64: return strconv.AppendInt(nil, value.GetInt64(), 10), nil case types.KindUint64: return strconv.AppendUint(nil, value.GetUint64(), 10), nil case types.KindFloat32: return strconv.AppendFloat(nil, value.GetFloat64(), 'f', -1, 32), nil case types.KindFloat64: return strconv.AppendFloat(nil, value.GetFloat64(), 'f', -1, 64), nil case types.KindString, types.KindBytes: return value.GetBytes(), nil case types.KindMysqlTime: return hack.Slice(value.GetMysqlTime().String()), nil case types.KindMysqlDuration: return hack.Slice(value.GetMysqlDuration().String()), nil case types.KindMysqlDecimal: return hack.Slice(value.GetMysqlDecimal().String()), nil case types.KindMysqlEnum: return hack.Slice(value.GetMysqlEnum().String()), nil case types.KindMysqlSet: return hack.Slice(value.GetMysqlSet().String()), nil case types.KindMysqlBit: return hack.Slice(value.GetMysqlBit().ToString()), nil case types.KindMysqlHex: return hack.Slice(value.GetMysqlHex().ToString()), nil default: return nil, errInvalidType.Gen("invalid type %T", value) } }
func flatten(data types.Datum) (types.Datum, error) { switch data.Kind() { case types.KindMysqlTime: // for mysql datetime, timestamp and date type b, err := data.GetMysqlTime().Marshal() if err != nil { return types.NewDatum(nil), errors.Trace(err) } return types.NewDatum(b), nil case types.KindMysqlDuration: // for mysql time type data.SetInt64(int64(data.GetMysqlDuration().Duration)) return data, nil case types.KindMysqlDecimal: data.SetString(data.GetMysqlDecimal().String()) return data, nil case types.KindMysqlEnum: data.SetUint64(data.GetMysqlEnum().Value) return data, nil case types.KindMysqlSet: data.SetUint64(data.GetMysqlSet().Value) return data, nil case types.KindMysqlBit: data.SetUint64(data.GetMysqlBit().Value) return data, nil case types.KindMysqlHex: data.SetInt64(data.GetMysqlHex().Value) return data, nil default: return data, nil } }
func flatten(data types.Datum) (types.Datum, error) { switch data.Kind() { case types.KindMysqlTime: // for mysql datetime, timestamp and date type return types.NewUintDatum(data.GetMysqlTime().ToPackedUint()), nil case types.KindMysqlDuration: // for mysql time type data.SetInt64(int64(data.GetMysqlDuration().Duration)) return data, nil case types.KindMysqlDecimal: data.SetString(data.GetMysqlDecimal().String()) return data, nil case types.KindMysqlEnum: data.SetUint64(data.GetMysqlEnum().Value) return data, nil case types.KindMysqlSet: data.SetUint64(data.GetMysqlSet().Value) return data, nil case types.KindMysqlBit: data.SetUint64(data.GetMysqlBit().Value) return data, nil case types.KindMysqlHex: data.SetInt64(data.GetMysqlHex().Value) return data, nil default: return data, nil } }
func datumExpr(d types.Datum) *tipb.Expr { expr := new(tipb.Expr) switch d.Kind() { case types.KindInt64: expr.Tp = tipb.ExprType_Int64.Enum() expr.Val = codec.EncodeInt(nil, d.GetInt64()) case types.KindUint64: expr.Tp = tipb.ExprType_Uint64.Enum() expr.Val = codec.EncodeUint(nil, d.GetUint64()) case types.KindString: expr.Tp = tipb.ExprType_String.Enum() expr.Val = d.GetBytes() case types.KindBytes: expr.Tp = tipb.ExprType_Bytes.Enum() expr.Val = d.GetBytes() case types.KindFloat32: expr.Tp = tipb.ExprType_Float32.Enum() expr.Val = codec.EncodeFloat(nil, d.GetFloat64()) case types.KindFloat64: expr.Tp = tipb.ExprType_Float64.Enum() expr.Val = codec.EncodeFloat(nil, d.GetFloat64()) case types.KindMysqlDuration: expr.Tp = tipb.ExprType_MysqlDuration.Enum() expr.Val = codec.EncodeInt(nil, int64(d.GetMysqlDuration().Duration)) case types.KindMysqlDecimal: expr.Tp = tipb.ExprType_MysqlDecimal.Enum() expr.Val = codec.EncodeDecimal(nil, d.GetMysqlDecimal()) default: expr.Tp = tipb.ExprType_Null.Enum() } return expr }
func testFrac(c *C, v *mysql.MyDecimal) { var d1 types.Datum d1.SetMysqlDecimal(v) b := EncodeDecimal([]byte{}, d1) _, d2, err := DecodeDecimal(b) c.Assert(err, IsNil) cmp, err := d1.CompareDatum(d2) c.Assert(err, IsNil) c.Assert(cmp, Equals, 0) c.Assert(d1.GetMysqlDecimal().String(), Equals, d2.GetMysqlDecimal().String()) }
func testFrac(c *C, v *types.MyDecimal) { var d1 types.Datum d1.SetMysqlDecimal(v) b := EncodeDecimal([]byte{}, d1) _, d2, err := DecodeDecimal(b) c.Assert(err, IsNil) sc := new(variable.StatementContext) cmp, err := d1.CompareDatum(sc, d2) c.Assert(err, IsNil) c.Assert(cmp, Equals, 0) c.Assert(d1.GetMysqlDecimal().String(), Equals, d2.GetMysqlDecimal().String()) }
// EncodeDecimal encodes a decimal d into a byte slice which can be sorted lexicographically later. func EncodeDecimal(b []byte, d types.Datum) []byte { dec := d.GetMysqlDecimal() precision := d.Length() frac := d.Frac() if precision == 0 { precision, frac = dec.PrecisionAndFrac() } b = append(b, byte(precision), byte(frac)) bin, err := dec.ToBin(precision, frac) if err != nil { log.Errorf("should not happen, precision %d, frac %d %v", precision, frac, err) return b } b = append(b, bin...) return b }
func computeMul(a, b types.Datum) (d types.Datum, err error) { switch a.Kind() { case types.KindInt64: switch b.Kind() { case types.KindInt64: r, err1 := types.MulInt64(a.GetInt64(), b.GetInt64()) d.SetInt64(r) return d, errors.Trace(err1) case types.KindUint64: r, err1 := types.MulInteger(b.GetUint64(), a.GetInt64()) d.SetUint64(r) return d, errors.Trace(err1) } case types.KindUint64: switch b.Kind() { case types.KindInt64: r, err1 := types.MulInteger(a.GetUint64(), b.GetInt64()) d.SetUint64(r) return d, errors.Trace(err1) case types.KindUint64: r, err1 := types.MulUint64(a.GetUint64(), b.GetUint64()) d.SetUint64(r) return d, errors.Trace(err1) } case types.KindFloat64: switch b.Kind() { case types.KindFloat64: r := a.GetFloat64() * b.GetFloat64() d.SetFloat64(r) return d, nil } case types.KindMysqlDecimal: switch b.Kind() { case types.KindMysqlDecimal: r := a.GetMysqlDecimal().Mul(b.GetMysqlDecimal()) d.SetMysqlDecimal(r) return d, nil } } _, err = types.InvOp2(a.GetValue(), b.GetValue(), opcode.Mul) return d, errors.Trace(err) }
func computeMinus(a, b types.Datum) (d types.Datum, err error) { switch a.Kind() { case types.KindInt64: switch b.Kind() { case types.KindInt64: r, err1 := types.SubInt64(a.GetInt64(), b.GetInt64()) d.SetInt64(r) return d, errors.Trace(err1) case types.KindUint64: r, err1 := types.SubIntWithUint(a.GetInt64(), b.GetUint64()) d.SetUint64(r) return d, errors.Trace(err1) } case types.KindUint64: switch b.Kind() { case types.KindInt64: r, err1 := types.SubUintWithInt(a.GetUint64(), b.GetInt64()) d.SetUint64(r) return d, errors.Trace(err1) case types.KindUint64: r, err1 := types.SubUint64(a.GetUint64(), b.GetUint64()) d.SetUint64(r) return d, errors.Trace(err1) } case types.KindFloat64: switch b.Kind() { case types.KindFloat64: r := a.GetFloat64() - b.GetFloat64() d.SetFloat64(r) return d, nil } case types.KindMysqlDecimal: switch b.Kind() { case types.KindMysqlDecimal: r := a.GetMysqlDecimal().Sub(b.GetMysqlDecimal()) d.SetMysqlDecimal(r) return d, nil } } _, err = types.InvOp2(a.GetValue(), b.GetValue(), opcode.Minus) return d, errors.Trace(err) }
func (b *executorBuilder) datumToPBExpr(client kv.Client, d types.Datum) *tipb.Expr { var tp tipb.ExprType var val []byte switch d.Kind() { case types.KindNull: tp = tipb.ExprType_Null case types.KindInt64: tp = tipb.ExprType_Int64 val = codec.EncodeInt(nil, d.GetInt64()) case types.KindUint64: tp = tipb.ExprType_Uint64 val = codec.EncodeUint(nil, d.GetUint64()) case types.KindString: tp = tipb.ExprType_String val = d.GetBytes() case types.KindBytes: tp = tipb.ExprType_Bytes val = d.GetBytes() case types.KindFloat32: tp = tipb.ExprType_Float32 val = codec.EncodeFloat(nil, d.GetFloat64()) case types.KindFloat64: tp = tipb.ExprType_Float64 val = codec.EncodeFloat(nil, d.GetFloat64()) case types.KindMysqlDuration: tp = tipb.ExprType_MysqlDuration val = codec.EncodeInt(nil, int64(d.GetMysqlDuration().Duration)) case types.KindMysqlDecimal: tp = tipb.ExprType_MysqlDecimal val = codec.EncodeDecimal(nil, d.GetMysqlDecimal()) default: return nil } if !client.SupportRequestType(kv.ReqTypeSelect, int64(tp)) { return nil } return &tipb.Expr{Tp: tp.Enum(), Val: val} }
func computeMod(a, b types.Datum) (d types.Datum, err error) { switch a.Kind() { case types.KindInt64: x := a.GetInt64() switch b.Kind() { case types.KindInt64: y := b.GetInt64() if y == 0 { return d, nil } d.SetInt64(x % y) return d, nil case types.KindUint64: y := b.GetUint64() if y == 0 { return d, nil } else if x < 0 { d.SetInt64(-int64(uint64(-x) % y)) // first is int64, return int64. return d, nil } d.SetInt64(int64(uint64(x) % y)) return d, nil } case types.KindUint64: x := a.GetUint64() switch b.Kind() { case types.KindInt64: y := b.GetInt64() if y == 0 { return d, nil } else if y < 0 { // first is uint64, return uint64. d.SetUint64(uint64(x % uint64(-y))) return d, nil } d.SetUint64(x % uint64(y)) return d, nil case types.KindUint64: y := b.GetUint64() if y == 0 { return d, nil } d.SetUint64(x % y) return d, nil } case types.KindFloat64: x := a.GetFloat64() switch b.Kind() { case types.KindFloat64: y := b.GetFloat64() if y == 0 { return d, nil } d.SetFloat64(math.Mod(x, y)) return d, nil } case types.KindMysqlDecimal: x := a.GetMysqlDecimal() switch b.Kind() { case types.KindMysqlDecimal: y := b.GetMysqlDecimal() xf, _ := x.Float64() yf, _ := y.Float64() if yf == 0 { return d, nil } d.SetFloat64(math.Mod(xf, yf)) return d, nil } } _, err = types.InvOp2(a.GetValue(), b.GetValue(), opcode.Mod) return d, errors.Trace(err) }
// unflatten converts a raw datum to a column datum. func unflatten(datum types.Datum, ft *types.FieldType) (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 err := t.Unmarshal(datum.GetBytes()) 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 }