From 94da1cb4a67ecb2e2590748381eebac072308ce6 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Tue, 23 Jan 2018 15:47:54 +0530 Subject: MDEV-14586 Assertion `0' failed in retrieve_auto_increment ... Problem:- If we create table using myisam/aria then this crashes the server. CREATE TABLE t1(a bit(1), b int auto_increment , index(a,b)); insert into t1 values(1,1); Or this query CREATE TABLE t1 (b BIT(1), pk INTEGER AUTO_INCREMENT PRIMARY KEY); ALTER TABLE t1 ADD INDEX(b,pk); INSERT INTO t1 VALUES (1,b'1'); ALTER TABLE t1 DROP PRIMARY KEY; Reason:- The reason for this is 1st- find_ref_key() finds what key an auto_increment field belongs to by comparing key_part->offset and field->ptr. But BIT fields might have zero length in the record, so a key might have many key parts with the same offset. That is, comparing offsets cannot uniquely identify the correct key part. 2nd- Since next_number_key_offset is zero it myisam/aria will think that auto_increment is in first part of key. 3nd- myisam/aria will call retrieve_auto_key which will see first key_part field as a bit field and call assert(0) Solution:- Many key parts might have the same offset, but BIT fields do not support auto_increment. So, we can skip all key parts over BIT fields, and then comparing offsets will be unambiguous. --- mysql-test/r/mdev_14586.result | 44 ++++++++++++++++++++++++++++++++++++++++++ mysql-test/t/mdev_14586.test | 27 ++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 mysql-test/r/mdev_14586.result create mode 100644 mysql-test/t/mdev_14586.test (limited to 'mysql-test') diff --git a/mysql-test/r/mdev_14586.result b/mysql-test/r/mdev_14586.result new file mode 100644 index 00000000000..f6c2095d3cd --- /dev/null +++ b/mysql-test/r/mdev_14586.result @@ -0,0 +1,44 @@ +create table t1(a bit(1), b int auto_increment ,id int, index(a,b)); +insert into t1 values(1,null,1); +insert into t1 values(1,null,2); +insert into t1 values(0,null,3); +insert into t1 values(0,null,4); +select a+0, b as auto_increment , id from t1 order by id; +a+0 auto_increment id +1 1 1 +1 2 2 +0 1 3 +0 2 4 +drop table t1; +create table t1(a int auto_increment, b bit(5) ,id int, index (b,a)); +insert into t1 values(null,b'1',1); +insert into t1 values(null,b'1',2); +insert into t1 values(null,b'11',3); +insert into t1 values(null,b'11',4); +select a as auto_increment, b+0, id from t1 order by id; +auto_increment b+0 id +1 1 1 +2 1 2 +1 3 3 +2 3 4 +drop table t1; +create table t1(a bit(1), b int auto_increment , c bit(1) , d bit(1), id int,index(a,c,b,d)); +insert into t1 values(1,null,1,1,1); +insert into t1 values(1,null,1,1,2); +insert into t1 values(0,null,1,1,3); +insert into t1 values(1,null,0,1,4); +select a+0, b as auto_increment, c+0, d+0, id from t1 order by id; +a+0 auto_increment c+0 d+0 id +1 1 1 1 1 +1 2 1 1 2 +0 1 1 1 3 +1 1 0 1 4 +drop table t1; +CREATE TABLE t1 (b BIT(1), pk INTEGER AUTO_INCREMENT PRIMARY KEY); +ALTER TABLE t1 ADD INDEX(b,pk); +INSERT INTO t1 VALUES (1,b'1'); +ALTER TABLE t1 DROP PRIMARY KEY; +select b+0, pk as auto_increment from t1; +b+0 auto_increment +1 1 +DROP TABLE t1; diff --git a/mysql-test/t/mdev_14586.test b/mysql-test/t/mdev_14586.test new file mode 100644 index 00000000000..8b3d3780151 --- /dev/null +++ b/mysql-test/t/mdev_14586.test @@ -0,0 +1,27 @@ +create table t1(a bit(1), b int auto_increment ,id int, index(a,b)); +insert into t1 values(1,null,1); +insert into t1 values(1,null,2); +insert into t1 values(0,null,3); +insert into t1 values(0,null,4); +select a+0, b as auto_increment , id from t1 order by id; +drop table t1; +create table t1(a int auto_increment, b bit(5) ,id int, index (b,a)); +insert into t1 values(null,b'1',1); +insert into t1 values(null,b'1',2); +insert into t1 values(null,b'11',3); +insert into t1 values(null,b'11',4); +select a as auto_increment, b+0, id from t1 order by id; +drop table t1; +create table t1(a bit(1), b int auto_increment , c bit(1) , d bit(1), id int,index(a,c,b,d)); +insert into t1 values(1,null,1,1,1); +insert into t1 values(1,null,1,1,2); +insert into t1 values(0,null,1,1,3); +insert into t1 values(1,null,0,1,4); +select a+0, b as auto_increment, c+0, d+0, id from t1 order by id; +drop table t1; +CREATE TABLE t1 (b BIT(1), pk INTEGER AUTO_INCREMENT PRIMARY KEY); +ALTER TABLE t1 ADD INDEX(b,pk); +INSERT INTO t1 VALUES (1,b'1'); +ALTER TABLE t1 DROP PRIMARY KEY; +select b+0, pk as auto_increment from t1; +DROP TABLE t1; -- cgit v1.2.1