diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 3910536ee5d..d844abc1847 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -2103,4 +2103,16 @@ a UNLOCK TABLES; # drop the created tables DROP TABLE t1, t2, t3; +# insert duplicate value in child table while merge table doesn't have key +create table t1 ( +col1 int(10), +primary key (col1) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +CREATE TABLE m1 ( +col1 int(10) NOT NULL +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(t1); +insert into m1 (col1) values (1); +insert into m1 (col1) values (1); +ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +drop table m1, t1; End of 5.1 tests diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index 2fbfe2721e2..f12187ea143 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -1496,4 +1496,22 @@ UNLOCK TABLES; --echo # drop the created tables DROP TABLE t1, t2, t3; +# +# Bug #41305 server crashes when inserting duplicate row into a merge table +# +--echo # insert duplicate value in child table while merge table doesn't have key +create table t1 ( + col1 int(10), + primary key (col1) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +CREATE TABLE m1 ( + col1 int(10) NOT NULL +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(t1); + +insert into m1 (col1) values (1); +--error ER_DUP_ENTRY +insert into m1 (col1) values (1); + +drop table m1, t1; --echo End of 5.1 tests diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index d674f6bc150..5bd7c7dd05c 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -872,6 +872,16 @@ int ha_myisammrg::info(uint flag) table->s->crashed= 1; #endif stats.data_file_length= mrg_info.data_file_length; + if (mrg_info.errkey >= table_share->keys) + { + /* + If value of errkey is higher than the number of keys + on the table set errkey to MAX_KEY. This will be + treated as unknown key case and error message generator + won't try to locate key causing segmentation fault. + */ + mrg_info.errkey= MAX_KEY; + } errkey= mrg_info.errkey; table->s->keys_in_use.set_prefix(table->s->keys); stats.mean_rec_length= mrg_info.reclength;