[This commit e-mail is a repeat.]
#At file:///home/anders/Work/bzrwork/wt1/mysql-trunk/ based on
revid:anders.song@stripped
3515 Libing Song 2011-01-26
BUG#33048 Not able to recover binary/blob data correctly using mysqlbinlog
The queries generated by mysqlbinlog could not be executed by 'mysql' client
if there was any 0x00 in it. Or the queries recovered diverged data if there
was any 0x0D0A sequence in it. The reason is that 'mysql' client always
translated '0x0D0A'('\r\n') to '0x0A'('\n') and treated '0x00' as the end
of a query if it is in non-interactive mode(receiving queries from a file
or a pipe).
This patch added the option 'binary-mode' in 'mysql' program. 'mysql' will
not translated '0x0D0A' to '0x0A' and not treat '0x00' as the end of a query
if binary-mode is set 1 and it is in non-interactive mode.
added:
mysql-test/r/mysql_binary_mode.result
mysql-test/t/mysql_binary_mode.test
modified:
client/client_priv.h
client/my_readline.h
client/mysql.cc
client/readline.cc
=== modified file 'client/client_priv.h'
--- a/client/client_priv.h 2010-11-24 13:09:52 +0000
+++ b/client/client_priv.h 2011-01-26 07:13:45 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2006 MySQL AB, 2009 Sun Microsystems, Inc
+/* Copyright 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
@@ -85,6 +85,7 @@ enum options_client
OPT_DEFAULT_PLUGIN,
OPT_RAW_OUTPUT, OPT_WAIT_SERVER_ID, OPT_STOP_NEVER,
OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
+ OPT_BINARY_MODE,
OPT_MAX_CLIENT_OPTION
};
=== modified file 'client/my_readline.h'
--- a/client/my_readline.h 2009-09-23 21:32:31 +0000
+++ b/client/my_readline.h 2011-01-26 07:13:45 +0000
@@ -1,7 +1,7 @@
#ifndef CLIENT_MY_READLINE_INCLUDED
#define CLIENT_MY_READLINE_INCLUDED
-/* Copyright (C) 2000 MySQL AB
+/* Copyright 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
@@ -32,7 +32,8 @@ typedef struct st_line_buffer
extern LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file);
extern LINE_BUFFER *batch_readline_command(LINE_BUFFER *buffer, char * str);
-extern char *batch_readline(LINE_BUFFER *buffer, bool *truncated);
+extern char *batch_readline(LINE_BUFFER *buffer, bool *truncated,
+ bool binary_mode);
extern void batch_readline_end(LINE_BUFFER *buffer);
#endif /* CLIENT_MY_READLINE_INCLUDED */
=== modified file 'client/mysql.cc'
--- a/client/mysql.cc 2010-11-26 14:37:59 +0000
+++ b/client/mysql.cc 2011-01-26 07:13:45 +0000
@@ -1,4 +1,4 @@
-/* Copyright 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright 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
@@ -150,6 +150,7 @@ static uint my_end_arg;
static char * opt_mysql_unix_port=0;
static char *opt_bind_addr = NULL;
static int connect_flag=CLIENT_INTERACTIVE;
+static my_bool opt_binary_mode= FALSE;
static char *current_host,*current_db,*current_user=0,*opt_password=0,
*current_prompt=0, *delimiter_str= 0,
*default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME,
@@ -1045,8 +1046,8 @@ static void fix_history(String *final_co
#endif
static COMMANDS *find_command(char *name,char cmd_name);
-static bool add_line(String &buffer,char *line,char *in_string,
- bool *ml_comment, bool truncated);
+static bool add_line(String &buffer, char *line, ulong line_length,
+ char *in_string, bool *ml_comment, bool truncated);
static void remove_cntrl(String &buffer);
static void print_table_data(MYSQL_RES *result);
static void print_table_data_html(MYSQL_RES *result);
@@ -1572,6 +1573,11 @@ static struct my_option my_long_options[
"Default authentication client-side plugin to use.",
(uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"binary-mode", OPT_BINARY_MODE,
+ "ASCII '0x00' is allowed in queries and '0x0D0A'('\\r\\n') sequence "
+ "is not translated to '0x0A'('\\n') if 'mysql' is non-interactive and "
+ "--binary-mode is set.",
+ &opt_binary_mode, &opt_binary_mode, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -1844,13 +1850,33 @@ static int read_and_execute(bool interac
bool ml_comment= 0;
COMMANDS *com;
bool truncated= 0;
+ ulong line_length= 0;
status.exit_status=1;
for (;;)
{
if (!interactive)
{
- line=batch_readline(status.line_buff, &truncated);
+ line=batch_readline(status.line_buff, &truncated, opt_binary_mode);
+ line_length= status.line_buff->read_length;
+ /*
+ ASCII 0x00 is not allowed appearing in queries if it is not in binary
+ mode.
+ */
+ if (!opt_binary_mode && line && strlen(line) != line_length)
+ {
+ status.exit_status= 1;
+ String msg;
+ msg.append("ASCII '0x00' appeared in the query. It is disallowed unless "
+ "option --binary-mode is set and 'mysql' is non-interactive. "
+ "Please set --binary-mode 1 if the ASCII '0x00' is expected. "
+ "Query: '");
+ msg.append(glob_buffer);
+ msg.append(line);
+ msg.append("'.");
+ put_info(msg.c_ptr(), INFO_ERROR);
+ break;
+ }
/*
Skip UTF8 Byte Order Marker (BOM) 0xEFBBBF.
Editors like "notepad" put this marker in
@@ -1912,6 +1938,8 @@ static int read_and_execute(bool interac
*/
if (opt_outfile && line)
fprintf(OUTFILE, "%s\n", line);
+
+ line_length= line ? strlen(line) : 0;
}
if (!line) // End of file
{
@@ -1936,7 +1964,8 @@ static int read_and_execute(bool interac
#endif
continue;
}
- if (add_line(glob_buffer,line,&in_string,&ml_comment, truncated))
+ if (add_line(glob_buffer, line, line_length, &in_string, &ml_comment,
+ truncated))
break;
}
/* if in batch mode, send last query even if it doesn't end with \g or go */
@@ -2019,8 +2048,8 @@ static COMMANDS *find_command(char *name
}
-static bool add_line(String &buffer,char *line,char *in_string,
- bool *ml_comment, bool truncated)
+static bool add_line(String &buffer, char *line, ulong line_length,
+ char *in_string, bool *ml_comment, bool truncated)
{
uchar inchar;
char buff[80], *pos, *out;
@@ -2035,10 +2064,11 @@ static bool add_line(String &buffer,char
if (status.add_to_history && line[0] && not_in_history(line))
add_history(line);
#endif
- char *end_of_line=line+(uint) strlen(line);
+ char *end_of_line= line + line_length;
- for (pos=out=line ; (inchar= (uchar) *pos) ; pos++)
+ for (pos=out=line; pos < end_of_line; pos++)
{
+ inchar= (uchar) *pos;
if (!preserve_comments)
{
// Skip spaces at the beginning of a statement
=== modified file 'client/readline.cc'
--- a/client/readline.cc 2010-07-08 21:20:08 +0000
+++ b/client/readline.cc 2011-01-26 07:13:45 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright 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
@@ -42,7 +42,7 @@ LINE_BUFFER *batch_readline_init(ulong m
}
-char *batch_readline(LINE_BUFFER *line_buff, bool *truncated)
+char *batch_readline(LINE_BUFFER *line_buff, bool *truncated, bool binary_mode)
{
char *pos;
ulong out_length;
@@ -51,10 +51,14 @@ char *batch_readline(LINE_BUFFER *line_b
if (!(pos=intern_read_line(line_buff,&out_length, truncated)))
return 0;
if (out_length && pos[out_length-1] == '\n')
- if (--out_length && pos[out_length-1] == '\r') /* Remove '\n' */
+ {
+ out_length--; /* Remove '\n' */
+ if (!binary_mode && pos[out_length-1] == '\r')
out_length--; /* Remove '\r' */
+ }
line_buff->read_length=out_length;
pos[out_length]=0;
+ DBUG_DUMP("Query: ", (unsigned char *)pos, out_length);
return pos;
}
@@ -209,7 +213,7 @@ char *intern_read_line(LINE_BUFFER *buff
for (;;)
{
pos=buffer->end_of_line;
- while (*pos != '\n' && *pos)
+ while (*pos != '\n' && pos != buffer->end)
pos++;
if (pos == buffer->end)
{
@@ -232,6 +236,7 @@ char *intern_read_line(LINE_BUFFER *buff
*truncated= 0;
buffer->end_of_line=pos+1;
*out_length=(ulong) (pos + 1 - buffer->eof - buffer->start_of_line);
+ DBUG_DUMP("Query: ", (unsigned char *)buffer->start_of_line, *out_length);
DBUG_RETURN(buffer->start_of_line);
}
}
=== added file 'mysql-test/r/mysql_binary_mode.result'
Binary files a/mysql-test/r/mysql_binary_mode.result 1970-01-01 00:00:00 +0000 and
b/mysql-test/r/mysql_binary_mode.result 2011-01-26 07:13:45 +0000 differ
=== added file 'mysql-test/t/mysql_binary_mode.test'
--- a/mysql-test/t/mysql_binary_mode.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/mysql_binary_mode.test 2011-01-26 07:13:45 +0000
@@ -0,0 +1,45 @@
+source include/have_binlog_format_statement.inc;
+
+--echo # Bug#33048 Not able to recover binary/blob data correctly using mysqlbinlog
+--echo # --------------------------------------------------------------------------
+--echo # The test verify that 0x00 and 0x0D0A sequence can be handled correctly by
+--echo # mysql
+--echo
+let $table_name= `SELECT 0x410D0A42`;
+eval CREATE TABLE `$table_name` (c1 CHAR(100));
+
+let $char= `SELECT 0x410042`;
+eval INSERT INTO `$table_name` VALUES("$char");
+
+let $char= `SELECT 0x410D0A42`;
+eval INSERT INTO `$table_name` VALUES("$char");
+
+eval SELECT HEX(c1) FROM `$table_name`;
+
+--echo
+FLUSH LOGS;
+eval DROP TABLE `$table_name`;
+
+--echo
+let $MYSQLD_DATADIR= `SELECT @@datadir`;
+--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/my.sql
+
+--echo # '--exec mysql ...' without --binary-mode option
+--echo # It creates the table with a wrong table name and generates an error.
+--error 1
+--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/my.sql 2>&1
+
+--echo
+--echo # It is not in binary_mode, so table name '0x410D0A42' is translated to
+--echo # '0x410A42' by mysql.
+let $table_name1= `SELECT 0x410A42`;
+eval DROP TABLE `$table_name1`;
+
+--echo
+--echo # In binary_mode, table name '0x410D0A42' and string '0x410042' can be
+--echo # handled correctly.
+--exec $MYSQL --binary-mode test < $MYSQLTEST_VARDIR/tmp/my.sql
+eval SELECT HEX(c1) FROM `$table_name`;
+
+--echo
+eval DROP TABLE `$table_name`;
Attachment: [text/bzr-bundle] bzr/anders.song@greatopensource.com-20110126071345-i34ksuanh1t0v8hk.bundle
| Thread |
|---|
| • [Resend] bzr commit into mysql-trunk branch (anders.song:3515) Bug#33048 | Libing Song | 26 Jan |