types: returns data too long error (#1837)

* types: returns data too long error when inserting a string longer than field type length.
This commit is contained in:
Ewan Chou
2016-10-18 14:12:06 +08:00
committed by GitHub
parent 450b554c9f
commit 2df4a4f29b
5 changed files with 51 additions and 5 deletions

View File

@ -102,6 +102,10 @@ func (s *testSuite) TestInsert(c *C) {
_, err = tk.Exec(`insert into insert_test (id, c2) values(1, 1) on duplicate key update t.c2 = 10`)
c.Assert(err, NotNil)
tk.MustExec("create table insert_err (id int, c1 varchar(8))")
_, err = tk.Exec("insert insert_err values (1, 'abcdabcdabcd')")
c.Assert(types.ErrDataTooLong.Equal(err), IsTrue)
}
func (s *testSuite) TestInsertAutoInc(c *C) {

View File

@ -75,6 +75,7 @@ const (
ClassVariable
ClassXEval
ClassTable
ClassTypes
// Add more as needed.
)
@ -115,6 +116,8 @@ func (ec ErrClass) String() string {
return "variable"
case ClassTable:
return "table"
case ClassTypes:
return "types"
}
return strconv.Itoa(int(ec))
}

View File

@ -39,13 +39,13 @@ func (s *testTypeConvertSuite) TestConvertType(c *C) {
ft.Flen = 4
ft.Charset = "utf8"
v, err := Convert("123456", ft)
c.Assert(err, IsNil)
c.Assert(ErrDataTooLong.Equal(err), IsTrue)
c.Assert(v, Equals, "1234")
ft = NewFieldType(mysql.TypeString)
ft.Flen = 4
ft.Charset = charset.CharsetBin
v, err = Convert("12345", ft)
c.Assert(err, IsNil)
c.Assert(ErrDataTooLong.Equal(err), IsTrue)
c.Assert(v, DeepEquals, []byte("1234"))
ft = NewFieldType(mysql.TypeFloat)
@ -120,13 +120,13 @@ func (s *testTypeConvertSuite) TestConvertType(c *C) {
ft = NewFieldType(mysql.TypeString)
ft.Flen = 3
v, err = Convert("12345", ft)
c.Assert(err, IsNil)
c.Assert(ErrDataTooLong.Equal(err), IsTrue)
c.Assert(v, Equals, "123")
ft = NewFieldType(mysql.TypeString)
ft.Flen = 3
ft.Charset = charset.CharsetBin
v, err = Convert("12345", ft)
c.Assert(err, IsNil)
c.Assert(ErrDataTooLong.Equal(err), IsTrue)
c.Assert(v, DeepEquals, []byte("123"))
// For TypeDuration

View File

@ -762,12 +762,16 @@ func (d *Datum) convertToString(target *FieldType) (Datum, error) {
return invalidConv(d, target.Tp)
}
// TODO: consider target.Charset/Collate
var err error
if target.Flen > 0 && target.Flen < len(s) {
err = ErrDataTooLong.Gen("Data Too Long, field len %d, data len %d", target.Flen, len(s))
}
s = truncateStr(s, target.Flen)
ret.SetString(s)
if target.Charset == charset.CharsetBin {
ret.k = KindBytes
}
return ret, nil
return ret, errors.Trace(err)
}
func (d *Datum) convertToInt(target *FieldType) (Datum, error) {

35
util/types/errors.go Normal file
View File

@ -0,0 +1,35 @@
// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/terror"
)
var (
// ErrDataTooLong is returned when converts a string value that is longer than field type length.
ErrDataTooLong *terror.Error = terror.ClassTypes.New(codeDataTooLong, "Data Too Long")
)
const (
codeDataTooLong terror.ErrCode = terror.ErrCode(mysql.ErrDataTooLong)
)
func init() {
typesMySQLErrCodes := map[terror.ErrCode]uint16{
codeDataTooLong: mysql.ErrDataTooLong,
}
terror.ErrClassToMySQLCodes[terror.ClassTypes] = typesMySQLErrCodes
}