Hi, Sachin!

On Jul 12, Sachin Kumar wrote:
> revision-id: cdb6db8ce38 (mariadb-10.3.26-155-gcdb6db8ce38)
> parent(s): 72753d2b65f
> author: Sachin Kumar <sachin.set...@mariadb.com>
> committer: Sachin Kumar <sachin.set...@mariadb.com>
> timestamp: 2021-05-19 15:46:57 +0100
> message:
> 
> MDEV-25444 mysql --binary-mode is not able to replay some mysqlbinlog outputs
> 
> Problem:- Some binary data is inserted into the table using Jconnector. When
> binlog dump of the data is applied using mysql cleint it gives syntax error.
> 
> Reason:-
> After investigating it turns out to be a issue of mysql client not able to 
> properly
> handle  \\\0 <0 in binary>. In all binary files where mysql client fails to 
> insert
> these 2 bytes are commom (0x5c00)
> 
> Solution:-
> I have changed mysql.cc to include for the possibility that binary string can
> have \\\0 in it.
> 
> ---
>  client/mysql.cc                            |   8 ++++++--
>  mysql-test/main/binary_zero_insert.result  |   6 ++++++
>  mysql-test/main/binary_zero_insert.test    |  15 +++++++++++++++
>  mysql-test/std_data/binary_zero_insert.bin | Bin 0 -> 87 bytes
>  4 files changed, 27 insertions(+), 2 deletions(-)
> 
> diff --git a/client/mysql.cc b/client/mysql.cc
> index 2a7c4eaf3e5..8530c105820 100644
> --- a/client/mysql.cc
> +++ b/client/mysql.cc
> @@ -2319,8 +2319,12 @@ static bool add_line(String &buffer, char *line, 
> size_t line_length,
>      {
>        // Found possbile one character command like \c
>  
> +      inchar = (uchar) *++pos;
> +      // In Binary mode , when in_string is not null \0 should not be 
> treated as
> +      // end statement. This can happen when we are in middle of binary data 
> which
> +      // can contain \0 and its quoted with ' '.
> +      if (!real_binary_mode && !*in_string && !inchar)

Two comments here.

1. if you check the history where this "real_binary_mode" came from,
you'd arrive at commit 2db4392bf4cb and the test file mysql_binary_mode.test
So, I'd say it make sense to add your test there too. And in the same
style, wthout a separate binary file.

in my experimening I did it as simple as

--- a/mysql-test/main/mysql_binary_mode.test
+++ b/mysql-test/main/mysql_binary_mode.test
@@ -16,14 +16,14 @@ let $table_name_right= `SELECT 0x410D0A42`;
 let $table_name_wrong= `SELECT 0x410A42`;

 # 0x410042 => 'A\0B'
-let $char0= `SELECT 0x410042`;
+let $char0= `SELECT 0x4100425C0043`;

(there already was a test for a \0 byte, but not for an escaped \\\0)
but if you'd like you can add a separate test with a header and
everything.

> -      if (!(inchar = (uchar) *++pos))
> -     break;                          // readline adds one '\'

2. What does the old code mean? Why returning if inchar==0 ?
What does the comment mean? It's the code from the last
millenium, does it even apply now? For example, there can be no
\0 bytes in the string, because of

  if (!real_binary_mode && strlen(line) != line_length)
    ...

in other words, shouldn't we just remove the if? I tried, at least the
main suite didn't break.

> +        break;                               // readline adds one '\'
>        if (*in_string || inchar == 'N')       // \N is short for NULL
>        {                                      // Don't allow commands in 
> string
>       *out++='\\';

Regards,
Sergei
VP of MariaDB Server Engineering
and secur...@mariadb.org

_______________________________________________
Mailing list: https://launchpad.net/~maria-developers
Post to     : maria-developers@lists.launchpad.net
Unsubscribe : https://launchpad.net/~maria-developers
More help   : https://help.launchpad.net/ListHelp

Reply via email to