From 955a412a1285ea03e29a64afca2e3a68c4bf13fb Mon Sep 17 00:00:00 2001 From: Tanner Date: Tue, 23 Jul 2019 15:13:24 +0800 Subject: [PATCH] ddl: disallow dropping index on auto_increment column (#11360) --- ddl/db_integration_test.go | 18 ++++++++++++++++++ ddl/ddl_api.go | 10 +++++++++- meta/autoid/errors.go | 2 ++ planner/core/preprocess.go | 3 ++- planner/core/preprocess_test.go | 6 +++--- 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/ddl/db_integration_test.go b/ddl/db_integration_test.go index 05be31f16d3f4..9becf4b72152f 100644 --- a/ddl/db_integration_test.go +++ b/ddl/db_integration_test.go @@ -426,6 +426,8 @@ func (s *testIntegrationSuite5) TestMySQLErrorCode(c *C) { assertErrorCode(c, tk, sql, tmysql.ErrPrimaryCantHaveNull) sql = "create table t2 (id int null, age int, primary key(id));" assertErrorCode(c, tk, sql, tmysql.ErrPrimaryCantHaveNull) + sql = "create table t2 (id int auto_increment);" + assertErrorCode(c, tk, sql, tmysql.ErrWrongAutoKey) sql = "create table t2 (id int primary key , age int);" tk.MustExec(sql) @@ -1815,3 +1817,19 @@ func (s *testIntegrationSuite11) TestChangingDBCharset(c *C) { tk.MustExec("ALTER SCHEMA CHARACTER SET = 'utf8mb4' COLLATE = 'utf8mb4_general_ci'") verifyDBCharsetAndCollate("alterdb2", "utf8mb4", "utf8mb4_general_ci") } + +func (s *testIntegrationSuite4) TestDropAutoIncrementIndex(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("create database if not exists test") + tk.MustExec("use test") + + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1 (a int auto_increment, unique key (a))") + dropIndexSQL := "alter table t1 drop index a" + assertErrorCode(c, tk, dropIndexSQL, mysql.ErrWrongAutoKey) + + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1 (a int(11) not null auto_increment, b int(11), c bigint, unique key (a, b, c))") + dropIndexSQL = "alter table t1 drop index a" + assertErrorCode(c, tk, dropIndexSQL, mysql.ErrWrongAutoKey) +} diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 890d1a721a29c..91a94aadcb8f3 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -3127,10 +3127,18 @@ func (d *ddl) DropIndex(ctx sessionctx.Context, ti ast.Ident, indexName model.CI return errors.Trace(infoschema.ErrTableNotExists.GenWithStackByArgs(ti.Schema, ti.Name)) } - if indexInfo := t.Meta().FindIndexByName(indexName.L); indexInfo == nil { + indexInfo := t.Meta().FindIndexByName(indexName.L) + if indexInfo == nil { return ErrCantDropFieldOrKey.GenWithStack("index %s doesn't exist", indexName) } + cols := t.Cols() + for _, idxCol := range indexInfo.Columns { + if mysql.HasAutoIncrementFlag(cols[idxCol.Offset].Flag) { + return autoid.ErrWrongAutoKey + } + } + job := &model.Job{ SchemaID: schema.ID, TableID: t.Meta().ID, diff --git a/meta/autoid/errors.go b/meta/autoid/errors.go index 44ef83650a202..e9b0b0fa6fae4 100644 --- a/meta/autoid/errors.go +++ b/meta/autoid/errors.go @@ -21,12 +21,14 @@ import ( // Error instances. var ( ErrAutoincReadFailed = terror.ClassAutoid.New(mysql.ErrAutoincReadFailed, mysql.MySQLErrName[mysql.ErrAutoincReadFailed]) + ErrWrongAutoKey = terror.ClassAutoid.New(mysql.ErrWrongAutoKey, mysql.MySQLErrName[mysql.ErrWrongAutoKey]) ) func init() { // Map error codes to mysql error codes. tableMySQLErrCodes := map[terror.ErrCode]uint16{ mysql.ErrAutoincReadFailed: mysql.ErrAutoincReadFailed, + mysql.ErrWrongAutoKey: mysql.ErrWrongAutoKey, } terror.ErrClassToMySQLCodes[terror.ClassAutoid] = tableMySQLErrCodes } diff --git a/planner/core/preprocess.go b/planner/core/preprocess.go index 770ba6f683e5a..d902ffba1f8e3 100644 --- a/planner/core/preprocess.go +++ b/planner/core/preprocess.go @@ -26,6 +26,7 @@ import ( "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/infoschema" + "github.com/pingcap/tidb/meta/autoid" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/types/parser_driver" @@ -295,7 +296,7 @@ func (p *preprocessor) checkAutoIncrement(stmt *ast.CreateTableStmt) { } } if (autoIncrementMustBeKey && !isKey) || count > 1 { - p.err = errors.New("Incorrect table definition; there can be only one auto column and it must be defined as a key") + p.err = autoid.ErrWrongAutoKey.GenWithStackByArgs() } switch autoIncrementCol.Tp.Tp { diff --git a/planner/core/preprocess_test.go b/planner/core/preprocess_test.go index 31fb17cf7f38f..818849959ed75 100644 --- a/planner/core/preprocess_test.go +++ b/planner/core/preprocess_test.go @@ -53,11 +53,11 @@ func (s *testValidatorSuite) TestValidator(c *C) { {"create table t(id int auto_increment default null, primary key (id))", true, nil}, {"create table t(id int default null auto_increment, primary key (id))", true, nil}, {"create table t(id int not null auto_increment)", true, - errors.New("Incorrect table definition; there can be only one auto column and it must be defined as a key")}, + errors.New("[autoid:1075]Incorrect table definition; there can be only one auto column and it must be defined as a key")}, {"create table t(id int not null auto_increment, c int auto_increment, key (id, c))", true, - errors.New("Incorrect table definition; there can be only one auto column and it must be defined as a key")}, + errors.New("[autoid:1075]Incorrect table definition; there can be only one auto column and it must be defined as a key")}, {"create table t(id int not null auto_increment, c int, key (c, id))", true, - errors.New("Incorrect table definition; there can be only one auto column and it must be defined as a key")}, + errors.New("[autoid:1075]Incorrect table definition; there can be only one auto column and it must be defined as a key")}, {"create table t(id decimal auto_increment, key (id))", true, errors.New("Incorrect column specifier for column 'id'")}, {"create table t(id float auto_increment, key (id))", true, nil},