Skip to content

Commit

Permalink
tablecodec,mysql, util: mysql TypeDuration Fsp (pingcap#3499)
Browse files Browse the repository at this point in the history
Fixed RoundError issue pingcap#3471
Bug Cause:
1. when deserialize mysqlDuration, the Fsp is setted with 0 instead of the Fsp from column information.
2. the default decimal for column with TypeDuration is 0.
  • Loading branch information
dreamquster authored and tiancaiamao committed Jun 20, 2017
1 parent 4b4378f commit 913037e
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 11 deletions.
10 changes: 8 additions & 2 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,12 @@ func (s *testSuite) TestBuiltin(c *C) {
result.Check(testkit.Rows("11:11:11"))
result = tk.MustQuery("select * from t where a > cast(2 as decimal)")
result.Check(testkit.Rows("3 2"))
// fixed issue #3471
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a time(6));")
tk.MustExec("insert into t value('12:59:59.999999')")
result = tk.MustQuery("select cast(a as signed) from t")
result.Check(testkit.Rows("130000"))

// test unhex and hex
result = tk.MustQuery("select unhex('4D7953514C')")
Expand Down Expand Up @@ -1176,9 +1182,9 @@ func (s *testSuite) TestDatumXAPI(c *C) {
tk.MustExec("insert t values ('11:11:12', '11:11:12')")
tk.MustExec("insert t values ('11:11:13', '11:11:13')")
result = tk.MustQuery("select * from t where a > '11:11:11.5'")
result.Check(testkit.Rows("11:11:12 11:11:12", "11:11:13 11:11:13"))
result.Check(testkit.Rows("11:11:12.000 11:11:12", "11:11:13.000 11:11:13"))
result = tk.MustQuery("select * from t where b > '11:11:11.5'")
result.Check(testkit.Rows("11:11:12 11:11:12", "11:11:13 11:11:13"))
result.Check(testkit.Rows("11:11:12.000 11:11:12", "11:11:13.000 11:11:13"))
}

func (s *testSuite) TestSQLMode(c *C) {
Expand Down
2 changes: 1 addition & 1 deletion mysql/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func GetDefaultDecimal(tp byte) int {
case TypeNewDecimal:
// See https://dev.mysql.com/doc/refman/5.7/en/fixed-point-types.html
return 0
case TypeDatetime:
case TypeDatetime, TypeDuration:
return 0
default:
//TODO: Add more types.
Expand Down
4 changes: 2 additions & 2 deletions tablecodec/tablecodec.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,8 +421,8 @@ func unflatten(datum types.Datum, ft *types.FieldType, loc *time.Location) (type
}
datum.SetMysqlTime(t)
return datum, nil
case mysql.TypeDuration:
dur := types.Duration{Duration: time.Duration(datum.GetInt64())}
case mysql.TypeDuration: //duration should read fsp from column meta data
dur := types.Duration{Duration: time.Duration(datum.GetInt64()), Fsp: ft.Decimal}
datum.SetValue(dur)
return datum, nil
case mysql.TypeEnum:
Expand Down
16 changes: 11 additions & 5 deletions tablecodec/tablecodec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,16 +143,22 @@ func (s *testTableCodecSuite) TestTimeCodec(c *C) {
c1 := &column{id: 1, tp: types.NewFieldType(mysql.TypeLonglong)}
c2 := &column{id: 2, tp: types.NewFieldType(mysql.TypeVarchar)}
c3 := &column{id: 3, tp: types.NewFieldType(mysql.TypeTimestamp)}
cols := []*column{c1, c2, c3}
c4 := &column{id: 4, tp: types.NewFieldType(mysql.TypeDuration)}
cols := []*column{c1, c2, c3, c4}
colLen := len(cols)

row := make([]types.Datum, 3)
row := make([]types.Datum, colLen)
row[0] = types.NewIntDatum(100)
row[1] = types.NewBytesDatum([]byte("abc"))
ts, err := types.ParseTimestamp("2016-06-23 11:30:45")
c.Assert(err, IsNil)
row[2] = types.NewDatum(ts)
du, err := types.ParseDuration("12:59:59.999999", 6)
c.Assert(err, IsNil)
row[3] = types.NewDatum(du)

// Encode
colIDs := make([]int64, 0, 3)
colIDs := make([]int64, 0, colLen)
for _, col := range cols {
colIDs = append(colIDs, col.id)
}
Expand All @@ -161,14 +167,14 @@ func (s *testTableCodecSuite) TestTimeCodec(c *C) {
c.Assert(bs, NotNil)

// Decode
colMap := make(map[int64]*types.FieldType, 3)
colMap := make(map[int64]*types.FieldType, colLen)
for _, col := range cols {
colMap[col.id] = col.tp
}
r, err := DecodeRow(bs, colMap, time.Local)
c.Assert(err, IsNil)
c.Assert(r, NotNil)
c.Assert(r, HasLen, 3)
c.Assert(r, HasLen, colLen)
sc := new(variable.StatementContext)
// Compare decoded row and original row
for i, col := range cols {
Expand Down
2 changes: 1 addition & 1 deletion util/types/field_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func (ft *FieldType) CompactStr() string {
es = append(es, e)
}
suffix = fmt.Sprintf("('%s')", strings.Join(es, "','"))
case mysql.TypeTimestamp, mysql.TypeDatetime, mysql.TypeDate:
case mysql.TypeTimestamp, mysql.TypeDatetime, mysql.TypeDate, mysql.TypeDuration:
if ft.Decimal != UnspecifiedLength && ft.Decimal != 0 {
suffix = fmt.Sprintf("(%d)", ft.Decimal)
}
Expand Down

0 comments on commit 913037e

Please sign in to comment.