Commit 5a598b55 authored by unknown's avatar unknown

Bug#17711: DELETE doesn't use index when ORDER BY, LIMIT and non-restricting

WHERE is present.

If a DELETE statement with ORDER BY and LIMIT contains a WHERE clause
with conditions that for sure cannot be used for index access (like in
WHERE @var:= field) the execution always follows the filesort path.    
It happens currently even when for the above case there is an index that
can be used to speedup sorting by the order by list.

Now if a DELETE statement with ORDER BY and LIMIT contains such WHERE
clause conditions that cannot be used to build any quick select then
the mysql_delete() tries to use an index like there is no WHERE clause at all.


mysql-test/t/delete.test:
  Added a test case for bug#17711: DELETE doesn't use index when ORDER BY, LIMIT and non-restricting
  WHERE is present.
mysql-test/r/delete.result:
  Added a test case for bug#17711: DELETE doesn't use index when ORDER BY, LIMIT and non-restricting WHERE is present.
sql/sql_delete.cc:
  Bug#17711: DELETE doesn't use index when ORDER BY, LIMIT and non-restricting WHERE is present.
  Now if a DELETE statement with ORDER BY and LIMIT contains such WHERE
  clause conditions that cannot be used to build any quick select then
  the mysql_delete() tries to use an index like there is no WHERE clause at all.
parent f9b95b29
......@@ -186,4 +186,11 @@ select count(*) from t1;
count(*)
0
drop table t1;
create table t1(f1 int primary key);
insert into t1 values (4),(3),(1),(2);
delete from t1 where (@a:= f1) order by f1 limit 1;
select @a;
@a
1
drop table t1;
End of 4.1 tests
......@@ -174,4 +174,14 @@ delete from t1 where a is null;
select count(*) from t1;
drop table t1;
#
# Bug#17711: DELETE doesn't use index when ORDER BY, LIMIT and
# non-restricting WHERE is present.
#
create table t1(f1 int primary key);
insert into t1 values (4),(3),(1),(2);
delete from t1 where (@a:= f1) order by f1 limit 1;
select @a;
drop table t1;
--echo End of 4.1 tests
......@@ -142,7 +142,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
DBUG_RETURN(-1); // This will force out message
}
if (!select && limit != HA_POS_ERROR)
if ((!select || table->quick_keys.is_clear_all()) && limit != HA_POS_ERROR)
usable_index= get_index_for_order(table, (ORDER*)(order->first), limit);
if (usable_index == MAX_KEY)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment