Skip to content

Commit 94e9dc9

Browse files
committed
MDEV-23600 Division by 0 in row_search_with_covering_prefix
The InnoDB index fields store bytes, not characters. Remove some unnecessary conversions from characters to bytes. This also fixes MDEV-20422 and the wrong-result bug MDEV-12486.
1 parent feac078 commit 94e9dc9

10 files changed

+439
-683
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[covering]
2+
innodb_prefix_index_cluster_optimization=on
3+
4+
[unoptimized]
5+
innodb_prefix_index_cluster_optimization=off
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--source include/have_innodb.inc

mysql-test/r/fast_prefix_index_fetch_innodb.result

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
drop table if exists prefixinno;
1+
SET @save_opt= @@GLOBAL.innodb_prefix_index_cluster_optimization;
22
set global innodb_prefix_index_cluster_optimization = ON;
33
show variables like 'innodb_prefix_index_cluster_optimization';
44
Variable_name Value
@@ -346,10 +346,10 @@ f1
346346
🐱🌑
347347
select @cluster_lookups;
348348
@cluster_lookups
349-
2
349+
1
350350
select @cluster_lookups_avoided;
351351
@cluster_lookups_avoided
352-
0
352+
1
353353
# Eligible - record length is shorter than prefix length
354354
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '🌑%';
355355
f1
@@ -366,10 +366,10 @@ f1
366366
🌒
367367
select @cluster_lookups;
368368
@cluster_lookups
369-
1
369+
0
370370
select @cluster_lookups_avoided;
371371
@cluster_lookups_avoided
372-
1
372+
2
373373
DROP TABLE t1;
374374
CREATE TABLE t1(
375375
col1 INT,
@@ -398,4 +398,49 @@ select @cluster_lookups_avoided;
398398
@cluster_lookups_avoided
399399
0
400400
DROP TABLE t1;
401-
set global innodb_prefix_index_cluster_optimization = OFF;
401+
#
402+
# MDEV-23600 Division by 0 in row_search_with_covering_prefix()
403+
#
404+
CREATE TABLE t(c POINT UNIQUE) ENGINE=InnoDB;
405+
INSERT t SET c=POINT(1,1);
406+
SELECT * FROM t WHERE c > (SELECT MAX(c) FROM t);
407+
c
408+
DROP TABLE t;
409+
#
410+
# MDEV-12486 Wrong results with innodb_prefix_index_cluster_optimization
411+
#
412+
CREATE TABLE wp_blogs (
413+
blog_id bigint(20) NOT NULL auto_increment,
414+
site_id bigint(20) NOT NULL default '0',
415+
domain varchar(200) NOT NULL default '',
416+
path varchar(100) NOT NULL default '',
417+
registered datetime NOT NULL default '0000-00-00 00:00:00',
418+
last_updated datetime NOT NULL default '0000-00-00 00:00:00',
419+
public tinyint(2) NOT NULL default '1',
420+
archived tinyint(2) NOT NULL default '0',
421+
mature tinyint(2) NOT NULL default '0',
422+
spam tinyint(2) NOT NULL default '0',
423+
deleted tinyint(2) NOT NULL default '0',
424+
lang_id int(11) NOT NULL default '0',
425+
PRIMARY KEY (blog_id),
426+
KEY domain (domain(50),path(5)),
427+
KEY lang_id (lang_id)
428+
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
429+
INSERT INTO wp_blogs (domain, path) VALUES
430+
('domain.no', '/fondsinvesteringer/'), ('domain.no', '/'),
431+
('foo', 'bar'), ('bar', 'foo'), ('foo', 'foo'), ('bar', 'bar'),
432+
('foo', 'foobar'), ('bar', 'foobar'), ('foobar', 'foobar');
433+
SET GLOBAL innodb_prefix_index_cluster_optimization=off;
434+
SELECT blog_id FROM wp_blogs WHERE domain IN ('domain.no')
435+
AND path IN ( '/fondsinvesteringer/', '/' );
436+
blog_id
437+
2
438+
1
439+
SET GLOBAL innodb_prefix_index_cluster_optimization=on;
440+
SELECT blog_id FROM wp_blogs WHERE domain IN ('domain.no')
441+
AND path IN ( '/fondsinvesteringer/', '/' );
442+
blog_id
443+
2
444+
1
445+
DROP TABLE wp_blogs;
446+
SET GLOBAL innodb_prefix_index_cluster_optimization = @save_opt;

mysql-test/r/innodb_ext_key,off.rdiff

Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
@@ -4,7 +4,7 @@
2+
explain
3+
select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01';
4+
id select_type table type possible_keys key key_len ref rows Extra
5+
-1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 8 const,const 1 Using index
6+
+1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 const 5 Using where
7+
flush status;
8+
select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01';
9+
count(*)
10+
@@ -14,7 +14,7 @@
11+
Handler_read_first 0
12+
Handler_read_key 1
13+
Handler_read_last 0
14+
-Handler_read_next 1
15+
+Handler_read_next 5
16+
Handler_read_prev 0
17+
Handler_read_retry 0
18+
Handler_read_rnd 0
19+
@@ -45,7 +45,7 @@
20+
select count(*) from lineitem
21+
where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000;
22+
id select_type table type possible_keys key key_len ref rows Extra
23+
-1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 8 NULL 1 Using where; Using index
24+
+1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 const 6 Using where; Using index
25+
flush status;
26+
select count(*) from lineitem
27+
where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000;
28+
@@ -56,7 +56,7 @@
29+
Handler_read_first 0
30+
Handler_read_key 1
31+
Handler_read_last 0
32+
-Handler_read_next 1
33+
+Handler_read_next 6
34+
Handler_read_prev 0
35+
Handler_read_retry 0
36+
Handler_read_rnd 0
37+
@@ -66,7 +66,7 @@
38+
select l_orderkey, l_linenumber from lineitem
39+
where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
40+
id select_type table type possible_keys key key_len ref rows Extra
41+
-1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 8 NULL 3 Using where; Using index
42+
+1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 const 6 Using where; Using index
43+
flush status;
44+
select l_orderkey, l_linenumber from lineitem
45+
where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
46+
@@ -79,7 +79,7 @@
47+
Handler_read_first 0
48+
Handler_read_key 1
49+
Handler_read_last 0
50+
-Handler_read_next 3
51+
+Handler_read_next 6
52+
Handler_read_prev 0
53+
Handler_read_retry 0
54+
Handler_read_rnd 0
55+
@@ -88,7 +88,7 @@
56+
explain
57+
select min(l_orderkey) from lineitem where l_shipdate='1992-07-01';
58+
id select_type table type possible_keys key key_len ref rows Extra
59+
-1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
60+
+1 SIMPLE lineitem ref i_l_shipdate i_l_shipdate 4 const 6 Using index
61+
flush status;
62+
select min(l_orderkey) from lineitem where l_shipdate='1992-07-01';
63+
min(l_orderkey)
64+
@@ -98,7 +98,7 @@
65+
Handler_read_first 0
66+
Handler_read_key 1
67+
Handler_read_last 0
68+
-Handler_read_next 0
69+
+Handler_read_next 6
70+
Handler_read_prev 0
71+
Handler_read_retry 0
72+
Handler_read_rnd 0
73+
@@ -108,7 +108,7 @@
74+
select min(l_orderkey) from lineitem
75+
where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
76+
id select_type table type possible_keys key key_len ref rows Extra
77+
-1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
78+
+1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 const 6 Using where; Using index
79+
flush status;
80+
select min(l_orderkey) from lineitem
81+
where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
82+
@@ -119,7 +119,7 @@
83+
Handler_read_first 0
84+
Handler_read_key 1
85+
Handler_read_last 0
86+
-Handler_read_next 0
87+
+Handler_read_next 6
88+
Handler_read_prev 0
89+
Handler_read_retry 0
90+
Handler_read_rnd 0
91+
@@ -129,7 +129,7 @@
92+
select max(l_linenumber) from lineitem
93+
where l_shipdate='1992-07-01' and l_orderkey=130;
94+
id select_type table type possible_keys key key_len ref rows Extra
95+
-1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
96+
+1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 const 5 Using where
97+
flush status;
98+
select max(l_linenumber) from lineitem
99+
where l_shipdate='1992-07-01' and l_orderkey=130;
100+
@@ -140,7 +140,7 @@
101+
Handler_read_first 0
102+
Handler_read_key 1
103+
Handler_read_last 0
104+
-Handler_read_next 0
105+
+Handler_read_next 5
106+
Handler_read_prev 0
107+
Handler_read_retry 0
108+
Handler_read_rnd 0
109+
@@ -152,7 +152,7 @@
110+
where l_shipdate='1992-07-01' and l_orderkey=130
111+
or l_receiptdate='1992-07-01' and l_orderkey=5603;
112+
id select_type table type possible_keys key key_len ref rows Extra
113+
-1 SIMPLE lineitem index_merge i_l_shipdate,i_l_receiptdate i_l_shipdate,i_l_receiptdate 8,8 NULL 2 Using union(i_l_shipdate,i_l_receiptdate); Using where
114+
+1 SIMPLE lineitem index_merge i_l_shipdate,i_l_receiptdate i_l_shipdate,i_l_receiptdate 4,4 NULL 9 Using union(i_l_shipdate,i_l_receiptdate); Using where
115+
flush status;
116+
select l_orderkey, l_linenumber
117+
from lineitem use index (i_l_shipdate, i_l_receiptdate)
118+
@@ -166,10 +166,10 @@
119+
Handler_read_first 0
120+
Handler_read_key 2
121+
Handler_read_last 0
122+
-Handler_read_next 2
123+
+Handler_read_next 9
124+
Handler_read_prev 0
125+
Handler_read_retry 0
126+
-Handler_read_rnd 2
127+
+Handler_read_rnd 9
128+
Handler_read_rnd_deleted 0
129+
Handler_read_rnd_next 0
130+
explain
131+
@@ -178,7 +178,7 @@
132+
where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
133+
or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000;
134+
id select_type table type possible_keys key key_len ref rows Extra
135+
-1 SIMPLE lineitem index_merge i_l_shipdate,i_l_receiptdate i_l_shipdate,i_l_receiptdate 8,8 NULL 3 Using sort_union(i_l_shipdate,i_l_receiptdate); Using where
136+
+1 SIMPLE lineitem index_merge i_l_shipdate,i_l_receiptdate i_l_shipdate,i_l_receiptdate 4,4 NULL 9 Using union(i_l_shipdate,i_l_receiptdate); Using where
137+
flush status;
138+
select l_orderkey, l_linenumber
139+
from lineitem use index (i_l_shipdate, i_l_receiptdate)
140+
@@ -193,10 +193,10 @@
141+
Handler_read_first 0
142+
Handler_read_key 2
143+
Handler_read_last 0
144+
-Handler_read_next 3
145+
+Handler_read_next 9
146+
Handler_read_prev 0
147+
Handler_read_retry 0
148+
-Handler_read_rnd 3
149+
+Handler_read_rnd 9
150+
Handler_read_rnd_deleted 0
151+
Handler_read_rnd_next 0
152+
explain
153+
@@ -204,7 +204,7 @@
154+
where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
155+
or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000;
156+
id select_type table type possible_keys key key_len ref rows Extra
157+
-1 SIMPLE lineitem index_merge PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate,i_l_receiptdate 8,8 NULL 3 Using sort_union(i_l_shipdate,i_l_receiptdate); Using where
158+
+1 SIMPLE lineitem index_merge PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate,PRIMARY,i_l_receiptdate,PRIMARY 4,4,4,4 NULL 2 Using union(intersect(i_l_shipdate,PRIMARY),intersect(i_l_receiptdate,PRIMARY)); Using where
159+
flush status;
160+
select l_orderkey, l_linenumber from lineitem
161+
where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
162+
@@ -218,7 +218,7 @@
163+
Handler_read_first 0
164+
Handler_read_key 2
165+
Handler_read_last 0
166+
-Handler_read_next 3
167+
+Handler_read_next 9
168+
Handler_read_prev 0
169+
Handler_read_retry 0
170+
Handler_read_rnd 3
171+
@@ -228,7 +228,7 @@
172+
select max(l_orderkey) from lineitem
173+
where l_partkey between 1 and 10 group by l_partkey;
174+
id select_type table type possible_keys key key_len ref rows Extra
175+
-1 SIMPLE lineitem range i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 NULL # Using where; Using index for group-by
176+
+1 SIMPLE lineitem range i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 NULL # Using where; Using index
177+
flush status;
178+
select max(l_orderkey) from lineitem
179+
where l_partkey between 1 and 10 group by l_partkey;
180+
@@ -246,9 +246,9 @@
181+
show status like 'handler_read%';
182+
Variable_name Value
183+
Handler_read_first 0
184+
-Handler_read_key 21
185+
-Handler_read_last 1
186+
-Handler_read_next 0
187+
+Handler_read_key 1
188+
+Handler_read_last 0
189+
+Handler_read_next 294
190+
Handler_read_prev 0
191+
Handler_read_retry 0
192+
Handler_read_rnd 0
193+
@@ -258,7 +258,7 @@
194+
select max(l_orderkey) from lineitem
195+
where l_suppkey in (1,4) group by l_suppkey;
196+
id select_type table type possible_keys key key_len ref rows Extra
197+
-1 SIMPLE lineitem range i_l_suppkey i_l_suppkey 5 NULL # Using where; Using index for group-by
198+
+1 SIMPLE lineitem range i_l_suppkey i_l_suppkey 5 NULL # Using where; Using index
199+
flush status;
200+
select max(l_orderkey) from lineitem
201+
where l_suppkey in (1,4) group by l_suppkey;
202+
@@ -268,9 +268,9 @@
203+
show status like 'handler_read%';
204+
Variable_name Value
205+
Handler_read_first 0
206+
-Handler_read_key 6
207+
-Handler_read_last 1
208+
-Handler_read_next 0
209+
+Handler_read_key 2
210+
+Handler_read_last 0
211+
+Handler_read_next 1230
212+
Handler_read_prev 0
213+
Handler_read_retry 0
214+
Handler_read_rnd 0
215+
@@ -286,7 +286,7 @@
216+
id select_type table type possible_keys key key_len ref rows Extra
217+
1 SIMPLE part range i_p_retailprice i_p_retailprice 9 NULL # Using where; Using index
218+
1 SIMPLE orders ref PRIMARY,i_o_orderdate i_o_orderdate 4 const # Using index
219+
-1 SIMPLE lineitem ref i_l_partkey i_l_partkey 9 dbt3_s001.part.p_partkey,dbt3_s001.orders.o_orderkey # Using index
220+
+1 SIMPLE lineitem ref i_l_partkey i_l_partkey 5 dbt3_s001.part.p_partkey # Using where; Using index
221+
flush status;
222+
select o_orderkey, p_partkey
223+
from part use index (i_p_retailprice),
224+
@@ -300,7 +300,7 @@
225+
Handler_read_first 0
226+
Handler_read_key 3
227+
Handler_read_last 0
228+
-Handler_read_next 3
229+
+Handler_read_next 26
230+
Handler_read_prev 0
231+
Handler_read_retry 0
232+
Handler_read_rnd 0
233+
@@ -317,8 +317,8 @@
234+
select * from t0, part ignore index (primary)
235+
where p_partkey=t0.a and p_size=1;
236+
id select_type table type possible_keys key key_len ref rows Extra
237+
-1 SIMPLE t0 ALL NULL NULL NULL NULL 5 Using where
238+
-1 SIMPLE part eq_ref i_p_size i_p_size 9 const,dbt3_s001.t0.a 1
239+
+1 SIMPLE t0 ALL NULL NULL NULL NULL 5
240+
+1 SIMPLE part ref i_p_size i_p_size 5 const 5 Using index condition
241+
select * from t0, part ignore index (primary)
242+
where p_partkey=t0.a and p_size=1;
243+
a p_partkey p_name p_mfgr p_brand p_type p_size p_container p_retailprice p_comment
244+
@@ -495,7 +495,7 @@
245+
select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a and t3.pk1=t1.a;
246+
id select_type table type possible_keys key key_len ref rows Extra
247+
1 SIMPLE t1 ALL NULL NULL NULL NULL # Using where
248+
-1 SIMPLE t3 ref PRIMARY,col1 col1 12 test.t1.a,test.t1.a,test.t1.a # Using index
249+
+1 SIMPLE t3 ref PRIMARY,col1 col1 8 test.t1.a,test.t1.a # Using where; Using index
250+
drop table t1,t2,t3;
251+
#
252+
# Bug mdev-4340: performance regression with extended_keys=on
253+
@@ -705,13 +705,13 @@
254+
select * from t1 force index(index_date_updated)
255+
where index_date_updated= 10 and index_id < 800;
256+
id select_type table type possible_keys key key_len ref rows Extra
257+
-1 SIMPLE t1 range index_date_updated index_date_updated 13 NULL # Using index condition
258+
+1 SIMPLE t1 ref index_date_updated index_date_updated 5 const # Using index condition
259+
# This used to work from the start:
260+
explain
261+
select * from t2 force index(index_date_updated)
262+
where index_date_updated= 10 and index_id < 800;
263+
id select_type table type possible_keys key key_len ref rows Extra
264+
-1 SIMPLE t2 range index_date_updated index_date_updated 13 NULL # Using index condition
265+
+1 SIMPLE t2 ref index_date_updated index_date_updated 5 const # Using index condition
266+
drop table t0,t1,t2;
267+
#
268+
# MDEV-11196: Error:Run-Time Check Failure #2 - Stack around the variable 'key_buff'
269+
@@ -746,11 +746,12 @@
270+
"select_id": 1,
271+
"table": {
272+
"table_name": "t1",
273+
- "access_type": "range",
274+
+ "access_type": "ref",
275+
"possible_keys": ["f2"],
276+
"key": "f2",
277+
- "key_length": "3070",
278+
- "used_key_parts": ["f2", "pk1"],
279+
+ "key_length": "3066",
280+
+ "used_key_parts": ["f2"],
281+
+ "ref": ["const"],
282+
"rows": 1,
283+
"filtered": 100,
284+
"index_condition": "t1.pk1 <= 5 and t1.pk2 <= 5 and t1.f2 = 'abc'",
285+
@@ -779,8 +780,8 @@
286+
"access_type": "range",
287+
"possible_keys": ["k1"],
288+
"key": "k1",
289+
- "key_length": "3011",
290+
- "used_key_parts": ["pk1", "f2", "pk2"],
291+
+ "key_length": "3007",
292+
+ "used_key_parts": ["pk1", "f2"],
293+
"rows": 1,
294+
"filtered": 100,
295+
"index_condition": "t1.f2 <= 5 and t1.pk2 <= 5 and t1.pk1 = 'abc'",

0 commit comments

Comments
 (0)