1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

BUG#21726: Incorrect result with multiple invocations of LAST_INSERT_ID.

Note: bug#21726 does not directly apply to 4.1, as it doesn't have stored
procedures.  However, 4.1 had some bugs that were fixed in 5.0 by the
patch for bug#21726, and this patch is a backport of those fixes.
Namely, in 4.1 it fixes:

  - LAST_INSERT_ID(expr) didn't return value of expr (4.1 specific).

  - LAST_INSERT_ID() could return the value generated by current
    statement if the call happens after the generation, like in

      CREATE TABLE t1 (i INT AUTO_INCREMENT PRIMARY KEY, j INT);
      INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID());

  - Redundant binary log LAST_INSERT_ID_EVENTs could be generated.
This commit is contained in:
kroki/tomash@moonlight.intranet
2006-10-06 13:34:07 +04:00
parent acaa584c55
commit ee0cebf9a7
13 changed files with 189 additions and 38 deletions

View File

@ -835,17 +835,29 @@ public:
generated auto_increment value in handler.cc
*/
ulonglong next_insert_id;
/*
The insert_id used for the last statement or set by SET LAST_INSERT_ID=#
or SELECT LAST_INSERT_ID(#). Used for binary log and returned by
LAST_INSERT_ID()
At the beginning of the statement last_insert_id holds the first
generated value of the previous statement. During statement
execution it is updated to the value just generated, but then
restored to the value that was generated first, so for the next
statement it will again be "the first generated value of the
previous statement".
It may also be set with "LAST_INSERT_ID(expr)" or
"@@LAST_INSERT_ID= expr", but the effect of such setting will be
seen only in the next statement.
*/
ulonglong last_insert_id;
/*
Set to the first value that LAST_INSERT_ID() returned for the last
statement. When this is set, last_insert_id_used is set to true.
current_insert_id remembers the first generated value of the
previous statement, and does not change during statement
execution. Its value returned from LAST_INSERT_ID() and
@@LAST_INSERT_ID.
*/
ulonglong current_insert_id;
ulonglong limit_found_rows;
ha_rows cuted_fields,
sent_row_count, examined_row_count;
@ -896,7 +908,22 @@ public:
bool locked, some_tables_deleted;
bool last_cuted_field;
bool no_errors, password, is_fatal_error;
bool query_start_used,last_insert_id_used,insert_id_used,rand_used;
bool query_start_used, rand_used;
/*
last_insert_id_used is set when current statement calls
LAST_INSERT_ID() or reads @@LAST_INSERT_ID, so that binary log
LAST_INSERT_ID_EVENT be generated.
*/
bool last_insert_id_used;
/*
insert_id_used is set when current statement updates
THD::last_insert_id, so that binary log INSERT_ID_EVENT be
generated.
*/
bool insert_id_used;
/* for IS NULL => = last_insert_id() fix in remove_eq_conds() */
bool substitute_null_with_insert_id;
bool time_zone_used;
@ -996,15 +1023,6 @@ public:
insert_id_used=1;
substitute_null_with_insert_id= TRUE;
}
inline ulonglong insert_id(void)
{
if (!last_insert_id_used)
{
last_insert_id_used=1;
current_insert_id=last_insert_id;
}
return last_insert_id;
}
inline ulonglong found_rows(void)
{
return limit_found_rows;