Skip to content

Commit dd7eeae

Browse files
committed
Issue#250: MyRocks/Innodb different output from query with order by on table with index and decimal type
Summary: Make open_binary_frm() set TABLE_SHARE::primary_key before it computes "handler->index_flags(keyno, ...) & HA_KEYREAD_ONLY". In MyRocks, the value of this expression depends on whether keyno is a clustered PK or not, so it's essential that MyRocks sees the correct value in TABLE_SHARE::primary_key. Test Plan: Run MTR Reviewers: yoshinorim, alexyang, jtolmer, jkedgar, hermanlee4 Reviewed By: hermanlee4 Subscribers: webscalesql-eng Differential Revision: https://reviews.facebook.net/D58329
1 parent 3da14f2 commit dd7eeae

File tree

4 files changed

+64
-7
lines changed

4 files changed

+64
-7
lines changed

mysql-test/suite/rocksdb/r/rocksdb.result

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2379,4 +2379,23 @@ Warning 1264 Out of range value for column 'a' at row 2
23792379
Warning 1264 Out of range value for column 'b' at row 2
23802380
UNLOCK TABLES;
23812381
DROP TABLE t1;
2382+
#
2383+
# Issue#250: MyRocks/Innodb different output from query with order by on table with index and decimal type
2384+
#
2385+
CREATE TABLE t1(
2386+
c1 DECIMAL(65,0) UNSIGNED NOT NULL,
2387+
c2 DECIMAL(65,0) SIGNED NULL,
2388+
c3 INT,
2389+
INDEX idx(c1,c2)
2390+
);
2391+
INSERT INTO t1 VALUES (0,'1999',5);
2392+
SELECT * FROM t1 force index(idx) WHERE c1 <> '1' ORDER BY c1 DESC;
2393+
c1 c2 c3
2394+
0 1999 5
2395+
# This must not use ICP. when/if MyRocks supports index-only for
2396+
# DECIMAL, switch this testcase to use another datatype
2397+
explain SELECT * FROM t1 force index(idx) WHERE c1 <> '1' ORDER BY c1 DESC;
2398+
id select_type table type possible_keys key key_len ref rows Extra
2399+
1 SIMPLE t1 range idx idx 29 NULL # Using where
2400+
drop table t1;
23822401
SET GLOBAL ROCKSDB_PAUSE_BACKGROUND_WORK = @ORIG_PAUSE_BACKGROUND_WORK;

mysql-test/suite/rocksdb/t/rocksdb.test

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1865,5 +1865,23 @@ INSERT INTO t1 VALUES(X'042000200020',X'042000200020'),(X'200400200020',X'200400
18651865
UNLOCK TABLES;
18661866
DROP TABLE t1;
18671867

1868+
--echo #
1869+
--echo # Issue#250: MyRocks/Innodb different output from query with order by on table with index and decimal type
1870+
--echo #
1871+
1872+
CREATE TABLE t1(
1873+
c1 DECIMAL(65,0) UNSIGNED NOT NULL,
1874+
c2 DECIMAL(65,0) SIGNED NULL,
1875+
c3 INT,
1876+
INDEX idx(c1,c2)
1877+
);
1878+
INSERT INTO t1 VALUES (0,'1999',5);
1879+
SELECT * FROM t1 force index(idx) WHERE c1 <> '1' ORDER BY c1 DESC;
1880+
--echo # This must not use ICP. when/if MyRocks supports index-only for
1881+
--echo # DECIMAL, switch this testcase to use another datatype
1882+
--replace_column 9 #
1883+
explain SELECT * FROM t1 force index(idx) WHERE c1 <> '1' ORDER BY c1 DESC;
1884+
1885+
drop table t1;
18681886

18691887
SET GLOBAL ROCKSDB_PAUSE_BACKGROUND_WORK = @ORIG_PAUSE_BACKGROUND_WORK;

sql/table.cc

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,6 +2016,17 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
20162016
{
20172017
uint primary_key=(uint) (find_type(primary_key_name, &share->keynames,
20182018
FIND_TYPE_NO_PREFIX) - 1);
2019+
/*
2020+
The following if-else is here for MyRocks:
2021+
set share->primary_key as early as possible, because the return value
2022+
of ha_rocksdb::index_flags(key, ...) (HA_KEYREAD_ONLY bit in particular)
2023+
depends on whether the key is the primary key.
2024+
*/
2025+
if (primary_key < MAX_KEY && share->keys_in_use.is_set(primary_key))
2026+
share->primary_key= primary_key;
2027+
else
2028+
share->primary_key= MAX_KEY;
2029+
20192030
longlong ha_option= handler_file->ha_table_flags();
20202031
keyinfo= share->key_info;
20212032
key_part= keyinfo->key_part;
@@ -2070,6 +2081,13 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
20702081
break;
20712082
}
20722083
}
2084+
2085+
/*
2086+
The following is here for MyRocks. See the comment above
2087+
about "set share->primary_key as early as possible"
2088+
*/
2089+
if (primary_key < MAX_KEY && share->keys_in_use.is_set(primary_key))
2090+
share->primary_key= primary_key;
20732091
}
20742092

20752093
for (i=0 ; i < keyinfo->user_defined_key_parts ; key_part++,i++)
@@ -2230,10 +2248,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
22302248
}
22312249
}
22322250

2233-
if (primary_key < MAX_KEY &&
2234-
(share->keys_in_use.is_set(primary_key)))
2251+
if (share->primary_key != MAX_KEY)
22352252
{
2236-
share->primary_key= primary_key;
22372253
/*
22382254
If we are using an integer as the primary key then allow the user to
22392255
refer to it as '_rowid'
@@ -2249,8 +2265,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
22492265
}
22502266
}
22512267
}
2252-
else
2253-
share->primary_key = MAX_KEY; // we do not have a primary key
22542268
}
22552269
else
22562270
share->primary_key= MAX_KEY;

storage/rocksdb/ha_rocksdb.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3204,8 +3204,14 @@ const char **ha_rocksdb::bas_ext() const
32043204
bool ha_rocksdb::init_with_fields()
32053205
{
32063206
uint pk= table_share->primary_key;
3207-
uint key_parts= table_share->key_info[pk].user_defined_key_parts;
3208-
check_keyread_allowed(pk /*PK*/, key_parts-1, true);
3207+
if (pk != MAX_KEY)
3208+
{
3209+
uint key_parts= table_share->key_info[pk].user_defined_key_parts;
3210+
check_keyread_allowed(pk /*PK*/, key_parts-1, true);
3211+
}
3212+
else
3213+
m_pk_can_be_decoded= false;
3214+
32093215
cached_table_flags= table_flags();
32103216
return false; /* Ok */
32113217
}

0 commit comments

Comments
 (0)