Skip to content

Commit 1394216

Browse files
committed
MDEV-21669 InnoDB: Table ... contains <n> indexes inside InnoDB, which is different from the number of indexes <n> defined in the MariaDB
compare_keys_but_name(): do not use KEY_PART_INFO::field for Field::is_equal(). Following the logic of that code we need to compare fields of a table. But KEY_PART_INFO::field sometimes (when key part is shorter than table field) is a different field. In that case Field::is_equal() returns incorrect result and problems occur. KEY_PART_INFO::field may become some strange field in open_frm_error open_table_from_share(). I think this is an incorrect logic, some tecnhical debt. I'm not fixing it right now, because I don't have time. But I'm making Field::field_length a const class member. Then, the only fishy code which changed that field requires now a const_cast<>. I'm bringing attention to that code with it. This change should not affect logic of the program in any way.
1 parent c5e00fe commit 1394216

File tree

5 files changed

+33
-5
lines changed

5 files changed

+33
-5
lines changed

mysql-test/suite/innodb/r/instant_alter_index_rename.result

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ select @a_key_returns_id = get_index_id(@table_id, 'a_key_returns'),
7474
@a_key_returns_id = get_index_id(@table_id, 'a_key_returns') @b_key_id = get_index_id(@table_id, 'b_key') @c_key_id = get_index_id(@table_id, 'c_key2') @primary_id = get_index_id(@table_id, 'primary')
7575
1 1 1 1
7676
drop table t;
77-
drop function get_index_id;
7877
create table errors (
7978
a int,
8079
unique key a_key (a),
@@ -183,3 +182,19 @@ CREATE TABLE t1 (f1 INT, f2 INT, f3 INT);
183182
ALTER TABLE t1 ADD FOREIGN KEY f (f2) REFERENCES xx(f2);
184183
ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t1(f2), ADD KEY (f3), ADD KEY (f1);
185184
DROP TABLE t1;
185+
#
186+
# MDEV-21669 InnoDB: Table ... contains <n> indexes inside InnoDB, which is different from the number of indexes <n> defined in the MariaDB
187+
#
188+
CREATE TABLE t1 (col_int INTEGER, col_char CHAR(20), col_varchar VARCHAR(500)) ENGINE=InnoDB;
189+
SET @table_id = (SELECT table_id FROM information_schema.innodb_sys_tables WHERE name='test/t1');
190+
ALTER TABLE t1 ADD KEY idx3 (col_varchar(9)), ADD KEY idX2 (col_char(9));
191+
SET @idx3_key_id = get_index_id(@table_id, 'iDx3');
192+
ALTER TABLE t1 DROP KEY iDx3, ADD KEY Idx3 (col_varchar(9));
193+
SELECT @idx3_key_id = get_index_id(@table_id, 'Idx3');
194+
@idx3_key_id = get_index_id(@table_id, 'Idx3')
195+
1
196+
CHECK TABLE t1 EXTENDED ;
197+
Table Op Msg_type Msg_text
198+
test.t1 check status OK
199+
DROP TABLE t1;
200+
DROP FUNCTION get_index_id;

mysql-test/suite/innodb/t/instant_alter_index_rename.test

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ select @a_key_returns_id = get_index_id(@table_id, 'a_key_returns'),
7373
@primary_id = get_index_id(@table_id, 'primary');
7474

7575
drop table t;
76-
drop function get_index_id;
7776

7877
create table errors (
7978
a int,
@@ -194,3 +193,17 @@ CREATE TABLE t1 (f1 INT, f2 INT, f3 INT);
194193
ALTER TABLE t1 ADD FOREIGN KEY f (f2) REFERENCES xx(f2);
195194
ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t1(f2), ADD KEY (f3), ADD KEY (f1);
196195
DROP TABLE t1;
196+
197+
--echo #
198+
--echo # MDEV-21669 InnoDB: Table ... contains <n> indexes inside InnoDB, which is different from the number of indexes <n> defined in the MariaDB
199+
--echo #
200+
CREATE TABLE t1 (col_int INTEGER, col_char CHAR(20), col_varchar VARCHAR(500)) ENGINE=InnoDB;
201+
SET @table_id = (SELECT table_id FROM information_schema.innodb_sys_tables WHERE name='test/t1');
202+
ALTER TABLE t1 ADD KEY idx3 (col_varchar(9)), ADD KEY idX2 (col_char(9));
203+
SET @idx3_key_id = get_index_id(@table_id, 'iDx3');
204+
ALTER TABLE t1 DROP KEY iDx3, ADD KEY Idx3 (col_varchar(9));
205+
SELECT @idx3_key_id = get_index_id(@table_id, 'Idx3');
206+
CHECK TABLE t1 EXTENDED ;
207+
DROP TABLE t1;
208+
209+
DROP FUNCTION get_index_id;

sql/field.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ class Field: public Value_source
694694
enum imagetype { itRAW, itMBR};
695695

696696
utype unireg_check;
697-
uint32 field_length;// Length of field
697+
const uint32 field_length;// Length of field
698698
uint32 flags;
699699
uint16 field_index; // field number in fields array
700700
uchar null_bit;// Bit used to test null bit

sql/sql_table.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6634,7 +6634,7 @@ Compare_keys compare_keys_but_name(const KEY *table_key, const KEY *new_key,
66346634
*/
66356635
const Field *old_field= table->field[key_part->fieldnr - 1];
66366636

6637-
bool is_equal= key_part->field->is_equal(*new_field);
6637+
bool is_equal= old_field->is_equal(*new_field);
66386638
/* TODO: below is an InnoDB specific code which should be moved to InnoDB */
66396639
if (!is_equal)
66406640
{

sql/table.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3759,7 +3759,7 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
37593759
*/
37603760
field= key_part->field=field->make_new_field(&outparam->mem_root,
37613761
outparam, 0);
3762-
field->field_length= key_part->length;
3762+
const_cast<uint32_t&>(field->field_length)= key_part->length;
37633763
}
37643764
}
37653765
if (!share->use_ext_keys)

0 commit comments

Comments
 (0)