Bug #21180 Subselect with index for both WHERE and ORDER BY produces empty result

Submitted: 20 Jul 2006 14:00 Modified: 25 Sep 2006 17:54
Reporter: Svetoslav Naidenov Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S2 (Serious)
Version:5.0.22/4.1/5.0/5.1BK OS:Linux (linux and windows)
Assigned to: Georgi Kodinov CPU Architecture:Any

[20 Jul 2006 14:00] Svetoslav Naidenov
Description:
Using subselect with ORDER BY LIMIT 1, produces empty result for Innodb tables
and error for MYISAM tables

How to repeat:
drop table if exists rr;
create table rr(
  routing_id int not null AUTO_INCREMENT,
  primary key (routing_id)
) engine=INNODB;
insert into rr values (1), (10);

drop table if exists rt;
create table rt
(
  route_id int not null AUTO_INCREMENT,
  route_prefix varchar(32),
  routing_id int not null,
  primary key (route_id),
  unique key route_prefix(routing_id, route_prefix)
) engine=INNODB;
insert into rt(routing_id, route_prefix) values 
  (1, '359'), (1, '35988'), (1,'35989'),(10, '359'),
  (10, '35988'), (10,'35989');

SELECT route_id
FROM rt
WHERE rt.routing_id = 10
  AND route_prefix <= '359899'
ORDER BY routing_id DESC, route_prefix DESC
LIMIT 1;
+----------+
| route_id |
+----------+
|        6 |
+----------+

SELECT
  rr.routing_id, r.route_id, r.route_prefix
FROM rr
  LEFT JOIN rt r ON r.route_id = (
    SELECT route_id
    FROM rt
    WHERE rt.routing_id = rr.routing_id
      AND route_prefix <= '359899'
    ORDER BY routing_id DESC, route_prefix DESC
    LIMIT 1)
WHERE rr.routing_id = 10;
+------------+--------------+
| routing_id | route_prefix |
+------------+--------------+
|         10 | NULL         |
+------------+--------------+

If table rt is in MYISAM format the second query either never finishes or
gives error:
Incorrect key file for table './bss/rt.MYI'; try to repair it

Rewriting the subquery with useless function to trick optimizer produces correct result (for the cost of performance if the table is large):
SELECT
  rr.routing_id, r.route_id, r.route_prefix
FROM rr
  LEFT JOIN rt r ON r.route_id = (
    SELECT route_id
    FROM rt
    WHERE rt.routing_id = rr.routing_id
      AND IFNULL(route_prefix,'') <= '359899'
    ORDER BY routing_id DESC, route_prefix DESC
    LIMIT 1)
WHERE rr.routing_id = 10;
+------------+----------+--------------+
| routing_id | route_id | route_prefix |
+------------+----------+--------------+
|         10 |        6 | 35989        |
+------------+----------+--------------+
[20 Jul 2006 16:35] MySQL Verification Team
Thank you for the bug report.
[3 Aug 2006 16:20] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/10017

ChangeSet@1.2532, 2006-08-03 19:20:30+03:00, gkodinov@macbook.gmz +4 -0
  Bug #21180: Subselect with index for both WHERE and ORDER BY produces empty result
   Reseting subqueries with "quick" access methods was incomplete.
   Partially backported the correct reseting of QUICK_SELECTs from 5.x.
[15 Sep 2006 16:02] Georgi Kodinov
I've partially back-ported the 5.0 code. In 5.0 this was fixed by the fix for either BUG#21077 or BUG#20869.
[19 Sep 2006 8:28] Georgi Kodinov
Pushed into 4.1.22/5.0.26/5.1.12-beta
[25 Sep 2006 17:54] Paul DuBois
Noted in 4.1.22, 5.0.26, 5.1.12 changelogs.

A subquery that uses an index for both the WHERE and ORDER BY clauses
produced an empty result.

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.061 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.