List:Commits« Previous MessageNext Message »
From:Satya B Date:October 5 2009 1:09pm
Subject:bzr commit into mysql-5.1-bugteam branch (satya.bn:3155) Bug#46000
View as plain text  
#At file:///home/satya/WORK/mysql/mysql-5.1-pe-stage/ based on
revid:joro@stripped

 3155 Satya B	2009-10-05
      Applying InnoDB snapshot 5.1-ss5921, Part 1. Fixes BUG#46000
      
      1. BUG#46000 - using index called GEN_CLUST_INDEX crashes server
      
      Detailed revision comments:
      
      r5895 | jyang | 2009-09-15 03:39:21 +0300 (Tue, 15 Sep 2009) | 5 lines
      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 Marko Makela.

    added:
      mysql-test/r/innodb_bug46000.result
      mysql-test/t/innodb_bug46000.test
    modified:
      mysql-test/lib/mtr_cases.pm
      storage/innobase/handler/ha_innodb.cc
=== modified file 'mysql-test/lib/mtr_cases.pm'
--- a/mysql-test/lib/mtr_cases.pm	2009-09-29 14:11:46 +0000
+++ b/mysql-test/lib/mtr_cases.pm	2009-10-05 11:09:07 +0000
@@ -507,6 +507,8 @@ sub collect_one_suite($)
       next if ($test->{'name'} eq 'sys_vars.innodb_lock_wait_timeout_basic');
       # Diff around innodb_thread_concurrency variable
       next if ($test->{'name'} eq 'sys_vars.innodb_thread_concurrency_basic');
+      # Disable for Innodb Plugin until the fix for Plugin is received
+      next if ($test->{'name'} eq 'main.innodb_bug46000');
       # Copy test options
       my $new_test= My::Test->new();
       while (my ($key, $value) = each(%$test))

=== added file 'mysql-test/r/innodb_bug46000.result'
--- a/mysql-test/r/innodb_bug46000.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/innodb_bug46000.result	2009-10-05 11:09:07 +0000
@@ -0,0 +1,17 @@
+create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb;
+ERROR HY000: Can't create table 'test.bug46000' (errno: -1)
+create table bug46000(`id` int, key `GEN_clust_INDEX`(`id`))engine=innodb;
+ERROR HY000: Can't create table 'test.bug46000' (errno: -1)
+show errors;
+Level	Code	Message
+Error	1005	Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the
system default primary index.
+Error	1005	Can't create table 'test.bug46000' (errno: -1)
+create table bug46000(id int) engine=innodb;
+create index GEN_CLUST_INDEX on bug46000(id);
+ERROR HY000: Can't create table '#sql-temporary' (errno: -1)
+show errors;
+Level	Code	Message
+Error	1005	Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the
system default primary index.
+Error	1005	Can't create table '#sql-temporary' (errno: -1)
+create index idx on bug46000(id);
+drop table bug46000;

=== added file 'mysql-test/t/innodb_bug46000.test'
--- a/mysql-test/t/innodb_bug46000.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/innodb_bug46000.test	2009-10-05 11:09:07 +0000
@@ -0,0 +1,34 @@
+# 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
+
+# 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);
+
+--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
+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;

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc	2009-09-17 06:29:43 +0000
+++ b/storage/innobase/handler/ha_innodb.cc	2009-10-05 11:09:07 +0000
@@ -155,17 +155,36 @@ static void free_share(INNOBASE_SHARE *s
 static int innobase_close_connection(handlerton *hton, THD* thd);
 static int innobase_commit(handlerton *hton, THD* thd, bool all);
 static int innobase_rollback(handlerton *hton, THD* thd, bool all);
-static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd, 
+static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
            void *savepoint);
 static int innobase_savepoint(handlerton *hton, THD* thd, void *savepoint);
