Commit 9286d1c1 authored by unknown's avatar unknown

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.)


mysql-test/t/insert_select.test:
  Add test case for Bug #6682
mysql-test/r/insert_select.result:
  Add results for test case for Bug #6682
sql/sql_table.cc:
  moved tmp_disable_binlog() and reenable_binlog macros to sql/sql_class.h
sql/sql_insert.cc:
  disable binlog during call to super's ::send_error in select_create class
sql/sql_class.h:
  add select_create::send_error()
BitKeeper/etc/logging_ok:
  Logging to logging@openlogging.org accepted
parent a845e882
...@@ -64,6 +64,7 @@ jcole@main.burghcom.com ...@@ -64,6 +64,7 @@ jcole@main.burghcom.com
jcole@mugatu.spaceapes.com jcole@mugatu.spaceapes.com
jcole@sarvik.tfr.cafe.ee jcole@sarvik.tfr.cafe.ee
jcole@tetra.spaceapes.com jcole@tetra.spaceapes.com
jimw@mysql.com
joerg@mysql.com joerg@mysql.com
jorge@linux.jorge.mysql.com jorge@linux.jorge.mysql.com
kaj@work.mysql.com kaj@work.mysql.com
......
...@@ -78,6 +78,15 @@ master-bin.001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3 ...@@ -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 master-bin.001 79 Query 1 79 use `test`; insert into t1 select * from t2
drop table t1, t2; drop table t1, t2;
drop table if exists 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 t1 (a int not null);
create table t2 (a int not null); create table t2 (a int not null);
insert into t1 values (1); insert into t1 values (1);
......
...@@ -86,6 +86,19 @@ show binlog events; ...@@ -86,6 +86,19 @@ show binlog events;
drop table t1, t2; drop table t1, t2;
drop table if exists 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 # Test of insert ... select from same table
# #
......
...@@ -637,6 +637,15 @@ public: ...@@ -637,6 +637,15 @@ public:
#endif #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 */ /* Flags for the THD::system_thread (bitmap) variable */
#define SYSTEM_THREAD_DELAYED_INSERT 1 #define SYSTEM_THREAD_DELAYED_INSERT 1
#define SYSTEM_THREAD_SLAVE_IO 2 #define SYSTEM_THREAD_SLAVE_IO 2
...@@ -781,6 +790,7 @@ public: ...@@ -781,6 +790,7 @@ public:
{} {}
int prepare(List<Item> &list); int prepare(List<Item> &list);
bool send_data(List<Item> &values); bool send_data(List<Item> &values);
void send_error(uint errcode,const char *err);
bool send_eof(); bool send_eof();
void abort(); void abort();
}; };
......
...@@ -1505,6 +1505,19 @@ bool select_create::send_data(List<Item> &values) ...@@ -1505,6 +1505,19 @@ bool select_create::send_data(List<Item> &values)
return 0; 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; extern HASH open_cache;
......
...@@ -31,14 +31,6 @@ ...@@ -31,14 +31,6 @@
#endif #endif
#include "sql_acl.h" // for SUPER_ACL #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; extern HASH open_cache;
static const char *primary_key_name="PRIMARY"; static const char *primary_key_name="PRIMARY";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment