Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions mysql-test/suite/rpl/r/rpl_reversed_comments.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
include/master-slave.inc
[connection master]
CREATE TABLE t1(c1 INT);
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; CREATE TABLE t1(c1 INT)

# Case 1:
# ------------------------------------------------------------------
# Mix of applied and not-applied reversed CCs in a single statement.
# /*!!999999 ... */ executes (server version < 999999).
# /*!!100000 ... */ does not execute (server version >= 100000).
# The not-applied ones must become plain comments in the binlog.
/*!!100000 --- */INSERT /*!!999999 INTO*/ /*!10000 t1 */ VALUES(10) /*!!100000 ,(11)*/;
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; /* 100000 --- */INSERT /*!!999999 INTO*/ /*!10000 t1 */ VALUES(10) /* 100000 ,(11)*/
master-bin.000001 # Query # # COMMIT
connection slave;
include/diff_tables.inc [master:t1,slave:t1]

# Case 2:
# -----------------------------------------------------------------
# Prepared statements with reversed executable comments.
connection master;
PREPARE stmt FROM 'INSERT INTO /*!!100000 blabla*/ t1 VALUES(60) /*!!100000 ,(61)*/';
EXECUTE stmt;
DROP TABLE t1;
CREATE TABLE t1(c1 INT);
EXECUTE stmt;
connection slave;
include/diff_tables.inc [master:t1,slave:t1]
connection master;

SET @value=62;
PREPARE stmt FROM 'INSERT INTO /*!!100000 blabla */ t1 VALUES(?) /*!!100000 ,(63)*/';
EXECUTE stmt USING @value;
DROP TABLE t1;
CREATE TABLE t1(c1 INT);
EXECUTE stmt USING @value;
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; INSERT INTO /* 100000 blabla*/ t1 VALUES(60) /* 100000 ,(61)*/
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; CREATE TABLE t1(c1 INT)
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; INSERT INTO /* 100000 blabla*/ t1 VALUES(60) /* 100000 ,(61)*/
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; INSERT INTO /* 100000 blabla */ t1 VALUES(62) /* 100000 ,(63)*/
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; CREATE TABLE t1(c1 INT)
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; INSERT INTO /* 100000 blabla */ t1 VALUES(62) /* 100000 ,(63)*/
master-bin.000001 # Query # # COMMIT
connection slave;
include/diff_tables.inc [master:t1,slave:t1]

# Case 3:
# -----------------------------------------------------------------
# Unclosed reversed executable comment — the '!!' must be restored
# so the parser produces a proper syntax error.
connection master;
SELECT c1 FROM /*!!100000 t1 WHEREN;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '/*!!100000 t1 WHEREN' at line 1

# Case 4:
# -----------------------------------------------------------------
# Nested comments inside reversed executable comments.
insert t1 values (/*!!999999 1 /* foo */ */ + 2);
insert t1 values (/*!!100000 10 /* foo */ */ + 20);
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; insert t1 values (/*!!999999 1 /* foo */ */ + 2)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; insert t1 values (/* 100000 10 (* foo *) */ + 20)
master-bin.000001 # Query # # COMMIT
connection slave;
select * from t1;
c1
62
3
20
connection master;

# Case 5:
# -----------------------------------------------------------------
# Delimiter change with reversed executable comment. A parse error
# must not cause master/slave divergence.
insert t1 values /*!! (100);insert t1 values */ (200) //
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'insert t1 values */ (200)' at line 1
select * from t1;
c1
62
3
20
connection slave;
select * from t1;
c1
62
3
20
connection master;

# Case 6:
# -----------------------------------------------------------------
# MariaDB-specific reversed comments /*M!!version */
# /*M!!100000 */ does not execute (server >= 100000), must be plain
# comment in binlog. /*M!!999999 */ executes (server < 999999).
DROP TABLE t1;
CREATE TABLE t1(c1 INT);
INSERT /*M!!100000 blabla */ INTO t1 VALUES(70);
INSERT INTO t1 VALUES(/*M!!999999 80 + */ 1);
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; INSERT /*M 100000 blabla */ INTO t1 VALUES(70)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES(/*M!!999999 80 + */ 1)
master-bin.000001 # Query # # COMMIT
connection slave;
include/diff_tables.inc [master:t1,slave:t1]
connection master;
DROP TABLE t1;
include/rpl_end.inc
126 changes: 126 additions & 0 deletions mysql-test/suite/rpl/t/rpl_reversed_comments.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
###############################################################################
# MDEV-39223: Reversed executable comments incorrectly written in binlog
#
# Mirrors rpl_conditional_comments.test for reversed executable comments
# (/*!!version */ and /*M!!version */ syntax).
#
# - Use ' ' instead of '!' in the conditional comments which are not applied on
# master. So they become common comments and will not be applied on slave.
#
# - Example:
# 'INSERT INTO t1 VALUES (1) /*!!10000, (2)*/ /*!!999999 ,(3)*/
# will be binlogged as
# 'INSERT INTO t1 VALUES (1) /* 10000, (2)*/ /*!!999999 ,(3)*/'.
###############################################################################
source include/have_binlog_format_statement.inc;
source include/master-slave.inc;