-static int innobase_release_savepoint(handlerton *hton, THD* thd, 
+static int innobase_release_savepoint(handlerton *hton, THD* thd,
            void *savepoint);
 static handler *innobase_create_handler(handlerton *hton,
                                         TABLE_SHARE *table,
                                         MEM_ROOT *mem_root);
 
+/***********************************************************************
+This function checks each index name for a table against reserved
+system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
+this function pushes an error message to the client, and returns true. */
+static
+bool
+innobase_index_name_is_reserved(
+/*============================*/
+					/* out: true if index name matches a
+					reserved name */
+	const trx_t*	trx,		/* in: InnoDB transaction handle */
+	const TABLE*	form,		/* in: information on table
+					columns and indexes */
+	const char*	norm_name);	/* in: table name */
+
 static const char innobase_hton_name[]= "InnoDB";
 
+/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
+system primary index. */
+static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX";
+
 /** @brief Initialize the default value of innodb_commit_concurrency.
 
 Once InnoDB is running, the innodb_commit_concurrency must not change
@@ -5199,6 +5218,9 @@ create_index(
 
 	n_fields = key->key_parts;
 
+	/* Assert that "GEN_CLUST_INDEX" cannot be used as non-primary index */
+	ut_a(innobase_strcasecmp(key->name, innobase_index_reserve_name) != 0);
+
 	ind_type = 0;
 
 	if (key_num == form->s->primary_key) {
@@ -5311,8 +5333,8 @@ 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_index_reserve_name,
 				      0, DICT_CLUSTERED, 0);
 	error = row_create_index_for_mysql(index, trx, NULL);
 
@@ -5444,14 +5466,6 @@ ha_innobase::create(
 		flags |= DICT_TF_COMPACT;
 	}
 
-	error = create_table_def(trx, form, norm_name,
-		create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
-		flags);
-
-	if (error) {
-		goto cleanup;
-	}
-
 	/* Look for a primary key */
 
 	primary_key_no= (form->s->primary_key != MAX_KEY ?
@@ -5463,6 +5477,22 @@ ha_innobase::create(
 
 	DBUG_ASSERT(primary_key_no == -1 || primary_key_no == 0);
 
+	/* Check for name conflicts (with reserved name) for
+	any user indices to be created. */
+	if (innobase_index_name_is_reserved(trx, form, norm_name)) {
+		error = -1;
+		goto cleanup;
+	}
+
+	error = create_table_def(trx, form, norm_name,
+		create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
+		flags);
+
+	if (error) {
+		goto cleanup;
+	}
+
+
 	/* Create the keys */
 
 	if (form->s->keys == 0 || primary_key_no == -1) {
@@ -8409,6 +8439,46 @@ static int show_innodb_vars(THD *thd, SH
   return 0;
 }
 
+/***********************************************************************
+This function checks each index name for a table against reserved
+system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
+this function pushes an error message to the client, and returns true. */
+static
+bool
+innobase_index_name_is_reserved(
+/*============================*/
+					/* out: true if an index name
+					matches the reserved name */
+	const trx_t*	trx,		/* in: InnoDB transaction handle */
+	const TABLE*	form,		/* in: information on table
+					columns and indexes */
+	const char*	norm_name)	/* in: table name */
+{
+	KEY*		key;
+	uint		key_num;	/* index number */
+
+	for (key_num = 0; key_num < form->s->keys; key_num++) {
+		key = form->key_info + key_num;
+
+		if (innobase_strcasecmp(key->name,
+					innobase_index_reserve_name) == 0) {
+			/* Push warning to mysql */
+			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_index_reserve_name);
+
+			return(true);
+		}
+	}
+
+	return(false);
+}
+
 static SHOW_VAR innodb_status_variables_export[]= {
   {"Innodb",                   (char*) &show_innodb_vars, SHOW_FUNC},
   {NullS, NullS, SHOW_LONG}


Attachment: [text/bzr-bundle] bzr/satya.bn@sun.com-20091005110907-sg1hb1ja1lm6ryf2.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (satya.bn:3155) Bug#46000Satya B5 Oct 2009