• unknown's avatar
    BUG#21726: Incorrect result with multiple invocations of LAST_INSERT_ID. · 7820e189
    unknown authored
    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.
    
    
    mysql-test/r/rpl_insert_id.result:
      Add result for bug#21726: Incorrect result with multiple invocations
      of LAST_INSERT_ID.
    mysql-test/t/rpl_insert_id.test:
      Add test case for bug#21726: Incorrect result with multiple invocations
      of LAST_INSERT_ID.
    sql/item_func.cc:
      Add implementation of Item_func_last_insert_id::fix_fields(), where we
      set THD::last_insert_id_used when statement calls LAST_INSERT_ID().
      In Item_func_last_insert_id::val_int(), return THD::current_insert_id
      if called like LAST_INSERT_ID(), otherwise return value of argument if
      called like LAST_INSERT_ID(expr).
    sql/item_func.h:
      Add declaration of Item_func_last_insert_id::fix_fields().
    sql/log_event.cc:
      Do not set THD::last_insert_id_used on LAST_INSERT_ID_EVENT.  Though we
      know the statement will call LAST_INSERT_ID(), it wasn't called yet.
    sql/set_var.cc:
      In sys_var_last_insert_id::value_ptr(), set THD::last_insert_id_used,
      and return THD::current_insert_id for @@LAST_INSERT_ID.
    sql/sql_class.h:
      Update comments.
      Remove THD::insert_id(), as it has lost its purpose now.
    sql/sql_insert.cc:
      Now it is OK to read THD::last_insert_id directly.
    sql/sql_load.cc:
      Now it is OK to read THD::last_insert_id directly.
    sql/sql_parse.cc:
      In mysql_execute_command(), remember THD::last_insert_id (first
      generated value of the previous statement) in THD::current_insert_id,
      which then will be returned for LAST_INSERT_ID() and @@LAST_INSERT_ID.
    sql/sql_select.cc:
      If "IS NULL" is replaced with "= <LAST_INSERT_ID>", use right value,
      which is THD::current_insert_id, and also set THD::last_insert_id_used
      to issue binary log LAST_INSERT_ID_EVENT.
    sql/sql_update.cc:
      Now it is OK to read THD::last_insert_id directly.
    tests/mysql_client_test.c:
      Add test case for bug#21726: Incorrect result with multiple invocations
      of LAST_INSERT_ID.
    7820e189
mysql_client_test.c 315 KB