revision-id: 5469d88e7b4e723e545cd7d511801a16a3642dc4 (mariadb-10.4.3-104-g5469d88e7b4)
parent(s): 0bc42602266815b81fe86b08c2228912c1a95340
author: Sachin
committer: Sachin
timestamp: 2019-03-28 11:29:25 +0530
message:
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_bugs.result | 46 ++++++++++++++++++++++
mysql-test/main/long_unique_bugs.test | 22 ++++++++++-
mysql-test/main/long_unique_innodb.result | 4 +-
mysql-test/main/long_unique_update.result | 8 ++--
sql/sql_table.cc | 9 +++++
6 files changed, 114 insertions(+), 39 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_bugs.result b/mysql-test/main/long_unique_bugs.result
index 87a57fb4614..48e74bdd564 100644
--- a/mysql-test/main/long_unique_bugs.result
+++ b/mysql-test/main/long_unique_bugs.result
@@ -239,3 +239,49 @@ CREATE TABLE t1 (a INT, UNIQUE USING HASH (a)) PARTITION BY HASH (a) PARTITIONS
INSERT INTO t1 VALUES (2);
REPLACE INTO t1 VALUES (2);
DROP TABLE t1;
+CREATE TABLE t1 (pk INT, a CHAR(4), b BLOB NOT NULL, PRIMARY KEY(pk));
+INSERT INTO t1 VALUES (1,'foo','bar');
+ALTER TABLE t1 ADD KEY (b(64));
+ALTER TABLE t1 ADD UNIQUE (b(165));
+ALTER TABLE t1 ADD KEY (b(1000));
+ALTER TABLE t1 ADD KEY (b(500));
+ALTER TABLE t1 ADD UNIQUE (a,b);
+ALTER TABLE t1 ADD UNIQUE (b(95));
+ALTER TABLE t1 ADD KEY (b(30));
+ALTER TABLE t1 ADD UNIQUE (b(20));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL,
+ `a` char(4) DEFAULT NULL,
+ `b` blob NOT NULL,
+ PRIMARY KEY (`pk`),
+ UNIQUE KEY `b_2` (`b`(165)),
+ UNIQUE KEY `b_5` (`b`(95)),
+ UNIQUE KEY `b_7` (`b`(20)),
+ UNIQUE KEY `a` (`a`,`b`) USING HASH,
+ KEY `b` (`b`(64)),
+ KEY `b_3` (`b`(1000)),
+ KEY `b_4` (`b`(500)),
+ KEY `b_6` (`b`(30))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t1 ADD UNIQUE (b);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL,
+ `a` char(4) DEFAULT NULL,
+ `b` blob NOT NULL,
+ PRIMARY KEY (`pk`),
+ UNIQUE KEY `b_2` (`b`(165)),
+ UNIQUE KEY `b_5` (`b`(95)),
+ UNIQUE KEY `b_7` (`b`(20)),
+ UNIQUE KEY `a` (`a`,`b`) USING HASH,
+ UNIQUE KEY `b_8` (`b`) USING HASH,
+ KEY `b` (`b`(64)),
+ KEY `b_3` (`b`(1000)),
+ KEY `b_4` (`b`(500)),
+ KEY `b_6` (`b`(30))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t1 FORCE;
+DROP TABLE t1;
diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test
index ed0daee426f..11b1c4f09b6 100644
--- a/mysql-test/main/long_unique_bugs.test
+++ b/mysql-test/main/long_unique_bugs.test
@@ -1,4 +1,5 @@
--source include/have_innodb.inc
+--source include/have_partition.inc
#
# MDEV-18707 Server crash in my_hash_sort_bin, ASAN heap-use-after-free in Field::is_null, server hang, corrupted double-linked list
@@ -269,8 +270,27 @@ drop table t1;
#
# MDEV-18904 Assertion `m_part_spec.start_part >= m_part_spec.end_part' failed in ha_partition::index_read_idx_map
#
---source include/have_partition.inc
CREATE TABLE t1 (a INT, UNIQUE USING HASH (a)) PARTITION BY HASH (a) PARTITIONS 2;
INSERT INTO t1 VALUES (2);
REPLACE INTO t1 VALUES (2);
DROP TABLE t1;
+
+#
+# MDEV-19049 Server crashes in check_duplicate_long_entry_key, ASAN stack-buffer-overflow in Field_blob::get_key_image
+#
+CREATE TABLE t1 (pk INT, a CHAR(4), b BLOB NOT NULL, PRIMARY KEY(pk));
+INSERT INTO t1 VALUES (1,'foo','bar');
+
+ALTER TABLE t1 ADD KEY (b(64));
+ALTER TABLE t1 ADD UNIQUE (b(165));
+ALTER TABLE t1 ADD KEY (b(1000));
+ALTER TABLE t1 ADD KEY (b(500));
+ALTER TABLE t1 ADD UNIQUE (a,b);
+ALTER TABLE t1 ADD UNIQUE (b(95));
+ALTER TABLE t1 ADD KEY (b(30));
+ALTER TABLE t1 ADD UNIQUE (b(20));
+show create table t1;
+ALTER TABLE t1 ADD UNIQUE (b);
+show create table t1;
+ALTER TABLE t1 FORCE;
+DROP TABLE t1;
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 ad62ecc1103..c755a74e174 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 */