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:
@ -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) {
|
||||
|
||||
@ -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))
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
35
util/types/errors.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user