Skip to content

Commit

Permalink
ddl: check foreign key constraint when drop,modify,change column (pin…
Browse files Browse the repository at this point in the history
  • Loading branch information
crazycs520 committed Dec 20, 2019
1 parent 98a0ce6 commit 06f4dd3
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 1 deletion.
10 changes: 10 additions & 0 deletions ddl/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,16 @@ func isColumnWithIndex(colName string, indices []*model.IndexInfo) bool {
}
return false
}
func getColumnForeignKeyInfo(colName string, fkInfos []*model.FKInfo) *model.FKInfo {
for _, fkInfo := range fkInfos {
for _, col := range fkInfo.Cols {
if col.L == colName {
return fkInfo
}
}
}
return nil
}

func allocateColumnID(tblInfo *model.TableInfo) int64 {
tblInfo.MaxColumnID++
Expand Down
15 changes: 14 additions & 1 deletion ddl/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2173,7 +2173,20 @@ func (s *testDBSuite) TestTableForeignKey(c *C) {
s.tk.MustExec("create table t3 (a int, b int);")
failSQL = "alter table t1 add foreign key (c) REFERENCES t3(a);"
s.testErrorCode(c, failSQL, tmysql.ErrKeyColumnDoesNotExits)
s.tk.MustExec("drop table if exists t1,t2,t3;")
// Test drop column with foreign key.
s.tk.MustExec("create table t4 (c int,d int,foreign key (d) references t1 (b));")
failSQL = "alter table t4 drop column d"
s.testErrorCode(c, failSQL, mysql.ErrFkColumnCannotDrop)
// Test change column with foreign key.
failSQL = "alter table t4 change column d e bigint;"
s.testErrorCode(c, failSQL, mysql.ErrFKIncompatibleColumns)
// Test modify column with foreign key.
failSQL = "alter table t4 modify column d bigint;"
s.testErrorCode(c, failSQL, mysql.ErrFKIncompatibleColumns)
s.tk.MustQuery("select count(*) from information_schema.KEY_COLUMN_USAGE;")
s.tk.MustExec("alter table t4 drop foreign key d")
s.tk.MustExec("alter table t4 modify column d bigint;")
s.tk.MustExec("drop table if exists t1,t2,t3,t4;")
}

func (s *testDBSuite) TestBitDefaultValue(c *C) {
Expand Down
6 changes: 6 additions & 0 deletions ddl/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ var (
errTooManyFields = terror.ClassDDL.New(codeTooManyFields, "Too many columns")
errInvalidSplitRegionRanges = terror.ClassDDL.New(codeInvalidRanges, "Failed to split region ranges")
errReorgPanic = terror.ClassDDL.New(codeReorgWorkerPanic, "reorg worker panic.")
errFkColumnCannotDrop = terror.ClassDDL.New(codeFkColumnCannotDrop, mysql.MySQLErrName[mysql.ErrFkColumnCannotDrop])
errReferencedForeignKey = terror.ClassDDL.New(codeFKIncompatibleColumns, mysql.MySQLErrName[mysql.ErrFKIncompatibleColumns])

// errWrongKeyColumn is for table column cannot be indexed.
errWrongKeyColumn = terror.ClassDDL.New(codeWrongKeyColumn, mysql.MySQLErrName[mysql.ErrWrongKeyColumn])
Expand Down Expand Up @@ -662,6 +664,8 @@ const (
codePrimaryCantHaveNull = terror.ErrCode(mysql.ErrPrimaryCantHaveNull)
codeWrongExprInPartitionFunc = terror.ErrCode(mysql.ErrWrongExprInPartitionFunc)
codeUnknownPartition = terror.ErrCode(mysql.ErrUnknownPartition)
codeFkColumnCannotDrop = terror.ErrCode(mysql.ErrFkColumnCannotDrop)
codeFKIncompatibleColumns = terror.ErrCode(mysql.ErrFKIncompatibleColumns)
)

func init() {
Expand Down Expand Up @@ -715,6 +719,8 @@ func init() {
codeUnknownCollation: mysql.ErrUnknownCollation,
codeCollationCharsetMismatch: mysql.ErrCollationCharsetMismatch,
codeConflictingDeclarations: mysql.ErrConflictingDeclarations,
codeFkColumnCannotDrop: mysql.ErrFkColumnCannotDrop,
codeFKIncompatibleColumns: mysql.ErrFKIncompatibleColumns,
}
terror.ErrClassToMySQLCodes[terror.ClassDDL] = ddlMySQLErrCodes
}
9 changes: 9 additions & 0 deletions ddl/ddl_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2080,6 +2080,11 @@ func (d *ddl) getModifiableColumnJob(ctx sessionctx.Context, ident ast.Ident, or
}
}

// Check the column with foreign key.
if fkInfo := getColumnForeignKeyInfo(originalColName.L, t.Meta().ForeignKeys); fkInfo != nil {
return nil, errReferencedForeignKey.GenWithStackByArgs(originalColName, fkInfo.Name)
}

// Constraints in the new column means adding new constraints. Errors should thrown,
// which will be done by `setDefaultAndComment` later.
if specNewColumn.Tp == nil {
Expand Down Expand Up @@ -2729,6 +2734,10 @@ func isDroppableColumn(tblInfo *model.TableInfo, colName model.CIStr) error {
if isColumnWithIndex(colName.L, tblInfo.Indices) {
return errCantDropColWithIndex.GenWithStack("can't drop column %s with index covered now", colName)
}
// Check the column with foreign key.
if fkInfo := getColumnForeignKeyInfo(colName.L, tblInfo.ForeignKeys); fkInfo != nil {
return errFkColumnCannotDrop.GenWithStackByArgs(colName, fkInfo.Name)
}
return nil
}

Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,5 @@ require (
)

go 1.13

replace github.com/pingcap/parser => github.com/crazycs520/parser v0.0.0-20191218034320-6d74113a3eb1
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ github.com/coreos/go-systemd v0.0.0-20180202092358-40e2722dffea h1:IHPWgevPcOUjT
github.com/coreos/go-systemd v0.0.0-20180202092358-40e2722dffea/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf h1:CAKfRE2YtTUIjjh1bkBtyYFaUT/WmOqsJjgtihT0vMI=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/crazycs520/parser v0.0.0-20191218034320-6d74113a3eb1 h1:niBvQ4RxusaR9Kzfl5LjcpaL57/ViBb9ywElZN0MjDE=
github.com/crazycs520/parser v0.0.0-20191218034320-6d74113a3eb1/go.mod h1:xLjI+gnWYexq011WPMEvCNS8rFM9qe1vdojIEzSKPuc=
github.com/cznic/mathutil v0.0.0-20160613104831-78ad7f262603 h1:hhR9hTi0ligs11JjfGDBP332clNOJRdW0Ci5oHtEC+0=
github.com/cznic/mathutil v0.0.0-20160613104831-78ad7f262603/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65 h1:hxuZop6tSoOi0sxFzoGGYdRqNrPubyaIf9KoBG9tPiE=
Expand Down

0 comments on commit 06f4dd3

Please sign in to comment.