From dbe4b2f2ff62a5f374db5e6a8ae4553d22dcb8b0 Mon Sep 17 00:00:00 2001 From: marko Date: Thu, 27 Aug 2009 10:56:24 +0000 Subject: [PATCH] branches/zip: dict_index_find_cols(): On column name lookup failure, return DB_CORRUPTION (HA_ERR_CRASHED) instead of abnormally terminating the server. Also, disable the previously added diagnostic output to the error log, because mysql-test-run does not like extra output in the error log. (Bug #44571) dict_index_add_to_cache(): Handle errors from dict_index_find_cols(). mysql-test/innodb_bug44571.test: A test case for triggering the bug. rb://135 approved by Sunny Bains. --- ChangeLog | 6 ++++++ dict/dict0dict.c | 23 ++++++++++++++++------- include/dict0dict.h | 2 +- mysql-test/innodb_bug44571.result | 9 +++++++++ mysql-test/innodb_bug44571.test | 17 +++++++++++++++++ 5 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 mysql-test/innodb_bug44571.result create mode 100644 mysql-test/innodb_bug44571.test diff --git a/ChangeLog b/ChangeLog index b2352b55eeb..8cec8eb465b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-08-27 The InnoDB Team + + * dict/dict0dict.c, include/dict0dict.h, + mysql-test/innodb_bug44571.result, mysql-test/innodb_bug44571.test: + Fix Bug#44571 InnoDB Plugin crashes on ADD INDEX + 2009-08-27 The InnoDB Team * row/row0merge.c: diff --git a/dict/dict0dict.c b/dict/dict0dict.c index d1f0e0ffc19..a8ee593e35c 100644 --- a/dict/dict0dict.c +++ b/dict/dict0dict.c @@ -82,9 +82,10 @@ static char dict_ibfk[] = "_ibfk_"; /*******************************************************************//** Tries to find column names for the index and sets the col field of the -index. */ +index. +@return TRUE if the column names were found */ static -void +ibool dict_index_find_cols( /*=================*/ dict_table_t* table, /*!< in: table */ @@ -1431,7 +1432,7 @@ add_field_size: /**********************************************************************//** Adds an index to the dictionary cache. -@return DB_SUCCESS or DB_TOO_BIG_RECORD */ +@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */ UNIV_INTERN ulint dict_index_add_to_cache( @@ -1457,7 +1458,10 @@ dict_index_add_to_cache( ut_a(!dict_index_is_clust(index) || UT_LIST_GET_LEN(table->indexes) == 0); - dict_index_find_cols(table, index); + if (!dict_index_find_cols(table, index)) { + + return(DB_CORRUPTION); + } /* Build the cache internal representation of the index, containing also the added system fields */ @@ -1665,9 +1669,10 @@ dict_index_remove_from_cache( /*******************************************************************//** Tries to find column names for the index and sets the col field of the -index. */ +index. +@return TRUE if the column names were found */ static -void +ibool dict_index_find_cols( /*=================*/ dict_table_t* table, /*!< in: table */ @@ -1692,17 +1697,21 @@ dict_index_find_cols( } } +#ifdef UNIV_DEBUG /* It is an error not to find a matching column. */ fputs("InnoDB: Error: no matching column for ", stderr); ut_print_name(stderr, NULL, FALSE, field->name); fputs(" in ", stderr); dict_index_name_print(stderr, NULL, index); fputs("!\n", stderr); - ut_error; +#endif /* UNIV_DEBUG */ + return(FALSE); found: ; } + + return(TRUE); } #endif /* !UNIV_HOTBACKUP */ diff --git a/include/dict0dict.h b/include/dict0dict.h index b2029699e51..d425241a3a2 100644 --- a/include/dict0dict.h +++ b/include/dict0dict.h @@ -712,7 +712,7 @@ dict_index_find_on_id_low( dulint id); /*!< in: index id */ /**********************************************************************//** Adds an index to the dictionary cache. -@return DB_SUCCESS or error code */ +@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */ UNIV_INTERN ulint dict_index_add_to_cache( diff --git a/mysql-test/innodb_bug44571.result b/mysql-test/innodb_bug44571.result new file mode 100644 index 00000000000..36374edcb3e --- /dev/null +++ b/mysql-test/innodb_bug44571.result @@ -0,0 +1,9 @@ +CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB; +ALTER TABLE bug44571 CHANGE foo bar INT; +ALTER TABLE bug44571 ADD INDEX bug44571b (foo); +ERROR 42000: Key column 'foo' doesn't exist in table +ALTER TABLE bug44571 ADD INDEX bug44571b (bar); +ERROR HY000: Incorrect key file for table 'bug44571'; try to repair it +CREATE INDEX bug44571b ON bug44571 (bar); +ERROR HY000: Incorrect key file for table 'bug44571'; try to repair it +DROP TABLE bug44571; diff --git a/mysql-test/innodb_bug44571.test b/mysql-test/innodb_bug44571.test new file mode 100644 index 00000000000..685463ceff9 --- /dev/null +++ b/mysql-test/innodb_bug44571.test @@ -0,0 +1,17 @@ +# +# Bug#44571 InnoDB Plugin crashes on ADD INDEX +# http://bugs.mysql.com/44571 +# +-- source include/have_innodb.inc + +CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB; +ALTER TABLE bug44571 CHANGE foo bar INT; +-- error ER_KEY_COLUMN_DOES_NOT_EXITS +ALTER TABLE bug44571 ADD INDEX bug44571b (foo); +# The following will fail, because the CHANGE foo bar was +# not communicated to InnoDB. +--error ER_NOT_KEYFILE +ALTER TABLE bug44571 ADD INDEX bug44571b (bar); +--error ER_NOT_KEYFILE +CREATE INDEX bug44571b ON bug44571 (bar); +DROP TABLE bug44571;