[Commits] b2714e7: Fix Issue #4: Crash when using pseudo-unique keys

Sergei Petrunia psergey at askmonty.org
Wed Jul 16 18:51:16 EEST 2014


revision-id: b2714e7ab467e9cf08b215e14a8e811740f91d6b
parent(s): 4a13b197b15dfe32ce521c5845444fd0f0468e0b
committer: Sergei Petrunia
branch nick: webscalesql-5.6
timestamp: 2014-07-16 19:51:16 +0400
message:

Fix Issue #4: Crash when using pseudo-unique keys

-----------------------

 mysql-test/r/rocksdb.result    |   16 ++++++++++++++++
 mysql-test/t/rocksdb.test      |   18 ++++++++++++++++++
 storage/rocksdb/rdb_datadic.cc |   27 +++++++++++++++++++++++----
 3 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/mysql-test/r/rocksdb.result b/mysql-test/r/rocksdb.result
index 1a82860..ef623f4 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 808c47c..83bec5c 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 72adb48..73ff69c 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;


More information about the commits mailing list