From 829383127c0b44da36508a525776afd03261eb6c Mon Sep 17 00:00:00 2001 From: crazycs Date: Wed, 17 Oct 2018 20:21:10 +0800 Subject: [PATCH] ddl: add check when create table with foreign key. (#7885) * ddl: add check when create table with foreign key --- ddl/ddl.go | 4 ++-- ddl/ddl_api.go | 3 +++ ddl/ddl_db_test.go | 9 +++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ddl/ddl.go b/ddl/ddl.go index c11ed5f9b4365..61ddd49bf92c5 100644 --- a/ddl/ddl.go +++ b/ddl/ddl.go @@ -89,7 +89,7 @@ var ( errIncorrectPrefixKey = terror.ClassDDL.New(codeIncorrectPrefixKey, "Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys") errTooLongKey = terror.ClassDDL.New(codeTooLongKey, fmt.Sprintf("Specified key was too long; max key length is %d bytes", maxPrefixLength)) - errKeyColumnDoesNotExits = terror.ClassDDL.New(codeKeyColumnDoesNotExits, "this key column doesn't exist in table") + errKeyColumnDoesNotExits = terror.ClassDDL.New(codeKeyColumnDoesNotExits, mysql.MySQLErrName[mysql.ErrKeyColumnDoesNotExits]) errUnknownTypeLength = terror.ClassDDL.New(codeUnknownTypeLength, "Unknown length for type tp %d") errUnknownFractionLength = terror.ClassDDL.New(codeUnknownFractionLength, "Unknown Length for type tp %d and fraction %d") errInvalidJobVersion = terror.ClassDDL.New(codeInvalidJobVersion, "DDL job with version %d greater than current %d") @@ -541,7 +541,7 @@ const ( codeTooLongIdent = 1059 codeDupKeyName = 1061 codeTooLongKey = 1071 - codeKeyColumnDoesNotExits = 1072 + codeKeyColumnDoesNotExits = mysql.ErrKeyColumnDoesNotExits codeIncorrectPrefixKey = 1089 codeCantRemoveAllFields = 1090 codeCantDropFieldOrKey = 1091 diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 85f715161dd6a..5a9dfb1fb1a69 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -633,6 +633,9 @@ func buildTableInfo(ctx sessionctx.Context, d *ddl, tableName model.CIStr, cols fk.RefTable = constr.Refer.Table.Name fk.State = model.StatePublic for _, key := range constr.Keys { + if table.FindCol(cols, key.Column.Name.O) == nil { + return nil, errKeyColumnDoesNotExits.Gen("key column %s doesn't exist in table", key.Column.Name) + } fk.Cols = append(fk.Cols, key.Column.Name) } for _, key := range constr.Refer.IndexColNames { diff --git a/ddl/ddl_db_test.go b/ddl/ddl_db_test.go index 51b9d52da646d..d3cabcad097df 100644 --- a/ddl/ddl_db_test.go +++ b/ddl/ddl_db_test.go @@ -1443,6 +1443,15 @@ func (s *testDBSuite) TestCreateTable(c *C) { c.Assert(err, NotNil) } +func (s *testDBSuite) TestTableForeignKey(c *C) { + s.tk = testkit.NewTestKit(c, s.store) + s.tk.MustExec("use test") + s.tk.MustExec("create table t1 (a int, b int);") + failSQL := "create table t2 (c int, foreign key (a) references t1(a));" + s.testErrorCode(c, failSQL, tmysql.ErrKeyColumnDoesNotExits) + s.tk.MustExec("drop table if exists t1,t2;") +} + func (s *testDBSuite) TestCreateTableWithPartition(c *C) { s.tk.MustExec("use test") s.tk.MustExec(`CREATE TABLE tp (a int) PARTITION BY RANGE(a) (