Manual merge
This commit is contained in:
commit
cb63e6d021
67
mysql-test/suite/rpl/r/rpl_conditional_comments.result
Normal file
67
mysql-test/suite/rpl/r/rpl_conditional_comments.result
Normal file
@ -0,0 +1,67 @@
|
||||
stop slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
reset master;
|
||||
reset slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
start slave;
|
||||
CREATE TABLE t1(c1 INT);
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE t1(c1 INT)
|
||||
|
||||
# Case 1:
|
||||
# ------------------------------------------------------------------
|
||||
# In a statement, some CCs are applied while others are not. The CCs
|
||||
# which are not applied on master will be binlogged as common comments.
|
||||
/*!99999 --- */INSERT /*!INTO*/ /*!10000 t1 */ VALUES(10) /*!99999 ,(11)*/;
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; /* 99999 --- */INSERT /*!INTO*/ /*!10000 t1 */ VALUES(10) /* 99999 ,(11)*/
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
|
||||
# Case 2:
|
||||
# -----------------------------------------------------------------
|
||||
# Verify whether it can be binlogged correctly when executing prepared
|
||||
# statement.
|
||||
PREPARE stmt FROM 'INSERT INTO /*!99999 blabla*/ t1 VALUES(60) /*!99999 ,(61)*/';
|
||||
EXECUTE stmt;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(c1 INT);
|
||||
EXECUTE stmt;
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
|
||||
SET @value=62;
|
||||
PREPARE stmt FROM 'INSERT INTO /*!99999 blabla */ t1 VALUES(?) /*!99999 ,(63)*/';
|
||||
EXECUTE stmt USING @value;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(c1 INT);
|
||||
EXECUTE stmt USING @value;
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO /* 99999 blabla*/ t1 VALUES(60) /* 99999 ,(61)*/
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # use `test`; DROP TABLE t1
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE t1(c1 INT)
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO /* 99999 blabla*/ t1 VALUES(60) /* 99999 ,(61)*/
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO /* 99999 blabla */ t1 VALUES(62) /* 99999 ,(63)*/
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
master-bin.000001 # Query # # use `test`; DROP TABLE t1
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE t1(c1 INT)
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO /* 99999 blabla */ t1 VALUES(62) /* 99999 ,(63)*/
|
||||
master-bin.000001 # Query # # COMMIT
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
|
||||
# Case 3:
|
||||
# -----------------------------------------------------------------
|
||||
# Verify it can restore the '!', if the it is an uncomplete conditional
|
||||
# comments
|
||||
SELECT c1 FROM /*!99999 t1 WHEREN;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*!99999 t1 WHEREN' at line 1
|
||||
DROP TABLE t1;
|
74
mysql-test/suite/rpl/t/rpl_conditional_comments.test
Normal file
74
mysql-test/suite/rpl/t/rpl_conditional_comments.test
Normal file
@ -0,0 +1,74 @@
|
||||
###############################################################################
|
||||
# After the patch for BUG#49124:
|
||||
# - 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)*/ /*!99999 ,(3)*/
|
||||
# will be binlogged as
|
||||
# 'INSERT INTO t1 VALUES (1) /*!10000, (2)*/ /* 99999 ,(3)*/'.
|
||||
###############################################################################
|
||||
source include/master-slave.inc;
|
||||
source include/have_binlog_format_statement.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 # In a statement, some CCs are applied while others are not. The CCs
|
||||
--echo # which are not applied on master will be binlogged as common comments.
|
||||
|
||||
/*!99999 --- */INSERT /*!INTO*/ /*!10000 t1 */ VALUES(10) /*!99999 ,(11)*/;
|
||||
|
||||
source include/show_binlog_events.inc;
|
||||
let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
|
||||
sync_slave_with_master;
|
||||
let $diff_table_1=master:test.t1;
|
||||
let $diff_table_2=slave:test.t1;
|
||||
source include/diff_tables.inc;
|
||||
|
||||
--echo
|
||||
--echo # Case 2:
|
||||
--echo # -----------------------------------------------------------------
|
||||
--echo # Verify whether it can be binlogged correctly when executing prepared
|
||||
--echo # statement.
|
||||
PREPARE stmt FROM 'INSERT INTO /*!99999 blabla*/ t1 VALUES(60) /*!99999 ,(61)*/';
|
||||
EXECUTE stmt;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(c1 INT);
|
||||
EXECUTE stmt;
|
||||
|
||||
sync_slave_with_master;
|
||||
let $diff_table_1=master:test.t1;
|
||||
let $diff_table_2=slave:test.t1;
|
||||
source include/diff_tables.inc;
|
||||
|
||||
--echo
|
||||
SET @value=62;
|
||||
PREPARE stmt FROM 'INSERT INTO /*!99999 blabla */ t1 VALUES(?) /*!99999 ,(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_table_1=master:test.t1;
|
||||
let $diff_table_2=slave:test.t1;
|
||||
source include/diff_tables.inc;
|
||||
|
||||
--echo
|
||||
--echo # Case 3:
|
||||
--echo # -----------------------------------------------------------------
|
||||
--echo # Verify it can restore the '!', if the it is an uncomplete conditional
|
||||
--echo # comments
|
||||
--error 1064
|
||||
SELECT c1 FROM /*!99999 t1 WHEREN;
|
||||
|
||||
DROP TABLE t1;
|
||||
source include/master-slave-end.inc;
|
@ -153,7 +153,7 @@ st_parsing_options::reset()
|
||||
*/
|
||||
|
||||
bool Lex_input_stream::init(THD *thd,
|
||||
const char* buff,
|
||||
char* buff,
|
||||
unsigned int length)
|
||||
{
|
||||
DBUG_EXECUTE_IF("bug42064_simulate_oom",
|
||||
@ -183,7 +183,7 @@ bool Lex_input_stream::init(THD *thd,
|
||||
*/
|
||||
|
||||
void
|
||||
Lex_input_stream::reset(const char *buffer, unsigned int length)
|
||||
Lex_input_stream::reset(char *buffer, unsigned int length)
|
||||
{
|
||||
yylineno= 1;
|
||||
yytoklen= 0;
|
||||
@ -1425,11 +1425,10 @@ int lex_one_token(void *arg, void *yythd)
|
||||
ulong version;
|
||||
version=strtol(version_str, NULL, 10);
|
||||
|
||||
/* Accept 'M' 'm' 'm' 'd' 'd' */
|
||||
lip->yySkipn(5);
|
||||
|
||||
if (version <= MYSQL_VERSION_ID)
|
||||
{
|
||||
/* Accept 'M' 'm' 'm' 'd' 'd' */
|
||||
lip->yySkipn(5);
|
||||
/* Expand the content of the special comment as real code */
|
||||
lip->set_echo(TRUE);
|
||||
state=MY_LEX_START;
|
||||
@ -1437,7 +1436,19 @@ int lex_one_token(void *arg, void *yythd)
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* version_mark= lip->get_ptr() - 1;
|
||||
DBUG_ASSERT(*version_mark == '!');
|
||||
/*
|
||||
Patch and skip the conditional comment to avoid it
|
||||
being propagated infinitely (eg. to a slave).
|
||||
*/
|
||||
char *pcom= lip->yyUnput(' ');
|
||||
comment_closed= ! consume_comment(lip, 1);
|
||||
if (! comment_closed)
|
||||
{
|
||||
DBUG_ASSERT(pcom == version_mark);
|
||||
*pcom= '!';
|
||||
}
|
||||
/* version allowed to have one level of comment inside. */
|
||||
}
|
||||
}
|
||||
|
@ -1394,9 +1394,9 @@ public:
|
||||
@retval FALSE OK
|
||||
@retval TRUE Error
|
||||
*/
|
||||
bool init(THD *thd, const char *buff, unsigned int length);
|
||||
bool init(THD *thd, char *buff, unsigned int length);
|
||||
|
||||
void reset(const char *buff, unsigned int length);
|
||||
void reset(char *buff, unsigned int length);
|
||||
|
||||
/**
|
||||
Set the echo mode.
|
||||
@ -1511,6 +1511,20 @@ public:
|
||||
m_ptr += n;
|
||||
}
|
||||
|
||||
/**
|
||||
Puts a character back into the stream, canceling
|
||||
the effect of the last yyGet() or yySkip().
|
||||
Note that the echo mode should not change between calls
|
||||
to unput, get, or skip from the stream.
|
||||
*/
|
||||
char *yyUnput(char ch)
|
||||
{
|
||||
*--m_ptr= ch;
|
||||
if (m_echo)
|
||||
m_cpp_ptr--;
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
End of file indicator for the query text to parse.
|
||||
@return true if there are no more characters to parse
|
||||
@ -1668,7 +1682,7 @@ public:
|
||||
|
||||
private:
|
||||
/** Pointer to the current position in the raw input stream. */
|
||||
const char *m_ptr;
|
||||
char *m_ptr;
|
||||
|
||||
/** Starting position of the last token parsed, in the raw buffer. */
|
||||
const char *m_tok_start;
|
||||
@ -2350,7 +2364,7 @@ public:
|
||||
@retval FALSE OK
|
||||
@retval TRUE Error
|
||||
*/
|
||||
bool init(THD *thd, const char *buff, unsigned int length)
|
||||
bool init(THD *thd, char *buff, unsigned int length)
|
||||
{
|
||||
return m_lip.init(thd, buff, length);
|
||||
}
|
||||
@ -2361,7 +2375,7 @@ public:
|
||||
Lex_input_stream m_lip;
|
||||
Yacc_state m_yacc;
|
||||
|
||||
void reset(const char *found_semicolon, unsigned int length)
|
||||
void reset(char *found_semicolon, unsigned int length)
|
||||
{
|
||||
m_lip.reset(found_semicolon, length);
|
||||
m_yacc.reset();
|
||||
|
@ -5817,13 +5817,13 @@ void mysql_init_multi_delete(LEX *lex)
|
||||
Parse a query.
|
||||
|
||||
@param thd Current thread
|
||||
@param inBuf Begining of the query text
|
||||
@param rawbuf Begining of the query text
|
||||
@param length Length of the query text
|
||||
@param[out] found_semicolon For multi queries, position of the character of
|
||||
the next query in the query text.
|
||||
*/
|
||||
|
||||
void mysql_parse(THD *thd, const char *inBuf, uint length,
|
||||
void mysql_parse(THD *thd, char *rawbuf, uint length,
|
||||
Parser_state *parser_state)
|
||||
{
|
||||
int error __attribute__((unused));
|
||||
@ -5850,7 +5850,7 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
|
||||
lex_start(thd);
|
||||
mysql_reset_thd_for_next_command(thd);
|
||||
|
||||
if (query_cache_send_result_to_client(thd, (char*) inBuf, length) <= 0)
|
||||
if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0)
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
|
||||
@ -5938,14 +5938,14 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
|
||||
1 can be ignored
|
||||
*/
|
||||
|
||||
bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
|
||||
bool mysql_test_parse_for_slave(THD *thd, char *rawbuf, uint length)
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
bool error= 0;
|
||||
DBUG_ENTER("mysql_test_parse_for_slave");
|
||||
|
||||
Parser_state parser_state;
|
||||
if (!(error= parser_state.init(thd, inBuf, length)))
|
||||
if (!(error= parser_state.init(thd, rawbuf, length)))
|
||||
{
|
||||
lex_start(thd);
|
||||
mysql_reset_thd_for_next_command(thd);
|
||||
|
@ -84,7 +84,7 @@ bool is_update_query(enum enum_sql_command command);
|
||||
bool is_log_table_write_query(enum enum_sql_command command);
|
||||
bool alloc_query(THD *thd, const char *packet, uint packet_length);
|
||||
void mysql_init_select(LEX *lex);
|
||||
void mysql_parse(THD *thd, const char *inBuf, uint length,
|
||||
void mysql_parse(THD *thd, char *rawbuf, uint length,
|
||||
Parser_state *parser_state);
|
||||
void mysql_reset_thd_for_next_command(THD *thd);
|
||||
bool mysql_new_select(LEX *lex, bool move_down);
|
||||
|
@ -4183,7 +4183,7 @@ void get_partition_set(const TABLE *table, uchar *buf, const uint index,
|
||||
*/
|
||||
|
||||
bool mysql_unpack_partition(THD *thd,
|
||||
const char *part_buf, uint part_info_len,
|
||||
char *part_buf, uint part_info_len,
|
||||
TABLE* table, bool is_create_table_ind,
|
||||
handlerton *default_db_type,
|
||||
bool *work_part_info_used)
|
||||
|
@ -110,7 +110,7 @@ void get_full_part_id_from_key(const TABLE *table, uchar *buf,
|
||||
KEY *key_info,
|
||||
const key_range *key_spec,
|
||||
part_id_range *part_spec);
|
||||
bool mysql_unpack_partition(THD *thd, const char *part_buf,
|
||||
bool mysql_unpack_partition(THD *thd, char *part_buf,
|
||||
uint part_info_len,
|
||||
TABLE *table, bool is_create_table_ind,
|
||||
handlerton *default_db_type,
|
||||
|
@ -629,7 +629,7 @@ struct TABLE_SHARE
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
/* filled in when reading from frm */
|
||||
bool auto_partitioned;
|
||||
const char *partition_info_str;
|
||||
char *partition_info_str;
|
||||
uint partition_info_str_len;
|
||||
uint partition_info_buffer_size;
|
||||
handlerton *default_part_db_type;
|
||||
|
Loading…
x
Reference in New Issue
Block a user