summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/binlog/r/binlog_switch_inside_trans.result76
-rw-r--r--mysql-test/suite/binlog/t/binlog_switch_inside_trans.test79
-rw-r--r--sql/sys_vars.cc43
3 files changed, 122 insertions, 76 deletions
diff --git a/mysql-test/suite/binlog/r/binlog_switch_inside_trans.result b/mysql-test/suite/binlog/r/binlog_switch_inside_trans.result
index 57feb3f50f0..de224a190c2 100644
--- a/mysql-test/suite/binlog/r/binlog_switch_inside_trans.result
+++ b/mysql-test/suite/binlog/r/binlog_switch_inside_trans.result
@@ -5,9 +5,14 @@ create table t2 (a int) engine= innodb;
SELECT @@session.binlog_format;
@@session.binlog_format
ROW
+SELECT @@session.binlog_direct_non_transactional_updates;
+@@session.binlog_direct_non_transactional_updates
+1
SET AUTOCOMMIT=1;
-# Test that the session variable 'binlog_format'
-# is writable outside a transaction.
+# Test that the session variable 'binlog_format' and
+# 'binlog_direct_non_transactional_updates' are
+# writable outside a transaction.
+# Current session values are ROW and FALSE, respectively.
set @@session.binlog_format= statement;
set @@session.binlog_direct_non_transactional_updates= TRUE;
SELECT @@session.binlog_format;
@@ -17,15 +22,19 @@ SELECT @@session.binlog_direct_non_transactional_updates;
@@session.binlog_direct_non_transactional_updates
1
begin;
-# Test that the session variable 'binlog_format' is read-only
-# inside a transaction with no preceding updates.
+# Test that the session variable 'binlog_format' and
+# 'binlog_direct_non_transactional_updates' are
+# read-only inside a transaction with no preceding updates.
+# Current session values are STATEMENT and TRUE, respectively.
set @@session.binlog_format= mixed;
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction
set @@session.binlog_direct_non_transactional_updates= FALSE;
ERROR HY000: Cannot modify @@session.binlog_direct_non_transactional_updates inside a transaction
insert into t2 values (1);
-# Test that the session variable 'binlog_format' is read-only
-# inside a transaction with preceding transactional updates.
+# Test that the session variable 'binlog_format' and
+# 'binlog_direct_non_transactional_updates' are
+# read-only inside a transaction with preceding transactional updates.
+# Current session values are STATEMENT and TRUE, respectively.
set @@session.binlog_format= row;
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction
set @@session.binlog_direct_non_transactional_updates= FALSE;
@@ -33,15 +42,19 @@ ERROR HY000: Cannot modify @@session.binlog_direct_non_transactional_updates ins
commit;
begin;
insert into t1 values (2);
-# Test that the session variable 'binlog_format' is read-only
-# inside a transaction with preceding non-transactional updates.
-set @@session.binlog_format= statement;
+# Test that the session variable 'binlog_format' and
+# 'binlog_direct_non_transactional_updates' are
+# read-only inside a transaction with preceding non-transactional updates.
+# Current session values are STATEMENT and TRUE, respectively.
+set @@session.binlog_format= mixed;
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction
set @@session.binlog_direct_non_transactional_updates= FALSE;
ERROR HY000: Cannot modify @@session.binlog_direct_non_transactional_updates inside a transaction
commit;
-# Test that the session variable 'binlog_format' is writable
-# when AUTOCOMMIT=0, before a transaction has started.
+# Test that the session variable 'binlog_format' and
+# 'binlog_direct_non_transactional_updates' are
+# writable when AUTOCOMMIT=0, before a transaction has started.
+# Current session values are STATEMENT and TRUE, respectively.
set AUTOCOMMIT=0;
set @@session.binlog_format= row;
set @@session.binlog_direct_non_transactional_updates= FALSE;
@@ -51,9 +64,12 @@ ROW
SELECT @@session.binlog_direct_non_transactional_updates;
@@session.binlog_direct_non_transactional_updates
0
-insert into t1 values (4);
-# Test that the session variable 'binlog_format' is read-only inside an
-# AUTOCOMMIT=0 transaction with preceding non-transactional updates.
+insert into t1 values (3);
+# Test that the session variable 'binlog_format' and
+# 'binlog_direct_non_transactional_updates' are
+# read-only inside an AUTOCOMMIT=0 transaction
+# with preceding non-transactional updates.
+# Current session values are ROW and FALSE, respectively.
set @@session.binlog_format= statement;
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction
set @@session.binlog_direct_non_transactional_updates= TRUE;
@@ -65,10 +81,13 @@ SELECT @@session.binlog_direct_non_transactional_updates;
@@session.binlog_direct_non_transactional_updates
0
commit;
-insert into t2 values (5);
-# Test that the session variable 'binlog_format' is read-only inside an
-# AUTOCOMMIT=0 transaction with preceding transactional updates.
-set @@session.binlog_format= row;
+insert into t2 values (4);
+# Test that the session variable 'binlog_format' and
+# 'binlog_direct_non_transactional_updates' are
+# read-only inside an AUTOCOMMIT=0 transaction with
+# preceding transactional updates.
+# Current session values are ROW and FALSE, respectively.
+set @@session.binlog_format= statement;
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction
set @@session.binlog_direct_non_transactional_updates= TRUE;
ERROR HY000: Cannot modify @@session.binlog_direct_non_transactional_updates inside a transaction
@@ -80,9 +99,11 @@ SELECT @@session.binlog_direct_non_transactional_updates;
0
commit;
begin;
-insert into t2 values (6);
-# Test that the global variable 'binlog_format' is writable
-# inside a transaction.
+insert into t2 values (5);
+# Test that the global variable 'binlog_format' and
+# 'binlog_direct_non_transactional_updates' are
+# writable inside a transaction.
+# Current session values are ROW and FALSE, respectively.
SELECT @@global.binlog_format;
@@global.binlog_format
ROW
@@ -96,18 +117,19 @@ SELECT @@global.binlog_direct_non_transactional_updates;
1
commit;
set @@global.binlog_format= @save_binlog_format;
-set @@global.binlog_direct_non_transactional_updates= @save_binlog_dirct;
+set @@global.binlog_direct_non_transactional_updates= @save_binlog_dirct;
create table t3(a int, b int) engine= innodb;
create table t4(a int) engine= innodb;
create table t5(a int) engine= innodb;
create trigger tr1 after insert on t3 for each row begin
insert into t4(a) values(1);
-set @@session.binlog_format= statement;
+set @@session.binlog_format= statement;
insert into t4(a) values(2);
insert into t5(a) values(3);
end |
# Test that the session variable 'binlog_format' is read-only
# in sub-statements.
+# Current session value is ROW.
insert into t3(a,b) values(1,1);
ERROR HY000: Cannot change the binary logging format inside a stored function or trigger
SELECT @@session.binlog_format;
@@ -118,12 +140,14 @@ create table t7(a int) engine= innodb;
create table t8(a int) engine= innodb;
create trigger tr2 after insert on t6 for each row begin
insert into t7(a) values(1);
-set @@global.binlog_direct_non_transactional_updates= FALSE;
+set @@session.binlog_direct_non_transactional_updates= TRUE;
insert into t7(a) values(2);
insert into t8(a) values(3);
end |
-# Test that the session variable 'binlog_format' is read-only
-# in sub-statements.
+# Test that the session variable
+# 'binlog_direct_non_transactional_updates' is
+# read-only in sub-statements.
+# Current session value is FALSE.
insert into t6(a,b) values(1,1);
ERROR HY000: Cannot change the binlog direct flag inside a stored function or trigger
SELECT @@session.binlog_direct_non_transactional_updates;
diff --git a/mysql-test/suite/binlog/t/binlog_switch_inside_trans.test b/mysql-test/suite/binlog/t/binlog_switch_inside_trans.test
index 7b98b5cd0d5..cdc94198933 100644
--- a/mysql-test/suite/binlog/t/binlog_switch_inside_trans.test
+++ b/mysql-test/suite/binlog/t/binlog_switch_inside_trans.test
@@ -1,7 +1,8 @@
#
# BUG#47863
-# This test verifies if the session variable 'binlog_format'
-# is read-only inside a transaction and in sub-statements.
+# This test verifies if the session variable 'binlog_format' and
+# 'binlog_direct_non_transactional_updates' are read-only inside
+# a transaction and in sub-statements.
#
source include/have_innodb.inc;
@@ -13,25 +14,32 @@ create table t1 (a int) engine= myisam;
create table t2 (a int) engine= innodb;
SELECT @@session.binlog_format;
+SELECT @@session.binlog_direct_non_transactional_updates;
SET AUTOCOMMIT=1;
---echo # Test that the session variable 'binlog_format'
---echo # is writable outside a transaction.
+--echo # Test that the session variable 'binlog_format' and
+--echo # 'binlog_direct_non_transactional_updates' are
+--echo # writable outside a transaction.
+--echo # Current session values are ROW and FALSE, respectively.
set @@session.binlog_format= statement;
set @@session.binlog_direct_non_transactional_updates= TRUE;
SELECT @@session.binlog_format;
SELECT @@session.binlog_direct_non_transactional_updates;
begin;
---echo # Test that the session variable 'binlog_format' is read-only
---echo # inside a transaction with no preceding updates.
+--echo # Test that the session variable 'binlog_format' and
+--echo # 'binlog_direct_non_transactional_updates' are
+--echo # read-only inside a transaction with no preceding updates.
+--echo # Current session values are STATEMENT and TRUE, respectively.
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT
set @@session.binlog_format= mixed;
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT
set @@session.binlog_direct_non_transactional_updates= FALSE;
insert into t2 values (1);
---echo # Test that the session variable 'binlog_format' is read-only
---echo # inside a transaction with preceding transactional updates.
+--echo # Test that the session variable 'binlog_format' and
+--echo # 'binlog_direct_non_transactional_updates' are
+--echo # read-only inside a transaction with preceding transactional updates.
+--echo # Current session values are STATEMENT and TRUE, respectively.
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT
set @@session.binlog_format= row;
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT
@@ -40,25 +48,32 @@ commit;
begin;
insert into t1 values (2);
---echo # Test that the session variable 'binlog_format' is read-only
---echo # inside a transaction with preceding non-transactional updates.
+--echo # Test that the session variable 'binlog_format' and
+--echo # 'binlog_direct_non_transactional_updates' are
+--echo # read-only inside a transaction with preceding non-transactional updates.
+--echo # Current session values are STATEMENT and TRUE, respectively.
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT
- set @@session.binlog_format= statement;
+ set @@session.binlog_format= mixed;
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT
set @@session.binlog_direct_non_transactional_updates= FALSE;
commit;
---echo # Test that the session variable 'binlog_format' is writable
---echo # when AUTOCOMMIT=0, before a transaction has started.
+--echo # Test that the session variable 'binlog_format' and
+--echo # 'binlog_direct_non_transactional_updates' are
+--echo # writable when AUTOCOMMIT=0, before a transaction has started.
+--echo # Current session values are STATEMENT and TRUE, respectively.
set AUTOCOMMIT=0;
set @@session.binlog_format= row;
set @@session.binlog_direct_non_transactional_updates= FALSE;
SELECT @@session.binlog_format;
SELECT @@session.binlog_direct_non_transactional_updates;
-insert into t1 values (4);
---echo # Test that the session variable 'binlog_format' is read-only inside an
---echo # AUTOCOMMIT=0 transaction with preceding non-transactional updates.
+insert into t1 values (3);
+--echo # Test that the session variable 'binlog_format' and
+--echo # 'binlog_direct_non_transactional_updates' are
+--echo # read-only inside an AUTOCOMMIT=0 transaction
+--echo # with preceding non-transactional updates.
+--echo # Current session values are ROW and FALSE, respectively.
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT
set @@session.binlog_format= statement;
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT
@@ -67,11 +82,14 @@ SELECT @@session.binlog_format;
SELECT @@session.binlog_direct_non_transactional_updates;
commit;
-insert into t2 values (5);
---echo # Test that the session variable 'binlog_format' is read-only inside an
---echo # AUTOCOMMIT=0 transaction with preceding transactional updates.
+insert into t2 values (4);
+--echo # Test that the session variable 'binlog_format' and
+--echo # 'binlog_direct_non_transactional_updates' are
+--echo # read-only inside an AUTOCOMMIT=0 transaction with
+--echo # preceding transactional updates.
+--echo # Current session values are ROW and FALSE, respectively.
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT
-set @@session.binlog_format= row;
+set @@session.binlog_format= statement;
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT
set @@session.binlog_direct_non_transactional_updates= TRUE;
SELECT @@session.binlog_format;
@@ -79,9 +97,11 @@ SELECT @@session.binlog_direct_non_transactional_updates;
commit;
begin;
- insert into t2 values (6);
---echo # Test that the global variable 'binlog_format' is writable
---echo # inside a transaction.
+ insert into t2 values (5);
+--echo # Test that the global variable 'binlog_format' and
+--echo # 'binlog_direct_non_transactional_updates' are
+--echo # writable inside a transaction.
+--echo # Current session values are ROW and FALSE, respectively.
SELECT @@global.binlog_format;
set @@global.binlog_format= statement;
set @@global.binlog_direct_non_transactional_updates= TRUE;
@@ -90,7 +110,7 @@ begin;
commit;
set @@global.binlog_format= @save_binlog_format;
-set @@global.binlog_direct_non_transactional_updates= @save_binlog_dirct;
+set @@global.binlog_direct_non_transactional_updates= @save_binlog_dirct;
create table t3(a int, b int) engine= innodb;
create table t4(a int) engine= innodb;
@@ -98,7 +118,7 @@ create table t5(a int) engine= innodb;
delimiter |;
eval create trigger tr1 after insert on t3 for each row begin
insert into t4(a) values(1);
- set @@session.binlog_format= statement;
+ set @@session.binlog_format= statement;
insert into t4(a) values(2);
insert into t5(a) values(3);
end |
@@ -106,6 +126,7 @@ delimiter ;|
--echo # Test that the session variable 'binlog_format' is read-only
--echo # in sub-statements.
+--echo # Current session value is ROW.
--error ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT
insert into t3(a,b) values(1,1);
SELECT @@session.binlog_format;
@@ -116,14 +137,16 @@ create table t8(a int) engine= innodb;
delimiter |;
eval create trigger tr2 after insert on t6 for each row begin
insert into t7(a) values(1);
- set @@global.binlog_direct_non_transactional_updates= FALSE;
+ set @@session.binlog_direct_non_transactional_updates= TRUE;
insert into t7(a) values(2);
insert into t8(a) values(3);
end |
delimiter ;|
---echo # Test that the session variable 'binlog_format' is read-only
---echo # in sub-statements.
+--echo # Test that the session variable
+--echo # 'binlog_direct_non_transactional_updates' is
+--echo # read-only in sub-statements.
+--echo # Current session value is FALSE.
--error ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT
insert into t6(a,b) values(1,1);
SELECT @@session.binlog_direct_non_transactional_updates;
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index e14286210b4..76f73765692 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -241,6 +241,12 @@ static bool check_has_super(sys_var *self, THD *thd, set_var *var)
}
static bool binlog_format_check(sys_var *self, THD *thd, set_var *var)
{
+ if (check_has_super(self, thd, var))
+ return true;
+
+ if (var->type == OPT_GLOBAL)
+ return false;
+
/*
If RBR and open temporary tables, their CREATE TABLE may not be in the
binlog, so we can't toggle to SBR in this connection.
@@ -272,18 +278,12 @@ static bool binlog_format_check(sys_var *self, THD *thd, set_var *var)
/*
Make the session variable 'binlog_format' read-only inside a transaction.
*/
- if (thd->active_transaction() && (var->type == OPT_SESSION))
+ if (thd->active_transaction())
{
my_error(ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0));
return true;
}
- if (check_has_super(self, thd, var))
- return true;
- if (var->type == OPT_GLOBAL ||
- (thd->variables.binlog_format == var->save_result.ulonglong_value))
- return false;
-
return false;
}
@@ -312,32 +312,31 @@ static Sys_var_enum Sys_binlog_format(
static bool binlog_direct_check(sys_var *self, THD *thd, set_var *var)
{
+ if (check_has_super(self, thd, var))
+ return true;
+
+ if (var->type == OPT_GLOBAL)
+ return false;
+
/*
Makes the session variable 'binlog_direct_non_transactional_updates'
- read-only inside a transaction.
+ read-only if within a procedure, trigger or function.
*/
- if (thd->active_transaction() && (var->type == OPT_SESSION))
+ if (thd->in_sub_stmt)
{
- my_error(ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT, MYF(0));
- return 1;
+ my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT, MYF(0));
+ return true;
}
/*
Makes the session variable 'binlog_direct_non_transactional_updates'
- read-only if within a procedure, trigger or function.
+ read-only inside a transaction.
*/
- if (thd->in_sub_stmt)
+ if (thd->active_transaction())
{
- my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT, MYF(0));
- return 1;
+ my_error(ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT, MYF(0));
+ return true;
}
- if (check_has_super(self, thd, var))
- return true;
- if (var->type == OPT_GLOBAL ||
- (thd->variables.binlog_direct_non_trans_update ==
- static_cast<my_bool>(var->save_result.ulonglong_value)))
- return false;
-
return false;
}