CREATE TABLE t1(c1 INT);
source include/show_binlog_events.inc;
let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);

--echo
--echo # Case 1:
--echo # ------------------------------------------------------------------
--echo # Mix of applied and not-applied reversed CCs in a single statement.
--echo # /*!!999999 ... */ executes (server version < 999999).
--echo # /*!!100000 ... */ does not execute (server version >= 100000).
--echo # The not-applied ones must become plain comments in the binlog.

/*!!100000 --- */INSERT /*!!999999 INTO*/ /*!10000 t1 */ VALUES(10) /*!!100000 ,(11)*/;

source include/show_binlog_events.inc;
let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
sync_slave_with_master;
--let $diff_tables= master:t1,slave:t1
--source include/diff_tables.inc

--echo
--echo # Case 2:
--echo # -----------------------------------------------------------------
--echo # Prepared statements with reversed executable comments.

--connection master
PREPARE stmt FROM 'INSERT INTO /*!!100000 blabla*/ t1 VALUES(60) /*!!100000 ,(61)*/';
EXECUTE stmt;
DROP TABLE t1;
CREATE TABLE t1(c1 INT);
EXECUTE stmt;

sync_slave_with_master;
--let $diff_tables= master:t1,slave:t1
--source include/diff_tables.inc

--connection master
--echo
SET @value=62;
PREPARE stmt FROM 'INSERT INTO /*!!100000 blabla */ t1 VALUES(?) /*!!100000 ,(63)*/';
EXECUTE stmt USING @value;
DROP TABLE t1;
CREATE TABLE t1(c1 INT);
EXECUTE stmt USING @value;

source include/show_binlog_events.inc;
let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);

sync_slave_with_master;
--let $diff_tables= master:t1,slave:t1
--source include/diff_tables.inc

--echo
--echo # Case 3:
--echo # -----------------------------------------------------------------
--echo # Unclosed reversed executable comment — the '!!' must be restored
--echo # so the parser produces a proper syntax error.

--connection master
--error 1064
SELECT c1 FROM /*!!100000 t1 WHEREN; #*/

--echo
--echo # Case 4:
--echo # -----------------------------------------------------------------
--echo # Nested comments inside reversed executable comments.

insert t1 values (/*!!999999 1 /* foo */ */ + 2);
insert t1 values (/*!!100000 10 /* foo */ */ + 20);
source include/show_binlog_events.inc;
sync_slave_with_master;
select * from t1;
connection master;

--echo
--echo # Case 5:
--echo # -----------------------------------------------------------------
--echo # Delimiter change with reversed executable comment. A parse error
--echo # must not cause master/slave divergence.

delimiter //;
--error ER_PARSE_ERROR
insert t1 values /*!! (100);insert t1 values */ (200) //
delimiter ;//
select * from t1;
sync_slave_with_master;
select * from t1;
connection master;

--echo
--echo # Case 6:
--echo # -----------------------------------------------------------------
--echo # MariaDB-specific reversed comments /*M!!version */
--echo # /*M!!100000 */ does not execute (server >= 100000), must be plain
--echo # comment in binlog. /*M!!999999 */ executes (server < 999999).

DROP TABLE t1;
CREATE TABLE t1(c1 INT);
let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
INSERT /*M!!100000 blabla */ INTO t1 VALUES(70);
INSERT INTO t1 VALUES(/*M!!999999 80 + */ 1);
source include/show_binlog_events.inc;
sync_slave_with_master;
--let $diff_tables= master:t1,slave:t1
--source include/diff_tables.inc

connection master;
DROP TABLE t1;
--source include/rpl_end.inc
4 changes: 4 additions & 0 deletions sql/sql_lex.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2504,10 +2504,14 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd)
being propagated infinitely (eg. to a slave).
*/
char *pcom= yyUnput(' ');
if (reversed_comment)
*(pcom - 1)= ' ';
comment_closed= ! consume_comment(1);
if (! comment_closed)
{
*pcom= '!';
if (reversed_comment)
*(pcom - 1)= '!';
}
/* version allowed to have one level of comment inside. */
}
Expand Down
Loading