diff --git a/server/util.go b/server/util.go index 3ecd3d617df9f..c7a2ac069e467 100644 --- a/server/util.go +++ b/server/util.go @@ -207,14 +207,22 @@ func dumpBinaryDateTime(data []byte, t types.Time) []byte { year, mon, day := t.Year(), t.Month(), t.Day() switch t.Type() { case mysql.TypeTimestamp, mysql.TypeDatetime: - data = append(data, 11) - data = dumpUint16(data, uint16(year)) - data = append(data, byte(mon), byte(day), byte(t.Hour()), byte(t.Minute()), byte(t.Second())) - data = dumpUint32(data, uint32(t.Microsecond())) + if t.IsZero() { + data = append(data, 0) + } else { + data = append(data, 11) + data = dumpUint16(data, uint16(year)) + data = append(data, byte(mon), byte(day), byte(t.Hour()), byte(t.Minute()), byte(t.Second())) + data = dumpUint32(data, uint32(t.Microsecond())) + } case mysql.TypeDate: - data = append(data, 4) - data = dumpUint16(data, uint16(year)) //year - data = append(data, byte(mon), byte(day)) + if t.IsZero() { + data = append(data, 0) + } else { + data = append(data, 4) + data = dumpUint16(data, uint16(year)) //year + data = append(data, byte(mon), byte(day)) + } } return data } diff --git a/server/util_test.go b/server/util_test.go index 884f7e0ad03c8..1417bf2e3f089 100644 --- a/server/util_test.go +++ b/server/util_test.go @@ -22,6 +22,7 @@ import ( "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/session" + "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/store/mockstore" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/types/json" @@ -63,26 +64,44 @@ func (s *testUtilSuite) TearDownSuite(c *C) { } func (s *testUtilSuite) TestDumpBinaryTime(c *C) { - t, err := types.ParseTimestamp(nil, "0000-00-00 00:00:00.0000000") + t, err := types.ParseTimestamp(nil, "0000-00-00 00:00:00.000000") c.Assert(err, IsNil) d := dumpBinaryDateTime(nil, t) - c.Assert(d, DeepEquals, []byte{11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) - t, err = types.ParseDatetime(nil, "0000-00-00 00:00:00.0000000") + c.Assert(d, DeepEquals, []byte{0}) + + t, err = types.ParseTimestamp(&stmtctx.StatementContext{TimeZone: time.Local}, "1991-05-01 01:01:01.100001") + c.Assert(err, IsNil) + d = dumpBinaryDateTime(nil, t) + // 199 & 7 composed to uint16 1991 (litter-endian) + // 160 & 134 & 1 & 0 composed to uint32 1000001 (litter-endian) + c.Assert(d, DeepEquals, []byte{11, 199, 7, 5, 1, 1, 1, 1, 161, 134, 1, 0}) + + t, err = types.ParseDatetime(nil, "0000-00-00 00:00:00.000000") + c.Assert(err, IsNil) + d = dumpBinaryDateTime(nil, t) + c.Assert(d, DeepEquals, []byte{0}) + t, err = types.ParseDatetime(nil, "1993-07-13 01:01:01.000000") c.Assert(err, IsNil) d = dumpBinaryDateTime(nil, t) - c.Assert(d, DeepEquals, []byte{11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) + // 201 & 7 composed to uint16 1993 (litter-endian) + c.Assert(d, DeepEquals, []byte{11, 201, 7, 7, 13, 1, 1, 1, 0, 0, 0, 0}) t, err = types.ParseDate(nil, "0000-00-00") c.Assert(err, IsNil) d = dumpBinaryDateTime(nil, t) - c.Assert(d, DeepEquals, []byte{4, 0, 0, 0, 0}) + c.Assert(d, DeepEquals, []byte{0}) + t, err = types.ParseDate(nil, "1992-06-01") + c.Assert(err, IsNil) + d = dumpBinaryDateTime(nil, t) + // 200 & 7 composed to uint16 1992 (litter-endian) + c.Assert(d, DeepEquals, []byte{4, 200, 7, 6, 1}) t, err = types.ParseDate(nil, "0000-00-00") c.Assert(err, IsNil) d = dumpBinaryDateTime(nil, t) - c.Assert(d, DeepEquals, []byte{4, 0, 0, 0, 0}) + c.Assert(d, DeepEquals, []byte{0}) - myDuration, err := types.ParseDuration(nil, "0000-00-00 00:00:00.0000000", 6) + myDuration, err := types.ParseDuration(nil, "0000-00-00 00:00:00.000000", 6) c.Assert(err, IsNil) d = dumpBinaryTime(myDuration.Duration) c.Assert(d, DeepEquals, []byte{0})