summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorJimmy Yang <jimmy.yang@oracle.com>2010-05-25 22:31:27 -0700
committerJimmy Yang <jimmy.yang@oracle.com>2010-05-25 22:31:27 -0700
commit602bb5c0fe0fa9f2df6425efe566d3e11452da69 (patch)
tree7c3a6f7bd1d87f6b175b8ac8bd4c756e57d1d7b6 /storage
parentf230391cbb64c8aea19cee0c111d8890fe63ae04 (diff)
downloadmariadb-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.cc67
-rw-r--r--storage/innodb_plugin/include/row0mysql.h9
-rw-r--r--storage/innodb_plugin/row/row0mysql.c31
-rwxr-xr-xstorage/innodb_plugin/setup.sh2
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"