#At file:///export/home/x/mysql-5.5-runtime-bug56678/ based on revid:jon.hauglid@stripped
3142 Jon Olav Hauglid 2010-09-23
Bug #56678 Valgrind warnings from binlog.binlog_unsafe
After the patch for Bug#54579, multi inserts done with INSERT DELAYED
are binlogged as normal INSERT. During processing of the statement,
a new query string without the DELAYED keyword is made. The problem
was that this new string was incorrectly made when the INSERT DELAYED
was part of a prepared statement - data was read outside the allocated
buffer.
The reason for this bug was that a pointer to the position of the
DELAYED keyword inside the query string was stored when parsing the
statement. This pointer was then later (at runtime) used (via pointer
subtraction) to find the number of characters to skip when making a
new query string without DELAYED. But when the statement was re-executed
as part of a prepared statement, the original pointer would be invalid
and the pointer subtraction would give a wrong/random result.
This patch fixes the problem by instead storing the number of characters
to skip at parse time. This value will not depend on the memory position
of the query string at runtime and therefore not give wrong results
when the statement is executed in a prepared statement.
This bug was a regression introduced by the patch for Bug#54579.
No test case added as this bug is already covered by the existing
binlog.binlog_unsafe test case when running with valgrind.
modified:
mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result
sql/sql_insert.cc
sql/sql_lex.h
sql/sql_yacc.yy
=== modified file 'mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result'
--- a/mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result 2010-08-30 06:03:28 +0000
+++ b/mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result 2010-09-23 08:24:17 +0000
@@ -28,11 +28,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 # Intvar # # INSERT_ID=301
-master-bin.000001 # Query # # use `test`; insert /* before delayed */ /* after delayed */ into t1 values (null),(null),(null),(null)
+master-bin.000001 # Query # # use `test`; insert /* before delayed */ /* after delayed */ into t1 values (null),(null),(null),(null)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Intvar # # INSERT_ID=305
-master-bin.000001 # Query # # use `test`; insert /*! */ into t1 values (null),(null),(400),(null)
+master-bin.000001 # Query # # use `test`; insert /*! */ into t1 values (null),(null),(400),(null)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; FLUSH TABLES
select * from t1;
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2010-09-15 14:15:31 +0000
+++ b/sql/sql_insert.cc 2010-09-23 08:24:17 +0000
@@ -634,14 +634,10 @@ bool open_and_lock_for_insert_delayed(TH
static int
create_insert_stmt_from_insert_delayed(THD *thd, String *buf)
{
- /* Append the part of thd->query before "DELAYED" keyword */
- if (buf->append(thd->query(),
- thd->lex->keyword_delayed_begin - thd->query()))
+ /* Make a copy of thd->query() and then remove the "DELAYED" keyword */
+ if (buf->append(thd->query()) ||
+ buf->replace(thd->lex->keyword_delayed_begin_offset, 8, 0))
return 1;
- /* Append the part of thd->query after "DELAYED" keyword */
- if (buf->append(thd->lex->keyword_delayed_begin + 7))
- return 1;
-
return 0;
}
=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h 2010-09-01 13:12:42 +0000
+++ b/sql/sql_lex.h 2010-09-23 08:24:17 +0000
@@ -2355,12 +2355,12 @@ struct LEX: public Query_tables_list
This pointer is required to add possibly omitted DEFINER-clause to the
DDL-statement before dumping it to the binlog.
- keyword_delayed_begin points to the begin of the DELAYED keyword in
- INSERT DELAYED statement.
+ keyword_delayed_begin_offset is the offset to the beginning of the DELAYED
+ keyword in INSERT DELAYED statement.
*/
union {
const char *stmt_definition_begin;
- const char *keyword_delayed_begin;
+ uint keyword_delayed_begin_offset;
};
const char *stmt_definition_end;
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2010-09-09 14:29:14 +0000
+++ b/sql/sql_yacc.yy 2010-09-23 08:24:17 +0000
@@ -10447,7 +10447,8 @@ insert_lock_option:
| LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }
| DELAYED_SYM
{
- Lex->keyword_delayed_begin= YYLIP->get_tok_start();
+ Lex->keyword_delayed_begin_offset= (uint)(YYLIP->get_tok_start() -
+ YYTHD->query());
$$= TL_WRITE_DELAYED;
}
| HIGH_PRIORITY { $$= TL_WRITE; }
@@ -10457,7 +10458,8 @@ replace_lock_option:
opt_low_priority { $$= $1; }
| DELAYED_SYM
{
- Lex->keyword_delayed_begin= YYLIP->get_tok_start();
+ Lex->keyword_delayed_begin_offset= (uint)(YYLIP->get_tok_start() -
+ YYTHD->query());
$$= TL_WRITE_DELAYED;
}
;
Attachment: [text/bzr-bundle] bzr/jon.hauglid@oracle.com-20100923082417-widvyuk3yit70gq2.bundle
| Thread |
|---|
| • bzr commit into mysql-5.5-runtime branch (jon.hauglid:3142) Bug#56678 | Jon Olav Hauglid | 23 Sep |