Commit 2db4392b authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-4297 mysql --binary-mode

backport mysql --binary-mode (bug#11747577, bug#33048)
parent 16807b58
/*
Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2001, 2012, Oracle and/or its affiliates.
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
......
......@@ -36,7 +36,7 @@ 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);
extern char *batch_readline(LINE_BUFFER *buffer, bool binary_mode);
extern void batch_readline_end(LINE_BUFFER *buffer);
#endif /* CLIENT_MY_READLINE_INCLUDED */
This diff is collapsed.
......@@ -206,10 +206,8 @@ void print_annotate_event(PRINT_EVENT_INFO *print_event_info)
}
}
static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
const char* logname);
static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
const char* logname);
static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *, const char*);
static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *, const char*);
static Exit_status dump_log_entries(const char* logname);
static Exit_status safe_connect();
......
......@@ -54,7 +54,7 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
}
char *batch_readline(LINE_BUFFER *line_buff)
char *batch_readline(LINE_BUFFER *line_buff, bool binary_mode)
{
char *pos;
ulong out_length;
......@@ -63,8 +63,17 @@ char *batch_readline(LINE_BUFFER *line_buff)
if (!(pos=intern_read_line(line_buff, &out_length)))
return 0;
if (out_length && pos[out_length-1] == '\n')
if (--out_length && pos[out_length-1] == '\r') /* Remove '\n' */
out_length--; /* Remove '\r' */
{
/*
On Windows platforms we also need to remove '\r', unconditionally. On
Unix-like platforms we only remove it if we are not on binary mode.
*/
/* Remove '\n' */
if (--out_length && IF_WIN(1,!binary_mode) && pos[out_length-1] == '\r')
/* Remove '\r' */
out_length--;
}
line_buff->read_length=out_length;
pos[out_length]=0;
return pos;
......@@ -226,7 +235,7 @@ char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length)
for (;;)
{
pos=buffer->end_of_line;
while (*pos != '\n' && *pos)
while (*pos != '\n' && pos != buffer->end)
pos++;
if (pos == buffer->end)
{
......
RESET MASTER;
# Bug#33048 Not able to recover binary/blob data correctly using mysqlbinlog
# --------------------------------------------------------------------------
# The test verify that 0x00 and 0x0D0A sequence can be handled correctly by
# mysql
CREATE TABLE `A
B` (c1 CHAR(100));
# It is a faked statement. ASCII 0 is in the original statement, it would
# make the test result to become a binary file which was difficult to get
# the diff result if the original query was logged in the result.
INSERT INTO `A\r\nB` VALUES("A\0B");
INSERT INTO `A
B` VALUES("A
B");
SELECT HEX(c1) FROM `A
B`;
HEX(c1)
410042
410D0A42
FLUSH LOGS;
DROP TABLE `A
B`;
RESET MASTER;
# '--exec mysql ...' without --binary-mode option
# It creates the table with a wrong table name and generates an error.
# (error output was suppressed to make the test case platform agnostic)
# It is not in binary_mode, so table name '0x410D0A42' can be translated to
# '0x410A42' by mysql depending on the OS - Windows or Unix-like.
DROP TABLE `TABLE_NAME_MASKED`;
# In binary_mode, table name '0x410D0A42' and string '0x410042' can be
# handled correctly.
RESET MASTER;
SELECT HEX(c1) FROM `A
B`;
HEX(c1)
410042
410D0A42
DROP TABLE `A
B`;
RESET MASTER;
include/assert.inc [Table and contents created through mysqltest match 0x610D0A62.]
include/assert.inc [Table and contents created while replaying binary log without --binary-mode set match 0x61(0D)0A62.]
include/assert.inc [Table and contents created while replaying binary log with --binary-mode set match 0x610D0A62.]
source include/have_binlog_format_mixed_or_statement.inc;
RESET MASTER;
--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
# zero => 0x00, newline => 0x0D0A, A => 0x41, B => 0x42
# 0x410D0A42 => 'A\r\nB'
let $table_name_right= `SELECT 0x410D0A42`;
# 0x410A42 => 'A\nB'
let $table_name_wrong= `SELECT 0x410A42`;
# 0x410042 => 'A\0B'
let $char0= `SELECT 0x410042`;
eval CREATE TABLE `$table_name_right` (c1 CHAR(100));
--echo # It is a faked statement. ASCII 0 is in the original statement, it would
--echo # make the test result to become a binary file which was difficult to get
--echo # the diff result if the original query was logged in the result.
--echo INSERT INTO `A\r\nB` VALUES("A\0B");
--echo
--disable_query_log
eval INSERT INTO `$table_name_right` VALUES("$char0");
--enable_query_log
let $char0= $table_name_right;
eval INSERT INTO `$table_name_right` VALUES("$char0");
eval SELECT HEX(c1) FROM `$table_name_right`;
--echo
let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1);
FLUSH LOGS;
eval DROP TABLE `$table_name_right`;
--echo
let $MYSQLD_DATADIR= `SELECT @@datadir`;
--exec $MYSQL_BINLOG $MYSQLD_DATADIR/$binlog_file > $MYSQLTEST_VARDIR/tmp/my.sql
RESET MASTER;
--echo # '--exec mysql ...' without --binary-mode option
--echo # It creates the table with a wrong table name and generates an error.
--echo # (error output was suppressed to make the test case platform agnostic)
## disabling result log because the error message has the
## table name in the output which is one byte different ('\r')
## on unixes and windows.
--disable_result_log
--error 1
--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/my.sql 2>&1
--enable_result_log
--echo
--echo # It is not in binary_mode, so table name '0x410D0A42' can be translated to
--echo # '0x410A42' by mysql depending on the OS - Windows or Unix-like.
--replace_result $table_name_wrong TABLE_NAME_MASKED $table_name_right TABLE_NAME_MASKED
if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) IN ('Win32', 'Win64', 'Windows')`)
{
eval DROP TABLE `$table_name_right`;
}
if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) NOT IN ('Win32', 'Win64', 'Windows')`)
{
eval DROP TABLE `$table_name_wrong`;
}
--echo
--echo # In binary_mode, table name '0x410D0A42' and string '0x410042' can be
--echo # handled correctly.
RESET MASTER;
--exec $MYSQL --binary-mode test < $MYSQLTEST_VARDIR/tmp/my.sql
eval SELECT HEX(c1) FROM `$table_name_right`;
--echo
eval DROP TABLE `$table_name_right`;
#
# BUG#12794048 - MAIN.MYSQL_BINARY_MODE FAILS ON WINDOWS RELEASE BUILD
#
RESET MASTER;
#
# This test case tests if the table names and their values
# are handled properly. For that we check
#
# 0x610D0A62 => 'a\r\nb'
let $tbl= `SELECT 0x610D0A62`;
--disable_result_log
--disable_query_log
--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
#### case #1: mysqltest
#### CREATE table and insert value through regular mysqltest session
--eval CREATE TABLE `$tbl` (c1 CHAR(100))
--eval INSERT INTO `$tbl` VALUES ("$tbl")
--let $table_name=`SELECT table_name FROM information_schema.tables WHERE table_schema='test'`
--let $tbl0= `SELECT HEX(table_name) FROM information_schema.tables WHERE table_schema='test'`
--let $val0= `SELECT HEX(c1) FROM `$table_name` LIMIT 1`
FLUSH LOGS;
--eval DROP TABLE `$table_name`;
#### case #2: mysql --binlog-mode=0
#### Replay through regular mysql client non-interactive mode
--let $MYSQLD_DATADIR= `SELECT @@datadir`
--let $prefix=`SELECT UUID()`
--let $binlog_uuid_filename= $MYSQLTEST_VARDIR/tmp/$prefix-bin.log
--copy_file $MYSQLD_DATADIR/$binlog_file $binlog_uuid_filename
RESET MASTER;
--exec $MYSQL_BINLOG $binlog_uuid_filename | $MYSQL
--let $table_name=`SELECT table_name FROM information_schema.tables WHERE table_schema='test'`
--let $tbl1= `SELECT hex(table_name) FROM information_schema.tables WHERE table_schema='test'`
--let $val1= `SELECT HEX(c1) FROM `$table_name` LIMIT 1`
--eval DROP TABLE `$table_name`;
#### case #3: mysql --binlog-mode=1
#### Replay through regular mysql client non-interactive mode and with binary mode set
RESET MASTER;
--exec $MYSQL_BINLOG $binlog_uuid_filename | $MYSQL --binary-mode
--let $table_name=`SELECT table_name FROM information_schema.tables WHERE table_schema='test'`
--let $tbl2= `SELECT hex(table_name) FROM information_schema.tables WHERE table_schema='test'`
--let $val2= `SELECT HEX(c1) FROM `$table_name` LIMIT 1`
--eval DROP TABLE `$table_name`;
--enable_result_log
--disable_query_log
##### OUTCOME
--let $assert_text= Table and contents created through mysqltest match 0x610D0A62.
--let $assert_cond= "$tbl0" = "610D0A62" AND "$val0" = "610D0A62"
--source include/assert.inc
--let $assert_text= Table and contents created while replaying binary log without --binary-mode set match 0x61(0D)0A62.
if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) IN ('Win32', 'Win64', 'Windows')`)
{
--let $assert_cond= "$tbl1" = "610D0A62" AND "$val1" = "610D0A62"
}
if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) NOT IN ('Win32', 'Win64', 'Windows')`)
{
--let $assert_cond= "$tbl1" = "610A62" AND "$val1" = "610A62"
}
--source include/assert.inc
--let $assert_text= Table and contents created while replaying binary log with --binary-mode set match 0x610D0A62.
--let $assert_cond= "$tbl2" = "610D0A62" AND "$val2" = "610D0A62"
--source include/assert.inc
RESET MASTER;
--remove_file $binlog_uuid_filename
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