mirror of
https://github.com/MariaDB/server.git
synced 2025-08-31 22:22:30 +03:00
BUG#21726: Incorrect result with multiple invocations of LAST_INSERT_ID
Non-upper-level INSERTs (the ones in the body of stored procedure, stored function, or trigger) into a table that have AUTO_INCREMENT column didn't affected the result of LAST_INSERT_ID() on this level. The problem was introduced with the fix of bug 6880, which in turn was introduced with the fix of bug 3117, where current insert_id value was remembered on the first call to LAST_INSERT_ID() (bug 3117) and was returned from that function until it was reset before the next _upper-level_ statement (bug 6880). The fix for bug#21726 brings back the behaviour of version 4.0, and implements the following: remember insert_id value at the beginning of the statement or expression (which at that point equals to the first insert_id value generated by the previous statement), and return that remembered value from LAST_INSERT_ID() or @@LAST_INSERT_ID. Thus, the value returned by LAST_INSERT_ID() is not affected by values generated by current statement, nor by LAST_INSERT_ID(expr) calls in this statement. Version 5.1 does not have this bug (it was fixed by WL 3146).
This commit is contained in:
@@ -2421,6 +2421,20 @@ mysql_execute_command(THD *thd)
|
||||
DBUG_ENTER("mysql_execute_command");
|
||||
thd->net.no_send_error= 0;
|
||||
|
||||
/*
|
||||
Remember first generated insert id value of the previous
|
||||
statement. We remember it here at the beginning of the statement,
|
||||
and also in Item_func_last_insert_id::fix_fields() and
|
||||
sys_var_last_insert_id::value_ptr(). Last two places are required
|
||||
because LAST_INSERT_ID() and @@LAST_INSERT_ID may also be used in
|
||||
expression that is not executed with mysql_execute_command().
|
||||
|
||||
And we remember it here because some statements read
|
||||
@@LAST_INSERT_ID indirectly, like "SELECT * FROM t1 WHERE id IS
|
||||
NULL", that may replace "id IS NULL" with "id = <LAST_INSERT_ID>".
|
||||
*/
|
||||
thd->current_insert_id= thd->last_insert_id;
|
||||
|
||||
/*
|
||||
In many cases first table of main SELECT_LEX have special meaning =>
|
||||
check that it is first table in global list and relink it first in
|
||||
@@ -5636,7 +5650,7 @@ void mysql_reset_thd_for_next_command(THD *thd)
|
||||
DBUG_ENTER("mysql_reset_thd_for_next_command");
|
||||
thd->free_list= 0;
|
||||
thd->select_number= 1;
|
||||
thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0;
|
||||
thd->query_start_used= thd->insert_id_used=0;
|
||||
thd->is_fatal_error= thd->time_zone_used= 0;
|
||||
thd->server_status&= ~ (SERVER_MORE_RESULTS_EXISTS |
|
||||
SERVER_QUERY_NO_INDEX_USED |
|
||||
|
Reference in New Issue
Block a user