Commit bd3aa7eb authored by Alfranio Correia's avatar Alfranio Correia

BUG#50312 Warnings for unsafe sub-statement not returned to client

                        
After BUG#36649, warnings for sub-statements are cleared when a 
new sub-statement is started. This is problematic since it suppresses
warnings for unsafe statements in some cases. It is important that we
always give a warning to the client, because the user needs to know
when there is a risk that the slave goes out of sync.
                        
We fixed the problem by generating warning messages for unsafe statements
while returning from a stored procedure, function, trigger or while
executing a top level statement.
                        
We also started checking unsafeness when both performance and log tables are
used. This is necessary after the performance schema which does a distinction
between performance and log tables.
parent 89ad5fa8
......@@ -200,7 +200,7 @@ if (`SELECT $CRC_ARG_type = 1`) {
if (`SELECT $CRC_ARG_type = 2`) {
# It will be unsafe to call this procedure.
--let $CRC_name= proc_$CRC_ARG_level
--let $CRC_create= CREATE PROCEDURE $CRC_name() BEGIN INSERT INTO ta$CRC_ARG_level VALUES (47); $CRC_ARG_stmt_sidef; END
--let $CRC_create= CREATE PROCEDURE $CRC_name() BEGIN $CRC_ARG_stmt_sidef; INSERT INTO ta$CRC_ARG_level VALUES (47); END
--let $CRC_RET_stmt_sidef= CALL $CRC_name()
--let $CRC_RET_value=
--let $CRC_RET_sel_retval=
......@@ -344,25 +344,8 @@ if (`SELECT '$CRC_RET_stmt_sidef' != ''`) {
if (`SELECT '$event_type' != 'Table_map'`) {
--enable_query_log
--echo ******** Failure! Event number 3 was a '$event_type', not a 'Table_map'. ********
# Currently, there is a bug causing some statements to be logged
# partially in statement format. Hence, we don't fail here, we
# just print the events (masking out nondeterministic components
# of the output) and continue. When binloggging works perfectly,
# we should instead execute:
#--enable_query_log
#SHOW BINLOG EVENTS;
#--die Wrong events in binlog.
# Here, we should really source
# include/show_binlog_events.inc. But due to BUG#41913, that
# doesn't work, and we have to inline the entire file here. Sigh
# :-(
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR 107 <binlog_start>
--replace_column 2 # 4 # 5 #
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /file_id=[0-9]+/file_id=#/ /block_len=[0-9]+/block_len=#/
--eval SHOW BINLOG EVENTS FROM 107
--disable_query_log
SHOW BINLOG EVENTS;
--die Wrong events in binlog.
}
SET binlog_format = STATEMENT;
......
......@@ -28,6 +28,25 @@ INSERT INTO t1 VALUES (1,2), (2,3);
UPDATE t1 SET b='4' WHERE a=1 LIMIT 1;
UPDATE t1 SET b='5' WHERE a=2 ORDER BY a LIMIT 1;
DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR(1000));
INSERT INTO t1 VALUES (CURRENT_USER());
INSERT INTO t1 VALUES (FOUND_ROWS());
INSERT INTO t1 VALUES (GET_LOCK('tmp', 1));
INSERT INTO t1 VALUES (IS_FREE_LOCK('tmp'));
INSERT INTO t1 VALUES (IS_USED_LOCK('tmp'));
INSERT INTO t1 VALUES (LOAD_FILE('../../std_data/words2.dat'));
INSERT INTO t1 VALUES (MASTER_POS_WAIT('dummy arg', 4711, 1));
INSERT INTO t1 VALUES (RELEASE_LOCK('tmp'));
INSERT INTO t1 VALUES (ROW_COUNT());
INSERT INTO t1 VALUES (SESSION_USER());
INSERT INTO t1 VALUES (SLEEP(1));
INSERT INTO t1 VALUES (SYSDATE());
INSERT INTO t1 VALUES (SYSTEM_USER());
INSERT INTO t1 VALUES (USER());
INSERT INTO t1 VALUES (UUID());
INSERT INTO t1 VALUES (UUID_SHORT());
INSERT INTO t1 VALUES (VERSION());
INSERT INTO t1 VALUES (RAND());
DROP DATABASE b42851;
USE test;
#
......@@ -67,8 +86,11 @@ Note 1592 Unsafe statement written to the binary log using statement format sinc
SELECT sf_bug50192();
sf_bug50192()
1
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column. Inserted values cannot be logged correctly.
SHOW WARNINGS;
Level Code Message
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column. Inserted values cannot be logged correctly.
DROP FUNCTION sf_bug50192;
DROP TRIGGER tr_bug50192;
DROP TABLE t1, t2;
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -72,6 +72,26 @@ UPDATE t1 SET b='4' WHERE a=1 LIMIT 1;
UPDATE t1 SET b='5' WHERE a=2 ORDER BY a LIMIT 1;
DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR(1000));
INSERT INTO t1 VALUES (CURRENT_USER()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (FOUND_ROWS()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (GET_LOCK('tmp', 1)); #marked unsafe in BUG#47995
INSERT INTO t1 VALUES (IS_FREE_LOCK('tmp')); #marked unsafe in BUG#47995
INSERT INTO t1 VALUES (IS_USED_LOCK('tmp')); #marked unsafe in BUG#47995
INSERT INTO t1 VALUES (LOAD_FILE('../../std_data/words2.dat')); #marked unsafe in BUG#39701
INSERT INTO t1 VALUES (MASTER_POS_WAIT('dummy arg', 4711, 1));
INSERT INTO t1 VALUES (RELEASE_LOCK('tmp')); #marked unsafe in BUG#47995
INSERT INTO t1 VALUES (ROW_COUNT()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (SESSION_USER()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (SLEEP(1)); #marked unsafe in BUG#47995
INSERT INTO t1 VALUES (SYSDATE()); #marked unsafe in BUG#47995
INSERT INTO t1 VALUES (SYSTEM_USER()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (USER()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (UUID()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (UUID_SHORT()); #marked unsafe before BUG#47995
INSERT INTO t1 VALUES (VERSION()); #marked unsafe in BUG#47995
INSERT INTO t1 VALUES (RAND()); #marked unsafe in BUG#49222
# clean up
DROP DATABASE b42851;
......
......@@ -468,6 +468,7 @@ BEGIN
END|
DELIMITER ;|
--echo "One unsafe warning should be issued in the following statement"
--error ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN
SELECT fun_check_log_bin();
--echo "SQL_LOG_BIN should be ON still"
SHOW VARIABLES LIKE "SQL_LOG_BIN";
......
......@@ -11,5 +11,4 @@
##############################################################################
binlog_truncate_innodb : BUG#42643 2009-02-06 mats Changes to InnoDB requires to complete fix for BUG#36763
binlog_unsafe : BUG#50312 2010-01-13 lsoares Warnings for unsafe sub-statement not returned to client
binlog_spurious_ddl_errors : BUG#54195 2010-06-03 alik binlog_spurious_ddl_errors.test fails, thus disabled
......@@ -72,6 +72,8 @@ before call db1.p1()
INSERT INTO db1.t2 VALUES ('before call db1.p2()');
BEGIN;
CALL db1.p2();
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
ROLLBACK;
INSERT INTO db1.t2 VALUES ('after call db1.p2()');
SELECT * FROM db1.t1;
......
......@@ -3661,6 +3661,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
SELECT fc_i_nt_5_suc (135, 4);
fc_i_nt_5_suc (135, 4)
fc_i_nt_5_suc
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -3689,6 +3691,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (136, 4);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -3781,6 +3785,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
SELECT fc_i_nt_5_suc (139, 4);
fc_i_nt_5_suc (139, 4)
fc_i_nt_5_suc
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -3809,6 +3815,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (140, 4);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -3907,6 +3915,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
SELECT fc_i_nt_5_suc (143, 4);
fc_i_nt_5_suc (143, 4)
fc_i_nt_5_suc
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -3937,6 +3947,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (144, 4);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -4033,6 +4045,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
SELECT fc_i_nt_5_suc (147, 4);
fc_i_nt_5_suc (147, 4)
fc_i_nt_5_suc
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -4063,6 +4077,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (148, 4);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -4295,6 +4311,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
SELECT fc_i_nt_5_suc (155, 4);
fc_i_nt_5_suc (155, 4)
fc_i_nt_5_suc
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -4325,6 +4343,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (156, 4);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -4423,6 +4443,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
SELECT fc_i_nt_5_suc (159, 4);
fc_i_nt_5_suc (159, 4)
fc_i_nt_5_suc
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -4453,6 +4475,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (160, 4);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -4557,6 +4581,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
SELECT fc_i_nt_5_suc (163, 4);
fc_i_nt_5_suc (163, 4)
fc_i_nt_5_suc
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -4589,6 +4615,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (164, 4);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -4691,6 +4719,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
SELECT fc_i_nt_5_suc (167, 4);
fc_i_nt_5_suc (167, 4)
fc_i_nt_5_suc
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -4723,6 +4753,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (168, 4);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b-
......@@ -5291,6 +5323,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (185, 2);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',185), NAME_CONST('in_stmt_id',1))
......@@ -5329,6 +5363,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (186, 2);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',186), NAME_CONST('in_stmt_id',1))
......@@ -5367,6 +5403,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (187, 2);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',187), NAME_CONST('in_stmt_id',1))
......@@ -5407,6 +5445,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (188, 2);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',188), NAME_CONST('in_stmt_id',1))
......@@ -5885,6 +5925,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (201, 2);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',201), NAME_CONST('in_stmt_id',1))
......@@ -5925,6 +5967,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (202, 2);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',202), NAME_CONST('in_stmt_id',1))
......@@ -5967,6 +6011,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (203, 2);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',203), NAME_CONST('in_stmt_id',1))
......@@ -6007,6 +6053,8 @@ Log_name Pos Event_type Server_id End_log_pos Info
-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b-
CALL pc_i_nt_5_suc (204, 2);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',204), NAME_CONST('in_stmt_id',1))
......
......@@ -39,6 +39,8 @@ INSERT INTO t2 VALUES (NULL);
RETURN i;
END//
CALL p1();
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column. Inserted values cannot be logged correctly.
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
......@@ -123,6 +125,8 @@ SELECT * FROM t2;
id
DROP TRIGGER tr1;
CALL p2();
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column. Inserted values cannot be logged correctly.
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
......
......@@ -4704,7 +4704,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
file= cache_mngr->get_binlog_cache_log(is_trans_cache);
cache_data= cache_mngr->get_binlog_cache_data(is_trans_cache);
if (thd->stmt_accessed_non_trans_temp_table())
if (thd->lex->stmt_accessed_non_trans_temp_table())
cache_data->set_changes_to_non_trans_temp_table();
thd->binlog_start_trans_and_stmt();
......
......@@ -679,7 +679,7 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
server_id= thd->server_id;
when= thd->start_time;
cache_type= ((using_trans || stmt_has_updated_trans_table(thd) ||
(thd->stmt_accessed_temp_table() &&
(thd->lex->stmt_accessed_temp_table() &&
trans_has_updated_trans_table(thd)))
? Log_event::EVENT_TRANSACTIONAL_CACHE :
Log_event::EVENT_STMT_CACHE);
......@@ -2573,7 +2573,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
else
{
cache_type= ((using_trans || stmt_has_updated_trans_table(thd) || trx_cache ||
(thd->stmt_accessed_temp_table() &&
(thd->lex->stmt_accessed_temp_table() &&
trans_has_updated_trans_table(thd)))
? Log_event::EVENT_TRANSACTIONAL_CACHE :
Log_event::EVENT_STMT_CACHE);
......
......@@ -1950,6 +1950,14 @@ err_with_cleanup:
free_root(&call_mem_root, MYF(0));
thd->spcont= octx;
/*
If not insided a procedure and a function printing warning
messsages.
*/
if (need_binlog_call &&
thd->spcont == NULL && !thd->binlog_evt_union.do_union)
thd->issue_unsafe_warnings();
DBUG_RETURN(err_status);
}
......@@ -2195,6 +2203,17 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
thd->spcont= save_spcont;
thd->utime_after_lock= utime_before_sp_exec;
/*
If not insided a procedure and a function printing warning
messsages.
*/
bool need_binlog_call= mysql_bin_log.is_open() &&
(thd->variables.option_bits & OPTION_BIN_LOG) &&
!thd->is_current_stmt_binlog_format_row();
if (need_binlog_call && thd->spcont == NULL &&
!thd->binlog_evt_union.do_union)
thd->issue_unsafe_warnings();
DBUG_RETURN(err_status);
}
......
......@@ -492,7 +492,6 @@ THD::THD()
rli_fake(0),
user_time(0), in_sub_stmt(0),
binlog_unsafe_warning_flags(0),
stmt_accessed_table_flag(0),
binlog_table_maps(0),
table_map_for_update(0),
arg_of_last_insert_id_function(FALSE),
......@@ -3675,8 +3674,17 @@ int THD::decide_logging_format(TABLE_LIST *tables)
Innodb and Falcon; Innodb and MyIsam.
*/
my_bool multi_access_engine= FALSE;
/*
Identifies if a table is changed.
*/
my_bool is_write= FALSE;
/*
A pointer to a previous table that was changed.
*/
TABLE* prev_write_table= NULL;
/*
A pointer to a previous table that was accessed.
*/
TABLE* prev_access_table= NULL;
#ifndef DBUG_OFF
......@@ -3700,7 +3708,8 @@ int THD::decide_logging_format(TABLE_LIST *tables)
if (table->placeholder())
continue;
if (table->table->s->table_category == TABLE_CATEGORY_PERFORMANCE)
if (table->table->s->table_category == TABLE_CATEGORY_PERFORMANCE ||
table->table->s->table_category == TABLE_CATEGORY_LOG)
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_TABLE);
handler::Table_flags const flags= table->table->file->ha_table_flags();
......@@ -3716,16 +3725,18 @@ int THD::decide_logging_format(TABLE_LIST *tables)
my_bool trans= table->table->file->has_transactions();
if (table->table->s->tmp_table)
set_stmt_accessed_table(trans ? STMT_WRITES_TEMP_TRANS_TABLE :
STMT_WRITES_TEMP_NON_TRANS_TABLE);
lex->set_stmt_accessed_table(trans ? LEX::STMT_WRITES_TEMP_TRANS_TABLE :
LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE);
else
set_stmt_accessed_table(trans ? STMT_WRITES_TRANS_TABLE :
STMT_WRITES_NON_TRANS_TABLE);
lex->set_stmt_accessed_table(trans ? LEX::STMT_WRITES_TRANS_TABLE :
LEX::STMT_WRITES_NON_TRANS_TABLE);
flags_write_all_set &= flags;
flags_write_some_set |= flags;
is_write= TRUE;
prev_write_table= table->table;
}
flags_access_some_set |= flags;
......@@ -3736,11 +3747,11 @@ int THD::decide_logging_format(TABLE_LIST *tables)
my_bool trans= table->table->file->has_transactions();
if (table->table->s->tmp_table)
set_stmt_accessed_table(trans ? STMT_READS_TEMP_TRANS_TABLE :
STMT_READS_TEMP_NON_TRANS_TABLE);
lex->set_stmt_accessed_table(trans ? LEX::STMT_READS_TEMP_TRANS_TABLE :
LEX::STMT_READS_TEMP_NON_TRANS_TABLE);
else
set_stmt_accessed_table(trans ? STMT_READS_TRANS_TABLE :
STMT_READS_NON_TRANS_TABLE);
lex->set_stmt_accessed_table(trans ? LEX::STMT_READS_TRANS_TABLE :
LEX::STMT_READS_NON_TRANS_TABLE);
}
if (prev_access_table && prev_access_table->file->ht !=
......@@ -3812,24 +3823,24 @@ int THD::decide_logging_format(TABLE_LIST *tables)
my_bool non_trans_unsafe= FALSE;
/* Case 1. */
if (stmt_accessed_table(STMT_WRITES_TRANS_TABLE) &&
stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE))
if (lex->stmt_accessed_table(LEX::STMT_WRITES_TRANS_TABLE) &&
lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE))
mixed_unsafe= TRUE;
/* Case 2. */
else if (stmt_accessed_table(STMT_WRITES_TEMP_TRANS_TABLE) &&
stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE))
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_TRANS_TABLE) &&
lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE))
mixed_unsafe= TRUE;
/* Case 3. */
else if (stmt_accessed_table(STMT_WRITES_TRANS_TABLE) &&
stmt_accessed_table(STMT_READS_NON_TRANS_TABLE))
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TRANS_TABLE) &&
lex->stmt_accessed_table(LEX::STMT_READS_NON_TRANS_TABLE))
mixed_unsafe= TRUE;
/* Case 4. */
else if (stmt_accessed_table(STMT_WRITES_TEMP_TRANS_TABLE) &&
stmt_accessed_table(STMT_READS_NON_TRANS_TABLE))
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_TRANS_TABLE) &&
lex->stmt_accessed_table(LEX::STMT_READS_NON_TRANS_TABLE))
mixed_unsafe= TRUE;
/* Case 5. */
else if (stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE) &&
stmt_accessed_table(STMT_READS_TRANS_TABLE) &&
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) &&
lex->stmt_accessed_table(LEX::STMT_READS_TRANS_TABLE) &&
tx_isolation < ISO_REPEATABLE_READ)
/*
By default, InnoDB operates in REPEATABLE READ and with the option
......@@ -3847,28 +3858,28 @@ int THD::decide_logging_format(TABLE_LIST *tables)
if (trans_has_updated_trans_table(this))
{
/* Case 6. */
if (stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE) &&
stmt_accessed_table(STMT_READS_TRANS_TABLE))
if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) &&
lex->stmt_accessed_table(LEX::STMT_READS_TRANS_TABLE))
mixed_unsafe= TRUE;
/* Case 7. */
else if (stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE) &&
stmt_accessed_table(STMT_READS_TEMP_TRANS_TABLE))
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) &&
lex->stmt_accessed_table(LEX::STMT_READS_TEMP_TRANS_TABLE))
mixed_unsafe= TRUE;
/* Case 8. */
else if (stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE) &&
stmt_accessed_table(STMT_READS_TEMP_NON_TRANS_TABLE))
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE) &&
lex->stmt_accessed_table(LEX::STMT_READS_TEMP_NON_TRANS_TABLE))
mixed_unsafe= TRUE;
/* Case 9. */
else if (stmt_accessed_table(STMT_WRITES_TEMP_NON_TRANS_TABLE) &&
stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE))
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE) &&
lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE))
mixed_unsafe= TRUE;
/* Case 10. */
else if (stmt_accessed_table(STMT_WRITES_TEMP_NON_TRANS_TABLE) &&
stmt_accessed_table(STMT_READS_NON_TRANS_TABLE))
else if (lex->stmt_accessed_table(LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE) &&
lex->stmt_accessed_table(LEX::STMT_READS_NON_TRANS_TABLE))
mixed_unsafe= TRUE;
/* Case 11. */
else if (!variables.binlog_direct_non_trans_update &&
stmt_accessed_table(STMT_WRITES_NON_TRANS_TABLE))
lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE))
non_trans_unsafe= TRUE;
}
......@@ -3959,13 +3970,14 @@ int THD::decide_logging_format(TABLE_LIST *tables)
*/
my_error((error= ER_BINLOG_STMT_MODE_AND_ROW_ENGINE), MYF(0), "");
}
else if ((unsafe_flags= lex->get_stmt_unsafe_flags()) != 0)
else if (is_write && (unsafe_flags= lex->get_stmt_unsafe_flags()) != 0)
{
/*
7. Warning: Unsafe statement logged as statement due to
binlog_format = STATEMENT
*/
binlog_unsafe_warning_flags|= unsafe_flags;
DBUG_PRINT("info", ("Scheduling warning to be issued by "
"binlog_query: '%s'",
ER(ER_BINLOG_UNSAFE_STATEMENT)));
......@@ -4441,23 +4453,10 @@ void THD::issue_unsafe_warnings()
Ensure that binlog_unsafe_warning_flags is big enough to hold all
bits. This is actually a constant expression.
*/
DBUG_ASSERT(2 * LEX::BINLOG_STMT_UNSAFE_COUNT <=
DBUG_ASSERT(LEX::BINLOG_STMT_UNSAFE_COUNT <=
sizeof(binlog_unsafe_warning_flags) * CHAR_BIT);
uint32 unsafe_type_flags= binlog_unsafe_warning_flags;
/*
Clear: (1) bits above BINLOG_STMT_UNSAFE_COUNT; (2) bits for
warnings that have been printed already.
*/
unsafe_type_flags &= (LEX::BINLOG_STMT_UNSAFE_ALL_FLAGS ^
(unsafe_type_flags >> LEX::BINLOG_STMT_UNSAFE_COUNT));
/* If all warnings have been printed already, return. */
if (unsafe_type_flags == 0)
DBUG_VOID_RETURN;
DBUG_PRINT("info", ("unsafe_type_flags: 0x%x", unsafe_type_flags));
/*
For each unsafe_type, check if the statement is unsafe in this way
and issue a warning.
......@@ -4481,12 +4480,6 @@ void THD::issue_unsafe_warnings()
}
}
}
/*
Mark these unsafe types as already printed, to avoid printing
warnings for them again.
*/
binlog_unsafe_warning_flags|=
unsafe_type_flags << LEX::BINLOG_STMT_UNSAFE_COUNT;
DBUG_VOID_RETURN;
}
......@@ -4540,19 +4533,32 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
/*
Warnings for unsafe statements logged in statement format are
printed here instead of in decide_logging_format(). This is
because the warnings should be printed only if the statement is
actually logged. When executing decide_logging_format(), we cannot
know for sure if the statement will be logged.
printed in three places instead of in decide_logging_format().
This is because the warnings should be printed only if the statement
is actually logged. When executing decide_logging_format(), we cannot
know for sure if the statement will be logged:
1 - sp_head::execute_procedure which prints out warnings for calls to
stored procedures.
2 - sp_head::execute_function which prints out warnings for calls
involving functions.
3 - THD::binlog_query (here) which prints warning for top level
statements not covered by the two cases above: i.e., if not insided a
procedure and a function.
Besides, we should not try to print these warnings if it is not
possible to write statements to the binary log as it happens when
the execution is inside a function, or generaly speaking, when
the variables.option_bits & OPTION_BIN_LOG is false.
*/
if (variables.option_bits & OPTION_BIN_LOG)
if ((variables.option_bits & OPTION_BIN_LOG) &&
spcont == NULL && !binlog_evt_union.do_union)
issue_unsafe_warnings();
switch (qtype) {
/*
ROW_QUERY_TYPE means that the statement may be logged either in
......
......@@ -1566,125 +1566,6 @@ public:
return current_stmt_binlog_format == BINLOG_FORMAT_ROW;
}
enum enum_stmt_accessed_table
{
/*
If a transactional table is about to be read. Note that
a write implies a read.
*/
STMT_READS_TRANS_TABLE= 0,
/*
If a transactional table is about to be updated.
*/
STMT_WRITES_TRANS_TABLE,
/*
If a non-transactional table is about to be read. Note that
a write implies a read.
*/
STMT_READS_NON_TRANS_TABLE,
/*
If a non-transactional table is about to be updated.
*/
STMT_WRITES_NON_TRANS_TABLE,
/*
If a temporary transactional table is about to be read. Note
that a write implies a read.
*/
STMT_READS_TEMP_TRANS_TABLE,
/*
If a temporary transactional table is about to be updated.
*/
STMT_WRITES_TEMP_TRANS_TABLE,
/*
If a temporary non-transactional table is about to be read. Note
that a write implies a read.
*/
STMT_READS_TEMP_NON_TRANS_TABLE,
/*
If a temporary non-transactional table is about to be updated.
*/
STMT_WRITES_TEMP_NON_TRANS_TABLE,
/*
The last element of the enumeration. Please, if necessary add
anything before this.
*/
STMT_ACCESS_TABLE_COUNT
};
/**
Sets the type of table that is about to be accessed while executing a
statement.
@param accessed_table Enumeration type that defines the type of table,
e.g. temporary, transactional, non-transactional.
*/
inline void set_stmt_accessed_table(enum_stmt_accessed_table accessed_table)
{
DBUG_ENTER("THD::set_stmt_accessed_table");
DBUG_ASSERT(accessed_table >= 0 && accessed_table < STMT_ACCESS_TABLE_COUNT);
stmt_accessed_table_flag |= (1U << accessed_table);
DBUG_VOID_RETURN;
}
/**
Checks if a type of table is about to be accessed while executing a
statement.
@param accessed_table Enumeration type that defines the type of table,
e.g. temporary, transactional, non-transactional.
@return
@retval TRUE if the type of the table is about to be accessed
@retval FALSE otherwise
*/
inline bool stmt_accessed_table(enum_stmt_accessed_table accessed_table)
{
DBUG_ENTER("THD::stmt_accessed_table");
DBUG_ASSERT(accessed_table >= 0 && accessed_table < STMT_ACCESS_TABLE_COUNT);
DBUG_RETURN((stmt_accessed_table_flag & (1U << accessed_table)) != 0);
}
/**
Checks if a temporary table is about to be accessed while executing a
statement.
@return
@retval TRUE if a temporary table is about to be accessed
@retval FALSE otherwise
*/
inline bool stmt_accessed_temp_table()
{
DBUG_ENTER("THD::stmt_accessed_temp_table");
DBUG_RETURN((stmt_accessed_table_flag &
((1U << STMT_READS_TEMP_TRANS_TABLE) |
(1U << STMT_WRITES_TEMP_TRANS_TABLE) |
(1U << STMT_READS_TEMP_NON_TRANS_TABLE) |
(1U << STMT_WRITES_TEMP_NON_TRANS_TABLE))) != 0);
}
/**
Checks if a temporary non-transactional table is about to be accessed
while executing a statement.
@return
@retval TRUE if a temporary non-transactional table is about to be
accessed
@retval FALSE otherwise
*/
inline bool stmt_accessed_non_trans_temp_table()
{
DBUG_ENTER("THD::stmt_accessed_non_trans_temp_table");
DBUG_RETURN((stmt_accessed_table_flag &
((1U << STMT_READS_TEMP_NON_TRANS_TABLE) |
(1U << STMT_WRITES_TEMP_NON_TRANS_TABLE))) != 0);
}
private:
/**
Indicates the format in which the current statement will be
......@@ -1695,25 +1576,9 @@ private:
/**
Bit field for the state of binlog warnings.
There are two groups of bits:
- The first Lex::BINLOG_STMT_UNSAFE_COUNT bits list all types of
The first Lex::BINLOG_STMT_UNSAFE_COUNT bits list all types of
unsafeness that the current statement has.
- The following Lex::BINLOG_STMT_UNSAFE_COUNT bits list all types
of unsafeness that the current statement has issued warnings
for.
Hence, this variable must be big enough to hold
2*Lex::BINLOG_STMT_UNSAFE_COUNT bits. This is asserted in @c
issue_unsafe_warnings().
The first and second groups of bits are set by @c
decide_logging_format() when it detects that a warning should be
issued. The third group of bits is set from @c binlog_query()
when a warning is issued. All bits are cleared at the end of the
top-level statement.
This must be a member of THD and not of LEX, because warnings are
detected and issued in different places (@c
decide_logging_format() and @c binlog_query(), respectively).
......@@ -1722,20 +1587,14 @@ private:
*/
uint32 binlog_unsafe_warning_flags;
/**
Bit field that determines the type of tables that are about to be
be accessed while executing a statement.
*/
uint32 stmt_accessed_table_flag;
void issue_unsafe_warnings();
/*
Number of outstanding table maps, i.e., table maps in the
transaction cache.
*/
uint binlog_table_maps;
public:
void issue_unsafe_warnings();
uint get_binlog_table_maps() const {
return binlog_table_maps;
}
......
......@@ -2300,6 +2300,7 @@ void Query_tables_list::reset_query_tables_list(bool init)
sroutines_list_own_last= sroutines_list.next;
sroutines_list_own_elements= 0;
binlog_stmt_flags= 0;
stmt_accessed_table_flag= 0;
}
......
......@@ -1276,6 +1276,125 @@ public:
DBUG_VOID_RETURN;
}
enum enum_stmt_accessed_table
{
/*
If a transactional table is about to be read. Note that
a write implies a read.
*/
STMT_READS_TRANS_TABLE= 0,
/*
If a transactional table is about to be updated.
*/
STMT_WRITES_TRANS_TABLE,
/*
If a non-transactional table is about to be read. Note that
a write implies a read.
*/
STMT_READS_NON_TRANS_TABLE,
/*
If a non-transactional table is about to be updated.
*/
STMT_WRITES_NON_TRANS_TABLE,
/*
If a temporary transactional table is about to be read. Note
that a write implies a read.
*/
STMT_READS_TEMP_TRANS_TABLE,
/*
If a temporary transactional table is about to be updated.
*/
STMT_WRITES_TEMP_TRANS_TABLE,
/*
If a temporary non-transactional table is about to be read. Note
that a write implies a read.
*/
STMT_READS_TEMP_NON_TRANS_TABLE,
/*
If a temporary non-transactional table is about to be updated.
*/
STMT_WRITES_TEMP_NON_TRANS_TABLE,
/*
The last element of the enumeration. Please, if necessary add
anything before this.
*/
STMT_ACCESS_TABLE_COUNT
};
/**
Sets the type of table that is about to be accessed while executing a
statement.
@param accessed_table Enumeration type that defines the type of table,
e.g. temporary, transactional, non-transactional.
*/
inline void set_stmt_accessed_table(enum_stmt_accessed_table accessed_table)
{
DBUG_ENTER("THD::set_stmt_accessed_table");
DBUG_ASSERT(accessed_table >= 0 && accessed_table < STMT_ACCESS_TABLE_COUNT);
stmt_accessed_table_flag |= (1U << accessed_table);
DBUG_VOID_RETURN;
}
/**
Checks if a type of table is about to be accessed while executing a
statement.
@param accessed_table Enumeration type that defines the type of table,
e.g. temporary, transactional, non-transactional.
@return
@retval TRUE if the type of the table is about to be accessed
@retval FALSE otherwise
*/
inline bool stmt_accessed_table(enum_stmt_accessed_table accessed_table)
{
DBUG_ENTER("THD::stmt_accessed_table");
DBUG_ASSERT(accessed_table >= 0 && accessed_table < STMT_ACCESS_TABLE_COUNT);
DBUG_RETURN((stmt_accessed_table_flag & (1U << accessed_table)) != 0);
}
/**
Checks if a temporary table is about to be accessed while executing a
statement.
@return
@retval TRUE if a temporary table is about to be accessed
@retval FALSE otherwise
*/
inline bool stmt_accessed_temp_table()
{
DBUG_ENTER("THD::stmt_accessed_temp_table");
DBUG_RETURN((stmt_accessed_table_flag &
((1U << STMT_READS_TEMP_TRANS_TABLE) |
(1U << STMT_WRITES_TEMP_TRANS_TABLE) |
(1U << STMT_READS_TEMP_NON_TRANS_TABLE) |
(1U << STMT_WRITES_TEMP_NON_TRANS_TABLE))) != 0);
}
/**
Checks if a temporary non-transactional table is about to be accessed
while executing a statement.
@return
@retval TRUE if a temporary non-transactional table is about to be
accessed
@retval FALSE otherwise
*/
inline bool stmt_accessed_non_trans_temp_table()
{
DBUG_ENTER("THD::stmt_accessed_non_trans_temp_table");
DBUG_RETURN((stmt_accessed_table_flag &
((1U << STMT_READS_TEMP_NON_TRANS_TABLE) |
(1U << STMT_WRITES_TEMP_NON_TRANS_TABLE))) != 0);
}
/**
true if the parsed tree contains references to stored procedures
or functions, false otherwise
......@@ -1317,6 +1436,12 @@ private:
stored procedure has its own LEX object (but no own THD object).
*/
uint32 binlog_stmt_flags;
/**
Bit field that determines the type of tables that are about to be
be accessed while executing a statement.
*/
uint32 stmt_accessed_table_flag;
};
......
......@@ -5640,7 +5640,6 @@ void THD::reset_for_next_command()
thd->reset_current_stmt_binlog_format_row();
thd->binlog_unsafe_warning_flags= 0;
thd->stmt_accessed_table_flag= 0;
DBUG_PRINT("debug",
("is_current_stmt_binlog_format_row(): %d",
......
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