• guilhem@gbichot3.local's avatar
    WL#3146 "less locking in auto_increment": · 0594e1b8
    guilhem@gbichot3.local authored
    this is a cleanup patch for our current auto_increment handling:
    new names for auto_increment variables in THD, new methods to manipulate them
    (see sql_class.h), some move into handler::, causing less backup/restore
    work when executing substatements. 
    This makes the logic hopefully clearer, less work is is needed in
    mysql_insert().
    By cleaning up, using different variables for different purposes (instead
    of one for 3 things...), we fix those bugs, which someone may want to fix
    in 5.0 too:
    BUG#20339 "stored procedure using LAST_INSERT_ID() does not replicate
    statement-based"
    BUG#20341 "stored function inserting into one auto_increment puts bad
    data in slave"
    BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY UPDATE"
    (now if a row is updated, LAST_INSERT_ID() will return its id)
    and re-fixes:
    BUG#6880 "LAST_INSERT_ID() value changes during multi-row INSERT"
    (already fixed differently by Ramil in 4.1)
    Test of documented behaviour of mysql_insert_id() (there was no test).
    The behaviour changes introduced are:
    - LAST_INSERT_ID() now returns "the first autogenerated auto_increment value
    successfully inserted", instead of "the first autogenerated auto_increment
    value if any row was successfully inserted", see auto_increment.test.
    Same for mysql_insert_id(), see mysql_client_test.c.
    - LAST_INSERT_ID() returns the id of the updated row if ON DUPLICATE KEY
    UPDATE, see auto_increment.test. Same for mysql_insert_id(), see
    mysql_client_test.c.
    - LAST_INSERT_ID() does not change if no autogenerated value was successfully 
    inserted (it used to then be 0), see auto_increment.test.
    - if in INSERT SELECT no autogenerated value was successfully inserted,
    mysql_insert_id() now returns the id of the last inserted row (it already
    did this for INSERT VALUES), see mysql_client_test.c.
    - if INSERT SELECT uses LAST_INSERT_ID(X), mysql_insert_id() now returns X
    (it already did this for INSERT VALUES), see mysql_client_test.c.
    - NDB now behaves like other engines wrt SET INSERT_ID: with INSERT IGNORE,
    the id passed in SET INSERT_ID is re-used until a row succeeds; SET INSERT_ID
    influences not only the first row now.
    
    Additionally, when unlocking a table we check that the thread is not keeping
    a next_insert_id (as the table is unlocked that id is potentially out-of-date);
    forgetting about this next_insert_id is done in a new
    handler::ha_release_auto_increment().
    
    Finally we prepare for engines capable of reserving finite-length intervals
    of auto_increment values: we store such intervals in THD. The next step
    (to be done by the replication team in 5.1) is to read those intervals from
    THD and actually store them in the statement-based binary log. NDB
    will be a good engine to test that.
    0594e1b8
item_func.cc 122 KB