Commit f22c429a authored by jyang's avatar jyang

branches/zip: Add index translation table to map mysql index

number to InnoDB index structure directly. Fix Bug #47622:
"the new index is added before the existing ones in MySQL,
but after one in SE".

rb://215, approved by Marko
parent 4f3d9229
This diff is collapsed.
...@@ -27,6 +27,18 @@ Place, Suite 330, Boston, MA 02111-1307 USA ...@@ -27,6 +27,18 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#pragma interface /* gcc class implementation */ #pragma interface /* gcc class implementation */
#endif #endif
/* Structure defines translation table between mysql index and innodb
index structures */
typedef struct innodb_idx_translate_struct {
ulint index_count; /*!< number of valid index entries
in the index_mapping array */
ulint array_size; /*!< array size of index_mapping */
dict_index_t** index_mapping; /*!< index pointer array directly
maps to index in Innodb from MySQL
array index */
} innodb_idx_translate_t;
/** InnoDB table share */ /** InnoDB table share */
typedef struct st_innobase_share { typedef struct st_innobase_share {
THR_LOCK lock; /*!< MySQL lock protecting THR_LOCK lock; /*!< MySQL lock protecting
...@@ -34,8 +46,12 @@ typedef struct st_innobase_share { ...@@ -34,8 +46,12 @@ typedef struct st_innobase_share {
const char* table_name; /*!< InnoDB table name */ const char* table_name; /*!< InnoDB table name */
uint use_count; /*!< reference count, uint use_count; /*!< reference count,
incremented in get_share() incremented in get_share()
and decremented in free_share() */ and decremented in
free_share() */
void* table_name_hash;/*!< hash table chain node */ void* table_name_hash;/*!< hash table chain node */
innodb_idx_translate_t idx_trans_tbl; /*!< index translation
table between MySQL and
Innodb */
} INNOBASE_SHARE; } INNOBASE_SHARE;
......
...@@ -764,6 +764,10 @@ err_exit: ...@@ -764,6 +764,10 @@ err_exit:
ut_ad(error == DB_SUCCESS); ut_ad(error == DB_SUCCESS);
/* We will need to rebuild index translation table. Set
valid index entry count in the translation table to zero */
share->idx_trans_tbl.index_count = 0;
/* Commit the data dictionary transaction in order to release /* Commit the data dictionary transaction in order to release
the table locks on the system tables. This means that if the table locks on the system tables. This means that if
MySQL crashes while creating a new primary key inside MySQL crashes while creating a new primary key inside
...@@ -1198,6 +1202,10 @@ ha_innobase::final_drop_index( ...@@ -1198,6 +1202,10 @@ ha_innobase::final_drop_index(
ut_a(!index->to_be_dropped); ut_a(!index->to_be_dropped);
} }
/* We will need to rebuild index translation table. Set
valid index entry count in the translation table to zero */
share->idx_trans_tbl.index_count = 0;
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
dict_table_check_for_dup_indexes(prebuilt->table); dict_table_check_for_dup_indexes(prebuilt->table);
#endif #endif
......
CREATE TABLE bug47622(
`rule_key` int(11) NOT NULL DEFAULT '0',
`seq` smallint(6) NOT NULL DEFAULT '0',
`action` smallint(6) NOT NULL DEFAULT '0',
`arg_id` smallint(6) DEFAULT NULL,
`else_ind` TINYINT NOT NULL,
KEY IDX_A (`arg_id`)
) ENGINE=InnoDB;
ALTER TABLE bug47622 ADD UNIQUE IDX_B (rule_key,else_ind,seq,action,arg_id);
drop index IDX_B on bug47622;
create index idx on bug47622(seq, arg_id);
ALTER TABLE bug47622 ADD UNIQUE IDX_X (rule_key,else_ind,seq,action);
drop table bug47622;
CREATE TABLE bug47622 (
`a` int(11) NOT NULL,
`b` int(11) DEFAULT NULL,
`c` char(10) DEFAULT NULL,
`d` varchar(20) DEFAULT NULL,
PRIMARY KEY (`a`),
KEY `b` (`b`)
) ENGINE=InnoDB;
alter table bug47622 add unique index (c), add index (d);
drop table bug47622;
# This is the test for bug 47622. There could be index
# metadata sequence mismatch between MySQL and Innodb
# after creating index through FIC interfaces.
# We resolve the problem by sync the index sequence
# up when opening the table.
--source include/have_innodb.inc
connect (a,localhost,root,,);
connect (b,localhost,root,,);
# Create a table with a non-unique index
CREATE TABLE bug47622(
`rule_key` int(11) NOT NULL DEFAULT '0',
`seq` smallint(6) NOT NULL DEFAULT '0',
`action` smallint(6) NOT NULL DEFAULT '0',
`arg_id` smallint(6) DEFAULT NULL,
`else_ind` TINYINT NOT NULL,
KEY IDX_A (`arg_id`)
) ENGINE=InnoDB;
connection a;
# A subsequent creating unique index should not trigger
# any error message. Unique index would be ranked ahead
# of regular index.
ALTER TABLE bug47622 ADD UNIQUE IDX_B (rule_key,else_ind,seq,action,arg_id);
drop index IDX_B on bug47622;
# In another connection, create additional set of normal
# index and unique index. Again, unique index would be ranked
# ahead of regular index.
connection b;
create index idx on bug47622(seq, arg_id);
ALTER TABLE bug47622 ADD UNIQUE IDX_X (rule_key,else_ind,seq,action);
drop table bug47622;
# Create a table with one Primary key and a non-unique key
CREATE TABLE bug47622 (
`a` int(11) NOT NULL,
`b` int(11) DEFAULT NULL,
`c` char(10) DEFAULT NULL,
`d` varchar(20) DEFAULT NULL,
PRIMARY KEY (`a`),
KEY `b` (`b`)
) ENGINE=InnoDB;
# Add two index with one unique and one non-unique.
# Index sequence is "PRIMARY", "c", "b" and "d"
alter table bug47622 add unique index (c), add index (d);
drop table bug47622;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment