From 181fccada28a38b4efe8e7d9840a329bfcb5d72c Mon Sep 17 00:00:00 2001 From: Sachin Date: Wed, 19 Jun 2019 10:35:39 +0530 Subject: MDEV-19049 Server crashes in check_duplicate_long_entry_key, ASAN stack-buffer-overflow in Field_blob::get_key_image Long Unique keys should always be last unique key. --- mysql-test/main/long_unique.result | 64 +++++++++++++++---------------- mysql-test/main/long_unique_innodb.result | 4 +- mysql-test/main/long_unique_update.result | 8 ++-- sql/sql_table.cc | 9 +++++ 4 files changed, 47 insertions(+), 38 deletions(-) diff --git a/mysql-test/main/long_unique.result b/mysql-test/main/long_unique.result index 3843ff4aff0..8ea6d36c321 100644 --- a/mysql-test/main/long_unique.result +++ b/mysql-test/main/long_unique.result @@ -184,8 +184,8 @@ t1 CREATE TABLE `t1` ( `a` blob DEFAULT NULL, `c` int(11) DEFAULT NULL, `db_row_hash_1` int(11) DEFAULT NULL, - UNIQUE KEY `a` (`a`) USING HASH, - UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`) + UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`), + UNIQUE KEY `a` (`a`) USING HASH ) ENGINE=MyISAM DEFAULT CHARSET=latin1 insert into t1 values(45,1,55),(46,1,55); ERROR 23000: Duplicate entry '55' for key 'db_row_hash_1' @@ -507,13 +507,13 @@ t1 CREATE TABLE `t1` ( `db_row_hash_1` int(11) DEFAULT NULL, `db_row_hash_2` int(11) DEFAULT NULL, `db_row_hash_3` int(11) DEFAULT NULL, + UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`), + UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`), + UNIQUE KEY `db_row_hash_3` (`db_row_hash_3`), UNIQUE KEY `a` (`a`) USING HASH, UNIQUE KEY `c` (`c`) USING HASH, UNIQUE KEY `d` (`d`) USING HASH, - UNIQUE KEY `e` (`e`) USING HASH, - UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`), - UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`), - UNIQUE KEY `db_row_hash_3` (`db_row_hash_3`) + UNIQUE KEY `e` (`e`) USING HASH ) ENGINE=MyISAM DEFAULT CHARSET=latin1 alter table t1 add column db_row_hash_7 int, add column db_row_hash_5 int , add column db_row_hash_4 int ; alter table t1 drop column db_row_hash_7,drop column db_row_hash_3, drop column db_row_hash_4; @@ -543,17 +543,17 @@ t1 CREATE TABLE `t1` ( `db_row_hash_1` int(11) DEFAULT NULL, `db_row_hash_2` int(11) DEFAULT NULL, `db_row_hash_5` int(11) DEFAULT NULL, - UNIQUE KEY `d` (`d`) USING HASH, - UNIQUE KEY `e` (`e`) USING HASH, UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`), - UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`) + UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`), + UNIQUE KEY `d` (`d`) USING HASH, + UNIQUE KEY `e` (`e`) USING HASH ) ENGINE=MyISAM DEFAULT CHARSET=latin1 show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t1 0 d 1 d A NULL NULL NULL YES HASH -t1 0 e 1 e A NULL NULL NULL YES HASH t1 0 db_row_hash_1 1 db_row_hash_1 A NULL NULL NULL YES BTREE t1 0 db_row_hash_2 1 db_row_hash_2 A NULL NULL NULL YES BTREE +t1 0 d 1 d A NULL NULL NULL YES HASH +t1 0 e 1 e A NULL NULL NULL YES HASH #add column with unique index on blob; alter table t1 add column a blob unique; show create table t1; @@ -567,18 +567,18 @@ t1 CREATE TABLE `t1` ( `db_row_hash_2` int(11) DEFAULT NULL, `db_row_hash_5` int(11) DEFAULT NULL, `a` blob DEFAULT NULL, - UNIQUE KEY `d` (`d`) USING HASH, - UNIQUE KEY `e` (`e`) USING HASH, UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`), UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`), + UNIQUE KEY `d` (`d`) USING HASH, + UNIQUE KEY `e` (`e`) USING HASH, UNIQUE KEY `a` (`a`) USING HASH ) ENGINE=MyISAM DEFAULT CHARSET=latin1 show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t1 0 d 1 d A NULL NULL NULL YES HASH -t1 0 e 1 e A NULL NULL NULL YES HASH t1 0 db_row_hash_1 1 db_row_hash_1 A NULL NULL NULL YES BTREE t1 0 db_row_hash_2 1 db_row_hash_2 A NULL NULL NULL YES BTREE +t1 0 d 1 d A NULL NULL NULL YES HASH +t1 0 e 1 e A NULL NULL NULL YES HASH t1 0 a 1 a A NULL NULL NULL YES HASH #try to change the blob unique column name; #this will change index to b tree; @@ -594,19 +594,19 @@ t1 CREATE TABLE `t1` ( `db_row_hash_2` int(11) DEFAULT NULL, `db_row_hash_5` int(11) DEFAULT NULL, `a` int(11) DEFAULT NULL, - UNIQUE KEY `d` (`d`) USING HASH, - UNIQUE KEY `e` (`e`), UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`), UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`), - UNIQUE KEY `a` (`a`) + UNIQUE KEY `e` (`e`), + UNIQUE KEY `a` (`a`), + UNIQUE KEY `d` (`d`) USING HASH ) ENGINE=MyISAM DEFAULT CHARSET=latin1 show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t1 0 d 1 d A NULL NULL NULL YES HASH -t1 0 e 1 e A NULL NULL NULL YES BTREE t1 0 db_row_hash_1 1 db_row_hash_1 A NULL NULL NULL YES BTREE t1 0 db_row_hash_2 1 db_row_hash_2 A NULL NULL NULL YES BTREE +t1 0 e 1 e A NULL NULL NULL YES BTREE t1 0 a 1 a A NULL NULL NULL YES BTREE +t1 0 d 1 d A NULL NULL NULL YES HASH alter table t1 add column clm1 blob unique,add column clm2 blob unique; #try changing the name; alter table t1 change column clm1 clm_changed1 blob, change column clm2 clm_changed2 blob; @@ -623,21 +623,21 @@ t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `clm_changed1` blob DEFAULT NULL, `clm_changed2` blob DEFAULT NULL, - UNIQUE KEY `d` (`d`) USING HASH, - UNIQUE KEY `e` (`e`), UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`), UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`), + UNIQUE KEY `e` (`e`), UNIQUE KEY `a` (`a`), + UNIQUE KEY `d` (`d`) USING HASH, UNIQUE KEY `clm1` (`clm_changed1`) USING HASH, UNIQUE KEY `clm2` (`clm_changed2`) USING HASH ) ENGINE=MyISAM DEFAULT CHARSET=latin1 show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t1 0 d 1 d A NULL NULL NULL YES HASH -t1 0 e 1 e A NULL NULL NULL YES BTREE t1 0 db_row_hash_1 1 db_row_hash_1 A NULL NULL NULL YES BTREE t1 0 db_row_hash_2 1 db_row_hash_2 A NULL NULL NULL YES BTREE +t1 0 e 1 e A NULL NULL NULL YES BTREE t1 0 a 1 a A NULL NULL NULL YES BTREE +t1 0 d 1 d A NULL NULL NULL YES HASH t1 0 clm1 1 clm_changed1 A NULL NULL NULL YES HASH t1 0 clm2 1 clm_changed2 A NULL NULL NULL YES HASH #now drop the unique key; @@ -655,19 +655,19 @@ t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `clm_changed1` blob DEFAULT NULL, `clm_changed2` blob DEFAULT NULL, - UNIQUE KEY `d` (`d`) USING HASH, - UNIQUE KEY `e` (`e`), UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`), UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`), - UNIQUE KEY `a` (`a`) + UNIQUE KEY `e` (`e`), + UNIQUE KEY `a` (`a`), + UNIQUE KEY `d` (`d`) USING HASH ) ENGINE=MyISAM DEFAULT CHARSET=latin1 show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t1 0 d 1 d A NULL NULL NULL YES HASH -t1 0 e 1 e A NULL NULL NULL YES BTREE t1 0 db_row_hash_1 1 db_row_hash_1 A NULL NULL NULL YES BTREE t1 0 db_row_hash_2 1 db_row_hash_2 A NULL NULL NULL YES BTREE +t1 0 e 1 e A NULL NULL NULL YES BTREE t1 0 a 1 a A NULL NULL NULL YES BTREE +t1 0 d 1 d A NULL NULL NULL YES HASH drop table t1; #now the table with key on multiple columns; the ultimate test; create table t1(a blob, b int , c varchar(2000) , d text , e varchar(3000) , f longblob , g int , h text , @@ -1130,17 +1130,17 @@ t1 CREATE TABLE `t1` ( `c` blob DEFAULT NULL, `d` blob DEFAULT NULL, `e` int(11) DEFAULT NULL, + UNIQUE KEY `e` (`e`), UNIQUE KEY `a` (`a`,`c`) USING HASH, - UNIQUE KEY `b` (`b`,`d`) USING HASH, - UNIQUE KEY `e` (`e`) + UNIQUE KEY `b` (`b`,`d`) USING HASH ) ENGINE=MyISAM DEFAULT CHARSET=latin1 show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +t1 0 e 1 e A NULL NULL NULL YES BTREE t1 0 a 1 a A NULL NULL NULL YES HASH t1 0 a 2 c A NULL NULL NULL YES HASH t1 0 b 1 b A NULL NULL NULL YES HASH t1 0 b 2 d A NULL NULL NULL YES HASH -t1 0 e 1 e A 0 NULL NULL YES BTREE drop table t1; #visibility of db_row_hash create table t1 (a blob unique , b blob unique); diff --git a/mysql-test/main/long_unique_innodb.result b/mysql-test/main/long_unique_innodb.result index cb8c3ea4858..135bb0808cc 100644 --- a/mysql-test/main/long_unique_innodb.result +++ b/mysql-test/main/long_unique_innodb.result @@ -9,8 +9,8 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` blob DEFAULT NULL, `c` int(11) DEFAULT NULL, - UNIQUE KEY `a` (`a`) USING HASH, - UNIQUE KEY `c` (`c`) + UNIQUE KEY `c` (`c`), + UNIQUE KEY `a` (`a`) USING HASH ) ENGINE=InnoDB DEFAULT CHARSET=latin1 drop table t1; #test for concurrent insert of long unique in innodb diff --git a/mysql-test/main/long_unique_update.result b/mysql-test/main/long_unique_update.result index 60a4fb46558..b508583f47c 100644 --- a/mysql-test/main/long_unique_update.result +++ b/mysql-test/main/long_unique_update.result @@ -71,8 +71,8 @@ create table t1 (a int primary key, b blob unique , c int unique ); show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t1 0 PRIMARY 1 a A 0 NULL NULL BTREE -t1 0 b 1 b A NULL NULL NULL YES HASH t1 0 c 1 c A NULL NULL NULL YES BTREE +t1 0 b 1 b A NULL NULL NULL YES HASH insert into t1 values(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6),(7,7,7); select * from t1 limit 3; a b c @@ -220,18 +220,18 @@ t1 CREATE TABLE `t1` ( `f` int(11) DEFAULT NULL, `g` text DEFAULT NULL, PRIMARY KEY (`a`), - UNIQUE KEY `b` (`b`,`c`) USING HASH, UNIQUE KEY `b_2` (`b`,`f`), + UNIQUE KEY `b` (`b`,`c`) USING HASH, UNIQUE KEY `e` (`e`,`g`) USING HASH, UNIQUE KEY `a` (`a`,`b`,`c`,`d`,`e`,`f`,`g`) USING HASH ) ENGINE=MyISAM DEFAULT CHARSET=latin1 show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t1 0 PRIMARY 1 a A 0 NULL NULL BTREE -t1 0 b 1 b A NULL NULL NULL YES HASH -t1 0 b 2 c A NULL NULL NULL YES HASH t1 0 b_2 1 b A NULL NULL NULL YES BTREE t1 0 b_2 2 f A NULL NULL NULL YES BTREE +t1 0 b 1 b A NULL NULL NULL YES HASH +t1 0 b 2 c A NULL NULL NULL YES HASH t1 0 e 1 e A NULL NULL NULL YES HASH t1 0 e 2 g A NULL NULL NULL YES HASH t1 0 a 1 a A NULL NULL NULL HASH diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f2be573d984..89f5c4b9d7f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2773,6 +2773,7 @@ bool quick_rm_table(THD *thd, handlerton *base, const LEX_CSTRING *db, - UNIQUE keys where all column are NOT NULL - UNIQUE keys that don't contain partial segments - Other UNIQUE keys + - LONG UNIQUE keys - Normal keys - Fulltext keys @@ -2796,6 +2797,14 @@ static int sort_keys(KEY *a, KEY *b) { if (!(b_flags & HA_NOSAME)) return -1; + /* + Long Unique keys should always be last unique key. + Before this patch they used to change order wrt to partial keys (MDEV-19049) + */ + if (a->algorithm == HA_KEY_ALG_LONG_HASH) + return 1; + if (b->algorithm == HA_KEY_ALG_LONG_HASH) + return -1; if ((a_flags ^ b_flags) & HA_NULL_PART_KEY) { /* Sort NOT NULL keys before other keys */ -- cgit v1.2.1