Fix for MDEV-14141 Crash in print_keydup_error()
May also fix: MDEV-14970 "MariaDB crashed with signal 11 and Aria table" I am not able to reproduce a crash, however there was no protection in print_keydup_error() if the storage engine reported the wrong key number. This patch adds such a protection and should stop any further crashes in this case. Other things: - Added extra protection in Aria to not set errkey to more than number of keys. (Don't think this is cause of this crash, but better safe than sorry) - Extend test_if_equal_repl_errors() to handle different cases of ER_DUP_ENTRY. This is just mainly precaution for the future.
This commit is contained in:
parent
a4663af05c
commit
b3c7cf81e3
@ -2167,7 +2167,7 @@ col1 int(10) NOT NULL
|
|||||||
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(t1);
|
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(t1);
|
||||||
insert into m1 (col1) values (1);
|
insert into m1 (col1) values (1);
|
||||||
insert into m1 (col1) values (1);
|
insert into m1 (col1) values (1);
|
||||||
ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
|
ERROR 23000: Can't write; duplicate key in table 'm1'
|
||||||
drop table m1, t1;
|
drop table m1, t1;
|
||||||
#
|
#
|
||||||
# Bug#45800 crash when replacing into a merge table and there is a duplicate
|
# Bug#45800 crash when replacing into a merge table and there is a duplicate
|
||||||
@ -2204,7 +2204,7 @@ CREATE TABLE m1 (c1 INT, c2 INT, UNIQUE (c1)) ENGINE=MRG_MyISAM INSERT_METHOD=LA
|
|||||||
INSERT INTO m1 VALUES (1,2);
|
INSERT INTO m1 VALUES (1,2);
|
||||||
# insert the duplicate value into the merge table
|
# insert the duplicate value into the merge table
|
||||||
INSERT INTO m1 VALUES (3,2);
|
INSERT INTO m1 VALUES (3,2);
|
||||||
ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
|
ERROR 23000: Can't write; duplicate key in table 'm1'
|
||||||
DROP TABLE m1,t1;
|
DROP TABLE m1,t1;
|
||||||
# Try to define MERGE and MyISAM with keys on different columns
|
# Try to define MERGE and MyISAM with keys on different columns
|
||||||
CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE (c1));
|
CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE (c1));
|
||||||
|
@ -1559,7 +1559,7 @@ CREATE TABLE m1 (
|
|||||||
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(t1);
|
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(t1);
|
||||||
|
|
||||||
insert into m1 (col1) values (1);
|
insert into m1 (col1) values (1);
|
||||||
--error ER_DUP_ENTRY
|
--error ER_DUP_KEY
|
||||||
insert into m1 (col1) values (1);
|
insert into m1 (col1) values (1);
|
||||||
|
|
||||||
drop table m1, t1;
|
drop table m1, t1;
|
||||||
@ -1593,7 +1593,7 @@ CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE (c1), UNIQUE (c2));
|
|||||||
CREATE TABLE m1 (c1 INT, c2 INT, UNIQUE (c1)) ENGINE=MRG_MyISAM INSERT_METHOD=LAST UNION=(t1);
|
CREATE TABLE m1 (c1 INT, c2 INT, UNIQUE (c1)) ENGINE=MRG_MyISAM INSERT_METHOD=LAST UNION=(t1);
|
||||||
INSERT INTO m1 VALUES (1,2);
|
INSERT INTO m1 VALUES (1,2);
|
||||||
--echo # insert the duplicate value into the merge table
|
--echo # insert the duplicate value into the merge table
|
||||||
--error ER_DUP_ENTRY
|
--error ER_DUP_KEY
|
||||||
INSERT INTO m1 VALUES (3,2);
|
INSERT INTO m1 VALUES (3,2);
|
||||||
DROP TABLE m1,t1;
|
DROP TABLE m1,t1;
|
||||||
|
|
||||||
|
@ -3338,9 +3338,11 @@ void print_keydup_error(TABLE *table, KEY *key, const char *msg, myf errflag)
|
|||||||
|
|
||||||
if (key == NULL)
|
if (key == NULL)
|
||||||
{
|
{
|
||||||
/* Key is unknown */
|
/*
|
||||||
str.copy("", 0, system_charset_info);
|
Key is unknown. Should only happen if storage engine reports wrong
|
||||||
my_printf_error(ER_DUP_ENTRY, msg, errflag, str.c_ptr(), "*UNKNOWN*");
|
duplicate key number.
|
||||||
|
*/
|
||||||
|
my_printf_error(ER_DUP_ENTRY, msg, errflag, "", "*UNKNOWN*");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3432,11 +3434,9 @@ void handler::print_error(int error, myf errflag)
|
|||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
uint key_nr=get_dup_key(error);
|
uint key_nr=get_dup_key(error);
|
||||||
if ((int) key_nr >= 0)
|
if ((int) key_nr >= 0 && key_nr < table->s->keys)
|
||||||
{
|
{
|
||||||
print_keydup_error(table,
|
print_keydup_error(table, &table->key_info[key_nr], errflag);
|
||||||
key_nr == MAX_KEY ? NULL : &table->key_info[key_nr],
|
|
||||||
errflag);
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4075,8 +4075,13 @@ bool test_if_equal_repl_errors(int expected_error, int actual_error)
|
|||||||
return 1;
|
return 1;
|
||||||
switch (expected_error) {
|
switch (expected_error) {
|
||||||
case ER_DUP_ENTRY:
|
case ER_DUP_ENTRY:
|
||||||
|
case ER_DUP_ENTRY_WITH_KEY_NAME:
|
||||||
|
case ER_DUP_KEY:
|
||||||
case ER_AUTOINC_READ_FAILED:
|
case ER_AUTOINC_READ_FAILED:
|
||||||
return (actual_error == ER_AUTOINC_READ_FAILED ||
|
return (actual_error == ER_DUP_ENTRY ||
|
||||||
|
actual_error == ER_DUP_ENTRY_WITH_KEY_NAME ||
|
||||||
|
actual_error == ER_DUP_KEY ||
|
||||||
|
actual_error == ER_AUTOINC_READ_FAILED ||
|
||||||
actual_error == HA_ERR_AUTOINC_ERANGE);
|
actual_error == HA_ERR_AUTOINC_ERANGE);
|
||||||
case ER_UNKNOWN_TABLE:
|
case ER_UNKNOWN_TABLE:
|
||||||
return actual_error == ER_IT_IS_A_VIEW;
|
return actual_error == ER_IT_IS_A_VIEW;
|
||||||
|
@ -9612,12 +9612,13 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
|
|||||||
if ((int) key_nr >= 0)
|
if ((int) key_nr >= 0)
|
||||||
{
|
{
|
||||||
const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
|
const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
|
||||||
if (key_nr == 0 &&
|
if (key_nr == 0 && to->s->keys > 0 &&
|
||||||
(to->key_info[0].key_part[0].field->flags &
|
(to->key_info[0].key_part[0].field->flags &
|
||||||
AUTO_INCREMENT_FLAG))
|
AUTO_INCREMENT_FLAG))
|
||||||
err_msg= ER(ER_DUP_ENTRY_AUTOINCREMENT_CASE);
|
err_msg= ER(ER_DUP_ENTRY_AUTOINCREMENT_CASE);
|
||||||
print_keydup_error(to, key_nr == MAX_KEY ? NULL :
|
print_keydup_error(to,
|
||||||
&to->key_info[key_nr],
|
key_nr >= to->s->keys ? NULL :
|
||||||
|
&to->key_info[key_nr],
|
||||||
err_msg, MYF(0));
|
err_msg, MYF(0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -340,7 +340,7 @@ err:
|
|||||||
for (j=0 ; j < share->base.keys ; j++)
|
for (j=0 ; j < share->base.keys ; j++)
|
||||||
maria_flush_bulk_insert(info, j);
|
maria_flush_bulk_insert(info, j);
|
||||||
}
|
}
|
||||||
info->errkey= (int) i;
|
info->errkey= i < share->base.keys ? (int) i : -1;
|
||||||
/*
|
/*
|
||||||
We delete keys in the reverse order of insertion. This is the order that
|
We delete keys in the reverse order of insertion. This is the order that
|
||||||
a rollback would do and is important for CLR_ENDs generated by
|
a rollback would do and is important for CLR_ENDs generated by
|
||||||
|
Loading…
x
Reference in New Issue
Block a user