Index: handler/ha_innodb.cc =================================================================== --- handler/ha_innodb.cc (revision 1572) +++ handler/ha_innodb.cc (working copy) @@ -3306,8 +3306,6 @@ no_commit: if (error == DB_DUPLICATE_KEY && auto_inc_used && (user_thd->lex->sql_command == SQLCOM_REPLACE || user_thd->lex->sql_command == SQLCOM_REPLACE_SELECT - || (user_thd->lex->sql_command == SQLCOM_INSERT - && user_thd->lex->duplicates == DUP_UPDATE) || (user_thd->lex->sql_command == SQLCOM_LOAD && user_thd->lex->duplicates == DUP_REPLACE))) { @@ -3538,6 +3536,27 @@ ha_innobase::update_row( error = row_update_for_mysql((byte*) old_row, prebuilt); + /* We need to do some special AUTOINC handling for the following case: + + INSERT INTO t (c1,c2) VALUES(x,y) ON DUPLICATE KEY UPDATE ... + + We need to use the AUTOINC counter that was actually used by + MySQL in the UPDATE statement, which can be different from the + value used in the INSERT statement.*/ + if (error == DB_SUCCESS + && table->next_number_field && new_row == table->record[0] + && user_thd->lex->sql_command == SQLCOM_INSERT + && user_thd->lex->duplicates == DUP_UPDATE) { + + longlong auto_inc; + + auto_inc = table->next_number_field->val_int(); + + if (auto_inc != 0) { + dict_table_autoinc_update(prebuilt->table, auto_inc); + } + } + innodb_srv_conc_exit_innodb(prebuilt->trx); error = convert_error_code_to_mysql(error, user_thd);