summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <elliot@mysql.com>2005-08-19 14:49:34 -0400
committerunknown <elliot@mysql.com>2005-08-19 14:49:34 -0400
commit1b970e94e0a736a2056cb94cfcba0b50133da1d6 (patch)
treee9b004d2e9d0b322b3e2006b7e0e0733ea5d65f9
parent496e86da3a2b0019a3d9c186063e2c4f56b2bb44 (diff)
downloadmariadb-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.h1
-rw-r--r--mysql-test/r/ctype_cp932.result14
-rw-r--r--mysql-test/t/ctype_cp932.test20
-rw-r--r--mysys/charset.c18
-rw-r--r--sql/item.cc15
-rw-r--r--sql/item.h3
-rw-r--r--sql/log_event.cc2
-rw-r--r--sql/log_event.h2
-rw-r--r--sql/sql_prepare.cc9
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 */