summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/insert_select.result14
-rw-r--r--mysql-test/r/rpl_insert_id.result28
-rw-r--r--mysql-test/t/insert_select.test19
-rw-r--r--mysql-test/t/rpl_insert_id.test33
-rw-r--r--sql/sql_insert.cc24
5 files changed, 109 insertions, 9 deletions
diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result
index e24c3179a0c..b49ca3a6c2f 100644
--- a/mysql-test/r/insert_select.result
+++ b/mysql-test/r/insert_select.result
@@ -66,3 +66,17 @@ INSERT INTO crash1 (numeropost,icone,contenu,pseudo,date,signature,ip)
SELECT 1718,icone,contenu,pseudo,date,signature,ip FROM crash2
WHERE numeropost=9 ORDER BY numreponse ASC;
DROP TABLE IF EXISTS crash1,crash2;
+drop table if exists t1;
+drop table if exists t2;
+create table t1(a int, unique(a));
+insert into t1 values(2);
+create table t2(a int);
+insert into t2 values(1),(2);
+reset master;
+insert into t1 select * from t2;
+Duplicate entry '2' for key 1
+show binlog events;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3
+master-bin.001 79 Query 1 79 use test; insert into t1 select * from t2
+drop table t1, t2;
diff --git a/mysql-test/r/rpl_insert_id.result b/mysql-test/r/rpl_insert_id.result
index d524818985e..6d996481a5c 100644
--- a/mysql-test/r/rpl_insert_id.result
+++ b/mysql-test/r/rpl_insert_id.result
@@ -39,3 +39,31 @@ b c
6 11
drop table t1;
drop table t2;
+create table t1(a int auto_increment, key(a));
+create table t2(b int auto_increment, c int, key(b));
+insert into t1 values (10);
+insert into t1 values (null),(null),(null);
+insert into t2 values (5,0);
+insert into t2 (c) select * from t1;
+select * from t2;
+b c
+5 0
+6 10
+7 11
+8 12
+9 13
+select * from t1;
+a
+10
+11
+12
+13
+select * from t2;
+b c
+5 0
+6 10
+7 11
+8 12
+9 13
+drop table t1;
+drop table t2;
diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test
index 42f65858d77..695f891f678 100644
--- a/mysql-test/t/insert_select.test
+++ b/mysql-test/t/insert_select.test
@@ -68,3 +68,22 @@ WHERE numeropost=9 ORDER BY numreponse ASC;
DROP TABLE IF EXISTS crash1,crash2;
+
+# Addendum by Guilhem:
+# Check if a partly-completed INSERT SELECT in a MyISAM table goes
+# into the binlog
+drop table if exists t1;
+drop table if exists t2;
+create table t1(a int, unique(a));
+insert into t1 values(2);
+create table t2(a int);
+insert into t2 values(1),(2);
+reset master;
+--error 1062
+insert into t1 select * from t2;
+# The above should produce an error, but still be in the binlog;
+# verify the binlog :
+let $VERSION=`select version()`;
+--replace_result $VERSION VERSION
+show binlog events;
+drop table t1, t2;
diff --git a/mysql-test/t/rpl_insert_id.test b/mysql-test/t/rpl_insert_id.test
index 3f3636d3082..3478aedf3eb 100644
--- a/mysql-test/t/rpl_insert_id.test
+++ b/mysql-test/t/rpl_insert_id.test
@@ -1,6 +1,7 @@
-#see if queries that use both
-#auto_increment and LAST_INSERT_ID()
-#are replicated well
+# see if queries that use both
+# auto_increment and LAST_INSERT_ID()
+# are replicated well
+
source include/master-slave.inc;
connection master;
drop table if exists t1;
@@ -15,9 +16,11 @@ sync_with_master;
select * from t1;
select * from t2;
connection master;
-#check if multi-line inserts,
-#which set last_insert_id to the first id inserted,
-#are replicated the same way
+
+# check if multi-line inserts,
+# which set last_insert_id to the first id inserted,
+# are replicated the same way
+
drop table t1;
drop table t2;
create table t1(a int auto_increment, key(a));
@@ -32,6 +35,24 @@ sync_with_master;
select * from t1;
select * from t2;
connection master;
+
+# check if INSERT SELECT in auto_increment is well replicated (bug #490)
+
+drop table t1;
+drop table t2;
+create table t1(a int auto_increment, key(a));
+create table t2(b int auto_increment, c int, key(b));
+insert into t1 values (10);
+insert into t1 values (null),(null),(null);
+insert into t2 values (5,0);
+insert into t2 (c) select * from t1;
+select * from t2;
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from t1;
+select * from t2;
+connection master;
drop table t1;
drop table t2;
save_master_pos;
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;
}
}