diff options
author | Sergey Vojtovich <sergey.vojtovich@oracle.com> | 2011-01-28 14:46:10 +0300 |
---|---|---|
committer | Sergey Vojtovich <sergey.vojtovich@oracle.com> | 2011-01-28 14:46:10 +0300 |
commit | e8ffaf4ae7f835534bf844410baa18d02f996cef (patch) | |
tree | d22345e12d2d7d0f20f6c722f56eeed8dac41d3a | |
parent | b7635ee9dccaf38e20934a51aab1f25e61bdb68b (diff) | |
parent | 7083cb0bd99c352dfb37828bee1c9de1d1edb068 (diff) | |
download | mariadb-git-e8ffaf4ae7f835534bf844410baa18d02f996cef.tar.gz |
Merge.
-rw-r--r-- | mysql-test/mysql-test-run-shell.sh | 2 | ||||
-rwxr-xr-x | mysql-test/mysql-test-run.pl | 1 | ||||
-rw-r--r-- | mysql-test/r/rpl_conditional_comments.result | 57 | ||||
-rw-r--r-- | mysql-test/t/rpl_conditional_comments.test | 73 | ||||
-rw-r--r-- | sql/mysql_priv.h | 4 | ||||
-rw-r--r-- | sql/sql_lex.cc | 27 | ||||
-rw-r--r-- | sql/sql_lex.h | 10 | ||||
-rw-r--r-- | sql/sql_parse.cc | 14 |
8 files changed, 168 insertions, 20 deletions
diff --git a/mysql-test/mysql-test-run-shell.sh b/mysql-test/mysql-test-run-shell.sh index d919246f2e1..d4d31506f23 100644 --- a/mysql-test/mysql-test-run-shell.sh +++ b/mysql-test/mysql-test-run-shell.sh @@ -150,7 +150,7 @@ find_valgrind() fi # >=2.1.2 requires the --tool option, some versions write to stdout, some to stderr valgrind --help 2>&1 | grep "\-\-tool" > /dev/null && FIND_VALGRIND="$FIND_VALGRIND --tool=memcheck" - FIND_VALGRIND="$FIND_VALGRIND --alignment=8 --leak-check=yes --num-callers=16 --suppressions=$MYSQL_TEST_DIR/valgrind.supp" + FIND_VALGRIND="$FIND_VALGRIND --leak-check=yes --num-callers=16 --suppressions=$MYSQL_TEST_DIR/valgrind.supp" } # No paths below as we can't be sure where the program is! diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 2cfd689b0e7..f0100593516 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -5135,7 +5135,6 @@ sub valgrind_arguments { else { mtr_add_arg($args, "--tool=memcheck"); # From >= 2.1.2 needs this option - mtr_add_arg($args, "--alignment=8"); mtr_add_arg($args, "--leak-check=yes"); mtr_add_arg($args, "--num-callers=16"); mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir) diff --git a/mysql-test/r/rpl_conditional_comments.result b/mysql-test/r/rpl_conditional_comments.result new file mode 100644 index 00000000000..105d3bc59f3 --- /dev/null +++ b/mysql-test/r/rpl_conditional_comments.result @@ -0,0 +1,57 @@ +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 # # use `test`; /* 99999 --- */INSERT /*!INTO*/ /*!10000 t1 */ VALUES(10) /* 99999 ,(11)*/ +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 # # use `test`; INSERT INTO /* 99999 blabla*/ t1 VALUES(60) /* 99999 ,(61)*/ +master-bin.000001 # Query # # use `test`; DROP TABLE t1 +master-bin.000001 # Query # # use `test`; CREATE TABLE t1(c1 INT) +master-bin.000001 # Query # # use `test`; INSERT INTO /* 99999 blabla*/ t1 VALUES(60) /* 99999 ,(61)*/ +master-bin.000001 # Query # # use `test`; INSERT INTO /* 99999 blabla */ t1 VALUES(62) /* 99999 ,(63)*/ +master-bin.000001 # Query # # use `test`; DROP TABLE t1 +master-bin.000001 # Query # # use `test`; CREATE TABLE t1(c1 INT) +master-bin.000001 # Query # # use `test`; INSERT INTO /* 99999 blabla */ t1 VALUES(62) /* 99999 ,(63)*/ +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; diff --git a/mysql-test/t/rpl_conditional_comments.test b/mysql-test/t/rpl_conditional_comments.test new file mode 100644 index 00000000000..f1f46b8fc41 --- /dev/null +++ b/mysql-test/t/rpl_conditional_comments.test @@ -0,0 +1,73 @@ +############################################################################### +# 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; + +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; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 55bcd30999d..d88e629b91b 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -751,7 +751,7 @@ bool do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch); -void mysql_parse(THD *thd, const char *inBuf, uint length, +void mysql_parse(THD *thd, char *rawbuf, uint length, const char ** semicolon); bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 17ee53d446b..97d9fe99eb3 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -109,7 +109,7 @@ st_parsing_options::reset() } Lex_input_stream::Lex_input_stream(THD *thd, - const char* buffer, + char* buffer, unsigned int length) : m_thd(thd), yylineno(1), @@ -580,7 +580,7 @@ int MYSQLlex(void *arg, void *yythd) state=MY_LEX_COMMENT; break; } - yylval->lex_str.str=(char*) (lip->ptr=lip->tok_start);// Set to first chr + yylval->lex_str.str=lip->ptr=(char*)lip->tok_start;// Set to first chr yylval->lex_str.length=1; c=yyGet(); if (c != ')') @@ -946,6 +946,9 @@ int MYSQLlex(void *arg, void *yythd) state = MY_LEX_START; // Try again break; case MY_LEX_LONG_COMMENT: /* Long C comment? */ + { + char *version_mark= NULL; + if (yyPeek() != '*') { state=MY_LEX_CHAR; // Probable division @@ -956,6 +959,8 @@ int MYSQLlex(void *arg, void *yythd) if (yyPeek() == '!') // MySQL command in comment { ulong version=MYSQL_VERSION_ID; + version_mark= lip->ptr; + yySkip(); state=MY_LEX_START; if (my_isdigit(cs,yyPeek())) @@ -964,9 +969,18 @@ int MYSQLlex(void *arg, void *yythd) } if (version <= MYSQL_VERSION_ID) { - lex->in_comment=1; + lex->in_comment=1; + version_mark= NULL; break; } + else + { + /* + Patch and skip the conditional comment to avoid it + being propagated infinitely (eg. to a slave). + */ + *version_mark= ' '; + } } /* Discard: @@ -995,8 +1009,13 @@ int MYSQLlex(void *arg, void *yythd) } /* Unbalanced comments with a missing '*' '/' are a syntax error */ if (! comment_closed) + { + if (version_mark != NULL) + *version_mark= '!'; return (ABORT_SYM); + } break; + } case MY_LEX_END_LONG_COMMENT: if (lex->in_comment && yyPeek() == '/') { diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 5c0367632e1..b3822f91afe 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -935,7 +935,7 @@ struct st_parsing_options class Lex_input_stream { public: - Lex_input_stream(THD *thd, const char* buff, unsigned int length); + Lex_input_stream(THD *thd, char* buff, unsigned int length); ~Lex_input_stream(); /** Current thread. */ @@ -951,7 +951,7 @@ public: LEX_YYSTYPE yylval; /** Pointer to the current position in the input stream. */ - const char* ptr; + char* ptr; /** Starting position of the last token parsed. */ const char* tok_start; @@ -966,7 +966,7 @@ public: const char* tok_start_prev; /** Begining of the query text in the input stream. */ - const char* buf; + char* buf; /** Current state of the lexical analyser. */ enum my_lex_states next_state; @@ -1355,7 +1355,7 @@ public: class Parser_state { public: - Parser_state(THD *thd, const char* buff, unsigned int length) + Parser_state(THD *thd, char* buff, unsigned int length) : m_lip(thd, buff, length), m_yacc() {} diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1bd68e5424f..de67b99b172 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -6414,13 +6414,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] 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, const char ** found_semicolon) { DBUG_ENTER("mysql_parse"); @@ -6446,14 +6446,14 @@ 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; sp_cache_flush_obsolete(&thd->sp_proc_cache); sp_cache_flush_obsolete(&thd->sp_func_cache); - Parser_state parser_state(thd, inBuf, length); + Parser_state parser_state(thd, rawbuf, length); thd->m_parser_state= &parser_state; int err= MYSQLparse(thd); @@ -6538,13 +6538,13 @@ 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(thd, inBuf, length); + Parser_state parser_state(thd, rawbuf, length); thd->m_parser_state= &parser_state; lex_start(thd); |