1
0
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:
kroki/tomash@moonlight.intranet
2006-10-02 14:28:23 +04:00
parent dead2e0f14
commit 5ea8adfae7
14 changed files with 405 additions and 41 deletions

View File

@@ -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 |