diff options
author | unknown <elliot@mysql.com> | 2005-08-19 14:49:34 -0400 |
---|---|---|
committer | unknown <elliot@mysql.com> | 2005-08-19 14:49:34 -0400 |
commit | 1b970e94e0a736a2056cb94cfcba0b50133da1d6 (patch) | |
tree | e9b004d2e9d0b322b3e2006b7e0e0733ea5d65f9 | |
parent | 496e86da3a2b0019a3d9c186063e2c4f56b2bb44 (diff) | |
download | mariadb-git-1b970e94e0a736a2056cb94cfcba0b50133da1d6.tar.gz |
Bug#11338 Fixes from review (identical functionality).
include/my_sys.h:
Fixes from review (use version in log_event.cc instead)
mysql-test/r/ctype_cp932.result:
Updated test for bug#11338 (logging of prepared statement w/ blob type)
mysql-test/t/ctype_cp932.test:
udpated test for bug#11338 (logging of prepared statement w/ blob type)
mysys/charset.c:
Fixes from review (use version in log_event.cc instead)
sql/item.cc:
Fixes from review (store character_set_client differently so that
fix can be merged forward to 5.0)
sql/item.h:
Fixes from review
sql/log_event.cc:
Fixes from review, str_to_hex is now used by item.cc
sql/log_event.h:
Added prototype for str_to_hex (now used by item.cc)
sql/sql_prepare.cc:
Fixes from review, store character_set_client differently so that
Item_param::query_val_str can use it.
-rw-r--r-- | include/my_sys.h | 1 | ||||
-rw-r--r-- | mysql-test/r/ctype_cp932.result | 14 | ||||
-rw-r--r-- | mysql-test/t/ctype_cp932.test | 20 | ||||
-rw-r--r-- | mysys/charset.c | 18 | ||||
-rw-r--r-- | sql/item.cc | 15 | ||||
-rw-r--r-- | sql/item.h | 3 | ||||
-rw-r--r-- | sql/log_event.cc | 2 | ||||
-rw-r--r-- | sql/log_event.h | 2 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 9 |
9 files changed, 51 insertions, 33 deletions
diff --git a/include/my_sys.h b/include/my_sys.h index eafa41a05c8..8752aa30772 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -788,7 +788,6 @@ extern my_bool init_compiled_charsets(myf flags); extern void add_compiled_collation(CHARSET_INFO *cs); extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to, const char *from, ulong length); -extern char *bare_str_to_hex(char *to, const char *from, uint len); #ifdef __WIN__ #define BACKSLASH_MBTAIL /* File system character set */ diff --git a/mysql-test/r/ctype_cp932.result b/mysql-test/r/ctype_cp932.result index 0e28edc6df3..85e317481d1 100644 --- a/mysql-test/r/ctype_cp932.result +++ b/mysql-test/r/ctype_cp932.result @@ -8576,6 +8576,20 @@ FC4B DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; +CREATE TABLE t1(f1 blob); +PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)'; +SET @var1= x'8300'; +EXECUTE stmt1 USING @var1; +SHOW BINLOG EVENTS FROM 27642; +Log_name Pos Event_type Server_id Orig_log_pos Info +master-bin.000001 27642 Query 1 27642 use `test`; CREATE TABLE t1(f1 blob) +master-bin.000001 27701 Query 1 27701 use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=95,COLLATION_CONNECTION=95,COLLATION_DATABASE=95,COLLATION_SERVER=8 +master-bin.000001 27837 User var 1 27837 @`var1`=_binary 0x8300 COLLATE binary +master-bin.000001 27876 Query 1 27876 use `test`; INSERT INTO t1 VALUES(@'var1') +SELECT HEX(f1) FROM t1; +HEX(f1) +8300 +DROP table t1; SET collation_connection='cp932_japanese_ci'; create table t1 select repeat('a',4000) a; delete from t1; diff --git a/mysql-test/t/ctype_cp932.test b/mysql-test/t/ctype_cp932.test index 7060d917ab0..34bf7965248 100644 --- a/mysql-test/t/ctype_cp932.test +++ b/mysql-test/t/ctype_cp932.test @@ -401,6 +401,26 @@ DROP TABLE t2; DROP TABLE t3; #DROP TABLE t4; +# Test prepared statement with 0x8300 sequence in parameter while +# running with cp932 client character set. +CREATE TABLE t1(f1 blob); +PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)'; +SET @var1= x'8300'; +# TODO: Note that this doesn't actually test the code which was added for +# bug#11338 because this syntax for prepared statements causes the PS to +# be replicated differently than if we executed the PS from C or Java. +# Using this syntax, variable names are inserted into the binlog instead +# of values. The real goal of this test is to check the code that was +# added to Item_param::query_val_str() in order to do hex encoding of +# PS parameters when the client character set is cp932; +# Bug#11338 has an example java program which can be used to verify this +# code (and I have used it to test the fix) until there is some way to +# exercise this code from mysql-test-run. +EXECUTE stmt1 USING @var1; +SHOW BINLOG EVENTS FROM 27642; +SELECT HEX(f1) FROM t1; +DROP table t1; +# end test for bug#11338 SET collation_connection='cp932_japanese_ci'; -- source include/ctype_filesort.inc diff --git a/mysys/charset.c b/mysys/charset.c index df3f1cfa279..3a39fce9437 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -663,21 +663,3 @@ CHARSET_INFO *fs_character_set() return fs_cset_cache; } #endif - -/* - Transforms a string into hex form. - */ -char *bare_str_to_hex(char *to, const char *from, uint len) -{ - char *p= to; - uint i; - for (i= 0; i < len; i++, p+= 2) - { - /* val[i] is char. Casting to uchar helps greatly if val[i] < 0 */ - uint tmp= (uint) (uchar) from[i]; - p[0]= _dig_vec_upper[tmp >> 4]; - p[1]= _dig_vec_upper[tmp & 15]; - } - *p= 0; - return p; // pointer to end 0 of 'to' -} diff --git a/sql/item.cc b/sql/item.cc index 79579eeeb67..2ae56d17b07 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1230,7 +1230,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry) CHARSET_INFO *tocs= thd->variables.collation_connection; uint32 dummy_offset; - value.cs_info.character_set_client= fromcs; + value.cs_info.character_set_of_placeholder= fromcs; /* Setup source and destination character sets so that they are different only if conversion is necessary: this will @@ -1443,7 +1443,7 @@ String *Item_param::val_str(String* str) and avoid one more memcpy/alloc between str and log string. */ -const String *Item_param::query_val_str(String* str, THD *thd) const +const String *Item_param::query_val_str(String* str) const { switch (state) { case INT_VALUE: @@ -1482,18 +1482,17 @@ const String *Item_param::query_val_str(String* str, THD *thd) const buf= str->c_ptr_quick(); ptr= buf; - if (thd->charset()->escape_with_backslash_is_dangerous) + if (value.cs_info.character_set_client->escape_with_backslash_is_dangerous) { - ptr= strmov(ptr, "x\'"); - ptr= bare_str_to_hex(ptr, str_value.ptr(), str_value.length()); + ptr= str_to_hex(ptr, str_value.ptr(), str_value.length()); } else { *ptr++= '\''; ptr+= escape_string_for_mysql(str_value.charset(), ptr, str_value.ptr(), str_value.length()); + *ptr++='\''; } - *ptr++='\''; str->length(ptr - buf); break; } @@ -1523,10 +1522,10 @@ bool Item_param::convert_str_value(THD *thd) here only if conversion is really necessary. */ if (value.cs_info.final_character_set_of_str_value != - value.cs_info.character_set_client) + value.cs_info.character_set_of_placeholder) { rc= thd->convert_string(&str_value, - value.cs_info.character_set_client, + value.cs_info.character_set_of_placeholder, value.cs_info.final_character_set_of_str_value); } else diff --git a/sql/item.h b/sql/item.h index ff34dfad025..080b804c730 100644 --- a/sql/item.h +++ b/sql/item.h @@ -532,6 +532,7 @@ public: struct CONVERSION_INFO { CHARSET_INFO *character_set_client; + CHARSET_INFO *character_set_of_placeholder; /* This points at character set of connection if conversion to it is required (i. e. if placeholder typecode is not BLOB). @@ -591,7 +592,7 @@ public: */ void (*set_param_func)(Item_param *param, uchar **pos, ulong len); - const String *query_val_str(String *str, THD *thd) const; + const String *query_val_str(String *str) const; bool convert_str_value(THD *thd); diff --git a/sql/log_event.cc b/sql/log_event.cc index 4d260763491..66c732e8cb0 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -207,7 +207,7 @@ static inline int read_str(char * &buf, char *buf_end, char * &str, /* Transforms a string into "" or its expression in 0x... form. */ -static char *str_to_hex(char *to, char *from, uint len) +char *str_to_hex(char *to, const char *from, uint len) { char *p= to; if (len) diff --git a/sql/log_event.h b/sql/log_event.h index 7ae4e863fc2..5c81d0c92f0 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1069,5 +1069,5 @@ public: bool is_valid() { return 1; } }; #endif - +char *str_to_hex(char *to, const char *from, uint len); #endif /* _log_event_h */ diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index d0c06a3eaf7..8a50d0bd50e 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -528,7 +528,9 @@ static void setup_one_conversion_function(THD *thd, Item_param *param, case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: param->set_param_func= set_param_str; - param->value.cs_info.character_set_client= &my_charset_bin; + param->value.cs_info.character_set_of_placeholder= &my_charset_bin; + param->value.cs_info.character_set_client= + thd->variables.character_set_client; param->value.cs_info.final_character_set_of_str_value= &my_charset_bin; param->item_type= Item::STRING_ITEM; param->item_result_type= STRING_RESULT; @@ -544,6 +546,7 @@ static void setup_one_conversion_function(THD *thd, Item_param *param, CHARSET_INFO *tocs= thd->variables.collation_connection; uint32 dummy_offset; + param->value.cs_info.character_set_of_placeholder= fromcs; param->value.cs_info.character_set_client= fromcs; /* @@ -601,7 +604,7 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array, param->set_param_func(param, &read_pos, data_end - read_pos); } } - res= param->query_val_str(&str, thd); + res= param->query_val_str(&str); if (param->convert_str_value(thd)) DBUG_RETURN(1); /* out of memory */ @@ -749,7 +752,7 @@ static bool emb_insert_params_withlog(Prepared_statement *stmt, String *query) client_param->buffer_length); } } - res= param->query_val_str(&str, thd); + res= param->query_val_str(&str); if (param->convert_str_value(thd)) DBUG_RETURN(1); /* out of memory */ |