Skip to content

Commit

Permalink
modify different character sets varchar type column maximum length limit
Browse files Browse the repository at this point in the history
  • Loading branch information
ciscoxll committed Jan 3, 2019
1 parent 235d04c commit 25f9ee4
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 12 deletions.
17 changes: 17 additions & 0 deletions ddl/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1945,6 +1945,23 @@ func (s *testDBSuite) TestColumnModifyingDefinition(c *C) {
s.testErrorCode(c, "alter table test2 change c1 a1 bigint not null;", tmysql.WarnDataTruncated)
}

func (s *testDBSuite) TestCheckTooBigFieldLength(c *C) {
s.tk = testkit.NewTestKit(c, s.store)
s.tk.MustExec("use test")
s.tk.MustExec("drop table if exists tr_01;")
s.tk.MustExec("create table tr_01 (id int, name varchar(20000), purchased date ) default charset=utf8 collate=utf8_bin;")

s.tk.MustExec("drop table if exists tr_02;")
s.tk.MustExec("create table tr_02 (id int, name varchar(16000), purchased date ) default charset=utf8mb4 collate=utf8mb4_bin;")

s.tk.MustExec("drop table if exists tr_03;")
s.tk.MustExec("create table tr_03 (id int, name varchar(65534), purchased date ) default charset=latin1;")

s.testErrorCode(c, "create table tr (id int, name varchar(30000), purchased date ) default charset=utf8 collate=utf8_bin;", tmysql.ErrTooBigFieldlength)
s.testErrorCode(c, "create table tr (id int, name varchar(20000) charset utf8mb4, purchased date ) default charset=utf8 collate=utf8;", tmysql.ErrTooBigFieldlength)
s.testErrorCode(c, "create table tr (id int, name varchar(65536), purchased date ) default charset=latin1;", tmysql.ErrTooBigFieldlength)
}

func (s *testDBSuite) TestModifyColumnRollBack(c *C) {
s.tk = testkit.NewTestKit(c, s.store)
s.mustExec(c, "use test_db")
Expand Down
44 changes: 44 additions & 0 deletions ddl/ddl_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,41 @@ func checkColumnsAttributes(colDefs []*ast.ColumnDef) error {
return nil
}

// checkColumnFieldLength check the maximum length limit for different character set varchar type columns.
func checkColumnFieldLength(schema *model.DBInfo, colDefs []*ast.ColumnDef, tbInfo *model.TableInfo) error {
for _, colDef := range colDefs {
if colDef.Tp.Tp == mysql.TypeVarchar {
var setCharset string
setCharset = mysql.DefaultCharset
if len(schema.Charset) != 0 {
setCharset = schema.Charset
}
if len(tbInfo.Charset) != 0 {
setCharset = tbInfo.Charset
}

err := IsTooBigFieldLength(colDef, setCharset)
if err != nil {
return errors.Trace(err)
}
}
}
return nil
}

func IsTooBigFieldLength(colDef *ast.ColumnDef, setCharset string) error {
desc, err := charset.GetCharsetDesc(setCharset)
if err != nil {
return errors.Trace(err)
}
maxFlen := mysql.MaxFieldVarCharLength
maxFlen /= desc.Maxlen
if colDef.Tp.Flen != types.UnspecifiedLength && colDef.Tp.Flen > maxFlen {
return types.ErrTooBigFieldLength.GenWithStack("Column length too big for column '%s' (max = %d); use BLOB or TEXT instead", colDef.Name.Name.O, maxFlen)
}
return errors.Trace(err)
}

// checkColumnAttributes check attributes for single column.
func checkColumnAttributes(colName string, tp *types.FieldType) error {
switch tp.Tp {
Expand Down Expand Up @@ -1007,6 +1042,10 @@ func (d *ddl) CreateTable(ctx sessionctx.Context, s *ast.CreateTableStmt) (err e
if err != nil {
return errors.Trace(err)
}
if err = checkColumnFieldLength(schema, s.Cols, tbInfo); err != nil {
return errors.Trace(err)
}

err = d.doDDLJob(ctx, job)
if err == nil {
if tbInfo.AutoIncID > 1 {
Expand Down Expand Up @@ -1982,6 +2021,11 @@ func (d *ddl) getModifiableColumnJob(ctx sessionctx.Context, ident ast.Ident, or
// `modifyColumnTp` indicates that there is a type modification.
modifyColumnTp = mysql.TypeNull
}

if err = checkColumnFieldLength(schema, spec.NewColumns, t.Meta()); err != nil {
return nil, errors.Trace(err)
}

// As same with MySQL, we don't support modifying the stored status for generated columns.
if err = checkModifyGeneratedColumn(t.Cols(), col, newCol); err != nil {
return nil, errors.Trace(err)
Expand Down
17 changes: 5 additions & 12 deletions planner/core/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"github.com/pingcap/errors"
"github.com/pingcap/parser"
"github.com/pingcap/parser/ast"
"github.com/pingcap/parser/charset"
"github.com/pingcap/parser/model"
"github.com/pingcap/parser/mysql"
"github.com/pingcap/tidb/ddl"
Expand Down Expand Up @@ -489,22 +488,16 @@ func checkColumn(colDef *ast.ColumnDef) error {
return types.ErrTooBigFieldLength.GenWithStack("Column length too big for column '%s' (max = %d); use BLOB or TEXT instead", colDef.Name.Name.O, mysql.MaxFieldCharLength)
}
case mysql.TypeVarchar:
maxFlen := mysql.MaxFieldVarCharLength
cs := tp.Charset
// TODO: TableDefaultCharset-->DatabaseDefaultCharset-->SystemDefaultCharset.
// TODO: Change TableOption parser to parse collate.
// Reference https://github.com/pingcap/tidb/blob/b091e828cfa1d506b014345fb8337e424a4ab905/ddl/ddl_api.go#L185-L204
// Here logical move backend processing, need to get all levels of character set to set the character set of column.
// It's not easy to get the schema charset and table charset here.
// ColumnDefaultCharset --> TableDefaultCharset-->DatabaseDefaultCharset-->SystemDefaultCharset.
if len(tp.Charset) == 0 {
cs = mysql.DefaultCharset
return nil
}
desc, err := charset.GetCharsetDesc(cs)
err := ddl.IsTooBigFieldLength(colDef, tp.Charset)
if err != nil {
return errors.Trace(err)
}
maxFlen /= desc.Maxlen
if tp.Flen != types.UnspecifiedLength && tp.Flen > maxFlen {
return types.ErrTooBigFieldLength.GenWithStack("Column length too big for column '%s' (max = %d); use BLOB or TEXT instead", colDef.Name.Name.O, maxFlen)
}
case mysql.TypeFloat, mysql.TypeDouble:
if tp.Decimal > mysql.MaxFloatingTypeScale {
return types.ErrTooBigScale.GenWithStackByArgs(tp.Decimal, colDef.Name.Name.O, mysql.MaxFloatingTypeScale)
Expand Down

0 comments on commit 25f9ee4

Please sign in to comment.