diff --git a/mysql-test/r/rocksdb.result b/mysql-test/r/rocksdb.result index 1a828608ef36..ef623f486681 100644 --- a/mysql-test/r/rocksdb.result +++ b/mysql-test/r/rocksdb.result @@ -1239,3 +1239,19 @@ Checksum NULL Create_options Comment drop table t1; +# +# Fix Issue #4: Crash when using pseudo-unique keys +# +CREATE TABLE t1 ( +i INT, +t TINYINT, +s SMALLINT, +m MEDIUMINT, +b BIGINT, +pk MEDIUMINT AUTO_INCREMENT PRIMARY KEY, +UNIQUE KEY b_t (b,t) +) ENGINE=rocksdb; +INSERT INTO t1 (i,t,s,m,b) VALUES (1,2,3,4,5),(1000,100,10000,1000000,1000000000000000000),(5,100,10000,1000000,100000000000000000),(2,3,4,5,6),(3,4,5,6,7),(101,102,103,104,105),(10001,103,10002,10003,10004),(10,11,12,13,14),(11,12,13,14,15),(12,13,14,15,16); +SELECT b+t FROM t1 WHERE (b,t) IN ( SELECT b, t FROM t1 WHERE i>1 ) ORDER BY b+t; +b+t +DROP TABLE t1; diff --git a/mysql-test/t/rocksdb.test b/mysql-test/t/rocksdb.test index 808c47c7fdd4..83bec5c2ab1b 100644 --- a/mysql-test/t/rocksdb.test +++ b/mysql-test/t/rocksdb.test @@ -1101,3 +1101,21 @@ insert into t1 values (null),(null); --query_vertical show table status like 't1'; drop table t1; +--echo # +--echo # Fix Issue #4: Crash when using pseudo-unique keys +--echo # +CREATE TABLE t1 ( + i INT, + t TINYINT, + s SMALLINT, + m MEDIUMINT, + b BIGINT, + pk MEDIUMINT AUTO_INCREMENT PRIMARY KEY, + UNIQUE KEY b_t (b,t) +) ENGINE=rocksdb; + +INSERT INTO t1 (i,t,s,m,b) VALUES (1,2,3,4,5),(1000,100,10000,1000000,1000000000000000000),(5,100,10000,1000000,100000000000000000),(2,3,4,5,6),(3,4,5,6,7),(101,102,103,104,105),(10001,103,10002,10003,10004),(10,11,12,13,14),(11,12,13,14,15),(12,13,14,15,16); + +SELECT b+t FROM t1 WHERE (b,t) IN ( SELECT b, t FROM t1 WHERE i>1 ) ORDER BY b+t; +DROP TABLE t1; + diff --git a/storage/rocksdb/rdb_datadic.cc b/storage/rocksdb/rdb_datadic.cc index 596e7364b735..46db8434c8c7 100644 --- a/storage/rocksdb/rdb_datadic.cc +++ b/storage/rocksdb/rdb_datadic.cc @@ -80,20 +80,32 @@ void RDBSE_KEYDEF::setup(TABLE *tbl) pk_key_parts= 0; } - size_t size= sizeof(Field_pack_info) * key_info->actual_key_parts; + // "unique" secondary keys support: + bool unique_secondary_index= false; + uint loop_actual_key_parts= key_info->actual_key_parts; + if (keyno != tbl->s->primary_key && (key_info->flags & HA_NOSAME)) + { + // From SQL layer's point of view, Unique secondary indexes do not + // have primary key columns at the end. Internally, they do. + loop_actual_key_parts += n_pk_key_parts; + unique_secondary_index= true; + } + + size_t size= sizeof(Field_pack_info) * loop_actual_key_parts; pack_info= (Field_pack_info*)my_malloc(size, MYF(0)); uint len= INDEX_NUMBER_SIZE; int unpack_len= 0; + KEY_PART_INFO *key_part= key_info->key_part; /* this loop also loops over the 'extended key' tail */ - for (uint i= 0; i < key_info->actual_key_parts; i++) + for (uint i= 0; i < loop_actual_key_parts; i++) { - Field *field= key_info->key_part[i].field; + Field *field= key_part->field; if (field->real_maybe_null()) len +=1; // NULL-byte - pack_info[i].setup(key_info->key_part[i].field); + pack_info[i].setup(field); pack_info[i].image_offset= len; pack_info[i].unpack_data_offset= unpack_len; @@ -111,6 +123,13 @@ void RDBSE_KEYDEF::setup(TABLE *tbl) len += pack_info[i].image_len; unpack_len += pack_info[i].unpack_data_len; + + key_part++; + /* For "unique" secondary indexes, pretend they have "index extensions" */ + if (unique_secondary_index && i+1 == key_info->actual_key_parts) + { + key_part= pk_info->key_part; + } } maxlength= len; unpack_data_len= unpack_len;