Skip to content

Commit 136bcfd

Browse files
committed
MDEV-27270: Wrong query plan with Range Checked for Each Record and ORDER BY ... LIMIT
Followup to fix for MDEV-25858: When test_if_skip_sort_order() decides to use an index to satisfy ORDER BY ... LIMIT clause, it should disable "Range Checked for Each Record" optimization. Do this in all cases.
1 parent f1ca949 commit 136bcfd

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

mysql-test/r/order_by_innodb.result

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,5 +198,28 @@ id id
198198
1 NULL
199199
2 1
200200
3 3
201+
#
202+
# MDEV-27270: Wrong query plan with Range Checked for Each Record and ORDER BY ... LIMIT
203+
#
204+
# This must NOT have "Range checked for each record" without any
205+
# provisions to produce rows in the required ordering:
206+
explain
207+
select
208+
t1.id,t2.id
209+
from
210+
t1 left join
211+
t2 on t2.id2 = t1.id and
212+
t2.id = (select dd.id
213+
from t2 dd
214+
where
215+
dd.id2 = t1.id and
216+
d1 > '2019-02-06 00:00:00'
217+
order by
218+
dd.d1, dd.d2, dd.id limit 1
219+
);
220+
id select_type table type possible_keys key key_len ref rows Extra
221+
1 PRIMARY t1 index NULL PRIMARY 4 NULL # Using index
222+
1 PRIMARY t2 eq_ref PRIMARY,id2 PRIMARY 4 func # Using where
223+
2 DEPENDENT SUBQUERY dd range id2,for_latest_sort for_latest_sort 6 NULL # Using where
201224
drop table t1,t2;
202225
# End of 10.2 tests

mysql-test/t/order_by_innodb.test

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,28 @@ from
184184
order by
185185
dd.d1 desc, dd.d2 desc, dd.id desc limit 1
186186
);
187+
188+
--echo #
189+
--echo # MDEV-27270: Wrong query plan with Range Checked for Each Record and ORDER BY ... LIMIT
190+
--echo #
191+
192+
--echo # This must NOT have "Range checked for each record" without any
193+
--echo # provisions to produce rows in the required ordering:
194+
--replace_column 9 #
195+
explain
196+
select
197+
t1.id,t2.id
198+
from
199+
t1 left join
200+
t2 on t2.id2 = t1.id and
201+
t2.id = (select dd.id
202+
from t2 dd
203+
where
204+
dd.id2 = t1.id and
205+
d1 > '2019-02-06 00:00:00'
206+
order by
207+
dd.d1, dd.d2, dd.id limit 1
208+
);
187209
drop table t1,t2;
188210

189211
--echo # End of 10.2 tests

sql/sql_select.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21986,7 +21986,15 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
2198621986
}
2198721987
}
2198821988
else if (select && select->quick)
21989+
{
21990+
/* Cancel "Range checked for each record" */
21991+
if (tab->use_quick == 2)
21992+
{
21993+
tab->use_quick= 1;
21994+
tab->read_first_record= join_init_read_record;
21995+
}
2198921996
select->quick->need_sorted_output();
21997+
}
2199021998

2199121999
tab->read_record.unlock_row= (tab->type == JT_EQ_REF) ?
2199222000
join_read_key_unlock_row : rr_unlock_row;

0 commit comments

Comments
 (0)