Skip to content

Commit

Permalink
ddl: add the reason for the unsupported modify column error. (pingcap…
Browse files Browse the repository at this point in the history
  • Loading branch information
coocood authored Apr 18, 2017
1 parent aa9a97a commit 5434d80
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 30 deletions.
25 changes: 15 additions & 10 deletions ddl/column_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -903,21 +903,26 @@ func (s *testColumnSuite) TestModifyColumn(c *C) {
cases := []struct {
origin string
to string
ok bool
err error
}{
{"int", "bigint", true},
{"int", "int unsigned", false},
{"varchar(10)", "text", true},
{"varbinary(10)", "blob", true},
{"text", "blob", false},
{"varchar(10)", "varchar(8)", false},
{"varchar(10)", "varchar(11)", true},
{"varchar(10) character set utf8 collate utf8_bin", "varchar(10) character set utf8", true},
{"int", "bigint", nil},
{"int", "int unsigned", errUnsupportedModifyColumn.GenByArgs("unsigned true not match origin false")},
{"varchar(10)", "text", nil},
{"varbinary(10)", "blob", nil},
{"text", "blob", errUnsupportedModifyColumn.GenByArgs("charset binary not match origin utf8")},
{"varchar(10)", "varchar(8)", errUnsupportedModifyColumn.GenByArgs("length 8 is less than origin 10")},
{"varchar(10)", "varchar(11)", nil},
{"varchar(10) character set utf8 collate utf8_bin", "varchar(10) character set utf8", nil},
}
for _, ca := range cases {
ftA := s.colDefStrToFieldType(c, ca.origin)
ftB := s.colDefStrToFieldType(c, ca.to)
c.Assert(modifiable(ftA, ftB), Equals, ca.ok)
err := modifiable(ftA, ftB)
if err == nil {
c.Assert(ca.err, IsNil)
} else {
c.Assert(err.Error(), Equals, ca.err.Error())
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion ddl/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ var (
// We don't support dropping column with index covered now.
errCantDropColWithIndex = terror.ClassDDL.New(codeCantDropColWithIndex, "can't drop column with index")
errUnsupportedAddColumn = terror.ClassDDL.New(codeUnsupportedAddColumn, "unsupported add column")
errUnsupportedModifyColumn = terror.ClassDDL.New(codeUnsupportedModifyColumn, "unsupported modify column")
errUnsupportedModifyColumn = terror.ClassDDL.New(codeUnsupportedModifyColumn, "unsupported modify column %s")
errUnsupportedPKHandle = terror.ClassDDL.New(codeUnsupportedDropPKHandle,
"unsupported drop integer primary key")

Expand Down
45 changes: 26 additions & 19 deletions ddl/ddl_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -896,43 +896,49 @@ func (d *ddl) DropColumn(ctx context.Context, ti ast.Ident, colName model.CIStr)
// change or check existing data in the table.
// It returns true if the two types has the same Charset and Collation, the same sign, both are
// integer types or string types, and new Flen and Decimal must be greater than or equal to origin.
func modifiable(origin *types.FieldType, to *types.FieldType) bool {
func modifiable(origin *types.FieldType, to *types.FieldType) error {
if to.Flen > 0 && to.Flen < origin.Flen {
return false
msg := fmt.Sprintf("length %d is less than origin %d", to.Flen, origin.Flen)
return errUnsupportedModifyColumn.GenByArgs(msg)
}
if to.Decimal > 0 && to.Decimal < origin.Decimal {
return false
msg := fmt.Sprintf("decimal %d is less than origin %d", to.Decimal, origin.Decimal)
return errUnsupportedModifyColumn.GenByArgs(msg)
}
if origin.Charset != to.Charset || origin.Collate != to.Collate {
return false
if to.Charset != origin.Charset {
msg := fmt.Sprintf("charset %s not match origin %s", to.Charset, origin.Charset)
return errUnsupportedModifyColumn.GenByArgs(msg)
}
if mysql.HasUnsignedFlag(uint(origin.Flag)) != mysql.HasUnsignedFlag(uint(to.Flag)) {
return false
if to.Collate != origin.Collate {
msg := fmt.Sprintf("collate %s not match origin %s", to.Collate, origin.Collate)
return errUnsupportedModifyColumn.GenByArgs(msg)
}
toUnsigned := mysql.HasUnsignedFlag(uint(to.Flag))
originUnsigned := mysql.HasUnsignedFlag(uint(origin.Flag))
if originUnsigned != toUnsigned {
msg := fmt.Sprintf("unsigned %v not match origin %v", toUnsigned, originUnsigned)
return errUnsupportedModifyColumn.GenByArgs(msg)
}
switch origin.Tp {
case mysql.TypeVarchar, mysql.TypeString, mysql.TypeVarString,
mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob:
switch to.Tp {
case mysql.TypeVarchar, mysql.TypeString, mysql.TypeVarString,
mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob:
return true
default:
return false
return nil
}
case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong:
switch to.Tp {
case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong:
return true
default:
return false
return nil
}
default:
if origin.Tp == to.Tp {
return true
return nil
}

return false
}
msg := fmt.Sprintf("type %v not match orgin %v", to.Tp, origin.Tp)
return errUnsupportedModifyColumn.GenByArgs(msg)
}

func setDefaultValue(ctx context.Context, col *table.Column, option *ast.ColumnOption) error {
Expand Down Expand Up @@ -1029,15 +1035,16 @@ func (d *ddl) getModifiableColumnJob(ctx context.Context, ident ast.Ident, origi
FieldType: *spec.NewColumn.Tp,
}
setCharsetCollationFlenDecimal(&newCol.FieldType)
if !modifiable(&col.FieldType, &newCol.FieldType) {
return nil, errors.Trace(errUnsupportedModifyColumn)
err = modifiable(&col.FieldType, &newCol.FieldType)
if err != nil {
return nil, errors.Trace(err)
}
if err := setDefaultAndComment(ctx, newCol, spec.NewColumn.Options); err != nil {
return nil, errors.Trace(err)
}
// We don't support modifying the type definitions from 'null' to 'not null' now.
if !mysql.HasNotNullFlag(col.Flag) && mysql.HasNotNullFlag(newCol.Flag) {
return nil, errors.Trace(errUnsupportedModifyColumn)
return nil, errUnsupportedModifyColumn.GenByArgs("null to not null")
}

newCol.Name = spec.NewColumn.Name.Name
Expand Down

0 comments on commit 5434d80

Please sign in to comment.