This is the one and only mysqlnd-libmysql difference of some practical
relevance. I consider it at least questionable if libmysql is correct.
If it was to be decided that mysqlnd is wrong, it is probably like five
lines of code in mysqlnd to change, if need be.
Am 02.09.2011 19:19, schrieb Stas Malyshev:
API vs. SQL LAST_INSERT_ID() [ext/mysqli/tests/mysqli_last_insert_id.phpt]
The reason is that this test relies on LAST_INSERT_ID() being reset on
SELECT. I have not observed such behavior neither via PHP not talking to
Mysql server directly from CLI interface, so I have no idea why this
test assumes such behavior.
Personal observation and memory may not be the best reference here. What
the test does is:
DROP TABLE IF EXISTS test
CREATE TABLE test(id INT AUTO_INCREMENT PRIMARY KEY) Engine=MyISAM
INSERT INTO test(id) VALUES (1);
printf("insert id for INSERT is: %d\n", mysqli_insert_id(link));
SELECT 1 FROM DUAL
printf("insert id for SELECT is: %d\n", mysqli_insert_id(link));
Libmysql will print:
insert id for INSERT is: 1
insert id for SELECT is: 1
Mysqlnd will print:
insert id for INSERT is: 1
insert id for SELECT is: 0
At the end of the day, we are discussing C library differences again,
thus we can consult the C API reference:
"Returns the value generated for an AUTO_INCREMENT column by the
previous INSERT or UPDATE statement. Use this function after you have
performed an INSERT statement into a table that contains an
AUTO_INCREMENT field, or have used INSERT or UPDATE to set a column
value with LAST_INSERT_ID(expr).",
http://dev.mysql.com/doc/refman/5.6/en/mysql-insert-id.html
The test is using the function not after an INSERT but after a SELECT.
The documentation continues:
"The return value of mysql_insert_id() is always zero unless explicitly
updated under one of the following conditions:
- [...] INSERT
- [...] INSERT multi-row ... MySQL version dependent
- [...} INSERT...SELECT and [...]
- [...] INSERT...SELECT and [...]"
Followed by:
"mysql_insert_id() returns 0 if the previous statement does not use an
AUTO_INCREMENT value. If you need to save the value for later, be sure
to call mysql_insert_id() immediately after the statement that generates
the value."
I read:
- "The return value of mysql_insert_id() is always zero unless
explicitly updated under one of the following conditions"
- "If you need to save the value for later, be sure to call
mysql_insert_id() immediately after the statement that generates the value."
If people like, we can call this mysqlnd interpretation a bug. In any
case, I find no reference in the documentation that the value must NOT
to be reset upon SELECT.
Searching bugs.php.net gives one related case:
https://bugs.php.net/bug.php?id=54190
Unfortunately, Andrey did not write down the MySQL bug he refers to.
However, back in March he wrote something that makes be believe he
interprets the manual similar to how I do:
"mysqli calls internally "SHOW WARNINGS" to fetch the warnings from
the server. The SHOW statement should reset insert_id in libmysql, but
it does not."
To sum up:
- debatable issue
- edge case going beyond primary use of function
- edge case not explicitly covered by the documentation
- five lines(?) to change, if need be
- quick check: no bug report on bugs.php.net against mysqlnd
Ulf
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php