Commit c61ce414 authored by 's avatar

Manual merge

parents a0d5be1f 2ad690fd
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;
###############################################################################
# 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() ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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); ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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;
......
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