Hi Anurag,
On Tue, Feb 24, 2009 at 12:52:20PM +0000, Anurag Shekhar wrote:
> #At file:///home/anurag/mysqlsrc/mysql-5.1-41305/ based on
> revid:azundris@stripped
>
> 2810 Anurag Shekhar 2009-02-24
> Bug#41305 server crashes when inserting duplicate row into a merge table
>
> This problem comes while inserting a duplicate row in merge table
> without key but the child table has a primary key.
> While forming the error message handler tries to locate the key field
> which is creating this problem but as there is no key on the merge
> table there is a segmentation fault.
>
> An additional check to ensure that the key fields are present
> fixes this problem.
> modified:
> mysql-test/r/merge.result
> mysql-test/t/merge.test
> sql/handler.cc
>
> per-file messages:
> mysql-test/r/merge.result
> Updated result file with additional test result.
> mysql-test/t/merge.test
> Added a test case to test the scenario described in bug#41305
> sql/handler.cc
> added an additional check to see if key_info of the table is not null. If it is
> an empty message is used.
> === modified file 'mysql-test/r/merge.result'
> --- a/mysql-test/r/merge.result 2009-02-12 10:25:12 +0000
> +++ b/mysql-test/r/merge.result 2009-02-24 12:52:11 +0000
> @@ -2103,4 +2103,20 @@ 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 t2 (
> +col1 int(10),
> +primary key (col1)
> +) ENGINE=MyISAM DEFAULT CHARSET=latin1;
I don't think you really need t2 here. t1 should be enough.
> +CREATE TABLE m1 (
> +col1 int(10) NOT NULL
> +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(t1,t2);
> +insert into m1 (col1) values (1);
> +insert into m1 (col1) values (1);
> +ERROR 23000: '''
> +drop table m1, t1, t2;
> End of 5.1 tests
>
> === modified file 'mysql-test/t/merge.test'
> --- a/mysql-test/t/merge.test 2009-02-12 10:25:12 +0000
> +++ b/mysql-test/t/merge.test 2009-02-24 12:52:11 +0000
> @@ -1496,4 +1496,27 @@ 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 t2 (
> + 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,t2);
> +
> +insert into m1 (col1) values (1);
> +--error ER_DUP_ENTRY
> +insert into m1 (col1) values (1);
> +
> +drop table m1, t1, t2;
> --echo End of 5.1 tests
>
> === modified file 'sql/handler.cc'
> --- a/sql/handler.cc 2009-02-18 20:29:30 +0000
> +++ b/sql/handler.cc 2009-02-24 12:52:11 +0000
> @@ -2539,6 +2539,15 @@ void handler::print_keydup_error(uint ke
> str.copy("", 0, system_charset_info);
> my_printf_error(ER_DUP_ENTRY, msg, MYF(0), str.c_ptr(), "*UNKNOWN*");
> }
> + else if (!table->key_info)
> + {
> + /*
> + Table doesn't have key info.
> + eg: in caseof merge table key may exist only on
> + child table.
> + */
> + my_printf_error(ER_DUP_ENTRY, "'''", MYF(0));
> + }
> else
> {
> /* Table is opened and defined at this point */
Thinking more on this, if we have multiple unique keys in an underlying
table and less in the merge table, the above condition will not work.
I think it should be fixed in ha_myisammrg::info(), probably by setting
errkey to MAX_KEY, if errkey was requested and errkey is bigger than
table->s->keys.
Regards,
Sergey
--
Sergey Vojtovich <svoj@stripped>
MySQL AB, Software Engineer
Izhevsk, Russia, www.mysql.com