diff --git a/executor/executor_write_test.go b/executor/executor_write_test.go index 094a7c7122..996bf0989d 100644 --- a/executor/executor_write_test.go +++ b/executor/executor_write_test.go @@ -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) { diff --git a/terror/terror.go b/terror/terror.go index aa80fdfa65..24ef348191 100644 --- a/terror/terror.go +++ b/terror/terror.go @@ -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)) } diff --git a/util/types/convert_test.go b/util/types/convert_test.go index dbe4879ce1..25559a3999 100644 --- a/util/types/convert_test.go +++ b/util/types/convert_test.go @@ -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 diff --git a/util/types/datum.go b/util/types/datum.go index f4633dc43a..eaeee6aa2b 100644 --- a/util/types/datum.go +++ b/util/types/datum.go @@ -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) { diff --git a/util/types/errors.go b/util/types/errors.go new file mode 100644 index 0000000000..9d97ae08c5 --- /dev/null +++ b/util/types/errors.go @@ -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 +}