Bug #30643 | Sql query returning different result sets when called more then once | ||
---|---|---|---|
Submitted: | 27 Aug 2007 9:19 | Modified: | 19 Nov 2007 15:47 |
Reporter: | walid bakkar | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: DML | Severity: | S2 (Serious) |
Version: | 5.0.27, 4.1, 5.0, 5.1, 5.2 BK | OS: | Any (Linux, Windows) |
Assigned to: | Martin Hansson | CPU Architecture: | Any |
[27 Aug 2007 9:19]
walid bakkar
[27 Aug 2007 10:23]
Sveta Smirnova
Thank you for the report. Verified as described.
[27 Aug 2007 10:23]
Sveta Smirnova
test case
Attachment: bug30643.test (application/octet-stream, text), 2.94 KiB.
[14 Sep 2007 13:45]
Martin Hansson
This appears to be a 'feature', albeit an inconsistent one. The following triggers the bug: CREATE TABLE t1 ( a INT AUTO_INCREMENT, KEY( a ) ); INSERT INTO t1 VALUES (1), (2), (3); CREATE TABLE t2 ( a INT, b INT AUTO_INCREMENT, KEY( b ) ); INSERT INTO t2( a ) SELECT a FROM t1; SELECT COUNT(*) FROM t1 WHERE a IS NULL; > 1 SELECT COUNT(*) FROM t1 WHERE a IS NULL; > 0 I found this comment in the code: Handles this special case for some ODBC applications: The are requesting the row that was just updated with a auto_increment value with this construct: SELECT * from table_name where auto_increment_column IS NULL This will be changed to: SELECT * from table_name where auto_increment_column = LAST_INSERT_ID
[14 Sep 2007 15:17]
Martin Hansson
In order to be compatible with odbc, MySQL has the feature that *right after* an update, a query with "auto_increment_column IS NULL" in the WHERE clause gets rewritten to: "auto_increment_column = last_insert_id()". This behavior is present for the duration of one statement only. The function last_insert_id() returns the last auto-generated value for a table. Hence: SELECT last_insert_id(-1); CREATE TABLE t1 ( a INT AUTO_INCREMENT, KEY( a ) ); INSERT INTO t1 VALUES (1), (2); SELECT last_insert_id(); +------------------+ | last_insert_id() | +------------------+ | -1 | +------------------+ INSERT INTO t1 VALUES (NULL); // forces auto-generation of value SELECT last_insert_id(); +------------------+ | last_insert_id() | +------------------+ | 3 | +------------------+ In Sveta's test what we saw was that after insert into af_vft, last_insert_id() = 1. So the first select count [...] following it gets rewritten to: select count(d_docid) from (select distinct d.docid as d_docid from document d where ((d.docid != 1 or d.docid = 1 ))) ids order by d_docid desc; Which returns the correct value of 1. This behavior cannot be changed since odbc, and thus many applications(including Delphi and Access) depend on it. Many other DBMSes behave the same way. For more information, please consult the manual: http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html http://dev.mysql.com/doc/refman/5.0/en/myodbc-usagenotes-functionality.html#myodbc-usageno...
[20 Nov 2007 8:28]
Martin Hansson
According to Monty, we have no choice. We must support ODBC. Using a statement such as WHERE column IS NULL on an autoincremented colun is not a statement that should normally be used. The result would under "normal" circumstances be always empty.