Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
2db4392b
Commit
2db4392b
authored
Jun 10, 2013
by
Sergei Golubchik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-4297 mysql --binary-mode
backport mysql --binary-mode (bug#11747577, bug#33048)
parent
16807b58
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
445 additions
and
72 deletions
+445
-72
client/client_priv.h
client/client_priv.h
+1
-1
client/my_readline.h
client/my_readline.h
+1
-1
client/mysql.cc
client/mysql.cc
+209
-62
client/mysqlbinlog.cc
client/mysqlbinlog.cc
+2
-4
client/readline.cc
client/readline.cc
+13
-4
mysql-test/r/mysql_binary_mode.result
mysql-test/r/mysql_binary_mode.result
+50
-0
mysql-test/t/mysql_binary_mode.test
mysql-test/t/mysql_binary_mode.test
+169
-0
No files found.
client/client_priv.h
View file @
2db4392b
/*
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
...
...
client/my_readline.h
View file @
2db4392b
...
...
@@ -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 */
client/mysql.cc
View file @
2db4392b
/*
Copyright (c) 2000, 2012, Oracle and/or its affiliates.
Copyright (c) 2009, 201
2
, Monty Program Ab.
Copyright (c) 2009, 201
3
, Monty Program Ab.
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
...
...
@@ -152,6 +152,7 @@ static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0;
static
uint
my_end_arg
;
static
char
*
opt_mysql_unix_port
=
0
;
static
int
connect_flag
=
CLIENT_INTERACTIVE
;
static
my_bool
opt_binary_mode
=
FALSE
;
static
int
interrupted_query
=
0
;
static
char
*
current_host
,
*
current_db
,
*
current_user
=
0
,
*
opt_password
=
0
,
*
current_prompt
=
0
,
*
delimiter_str
=
0
,
...
...
@@ -1056,9 +1057,10 @@ static void initialize_readline (char *name);
static
void
fix_history
(
String
*
final_command
);
#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
COMMANDS
*
find_command
(
char
*
name
);
static
COMMANDS
*
find_command
(
char
cmd_name
);
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
);
...
...
@@ -1077,6 +1079,45 @@ static sig_handler window_resize(int sig);
#endif
const
char
DELIMITER_NAME
[]
=
"delimiter"
;
const
uint
DELIMITER_NAME_LEN
=
sizeof
(
DELIMITER_NAME
)
-
1
;
inline
bool
is_delimiter_command
(
char
*
name
,
ulong
len
)
{
/*
Delimiter command has a parameter, so the length of the whole command
is larger than DELIMITER_NAME_LEN. We don't care the parameter, so
only name(first DELIMITER_NAME_LEN bytes) is checked.
*/
return
(
len
>=
DELIMITER_NAME_LEN
&&
!
my_strnncoll
(
charset_info
,
(
uchar
*
)
name
,
DELIMITER_NAME_LEN
,
(
uchar
*
)
DELIMITER_NAME
,
DELIMITER_NAME_LEN
));
}
/**
Get the index of a command in the commands array.
@param cmd_char Short form command.
@return int
The index of the command is returned if it is found, else -1 is returned.
*/
inline
int
get_command_index
(
char
cmd_char
)
{
/*
All client-specific commands are in the first part of commands array
and have a function to implement it.
*/
for
(
uint
i
=
0
;
*
commands
[
i
].
func
;
i
++
)
if
(
commands
[
i
].
cmd_char
==
cmd_char
)
return
i
;
return
-
1
;
}
static
int
delimiter_index
=
-
1
;
static
int
charset_index
=
-
1
;
static
bool
real_binary_mode
=
FALSE
;
int
main
(
int
argc
,
char
*
argv
[])
{
char
buff
[
80
];
...
...
@@ -1085,6 +1126,8 @@ int main(int argc,char *argv[])
DBUG_ENTER
(
"main"
);
DBUG_PROCESS
(
argv
[
0
]);
charset_index
=
get_command_index
(
'C'
);
delimiter_index
=
get_command_index
(
'd'
);
delimiter_str
=
delimiter
;
default_prompt
=
my_strdup
(
getenv
(
"MYSQL_PS1"
)
?
getenv
(
"MYSQL_PS1"
)
:
...
...
@@ -1598,6 +1641,13 @@ static struct my_option my_long_options[] =
"Default authentication client-side plugin to use."
,
&
opt_default_auth
,
&
opt_default_auth
,
0
,
GET_STR
,
REQUIRED_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
{
"binary-mode"
,
0
,
"By default, ASCII '
\\
0' is disallowed and '
\\
r
\\
n' is translated to '
\\
n'. "
"This switch turns off both features, and also turns off parsing of all client"
"commands except
\\
C and DELIMITER, in non-interactive mode (for input "
"piped to mysql or loaded using the 'source' command). This is necessary "
"when processing output from mysqlbinlog that may contain blobs."
,
&
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
}
};
...
...
@@ -1878,24 +1928,59 @@ static int read_and_execute(bool interactive)
ulong
line_number
=
0
;
bool
ml_comment
=
0
;
COMMANDS
*
com
;
ulong
line_length
=
0
;
status
.
exit_status
=
1
;
real_binary_mode
=
!
interactive
&&
opt_binary_mode
;
while
(
!
aborted
)
{
if
(
!
interactive
)
{
line
=
batch_readline
(
status
.
line_buff
);
/*
Skip UTF8 Byte Order Marker (BOM) 0xEFBBBF.
Editors like "notepad" put this marker in
the very beginning of a text file when
you save the file using "Unicode UTF-8" format.
batch_readline can return 0 on EOF or error.
In that case, we need to double check that we have a valid
line before actually setting line_length to read_length.
*/
if
(
line
&&
!
line_number
&&
(
uchar
)
line
[
0
]
==
0xEF
&&
(
uchar
)
line
[
1
]
==
0xBB
&&
(
uchar
)
line
[
2
]
==
0xBF
)
line
+=
3
;
line
=
batch_readline
(
status
.
line_buff
,
real_binary_mode
);
if
(
line
)
{
line_length
=
status
.
line_buff
->
read_length
;
/*
ASCII 0x00 is not allowed appearing in queries if it is not in binary
mode.
*/
if
(
!
real_binary_mode
&&
strlen
(
line
)
!=
line_length
)
{
status
.
exit_status
=
1
;
String
msg
;
msg
.
append
(
"ASCII '
\\
0' appeared in the statement, but this is not "
"allowed unless option --binary-mode is enabled and mysql is "
"run in non-interactive mode. Set --binary-mode to 1 if ASCII "
"'
\\
0' 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
the very beginning of a text file when
you save the file using "Unicode UTF-8" format.
*/
if
(
!
line_number
&&
(
uchar
)
line
[
0
]
==
0xEF
&&
(
uchar
)
line
[
1
]
==
0xBB
&&
(
uchar
)
line
[
2
]
==
0xBF
)
{
line
+=
3
;
// decrease the line length accordingly to the 3 bytes chopped
line_length
-=
3
;
}
}
line_number
++
;
if
(
!
glob_buffer
.
length
())
status
.
query_start_line
=
line_number
;
...
...
@@ -1946,6 +2031,8 @@ static int read_and_execute(bool interactive)
*/
if
(
opt_outfile
&&
line
)
fprintf
(
OUTFILE
,
"%s
\n
"
,
line
);
line_length
=
line
?
strlen
(
line
)
:
0
;
}
// End of file or system error
if
(
!
line
)
...
...
@@ -1962,7 +2049,7 @@ static int read_and_execute(bool interactive)
(We want to allow help, print and clear anywhere at line start
*/
if
((
named_cmds
||
glob_buffer
.
is_empty
())
&&
!
ml_comment
&&
!
in_string
&&
(
com
=
find_command
(
line
,
0
)))
&&
!
ml_comment
&&
!
in_string
&&
(
com
=
find_command
(
line
)))
{
if
((
*
com
->
func
)(
&
glob_buffer
,
line
)
>
0
)
break
;
...
...
@@ -1974,7 +2061,7 @@ static int read_and_execute(bool interactive)
#endif
continue
;
}
if
(
add_line
(
glob_buffer
,
line
,
&
in_string
,
&
ml_comment
,
if
(
add_line
(
glob_buffer
,
line
,
line_length
,
&
in_string
,
&
ml_comment
,
status
.
line_buff
?
status
.
line_buff
->
truncated
:
0
))
break
;
}
...
...
@@ -1996,70 +2083,131 @@ static int read_and_execute(bool interactive)
tmpbuf
.
free
();
#endif
/*
If the function is called by 'source' command, it will return to interactive
mode, so real_binary_mode should be FALSE. Otherwise, it will exit the
program, it is safe to set real_binary_mode to FALSE.
*/
real_binary_mode
=
FALSE
;
return
status
.
exit_status
;
}
static
COMMANDS
*
find_command
(
char
*
name
,
char
cmd_char
)
/**
It checks if the input is a short form command. It returns the command's
pointer if a command is found, else return NULL. Note that if binary-mode
is set, then only \C is searched for.
@param cmd_char A character of one byte.
@return
the command's pointer or NULL.
*/
static
COMMANDS
*
find_command
(
char
cmd_char
)
{
DBUG_ENTER
(
"find_command"
);
DBUG_PRINT
(
"enter"
,
(
"cmd_char: %d"
,
cmd_char
));
int
index
=
-
1
;
/*
In binary-mode, we disallow all mysql commands except '\C'
and DELIMITER.
*/
if
(
real_binary_mode
)
{
if
(
cmd_char
==
'C'
)
index
=
charset_index
;
}
else
index
=
get_command_index
(
cmd_char
);
if
(
index
>=
0
)
{
DBUG_PRINT
(
"exit"
,(
"found command: %s"
,
commands
[
index
].
name
));
DBUG_RETURN
(
&
commands
[
index
]);
}
else
DBUG_RETURN
((
COMMANDS
*
)
0
);
}
/**
It checks if the input is a long form command. It returns the command's
pointer if a command is found, else return NULL. Note that if binary-mode
is set, then only DELIMITER is searched for.
@param name A string.
@return
the command's pointer or NULL.
*/
static
COMMANDS
*
find_command
(
char
*
name
)
{
uint
len
;
char
*
end
;
DBUG_ENTER
(
"find_command"
);
DBUG_PRINT
(
"enter"
,(
"name: '%s' char: %d"
,
name
?
name
:
"NULL"
,
cmd_char
));
if
(
!
name
)
DBUG_ASSERT
(
name
!=
NULL
);
DBUG_PRINT
(
"enter"
,
(
"name: '%s'"
,
name
));
while
(
my_isspace
(
charset_info
,
*
name
))
name
++
;
/*
If there is an \\g in the row or if the row has a delimiter but
this is not a delimiter command, let add_line() take care of
parsing the row and calling find_command().
*/
if
((
!
real_binary_mode
&&
strstr
(
name
,
"
\\
g"
))
||
(
strstr
(
name
,
delimiter
)
&&
!
is_delimiter_command
(
name
,
DELIMITER_NAME_LEN
)))
DBUG_RETURN
((
COMMANDS
*
)
0
);
if
((
end
=
strcont
(
name
,
"
\t
"
)))
{
len
=
0
;
end
=
0
;
len
=
(
uint
)
(
end
-
name
);
while
(
my_isspace
(
charset_info
,
*
end
))
end
++
;
if
(
!*
end
)
end
=
0
;
// no arguments to function
}
else
len
=
(
uint
)
strlen
(
name
);
int
index
=
-
1
;
if
(
real_binary_mode
)
{
if
(
is_delimiter_command
(
name
,
len
))
index
=
delimiter_index
;
}
else
{
while
(
my_isspace
(
charset_info
,
*
name
))
name
++
;
/*
If there is an \\g in the row or if the row has a delimiter but
this is not a delimiter command, let add_line() take care of
parsing the row and calling find_command()
All commands are in the first part of commands array and have a function
to implement it.
*/
if
(
strstr
(
name
,
"
\\
g"
)
||
(
strstr
(
name
,
delimiter
)
&&
!
(
strlen
(
name
)
>=
9
&&
!
my_strnncoll
(
&
my_charset_latin1
,
(
uchar
*
)
name
,
9
,
(
const
uchar
*
)
"delimiter"
,
9
))))
DBUG_RETURN
((
COMMANDS
*
)
0
);
if
((
end
=
strcont
(
name
,
"
\t
"
)))
for
(
uint
i
=
0
;
commands
[
i
].
func
;
i
++
)
{
len
=
(
uint
)
(
end
-
name
);
while
(
my_isspace
(
charset_info
,
*
end
))
end
++
;
if
(
!*
end
)
end
=
0
;
// no arguments to function
if
(
!
my_strnncoll
(
&
my_charset_latin1
,
(
uchar
*
)
name
,
len
,
(
uchar
*
)
commands
[
i
].
name
,
len
)
&&
(
commands
[
i
].
name
[
len
]
==
'\0'
)
&&
(
!
end
||
commands
[
i
].
takes_params
))
{
index
=
i
;
break
;
}
}
else
len
=
(
uint
)
strlen
(
name
);
}
for
(
uint
i
=
0
;
commands
[
i
].
name
;
i
++
)
if
(
index
>=
0
)
{
if
(
commands
[
i
].
func
&&
(((
name
&&
!
my_strnncoll
(
&
my_charset_latin1
,
(
uchar
*
)
name
,
len
,
(
uchar
*
)
commands
[
i
].
name
,
len
)
&&
!
commands
[
i
].
name
[
len
]
&&
(
!
end
||
(
end
&&
commands
[
i
].
takes_params
))))
||
(
!
name
&&
commands
[
i
].
cmd_char
==
cmd_char
)))
{
DBUG_PRINT
(
"exit"
,(
"found command: %s"
,
commands
[
i
].
name
));
DBUG_RETURN
(
&
commands
[
i
]);
}
DBUG_PRINT
(
"exit"
,
(
"found command: %s"
,
commands
[
index
].
name
));
DBUG_RETURN
(
&
commands
[
index
]);
}
DBUG_RETURN
((
COMMANDS
*
)
0
);
}
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
;
...
...
@@ -2074,10 +2222,11 @@ static bool add_line(String &buffer,char *line,char *in_string,
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
...
...
@@ -2117,7 +2266,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
*
out
++=
(
char
)
inchar
;
continue
;
}
if
((
com
=
find_command
(
NullS
,
(
char
)
inchar
)))
if
((
com
=
find_command
(
(
char
)
inchar
)))
{
// Flush previously accepted characters
if
(
out
!=
line
)
...
...
@@ -2193,7 +2342,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
pos
--
;
if
((
com
=
find_command
(
buffer
.
c_ptr
()
,
0
)))
if
((
com
=
find_command
(
buffer
.
c_ptr
())))
{
if
((
*
com
->
func
)(
&
buffer
,
buffer
.
c_ptr
())
>
0
)
...
...
@@ -2312,9 +2461,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
{
uint
length
=
(
uint
)
(
out
-
line
);
if
(
!
truncated
&&
(
length
<
9
||
my_strnncoll
(
charset_info
,
(
uchar
*
)
line
,
9
,
(
const
uchar
*
)
"delimiter"
,
9
)
||
if
(
!
truncated
&&
(
!
is_delimiter_command
(
line
,
length
)
||
(
*
in_string
||
*
ml_comment
)))
{
/*
...
...
client/mysqlbinlog.cc
View file @
2db4392b
...
...
@@ -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
();
...
...
client/readline.cc
View file @
2db4392b
...
...
@@ -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
)
{
...
...
mysql-test/r/mysql_binary_mode.result
0 → 100644
View file @
2db4392b
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.]
mysql-test/t/mysql_binary_mode.test
0 → 100644
View file @
2db4392b
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
\0
B"
);
--
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
(
0
D
)
0
A62
.
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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment