diff options
author | Jimmy Yang <jimmy.yang@oracle.com> | 2010-05-25 22:31:27 -0700 |
---|---|---|
committer | Jimmy Yang <jimmy.yang@oracle.com> | 2010-05-25 22:31:27 -0700 |
commit | 602bb5c0fe0fa9f2df6425efe566d3e11452da69 (patch) | |
tree | 7c3a6f7bd1d87f6b175b8ac8bd4c756e57d1d7b6 /storage | |
parent | f230391cbb64c8aea19cee0c111d8890fe63ae04 (diff) | |
download | mariadb-git-602bb5c0fe0fa9f2df6425efe566d3e11452da69.tar.gz |
Fix Bug #53592 in plugin code, "crash replacing duplicates into table
after fast alter table added unique key". Look up MySQL index number should
go through index translation table.
rb://347, approved by Marko
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innodb_plugin/handler/ha_innodb.cc | 67 | ||||
-rw-r--r-- | storage/innodb_plugin/include/row0mysql.h | 9 | ||||
-rw-r--r-- | storage/innodb_plugin/row/row0mysql.c | 31 | ||||
-rwxr-xr-x | storage/innodb_plugin/setup.sh | 2 |
4 files changed, 65 insertions, 44 deletions
diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index bd0618b7424..f753e2d1cbd 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -6673,7 +6673,7 @@ ha_innobase::create( (int) form->s->primary_key : -1); - /* Our function row_get_mysql_key_number_for_index assumes + /* Our function innobase_get_mysql_key_number_for_index assumes the primary key is always number 0, if it exists */ ut_a(primary_key_no == -1 || primary_key_no == 0); @@ -7390,6 +7390,67 @@ ha_innobase::read_time( } /*********************************************************************//** +Calculates the key number used inside MySQL for an Innobase index. We will +first check the "index translation table" for a match of the index to get +the index number. If there does not exist an "index translation table", +or not able to find the index in the translation table, then we will fall back +to the traditional way of looping through dict_index_t list to find a +match. In this case, we have to take into account if we generated a +default clustered index for the table +@return the key number used inside MySQL */ +static +unsigned int +innobase_get_mysql_key_number_for_index( +/*====================================*/ + INNOBASE_SHARE* share, /*!< in: share structure for index + translation table. */ + const TABLE* table, /*!< in: table in MySQL data + dictionary */ + dict_table_t* ib_table,/*!< in: table in Innodb data + dictionary */ + const dict_index_t* index) /*!< in: index */ +{ + const dict_index_t* ind; + unsigned int i; + + ut_ad(index); + ut_ad(ib_table); + ut_ad(table); + ut_ad(share); + + /* If index translation table exists, we will first check + the index through index translation table for a match. */ + if (share->idx_trans_tbl.index_mapping) { + for (i = 0; i < share->idx_trans_tbl.index_count; i++) { + if (share->idx_trans_tbl.index_mapping[i] == index) { + return(i); + } + } + + /* Print an error message if we cannot find the index + ** in the "index translation table". */ + sql_print_error("Cannot find index %s in InnoDB index " + "translation table.", index->name); + } + + /* If we do not have an "index translation table", or not able + to find the index in the translation table, we'll directly find + matching index in the dict_index_t list */ + for (i = 0; i < table->s->keys; i++) { + ind = dict_table_get_index_on_name( + ib_table, table->key_info[i].name); + + if (index == ind) { + return(i); + } + } + + sql_print_error("Cannot find matching index number for index %s " + "in InnoDB index list.", index->name); + + return(0); +} +/*********************************************************************//** Returns statistics information of the table to the MySQL interpreter, in various fields of the handle object. */ UNIV_INTERN @@ -7658,8 +7719,8 @@ ha_innobase::info( err_index = trx_get_error_info(prebuilt->trx); if (err_index) { - errkey = (unsigned int) - row_get_mysql_key_number_for_index(err_index); + errkey = innobase_get_mysql_key_number_for_index( + share, table, ib_table, err_index); } else { errkey = (unsigned int) prebuilt->trx->error_key_num; } diff --git a/storage/innodb_plugin/include/row0mysql.h b/storage/innodb_plugin/include/row0mysql.h index bf9cda1ba80..e90742abe7c 100644 --- a/storage/innodb_plugin/include/row0mysql.h +++ b/storage/innodb_plugin/include/row0mysql.h @@ -253,15 +253,6 @@ row_table_got_default_clust_index( /*==============================*/ const dict_table_t* table); /*!< in: table */ /*********************************************************************//** -Calculates the key number used inside MySQL for an Innobase index. We have -to take into account if we generated a default clustered index for the table -@return the key number used inside MySQL */ -UNIV_INTERN -ulint -row_get_mysql_key_number_for_index( -/*===============================*/ - const dict_index_t* index); /*!< in: index */ -/*********************************************************************//** Does an update or delete of a row for MySQL. @return error code or DB_SUCCESS */ UNIV_INTERN diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index a98dd8d2900..8d47d0f25fc 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -1646,37 +1646,6 @@ row_table_got_default_clust_index( } /*********************************************************************//** -Calculates the key number used inside MySQL for an Innobase index. We have -to take into account if we generated a default clustered index for the table -@return the key number used inside MySQL */ -UNIV_INTERN -ulint -row_get_mysql_key_number_for_index( -/*===============================*/ - const dict_index_t* index) /*!< in: index */ -{ - const dict_index_t* ind; - ulint i; - - ut_a(index); - - i = 0; - ind = dict_table_get_first_index(index->table); - - while (index != ind) { - ind = dict_table_get_next_index(ind); - i++; - } - - if (row_table_got_default_clust_index(index->table)) { - ut_a(i > 0); - i--; - } - - return(i); -} - -/*********************************************************************//** Locks the data dictionary in shared mode from modifications, for performing foreign key check, rollback, or other operation invisible to MySQL. */ UNIV_INTERN diff --git a/storage/innodb_plugin/setup.sh b/storage/innodb_plugin/setup.sh index 23fe729a406..b5d8299d411 100755 --- a/storage/innodb_plugin/setup.sh +++ b/storage/innodb_plugin/setup.sh @@ -21,7 +21,7 @@ set -eu -TARGETDIR=../storage/innobase +TARGETDIR=../storage/innodb_plugin # link the build scripts BUILDSCRIPTS="compile-innodb compile-innodb-debug" |