From db852b78501d9a4ea11dcc85e6c4dd85830c4953 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Wed, 16 Jul 2014 21:01:17 +0400 Subject: [PATCH] Fix Issue #4, part#2: make other members of class RDBSE_KEYDEF aware that unique keys do not have index extensions defined. Also add suite/rocksdb/type_int_indexes.test --- mysql-test/r/rocksdb.result | 9 ++ .../suite/rocksdb/type_int_indexes.result | 96 +++++++++++++++++++ .../suite/rocksdb/type_int_indexes.test | 67 +++++++++++++ storage/rocksdb/rdb_datadic.cc | 36 +++++-- storage/rocksdb/rdb_datadic.h | 7 ++ 5 files changed, 207 insertions(+), 8 deletions(-) create mode 100644 mysql-test/suite/rocksdb/type_int_indexes.result create mode 100644 mysql-test/suite/rocksdb/type_int_indexes.test diff --git a/mysql-test/r/rocksdb.result b/mysql-test/r/rocksdb.result index ef623f486681..c587b7551000 100644 --- a/mysql-test/r/rocksdb.result +++ b/mysql-test/r/rocksdb.result @@ -1254,4 +1254,13 @@ UNIQUE KEY b_t (b,t) 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 +9 +11 +25 +27 +29 +207 +10107 +100000000000000100 +1000000000000000100 DROP TABLE t1; diff --git a/mysql-test/suite/rocksdb/type_int_indexes.result b/mysql-test/suite/rocksdb/type_int_indexes.result new file mode 100644 index 000000000000..6a8565fe03ba --- /dev/null +++ b/mysql-test/suite/rocksdb/type_int_indexes.result @@ -0,0 +1,96 @@ +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 ( +i INT PRIMARY KEY, +t TINYINT, +s SMALLINT, +m MEDIUMINT, +b BIGINT +) 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); +EXPLAIN SELECT i FROM t1 ORDER BY i; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 4 NULL 1000 Using index +SELECT i FROM t1 ORDER BY i; +i +1 +2 +3 +5 +10 +11 +12 +101 +1000 +10001 +DROP TABLE t1; +CREATE TABLE t1 ( +i INT, +t TINYINT, +s SMALLINT, +m MEDIUMINT, +b BIGINT, +pk SMALLINT AUTO_INCREMENT PRIMARY KEY, +INDEX s_m (s,m) +) 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); +EXPLAIN SELECT s, m FROM t1 WHERE s != 10 AND m != 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range s_m s_m 3 NULL 20 Using where; Using index +SELECT s, m FROM t1 WHERE s != 10 AND m != 1; +s m +10000 1000000 +10000 1000000 +10002 10003 +103 104 +12 13 +13 14 +14 15 +3 4 +4 5 +5 6 +DROP TABLE t1; +# RocksDB: unique indexes allowed +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 +9 +11 +25 +27 +29 +207 +10107 +100000000000000100 +1000000000000000100 +SELECT b+t FROM t1 FORCE INDEX (b_t) WHERE (b,t) IN ( SELECT b, t FROM t1 WHERE i>1 ) ORDER BY b+t; +b+t +9 +11 +25 +27 +29 +207 +10107 +100000000000000100 +1000000000000000100 +SELECT b+t FROM t1 IGNORE INDEX (b_t) WHERE (b,t) IN ( SELECT b, t FROM t1 WHERE i>1 ) ORDER BY b+t; +b+t +9 +11 +25 +27 +29 +207 +10107 +100000000000000100 +1000000000000000100 +DROP TABLE t1; diff --git a/mysql-test/suite/rocksdb/type_int_indexes.test b/mysql-test/suite/rocksdb/type_int_indexes.test new file mode 100644 index 000000000000..65e92360c96f --- /dev/null +++ b/mysql-test/suite/rocksdb/type_int_indexes.test @@ -0,0 +1,67 @@ +# +# INT column types with indexes +# + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 ( + i INT PRIMARY KEY, + t TINYINT, + s SMALLINT, + m MEDIUMINT, + b BIGINT +) 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); + +EXPLAIN SELECT i FROM t1 ORDER BY i; +SELECT i FROM t1 ORDER BY i; + +DROP TABLE t1; + +CREATE TABLE t1 ( + i INT, + t TINYINT, + s SMALLINT, + m MEDIUMINT, + b BIGINT, + pk SMALLINT AUTO_INCREMENT PRIMARY KEY, + INDEX s_m (s,m) +) 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); + +EXPLAIN SELECT s, m FROM t1 WHERE s != 10 AND m != 1; +--sorted_result +SELECT s, m FROM t1 WHERE s != 10 AND m != 1; + +DROP TABLE t1; + +--echo # RocksDB: unique indexes allowed +#--error ER_GET_ERRMSG +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; + +##--disable_parsing + +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); + +# This query should use the index b_t, we just don't want to run EXPLAIN +# (to avoid mismatches due to different subquery-related plans) +SELECT b+t FROM t1 WHERE (b,t) IN ( SELECT b, t FROM t1 WHERE i>1 ) ORDER BY b+t; +SELECT b+t FROM t1 FORCE INDEX (b_t) WHERE (b,t) IN ( SELECT b, t FROM t1 WHERE i>1 ) ORDER BY b+t; +SELECT b+t FROM t1 IGNORE INDEX (b_t) WHERE (b,t) IN ( SELECT b, t FROM t1 WHERE i>1 ) ORDER BY b+t; + +DROP TABLE t1; + +##--enable_parsing + diff --git a/storage/rocksdb/rdb_datadic.cc b/storage/rocksdb/rdb_datadic.cc index 26a408503012..93a3198cd72e 100644 --- a/storage/rocksdb/rdb_datadic.cc +++ b/storage/rocksdb/rdb_datadic.cc @@ -82,23 +82,23 @@ void RDBSE_KEYDEF::setup(TABLE *tbl) // "unique" secondary keys support: bool unique_secondary_index= false; - uint loop_actual_key_parts= key_info->actual_key_parts; + m_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; + m_key_parts += n_pk_key_parts; unique_secondary_index= true; } - size_t size= sizeof(Field_pack_info) * loop_actual_key_parts; + size_t size= sizeof(Field_pack_info) * m_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 < loop_actual_key_parts; i++) + for (uint i= 0; i < m_key_parts; i++) { Field *field= key_part->field; @@ -213,6 +213,19 @@ void RDBSE_KEYDEF::successor(uchar *packed_tuple, uint len) } } +static Field *get_field_by_keynr(TABLE *tbl, KEY *key_info, uint part) +{ + if (part < key_info->actual_key_parts) + { + return key_info->key_part[part].field; + } + else + { + uint pk= tbl->s->primary_key; + KEY *pk_info= &tbl->key_info[pk]; + return pk_info->key_part[part - key_info->actual_key_parts].field; + } +} /* Get index columns from the record and pack them into mem-comparable form. @@ -244,11 +257,17 @@ uint RDBSE_KEYDEF::pack_record(TABLE *tbl, const uchar *record, // The following includes the 'extended key' tail: if (n_key_parts == 0 || n_key_parts == MAX_REF_PARTS) - n_key_parts= key_info->actual_key_parts; + n_key_parts= m_key_parts; for (uint i=0; i < n_key_parts; i++) { - Field *field= key_info->key_part[i].field; + /* + Field *field= (i < key_info->actual_key_parts)? + key_info->key_part[i].field : + tbl->key_info[tbl->s->primary_key].key_part[i - + key_info->actual_key_parts].field;*/ + Field *field= get_field_by_keynr(tbl, key_info, i); + my_ptrdiff_t ptr_diff= record - tbl->record[0]; field->move_field_offset(ptr_diff); @@ -312,10 +331,11 @@ int RDBSE_KEYDEF::unpack_record(TABLE *table, uchar *buf, if (unpack_info->size() != unpack_data_len) return 1; - for (uint i= 0; i < key_info->actual_key_parts ; i++) + for (uint i= 0; i < m_key_parts ; i++) { - Field *field= key_info->key_part[i].field; Field_pack_info *fpi= &pack_info[i]; + //Field *field= fpi->field; + Field *field= get_field_by_keynr(table, key_info, i); if (fpi->unpack_func) { diff --git a/storage/rocksdb/rdb_datadic.h b/storage/rocksdb/rdb_datadic.h index 362a30cb62b4..784518286c42 100644 --- a/storage/rocksdb/rdb_datadic.h +++ b/storage/rocksdb/rdb_datadic.h @@ -138,6 +138,7 @@ class RDBSE_KEYDEF pk_key_parts(NULL), pack_info(NULL), keyno(keyno_arg), + m_key_parts(0), maxlength(0) // means 'not intialized' { store_index_number(index_number_storage_form, indexnr_arg); @@ -181,6 +182,12 @@ class RDBSE_KEYDEF uint keyno; /* number of this index in the table */ + /* + Number of key parts in the index (including "index extension"). This is how + many elemants are in the pack_info array. + */ + uint m_key_parts; + /* Length of the mem-comparable form. In the encoding we're using, it is constant (any value will have this length).