Skip to content

Commit

Permalink
MDEV-27270: Wrong query plan with Range Checked for Each Record and O…
Browse files Browse the repository at this point in the history
…RDER 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.
  • Loading branch information
spetrunia committed Dec 15, 2021
1 parent f1ca949 commit 136bcfd
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
23 changes: 23 additions & 0 deletions mysql-test/r/order_by_innodb.result
Original file line number Diff line number Diff line change
Expand Up @@ -198,5 +198,28 @@ id id
1 NULL
2 1
3 3
#
# MDEV-27270: Wrong query plan with Range Checked for Each Record and ORDER BY ... LIMIT
#
# This must NOT have "Range checked for each record" without any
# provisions to produce rows in the required ordering:
explain
select
t1.id,t2.id
from
t1 left join
t2 on t2.id2 = t1.id and
t2.id = (select dd.id
from t2 dd
where
dd.id2 = t1.id and
d1 > '2019-02-06 00:00:00'
order by
dd.d1, dd.d2, dd.id limit 1
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL PRIMARY 4 NULL # Using index
1 PRIMARY t2 eq_ref PRIMARY,id2 PRIMARY 4 func # Using where
2 DEPENDENT SUBQUERY dd range id2,for_latest_sort for_latest_sort 6 NULL # Using where
drop table t1,t2;
# End of 10.2 tests
22 changes: 22 additions & 0 deletions mysql-test/t/order_by_innodb.test
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,28 @@ from
order by
dd.d1 desc, dd.d2 desc, dd.id desc limit 1
);

--echo #
--echo # MDEV-27270: Wrong query plan with Range Checked for Each Record and ORDER BY ... LIMIT
--echo #

--echo # This must NOT have "Range checked for each record" without any
--echo # provisions to produce rows in the required ordering:
--replace_column 9 #
explain
select
t1.id,t2.id
from
t1 left join
t2 on t2.id2 = t1.id and
t2.id = (select dd.id
from t2 dd
where
dd.id2 = t1.id and
d1 > '2019-02-06 00:00:00'
order by
dd.d1, dd.d2, dd.id limit 1
);
drop table t1,t2;

--echo # End of 10.2 tests
8 changes: 8 additions & 0 deletions sql/sql_select.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21986,7 +21986,15 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
}
}
else if (select && select->quick)
{
/* Cancel "Range checked for each record" */
if (tab->use_quick == 2)
{
tab->use_quick= 1;
tab->read_first_record= join_init_read_record;
}
select->quick->need_sorted_output();
}

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

0 comments on commit 136bcfd

Please sign in to comment.