From 73e80314aa17b13d8bb0a6f0f230b99c439bee8a Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 24 May 2003 16:43:53 +0200 Subject: Fix for bug #490 and #491 (see details below) mysql-test/r/insert_select.result: Result update. mysql-test/r/rpl_insert_id.result: Test update mysql-test/t/insert_select.test: Check if a partly completed INSERT SELECT (failing because of "Duplicate key" after successfully inserting other rows) is written to the binlog if the table is not transactional and at least one row has been inserted (bug #491) mysql-test/t/rpl_insert_id.test: Test for bug #490 (INSERT SELECT in auto_increment) sql/sql_insert.cc: - In INSERT ... SELECT, if it fails with error but one row has been inserted and the table is not transactional, we must write to the binlog (the slave will stop because of the error code in the binlog event, this is normal). bug 491. - we must set INSERT_ID before writing to the binlog (bug 490 accidentally introduced by another dev in 4.0.13). --- sql/sql_insert.cc | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'sql/sql_insert.cc') diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 33a13fabdc6..167ccf974c7 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1350,6 +1350,24 @@ void select_insert::send_error(uint errcode,const char *err) ::send_error(&thd->net,errcode,err); table->file->extra(HA_EXTRA_NO_CACHE); table->file->activate_all_index(thd); + /* + If at least one row has been inserted/modified and will stay in the table + (the table doesn't have transactions) (example: we got a duplicate key + error while inserting into a MyISAM table) we must write to the binlog (and + the error code will make the slave stop). + */ + if ((info.copied || info.deleted) && !table->file->has_transactions()) + { + if (last_insert_id) + thd->insert_id(last_insert_id); // For binary log + mysql_update_log.write(thd,thd->query,thd->query_length); + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query, thd->query_length, + table->file->has_transactions()); + mysql_bin_log.write(&qinfo); + } + } ha_rollback_stmt(thd); if (info.copied || info.deleted) { @@ -1365,7 +1383,10 @@ bool select_insert::send_eof() error=table->file->activate_all_index(thd); table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); + if (last_insert_id) + thd->insert_id(last_insert_id); // For binary log /* Write to binlog before commiting transaction */ + mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, @@ -1393,10 +1414,7 @@ bool select_insert::send_eof() else sprintf(buff,ER(ER_INSERT_INFO),info.records,info.deleted, thd->cuted_fields); - if (last_insert_id) - thd->insert_id(last_insert_id); // For update log ::send_ok(&thd->net,info.copied+info.deleted,last_insert_id,buff); - mysql_update_log.write(thd,thd->query,thd->query_length); return 0; } } -- cgit v1.2.1