Bug #241 UPDATE ... ORDER BY does not work with InnoDB
Submitted: 7 Apr 2003 19:24 Modified: 23 Apr 2003 4:27
Reporter: Mark Mentovai
Status: Closed
Category:Server: InnoDB Severity:S2 (Serious)
Version:4.0.12 OS:sparc-sun-solaris2.8
Assigned to: Bugs System Target Version:

[7 Apr 2003 19:24] Mark Mentovai
Description:
UPDATE ... ORDER BY does not work properly with InnoDB when the WHERE clause references
an indexed column.  When ORDER BY is specified, the UPDATE statement will not find any
matching rows to update, even though a similar SELECT statement indicates that rows to be
updated are present in the table.  The correct behavior of UPDATE ... ORDER BY is
described in section 6.4.5 of the manual, at http://www.mysql.com/doc/en/UPDATE.html . 
MyISAM tables function as advertised.

Table Set-Up:
create table innodb (
  id int primary key auto_increment,
  fk int,
  index index_fk (fk)
) type=innodb;
insert into innodb (id) values (null),(null),(null),(null),(null);
+----+------+
| id | fk   |
+----+------+
|  1 | NULL |
|  2 | NULL |
|  3 | NULL |
|  4 | NULL |
|  5 | NULL |
+----+------+

Then, execute:
update innodb set fk=69 where fk is null order by id limit 1;

Observed result:
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0
+----+------+
| id | fk   |
+----+------+
|  1 | NULL |
|  2 | NULL |
|  3 | NULL |
|  4 | NULL |
|  5 | NULL |
+----+------+

Expected result:
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
+----+------+
| id | fk   |
+----+------+
|  1 |   69 |
|  2 | NULL |
|  3 | NULL |
|  4 | NULL |
|  5 | NULL |
+----+------+

Workaround: Do not use ORDER BY in UPDATE on InnoDB tables.

How to repeat:
# The following two sets of operations are identical except for the table
# type.  The first uses InnoDB and exposes the bug.  The second uses MyISAM,
# where the correct behavior is observed.

create table innodb (
  id int primary key auto_increment,
  fk int,
  index index_fk (fk)
) type=innodb;
insert into innodb (id) values (null),(null),(null),(null),(null);
# The WHERE ... ORDER BY ... LIMIT clause functions properly with SELECT.
select * from innodb where fk is null order by id limit 1;
# But it does not function properly with UPDATE, which will not find anything
# to update.
update innodb set fk=69 where fk is null order by id limit 1;
# This should return one row if the update was made as expected.
select * from innodb where fk=69;

# In contrast, it functions properly with a MyISAM table:
create table myisam (
  id int primary key auto_increment,
  fk int,
  index index_fk (fk)
) type=myisam;
insert into myisam (id) values (null),(null),(null),(null),(null);
select * from myisam where fk is null order by id limit 1;
update myisam set fk=69 where fk is null order by id limit 1;
select * from myisam where fk=69;
[22 Apr 2003 12:41] Heikki Tuuri
The code in sql_update.cc seems to ignore the sorted file for all table types. Also for
MyISAM tables

UPDATE ... ORDER BY ... LIMIT 1

updates the rows in an arbitrary order, not in the order specified in ORDER BY. See my
email sent to MySQL AB mailing lists a few days ago.

I modified 4.0.13 so that InnoDB now updates some rows, but the general bug that the
order is not right remains.
[23 Apr 2003 4:27] Michael Widenius
Thank you for your bug report. This issue has been fixed in the latest
development tree for that product. You can find more information about
accessing our development trees at 
    http://www.mysql.com/doc/en/Installing_source_tree.html

Fix will appear in 4.0.13 and 4.1.1