summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjimw@mysql.com <>2004-12-03 00:05:11 +0100
committerjimw@mysql.com <>2004-12-03 00:05:11 +0100
commit13649d90ae90257620461cdd97bbf217bd1b1755 (patch)
treec6630df438ab32a1664bb54903e60729d5755629
parent7ed2753300a9fe874149ba9f3d8255726c60414e (diff)
downloadmariadb-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_ok1
-rw-r--r--mysql-test/r/insert_select.result9
-rw-r--r--mysql-test/t/insert_select.test13
-rw-r--r--sql/sql_class.h10
-rw-r--r--sql/sql_insert.cc13
-rw-r--r--sql/sql_table.cc8
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";