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
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
......
......@@ -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);
......
......@@ -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
#
......
......@@ -637,6 +637,15 @@ class THD :public ilink
#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 @@ class select_create: public select_insert {
{}
int prepare(List<Item> &list);
bool send_data(List<Item> &values);
void send_error(uint errcode,const char *err);
bool send_eof();
void abort();
};
......
......@@ -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;
......
......@@ -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";
......
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