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,
|
bool Lex_input_stream::init(THD *thd,
|
||||||
const char* buff,
|
char* buff,
|
||||||
unsigned int length)
|
unsigned int length)
|
||||||
{
|
{
|
||||||
DBUG_EXECUTE_IF("bug42064_simulate_oom",
|
DBUG_EXECUTE_IF("bug42064_simulate_oom",
|
||||||
@ -183,7 +183,7 @@ bool Lex_input_stream::init(THD *thd,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
Lex_input_stream::reset(const char *buffer, unsigned int length)
|
Lex_input_stream::reset(char *buffer, unsigned int length)
|
||||||
{
|
{
|
||||||
yylineno= 1;
|
yylineno= 1;
|
||||||
yytoklen= 0;
|
yytoklen= 0;
|
||||||
@ -1425,11 +1425,10 @@ int lex_one_token(void *arg, void *yythd)
|
|||||||
ulong version;
|
ulong version;
|
||||||
version=strtol(version_str, NULL, 10);
|
version=strtol(version_str, NULL, 10);
|
||||||
|
|
||||||
/* Accept 'M' 'm' 'm' 'd' 'd' */
|
|
||||||
lip->yySkipn(5);
|
|
||||||
|
|
||||||
if (version <= MYSQL_VERSION_ID)
|
if (version <= MYSQL_VERSION_ID)
|
||||||
{
|
{
|
||||||
|
/* Accept 'M' 'm' 'm' 'd' 'd' */
|
||||||
|
lip->yySkipn(5);
|
||||||
/* Expand the content of the special comment as real code */
|
/* Expand the content of the special comment as real code */
|
||||||
lip->set_echo(TRUE);
|
lip->set_echo(TRUE);
|
||||||
state=MY_LEX_START;
|
state=MY_LEX_START;
|
||||||
@ -1437,7 +1436,19 @@ int lex_one_token(void *arg, void *yythd)
|
|||||||
}
|
}
|
||||||
else
|
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);
|
comment_closed= ! consume_comment(lip, 1);
|
||||||
|
if (! comment_closed)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(pcom == version_mark);
|
||||||
|
*pcom= '!';
|
||||||
|
}
|
||||||
/* version allowed to have one level of comment inside. */
|
/* version allowed to have one level of comment inside. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1394,9 +1394,9 @@ public:
|
|||||||
@retval FALSE OK
|
@retval FALSE OK
|
||||||
@retval TRUE Error
|
@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.
|
Set the echo mode.
|
||||||
@ -1511,6 +1511,20 @@ public:
|
|||||||
m_ptr += n;
|
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.
|
End of file indicator for the query text to parse.
|
||||||
@return true if there are no more characters to parse
|
@return true if there are no more characters to parse
|
||||||
@ -1668,7 +1682,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
/** Pointer to the current position in the raw input stream. */
|
/** 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. */
|
/** Starting position of the last token parsed, in the raw buffer. */
|
||||||
const char *m_tok_start;
|
const char *m_tok_start;
|
||||||
@ -2350,7 +2364,7 @@ public:
|
|||||||
@retval FALSE OK
|
@retval FALSE OK
|
||||||
@retval TRUE Error
|
@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);
|
return m_lip.init(thd, buff, length);
|
||||||
}
|
}
|
||||||
@ -2361,7 +2375,7 @@ public:
|
|||||||
Lex_input_stream m_lip;
|
Lex_input_stream m_lip;
|
||||||
Yacc_state m_yacc;
|
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_lip.reset(found_semicolon, length);
|
||||||
m_yacc.reset();
|
m_yacc.reset();
|
||||||
|
@ -5817,13 +5817,13 @@ void mysql_init_multi_delete(LEX *lex)
|
|||||||
Parse a query.
|
Parse a query.
|
||||||
|
|
||||||
@param thd Current thread
|
@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 length Length of the query text
|
||||||
@param[out] found_semicolon For multi queries, position of the character of
|
@param[out] found_semicolon For multi queries, position of the character of
|
||||||
the next query in the query text.
|
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)
|
Parser_state *parser_state)
|
||||||
{
|
{
|
||||||
int error __attribute__((unused));
|
int error __attribute__((unused));
|
||||||
@ -5850,7 +5850,7 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
|
|||||||
lex_start(thd);
|
lex_start(thd);
|
||||||
mysql_reset_thd_for_next_command(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;
|
LEX *lex= thd->lex;
|
||||||
|
|
||||||
@ -5938,14 +5938,14 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
|
|||||||
1 can be ignored
|
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;
|
LEX *lex= thd->lex;
|
||||||
bool error= 0;
|
bool error= 0;
|
||||||
DBUG_ENTER("mysql_test_parse_for_slave");
|
DBUG_ENTER("mysql_test_parse_for_slave");
|
||||||
|
|
||||||
Parser_state parser_state;
|
Parser_state parser_state;
|
||||||
if (!(error= parser_state.init(thd, inBuf, length)))
|
if (!(error= parser_state.init(thd, rawbuf, length)))
|
||||||
{
|
{
|
||||||
lex_start(thd);
|
lex_start(thd);
|
||||||
mysql_reset_thd_for_next_command(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 is_log_table_write_query(enum enum_sql_command command);
|
||||||
bool alloc_query(THD *thd, const char *packet, uint packet_length);
|
bool alloc_query(THD *thd, const char *packet, uint packet_length);
|
||||||
void mysql_init_select(LEX *lex);
|
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);
|
Parser_state *parser_state);
|
||||||
void mysql_reset_thd_for_next_command(THD *thd);
|
void mysql_reset_thd_for_next_command(THD *thd);
|
||||||
bool mysql_new_select(LEX *lex, bool move_down);
|
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,
|
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,
|
TABLE* table, bool is_create_table_ind,
|
||||||
handlerton *default_db_type,
|
handlerton *default_db_type,
|
||||||
bool *work_part_info_used)
|
bool *work_part_info_used)
|
||||||
|
@ -110,7 +110,7 @@ void get_full_part_id_from_key(const TABLE *table, uchar *buf,
|
|||||||
KEY *key_info,
|
KEY *key_info,
|
||||||
const key_range *key_spec,
|
const key_range *key_spec,
|
||||||
part_id_range *part_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,
|
uint part_info_len,
|
||||||
TABLE *table, bool is_create_table_ind,
|
TABLE *table, bool is_create_table_ind,
|
||||||
handlerton *default_db_type,
|
handlerton *default_db_type,
|
||||||
|
@ -629,7 +629,7 @@ struct TABLE_SHARE
|
|||||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||||
/* filled in when reading from frm */
|
/* filled in when reading from frm */
|
||||||
bool auto_partitioned;
|
bool auto_partitioned;
|
||||||
const char *partition_info_str;
|
char *partition_info_str;
|
||||||
uint partition_info_str_len;
|
uint partition_info_str_len;
|
||||||
uint partition_info_buffer_size;
|
uint partition_info_buffer_size;
|
||||||
handlerton *default_part_db_type;
|
handlerton *default_part_db_type;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user