Skip to content

Commit e4cffc9

Browse files
MDEV-27172 Prefix indices on Spider tables may lead to wrong query results
Spider converts HA_READ_KEY_EXACT to the equality (=) in the function spider_db_append_key_where_internal() but the conversion is not necessarily correct for tables with prefix indices. We fix the bug by converting HA_READ_KEY_EXACT to 'LIKE "foo%"' when a target key is a prefix key. The fix is partly inspired by FEDERATED. See ha_federated::create_where_from_key() for more details.
1 parent 4f2dc71 commit e4cffc9

File tree

7 files changed

+334
-251
lines changed

7 files changed

+334
-251
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#
2+
# MDEV-27172 Prefix indices on Spider tables may lead to wrong query results
3+
#
4+
for master_1
5+
for child2
6+
child2_1
7+
child2_2
8+
child2_3
9+
for child3
10+
connection child2_1;
11+
SET @general_log_backup = @@global.general_log;
12+
SET @log_output_backup = @@global.log_output;
13+
SET @@global.general_log = 1;
14+
SET @@global.log_output = "TABLE";
15+
CREATE DATABASE auto_test_remote;
16+
USE auto_test_remote;
17+
CREATE TABLE tbl_a (
18+
id int NOT NULL,
19+
greeting VARCHAR(255),
20+
KEY(greeting)
21+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
22+
CREATE TABLE tbl_b (
23+
id int NOT NULL,
24+
greeting VARCHAR(255),
25+
KEY k (greeting(5))
26+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
27+
CREATE TABLE tbl_c (
28+
id int NOT NULL,
29+
greeting TEXT,
30+
KEY k (greeting(5))
31+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
32+
TRUNCATE TABLE mysql.general_log;
33+
connection master_1;
34+
CREATE DATABASE auto_test_local;
35+
USE auto_test_local;
36+
CREATE TABLE tbl_a (
37+
id int NOT NULL,
38+
greeting VARCHAR(255),
39+
KEY k (greeting)
40+
) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"';
41+
INSERT INTO tbl_a VALUES (1, "Hi!"),(2, "Aloha!"),(3, "Aloha!!!");
42+
SELECT * FROM tbl_a WHERE greeting = "Aloha!"
43+
AND CASE greeting WHEN "Aloha!" THEN "one" ELSE 'more' END = "one";
44+
id greeting
45+
2 Aloha!
46+
CREATE TABLE tbl_b (
47+
id int NOT NULL,
48+
greeting VARCHAR(255),
49+
KEY k (greeting(5))
50+
) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_b", srv "s_2_1"';
51+
INSERT INTO tbl_b VALUES (1, "Hi!"),(2, "Aloha!"),(3, "Aloha!!!");
52+
SELECT * FROM tbl_b WHERE greeting = "Aloha!"
53+
AND CASE greeting WHEN "Aloha!" THEN "one" ELSE 'more' END = "one";
54+
id greeting
55+
2 Aloha!
56+
CREATE TABLE tbl_c (
57+
id int NOT NULL,
58+
greeting TEXT,
59+
KEY k (greeting(5))
60+
) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_c", srv "s_2_1"';
61+
INSERT INTO tbl_c VALUES (1, "Hi!"),(2, "Aloha!"),(3, "Aloha!!!");
62+
SELECT * FROM tbl_c WHERE greeting = "Aloha!"
63+
AND CASE greeting WHEN "Aloha!" THEN "one" ELSE 'more' END = "one";
64+
id greeting
65+
2 Aloha!
66+
connection child2_1;
67+
SELECT argument FROM mysql.general_log WHERE argument LIKE 'select %';
68+
argument
69+
select `id`,`greeting` from `auto_test_remote`.`tbl_a` where `greeting` = 'Aloha!' and ((`greeting` = 'Aloha!'))
70+
select `id`,`greeting` from `auto_test_remote`.`tbl_b` where `greeting` like 'Aloha%' and ((`greeting` = 'Aloha!'))
71+
select `id`,`greeting` from `auto_test_remote`.`tbl_c` where `greeting` like 'Aloha%' and ((`greeting` = 'Aloha!'))
72+
SELECT argument FROM mysql.general_log WHERE argument LIKE 'select %'
73+
connection child2_1;
74+
SET @@global.general_log = @general_log_backup;
75+
SET @@global.log_output = @log_output_backup;
76+
DROP DATABASE auto_test_remote;
77+
connection master_1;
78+
DROP DATABASE auto_test_local;
79+
for master_1
80+
for child2
81+
child2_1
82+
child2_2
83+
child2_3
84+
for child3
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
!include include/default_mysqld.cnf
2+
!include ../my_1_1.cnf
3+
!include ../my_2_1.cnf
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
--echo #
2+
--echo # MDEV-27172 Prefix indices on Spider tables may lead to wrong query results
3+
--echo #
4+
5+
--disable_query_log
6+
--disable_result_log
7+
--source ../../t/test_init.inc
8+
--enable_result_log
9+
--enable_query_log
10+
11+
--connection child2_1
12+
SET @general_log_backup = @@global.general_log;
13+
SET @log_output_backup = @@global.log_output;
14+
SET @@global.general_log = 1;
15+
SET @@global.log_output = "TABLE";
16+
17+
CREATE DATABASE auto_test_remote;
18+
USE auto_test_remote;
19+
20+
eval CREATE TABLE tbl_a (
21+
id int NOT NULL,
22+
greeting VARCHAR(255),
23+
KEY(greeting)
24+
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
25+
26+
eval CREATE TABLE tbl_b (
27+
id int NOT NULL,
28+
greeting VARCHAR(255),
29+
KEY k (greeting(5))
30+
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
31+
32+
eval CREATE TABLE tbl_c (
33+
id int NOT NULL,
34+
greeting TEXT,
35+
KEY k (greeting(5))
36+
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
37+
38+
TRUNCATE TABLE mysql.general_log;
39+
40+
--connection master_1
41+
CREATE DATABASE auto_test_local;
42+
USE auto_test_local;
43+
44+
# = (equality)
45+
eval CREATE TABLE tbl_a (
46+
id int NOT NULL,
47+
greeting VARCHAR(255),
48+
KEY k (greeting)
49+
) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"';
50+
51+
INSERT INTO tbl_a VALUES (1, "Hi!"),(2, "Aloha!"),(3, "Aloha!!!");
52+
SELECT * FROM tbl_a WHERE greeting = "Aloha!"
53+
AND CASE greeting WHEN "Aloha!" THEN "one" ELSE 'more' END = "one"; # hack to disable GBH
54+
55+
# LIKE
56+
eval CREATE TABLE tbl_b (
57+
id int NOT NULL,
58+
greeting VARCHAR(255),
59+
KEY k (greeting(5))
60+
) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_b", srv "s_2_1"';
61+
62+
INSERT INTO tbl_b VALUES (1, "Hi!"),(2, "Aloha!"),(3, "Aloha!!!");
63+
SELECT * FROM tbl_b WHERE greeting = "Aloha!"
64+
AND CASE greeting WHEN "Aloha!" THEN "one" ELSE 'more' END = "one"; # hack to disable GBH
65+
66+
# LIKE
67+
eval CREATE TABLE tbl_c (
68+
id int NOT NULL,
69+
greeting TEXT,
70+
KEY k (greeting(5))
71+
) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_c", srv "s_2_1"';
72+
73+
INSERT INTO tbl_c VALUES (1, "Hi!"),(2, "Aloha!"),(3, "Aloha!!!");
74+
SELECT * FROM tbl_c WHERE greeting = "Aloha!"
75+
AND CASE greeting WHEN "Aloha!" THEN "one" ELSE 'more' END = "one"; # hack to disable GBH
76+
77+
--connection child2_1
78+
SELECT argument FROM mysql.general_log WHERE argument LIKE 'select %';
79+
80+
--connection child2_1
81+
SET @@global.general_log = @general_log_backup;
82+
SET @@global.log_output = @log_output_backup;
83+
DROP DATABASE auto_test_remote;
84+
85+
--connection master_1
86+
DROP DATABASE auto_test_local;
87+
88+
--disable_query_log
89+
--disable_result_log
90+
--source ../../t/test_deinit.inc
91+
--enable_result_log
92+
--enable_query_log

0 commit comments

Comments
 (0)