Bug #28505 | Update count for an INSERT DUPLICATE KEY not correct when CLIENT_FOUND_ROWS set | ||
---|---|---|---|
Submitted: | 18 May 2007 0:19 | Modified: | 19 Jun 2007 0:56 |
Reporter: | Chris Lamprecht | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server | Severity: | S2 (Serious) |
Version: | 3.1.10, and 5.0.6 | OS: | Any |
Assigned to: | Evgeny Potemkin | CPU Architecture: | Any |
Tags: | connectorj, getgeneratedkeys, jdbc, LAST_INSERT_ID |
[18 May 2007 0:19]
Chris Lamprecht
[18 May 2007 12:36]
Mark Matthews
Sveta, I'd take a look on the wire to see if MySQL is returning the auto-increment value as part of the return for the DML statement, as that's what Connector/J uses for Statement.getGeneratedKeys(). It sounds like there's a disconnect between LAST_INSERT_ID() and what's returned directly by the server to the client for the DML (you could test this with a C testcase and mysql_insert_id(), or you could just look at the update reply packet with Wireshark).
[23 May 2007 10:33]
Sveta Smirnova
Thank you for the report. According to JDBC manual (http://java.sun.com/j2se/1.4.2/docs/api/java/sql/Statement.html#getGeneratedKeys()) : "public ResultSet getGeneratedKeys() throws SQLException Retrieves any auto-generated keys created as a result of executing this Statement object. If this Statement object did not generate any keys, an empty ResultSet object is returned" But when I run presented test case in mysql command line client, I get information for last statement about data has not been changed: $mysql test Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 268 Server version: 5.0.41 MySQL Community Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> CREATE TABLE genkeytest (id int(10) PRIMARY KEY AUTO_INCREMENT NOT NULL, name char(20) NOT NULL, UNIQUE INDEX name (name)); Query OK, 0 rows affected (0.07 sec) mysql> INSERT INTO genkeytest (id, name) VALUES (NULL, 'test1') ON DUPLICATE KEY UPDATE id = last_insert_id(id); Query OK, 1 row affected (0.00 sec) mysql> SELECT LAST_INSERT_ID(); +------------------+ | LAST_INSERT_ID() | +------------------+ | 1 | +------------------+ 1 row in set (0.00 sec) mysql> INSERT INTO genkeytest (id, name) VALUES (NULL, 'test1') ON DUPLICATE KEY UPDATE id = last_insert_id(id); Query OK, 0 rows affected (0.00 sec) Why do you think getGeneratedKeys should return not empty ResultSet for the last query?
[23 May 2007 13:39]
Mark Matthews
Sveta, The issue is that whatever LAST_INSERT_ID() returns, the _same_ value should be returned by the server to the client as part of the DML statement. Also, JDBC (and ODBC), set flags for the server to return _matched_ rows, not affected rows. The fact that MySQL decided not to physically update rows is not relevent as far as I can tell, there was a row _matched_ to be updated.
[30 May 2007 10:28]
Sveta Smirnova
test case
Attachment: bug28505_3.java (text/plain), 2.61 KiB.
[30 May 2007 10:28]
Sveta Smirnova
Thank you for the report. Verified as described.
[6 Jun 2007 19:50]
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/28239 ChangeSet@1.2517, 2007-06-06 23:46:51+04:00, evgen@moonbone.local +2 -0 Bug#28505: mysql_affected_rows() may return wrong result if CLIENT_FOUND_ROWS flag is set. When the CLIENT_FOUND_ROWS flag is set then the server should return found number of rows independently whether they were updated or not. But this wasn't the case for the INSERT statement which always returned number of rows that were actually changed thus providing wrong info to a user. Now the select_insert::send_eof method and the mysql_insert function are sending the number of touched rows if the CLIENT_FOUND_ROWS flag is set.
[6 Jun 2007 20:33]
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/28241 ChangeSet@1.2517, 2007-06-07 00:30:00+04:00, evgen@moonbone.local +2 -0 Bug#28505: mysql_affected_rows() may return wrong result if CLIENT_FOUND_ROWS flag is set. When the CLIENT_FOUND_ROWS flag is set then the server should return found number of rows independently whether they were updated or not. But this wasn't the case for the INSERT statement which always returned number of rows that were actually changed thus providing wrong info to the user. Now the select_insert::send_eof method and the mysql_insert function are sending the number of touched rows if the CLIENT_FOUND_ROWS flag is set.
[14 Jun 2007 19:00]
Bugs System
Pushed into 5.1.20-beta
[14 Jun 2007 19:00]
Bugs System
Pushed into 5.0.44
[19 Jun 2007 0:56]
Paul DuBois
Noted in 5.0.44, 5.1.20 changelogs.