Commit 1394216e authored by Eugene Kosov's avatar Eugene Kosov

MDEV-21669 InnoDB: Table ... contains <n> indexes inside InnoDB, which is...

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.
parent c5e00fea
......@@ -74,7 +74,6 @@ select @a_key_returns_id = get_index_id(@table_id, 'a_key_returns'),
@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')
1 1 1 1
drop table t;
drop function get_index_id;
create table errors (
a int,
unique key a_key (a),
......@@ -183,3 +182,19 @@ CREATE TABLE t1 (f1 INT, f2 INT, f3 INT);
ALTER TABLE t1 ADD FOREIGN KEY f (f2) REFERENCES xx(f2);
ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t1(f2), ADD KEY (f3), ADD KEY (f1);
DROP TABLE t1;
#
# MDEV-21669 InnoDB: Table ... contains <n> indexes inside InnoDB, which is different from the number of indexes <n> defined in the MariaDB
#
CREATE TABLE t1 (col_int INTEGER, col_char CHAR(20), col_varchar VARCHAR(500)) ENGINE=InnoDB;
SET @table_id = (SELECT table_id FROM information_schema.innodb_sys_tables WHERE name='test/t1');
ALTER TABLE t1 ADD KEY idx3 (col_varchar(9)), ADD KEY idX2 (col_char(9));
SET @idx3_key_id = get_index_id(@table_id, 'iDx3');
ALTER TABLE t1 DROP KEY iDx3, ADD KEY Idx3 (col_varchar(9));
SELECT @idx3_key_id = get_index_id(@table_id, 'Idx3');
@idx3_key_id = get_index_id(@table_id, 'Idx3')
1
CHECK TABLE t1 EXTENDED ;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
DROP FUNCTION get_index_id;
......@@ -73,7 +73,6 @@ select @a_key_returns_id = get_index_id(@table_id, 'a_key_returns'),
@primary_id = get_index_id(@table_id, 'primary');
drop table t;
drop function get_index_id;
create table errors (
a int,
......@@ -194,3 +193,17 @@ CREATE TABLE t1 (f1 INT, f2 INT, f3 INT);
ALTER TABLE t1 ADD FOREIGN KEY f (f2) REFERENCES xx(f2);
ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t1(f2), ADD KEY (f3), ADD KEY (f1);
DROP TABLE t1;
--echo #
--echo # MDEV-21669 InnoDB: Table ... contains <n> indexes inside InnoDB, which is different from the number of indexes <n> defined in the MariaDB
--echo #
CREATE TABLE t1 (col_int INTEGER, col_char CHAR(20), col_varchar VARCHAR(500)) ENGINE=InnoDB;
SET @table_id = (SELECT table_id FROM information_schema.innodb_sys_tables WHERE name='test/t1');
ALTER TABLE t1 ADD KEY idx3 (col_varchar(9)), ADD KEY idX2 (col_char(9));
SET @idx3_key_id = get_index_id(@table_id, 'iDx3');
ALTER TABLE t1 DROP KEY iDx3, ADD KEY Idx3 (col_varchar(9));
SELECT @idx3_key_id = get_index_id(@table_id, 'Idx3');
CHECK TABLE t1 EXTENDED ;
DROP TABLE t1;
DROP FUNCTION get_index_id;
......@@ -694,7 +694,7 @@ class Field: public Value_source
enum imagetype { itRAW, itMBR};
utype unireg_check;
uint32 field_length; // Length of field
const uint32 field_length; // Length of field
uint32 flags;
uint16 field_index; // field number in fields array
uchar null_bit; // Bit used to test null bit
......
......@@ -6634,7 +6634,7 @@ Compare_keys compare_keys_but_name(const KEY *table_key, const KEY *new_key,
*/
const Field *old_field= table->field[key_part->fieldnr - 1];
bool is_equal= key_part->field->is_equal(*new_field);
bool is_equal= old_field->is_equal(*new_field);
/* TODO: below is an InnoDB specific code which should be moved to InnoDB */
if (!is_equal)
{
......
......@@ -3759,7 +3759,7 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
*/
field= key_part->field=field->make_new_field(&outparam->mem_root,
outparam, 0);
field->field_length= key_part->length;
const_cast<uint32_t&>(field->field_length)= key_part->length;
}
}
if (!share->use_ext_keys)
......
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