Below is the list of changes that have just been committed into a local
5.1 repository of bar. When bar does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-02-29 16:41:02+04:00, bar@stripped +7 -0
Bug#23924 general_log truncates queries with character set introducers.
Problem: logging of utf8-incompatible binary strings didn't work
Fix: hex-encoding of incompatible sequences.
mysql-test/r/log_tables.result@stripped, 2008-02-29 16:40:59+04:00, bar@stripped +11 -0
Adding test
mysql-test/t/log_tables.test@stripped, 2008-02-29 16:40:59+04:00, bar@stripped +10 -0
Adding test
sql/field.cc@stripped, 2008-02-29 16:40:59+04:00, bar@stripped +11 -0
Copying with hex escaping
sql/field.h@stripped, 2008-02-29 16:40:59+04:00, bar@stripped +2 -0
New field flag
sql/log.cc@stripped, 2008-02-29 16:40:59+04:00, bar@stripped +1 -0
Marking the column "general_log.argument" as hex-escaping field.
sql/sql_string.cc@stripped, 2008-02-29 16:40:59+04:00, bar@stripped +62 -0
New function to copy strings with hex-encoding of incompatible characters.
sql/sql_string.h@stripped, 2008-02-29 16:40:59+04:00, bar@stripped +3 -0
Prototype for the new function
diff -Nrup a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result
--- a/mysql-test/r/log_tables.result 2007-12-05 15:48:11 +04:00
+++ b/mysql-test/r/log_tables.result 2008-02-29 16:40:59 +04:00
@@ -107,6 +107,17 @@ Database Table In_use Name_locked
SET GLOBAL GENERAL_LOG=ON;
SET GLOBAL SLOW_QUERY_LOG=ON;
truncate table mysql.general_log;
+set names binary;
+test
+select * from mysql.general_log;
+event_time user_host thread_id server_id command_type argument
+TIMESTAMP USER_HOST THREAD_ID 1 Query set names binary
+TIMESTAMP USER_HOST THREAD_ID 1 Query select _koi8r'\xD4\xC5\xD3\xD4' as test
+TIMESTAMP USER_HOST THREAD_ID 1 Query select * from mysql.general_log
+set names utf8;
+truncate table mysql.general_log;
set names utf8;
create table bug16905 (s char(15) character set utf8 default 'пусто');
insert into bug16905 values ('новое');
diff -Nrup a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test
--- a/mysql-test/t/log_tables.test 2007-12-05 15:48:11 +04:00
+++ b/mysql-test/t/log_tables.test 2008-02-29 16:40:59 +04:00
@@ -131,6 +131,16 @@ SET GLOBAL GENERAL_LOG=ON;
SET GLOBAL SLOW_QUERY_LOG=ON;
#
+# Bug#23924 general_log truncates queries with character set introducers.
+#
+truncate table mysql.general_log;
+set names binary;
+--replace_column 1 TIMESTAMP 2 USER_HOST 3 THREAD_ID
+select * from mysql.general_log;
+set names utf8;
+
+#
# Bug #16905 Log tables: unicode statements are logged incorrectly
#
diff -Nrup a/sql/field.cc b/sql/field.cc
--- a/sql/field.cc 2008-02-07 15:28:36 +04:00
+++ b/sql/field.cc 2008-02-29 16:40:59 +04:00
@@ -7644,6 +7644,17 @@ int Field_blob::store(const char *from,u
if (value.alloc(new_length))
goto oom_error;
+
+ if (f_is_hex_escape(flags))
+ {
+ copy_length= my_copy_with_hex_escaping(field_charset,
+ (char*) value.ptr(), new_length,
+ from, length);
+ Field_blob::store_length(copy_length);
+ tmp= value.ptr();
+ bmove(ptr + packlength, (uchar*) &tmp, sizeof(char*));
+ return 0;
+ }
/*
"length" is OK as "nchars" argument to well_formed_copy_nchars as this
is never used to limit the length of the data. The cut of long data
diff -Nrup a/sql/field.h b/sql/field.h
--- a/sql/field.h 2008-02-07 15:28:36 +04:00
+++ b/sql/field.h 2008-02-29 16:40:59 +04:00
@@ -2069,6 +2069,7 @@ int set_field_to_null_with_conversions(F
#define FIELDFLAG_NO_DEFAULT 16384 /* sql */
#define FIELDFLAG_SUM ((uint) 32768)// predit: +#fieldflag
#define FIELDFLAG_MAYBE_NULL ((uint) 32768)// sql
+#define FIELDFLAG_HEX_ESCAPE ((uint) 0x10000)
#define FIELDFLAG_PACK_SHIFT 3
#define FIELDFLAG_DEC_SHIFT 8
#define FIELDFLAG_MAX_DEC 31
@@ -2094,3 +2095,4 @@ int set_field_to_null_with_conversions(F
#define f_maybe_null(x) (x & FIELDFLAG_MAYBE_NULL)
#define f_no_default(x) (x & FIELDFLAG_NO_DEFAULT)
#define f_bit_as_char(x) ((x) & FIELDFLAG_TREAT_BIT_AS_CHAR)
+#define f_is_hex_escape(x) ((x) & FIELDFLAG_HEX_ESCAPE)
diff -Nrup a/sql/log.cc b/sql/log.cc
--- a/sql/log.cc 2008-02-09 06:37:53 +04:00
+++ b/sql/log.cc 2008-02-29 16:40:59 +04:00
@@ -418,6 +418,7 @@ bool Log_to_csv_event_handler::
A positive return value in store() means truncation.
Still logging a message in the log in this case.
*/
+ table->field[5]->flags|= FIELDFLAG_HEX_ESCAPE;
if (table->field[5]->store(sql_text, sql_text_len, client_cs) < 0)
goto err;
diff -Nrup a/sql/sql_string.cc b/sql/sql_string.cc
--- a/sql/sql_string.cc 2007-12-19 22:04:21 +04:00
+++ b/sql/sql_string.cc 2008-02-29 16:40:59 +04:00
@@ -840,6 +840,68 @@ outp:
}
+/**
+ Copy string with HEX-encoding of "bad" characters.
+
+ @details This functions copies the string pointed by "src"
+ to the string pointed by "dst". Not more than "srclen" bytes
+ are read from "src". Any sequences of bytes representing
+ a not-well-formed substring (according to cs) are hex-encoded,
+ and all well-formed substrings (according to cs) are copied as is.
+ Not more than "dstlen" bytes are written to "dst". The number
+ of bytes written to "dst" is returned.
+
+ @param cs character set pointer of the destination string
+ @param[out] dst destination string
+ @param dstlen size of dst
+ @param src source string
+ @param srclen length of src
+
+ @retval result length
+*/
+
+size_t
+my_copy_with_hex_escaping(CHARSET_INFO *cs,
+ char *dst, size_t dstlen,
+ const char *src, size_t srclen)
+{
+ const char *srcend= src + srclen;
+ char *dst0= dst;
+
+ for ( ; src < srcend ; )
+ {
+ size_t chlen;
+ if ((chlen= my_ismbchar(cs, src, srcend)))
+ {
+ if (dstlen < chlen)
+ break;
+ memcpy(dst, src, chlen);
+ src+= chlen;
+ dst+= chlen;
+ dstlen-= chlen;
+ }
+ else if (*src & 0x80)
+ {
+ if (dstlen < 4)
+ break;
+ *dst++= '\\';
+ *dst++= 'x';
+ *dst++= _dig_vec_upper[((unsigned char) *src) >> 4];
+ *dst++= _dig_vec_upper[((unsigned char) *src) & 15];
+ src++;
+ dstlen-= 4;
+ }
+ else
+ {
+ if (dstlen < 1)
+ break;
+ *dst++= *src++;
+ dstlen--;
+ }
+ }
+ return dst - dst0;
+}
+
/*
copy a string,
with optional character set conversion,
diff -Nrup a/sql/sql_string.h b/sql/sql_string.h
--- a/sql/sql_string.h 2007-01-24 21:57:01 +04:00
+++ b/sql/sql_string.h 2008-02-29 16:40:59 +04:00
@@ -37,6 +37,9 @@ uint32 well_formed_copy_nchars(CHARSET_I
const char **well_formed_error_pos,
const char **cannot_convert_error_pos,
const char **from_end_pos);
+size_t my_copy_with_hex_escaping(CHARSET_INFO *cs,
+ char *dst, size_t dstlen,
+ const char *src, size_t srclen);
class String
{
Thread |
---|
• bk commit into 5.1 tree (bar:1.2530) BUG#23924 | bar | 29 Feb |