From 09ced1197ddade06e9ab8dbf37f394746c44f67a Mon Sep 17 00:00:00 2001 From: jyang Date: Thu, 3 Sep 2009 02:33:47 +0000 Subject: [PATCH] branches/5.1: Disallow creating index with the name of "GEN_CLUST_INDEX" which is reserved for the default system primary index. (Bug #46000) rb://149 approved by Sunny Bains. --- handler/ha_innodb.cc | 25 ++++++++++++++++++++- include/db0err.h | 3 +++ mysql-test/innodb_bug46000.result | 18 ++++++++++++++++ mysql-test/innodb_bug46000.test | 36 +++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 mysql-test/innodb_bug46000.result create mode 100644 mysql-test/innodb_bug46000.test diff --git a/handler/ha_innodb.cc b/handler/ha_innodb.cc index b9dbeb7045d..e8714e88cd7 100644 --- a/handler/ha_innodb.cc +++ b/handler/ha_innodb.cc @@ -165,6 +165,7 @@ static handler *innobase_create_handler(handlerton *hton, MEM_ROOT *mem_root); static const char innobase_hton_name[]= "InnoDB"; +static const char innobase_idx_reserve_name[]= "GEN_CLUST_INDEX"; /** @brief Initialize the default value of innodb_commit_concurrency. @@ -5114,6 +5115,22 @@ create_index( n_fields = key->key_parts; + /* Do not allow creating index with the name of "GEN_CLUST_INDEX", + which is the name reserved for default primary index created by + innodb. Innodb does not support indices with duplicated name. */ + if (innobase_strcasecmp(key->name, innobase_idx_reserve_name) == 0) { + push_warning_printf( + (THD *)trx->mysql_thd, + MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_CANT_CREATE_TABLE, + "Cannot Create Index with name " + "'%s'. The name is reserved " + "for the system default primary index.", + innobase_idx_reserve_name); + + DBUG_RETURN(DB_RESERVED_NAME); + } + ind_type = 0; if (key_num == form->s->primary_key) { @@ -5227,7 +5244,7 @@ create_clustered_index_when_no_primary( /* We pass 0 as the space id, and determine at a lower level the space id where to store the table */ - index = dict_mem_index_create(table_name, "GEN_CLUST_INDEX", + index = dict_mem_index_create(table_name, innobase_idx_reserve_name, 0, DICT_CLUSTERED, 0); error = row_create_index_for_mysql(index, trx, NULL); @@ -5472,6 +5489,12 @@ ha_innobase::create( DBUG_RETURN(0); cleanup: + /* Fail to create index with name conflicting with system + reserved names. Drop the (temp) table before return. */ + if (error == DB_RESERVED_NAME) { + row_drop_table_for_mysql(norm_name, trx, 0); + } + innobase_commit_low(trx); row_mysql_unlock_data_dictionary(trx); diff --git a/include/db0err.h b/include/db0err.h index ed7ce151718..c13c7394a2e 100644 --- a/include/db0err.h +++ b/include/db0err.h @@ -69,6 +69,9 @@ Created 5/24/1996 Heikki Tuuri a feature that it can't recoginize or work with e.g., FT indexes created by a later version of the engine. */ +#define DB_RESERVED_NAME 49 /* Name used is conflicting with an + internal System Reserved Name. */ + /* The following are partial failure codes */ #define DB_FAIL 1000 #define DB_OVERFLOW 1001 diff --git a/mysql-test/innodb_bug46000.result b/mysql-test/innodb_bug46000.result new file mode 100644 index 00000000000..22cd75b88af --- /dev/null +++ b/mysql-test/innodb_bug46000.result @@ -0,0 +1,18 @@ +SET storage_engine=InnoDB; +create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb; +ERROR HY000: Can't create table 'test.bug46000' (errno: 49) +create table bug46000(`id` int,key `GEN_clust_INDEX`(`id`))engine=innodb; +ERROR HY000: Can't create table 'test.bug46000' (errno: 49) +show errors; +Level Code Message +Error 1005 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for system default primary index. +Error 1005 Can't create table 'test.bug46000' (errno: 49) +create table bug46000(id int) engine = innodb; +create index GEN_CLUST_INDEX on bug46000(id); +ERROR HY000: Can't create table '#sql-temporary' (errno: 49) +show errors; +Level Code Message +Error 1005 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for system default primary index. +Error 1005 Can't create table 'test.#sql-2cb4_2' (errno: 49) +create index idx on bug46000(id); +drop table bug46000; diff --git a/mysql-test/innodb_bug46000.test b/mysql-test/innodb_bug46000.test new file mode 100644 index 00000000000..aa66222d95c --- /dev/null +++ b/mysql-test/innodb_bug46000.test @@ -0,0 +1,36 @@ +# This is the test for bug 46000. We shall +# block any index creation with the name of +# "GEN_CLUST_INDEX", which is the reserved +# name for innodb default primary index. + +--source include/have_innodb.inc + +SET storage_engine=InnoDB; + + +# This 'create table' operation should fail because of +# using the reserve name as its index name. +--error ER_CANT_CREATE_TABLE +create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb; + +# Mixed upper/lower case of the reserved key words +--error ER_CANT_CREATE_TABLE +create table bug46000(`id` int,key `GEN_clust_INDEX`(`id`))engine=innodb; + +show errors; + +create table bug46000(id int) engine = innodb; + +# This 'create index' operation should fail. +--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +create index GEN_CLUST_INDEX on bug46000(id); + +show errors; + +# This 'create index' operation should succeed, no +# temp table left from last failed create index +# operation. +create index idx on bug46000(id); + +drop table bug46000;