diff options
author | jimw@mysql.com <> | 2004-12-03 00:05:11 +0100 |
---|---|---|
committer | jimw@mysql.com <> | 2004-12-03 00:05:11 +0100 |
commit | 13649d90ae90257620461cdd97bbf217bd1b1755 (patch) | |
tree | c6630df438ab32a1664bb54903e60729d5755629 | |
parent | 7ed2753300a9fe874149ba9f3d8255726c60414e (diff) | |
download | mariadb-git-13649d90ae90257620461cdd97bbf217bd1b1755.tar.gz |
Prevent adding 'CREATE TABLE .. SELECT' query to the binary log when the
insertion of new records partially failed. It would get logged because of the
logic to log a partially-failed 'INSERT ... SELECT' (which can't be rolled back
in non-transactional tables), but 'CREATE TABLE ... SELECT' is always rolled
back on failure, even for non-transactional tables. (Bug #6682)
(Original fix reimplemented after review by Serg and Guilhem.)
-rw-r--r-- | BitKeeper/etc/logging_ok | 1 | ||||
-rw-r--r-- | mysql-test/r/insert_select.result | 9 | ||||
-rw-r--r-- | mysql-test/t/insert_select.test | 13 | ||||
-rw-r--r-- | sql/sql_class.h | 10 | ||||
-rw-r--r-- | sql/sql_insert.cc | 13 | ||||
-rw-r--r-- | sql/sql_table.cc | 8 |
6 files changed, 46 insertions, 8 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index e8b795c4d80..6e6433a80ae 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -64,6 +64,7 @@ jcole@main.burghcom.com jcole@mugatu.spaceapes.com jcole@sarvik.tfr.cafe.ee jcole@tetra.spaceapes.com +jimw@mysql.com joerg@mysql.com jorge@linux.jorge.mysql.com kaj@work.mysql.com diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index a10e7fc02bb..ecd26f2d9fb 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -78,6 +78,15 @@ 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; drop table if exists t1, t2; +create table t1(a int); +insert into t1 values(1),(1); +reset master; +create table t2(unique(a)) select a from t1; +Duplicate entry '1' 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 +drop table t1; create table t1 (a int not null); create table t2 (a int not null); insert into t1 values (1); diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index d9a8cfaf1be..deb80dbcdbf 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -86,6 +86,19 @@ show binlog events; drop table t1, t2; drop table if exists t1, t2; +# Verify that a partly-completed CREATE TABLE .. SELECT does not +# get into the binlog (Bug #6682) +create table t1(a int); +insert into t1 values(1),(1); +reset master; +--error 1062 +create table t2(unique(a)) select a from t1; +# The above should produce an error, *and* not appear in the binlog +let $VERSION=`select version()`; +--replace_result $VERSION VERSION +show binlog events; +drop table t1; + # # Test of insert ... select from same table # diff --git a/sql/sql_class.h b/sql/sql_class.h index 4250ebdd568..17d371d3dc0 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -637,6 +637,15 @@ public: #endif }; +# define tmp_disable_binlog(A) \ + ulong save_options= (A)->options, save_master_access= (A)->master_access; \ + (A)->options&= ~OPTION_BIN_LOG; \ + (A)->master_access|= SUPER_ACL; /* unneeded in 4.1 */ + +#define reenable_binlog(A) \ + (A)->options= save_options; \ + (A)->master_access= save_master_access; + /* Flags for the THD::system_thread (bitmap) variable */ #define SYSTEM_THREAD_DELAYED_INSERT 1 #define SYSTEM_THREAD_SLAVE_IO 2 @@ -781,6 +790,7 @@ public: {} int prepare(List<Item> &list); bool send_data(List<Item> &values); + void send_error(uint errcode,const char *err); bool send_eof(); void abort(); }; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 8912c1faf2a..0c62a9af7ba 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1505,6 +1505,19 @@ bool select_create::send_data(List<Item> &values) return 0; } + +void select_create::send_error(uint errcode,const char *err) +{ + /* + Disable binlog, because we "roll back" partial inserts in ::abort + by removing the table, even for non-transactional tables. + */ + tmp_disable_binlog(thd); + select_insert::send_error(errcode, err); + reenable_binlog(thd); +} + + extern HASH open_cache; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 1e5237b1428..33bdd992efb 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -31,14 +31,6 @@ #endif #include "sql_acl.h" // for SUPER_ACL -# define tmp_disable_binlog(A) \ - ulong save_options= (A)->options, save_master_access= (A)->master_access; \ - (A)->options&= ~OPTION_BIN_LOG; \ - (A)->master_access|= SUPER_ACL; /* unneeded in 4.1 */ - -#define reenable_binlog(A) \ - (A)->options= save_options; \ - (A)->master_access= save_master_access; extern HASH open_cache; static const char *primary_key_name="PRIMARY"; |