summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorunknown <bar@mysql.com/bar.intranet.mysql.r18.ru>2006-11-09 14:27:34 +0400
committerunknown <bar@mysql.com/bar.intranet.mysql.r18.ru>2006-11-09 14:27:34 +0400
commite0fc25e98209cefe40c3e3ee78ae2e338e2a8caa (patch)
treeb32f081e145620bd28a94e6f2294d3e2f0b7ffb7 /sql/sp_head.cc
parenta39b8a064ed1cd200e34be4ee0af078da7b2412c (diff)
downloadmariadb-git-e0fc25e98209cefe40c3e3ee78ae2e338e2a8caa.tar.gz
Bug#23619 Incorrectly escaped multibyte characters in binary log break replication
Problem: when embedding a character string with introducer with charset X into a SQL query which is generally in character set Y, the string constants were escaped according to their own character set (i.e.X), then after reading such a "mixed" query from binlog, the string constants were unescaped using character set of the query (i.e. Y), instead of X, which gave wrong results or even syntax errors with tricky charsets (e.g. sjis) Fix: when embedding a string constant of charset X into a query of charset Y, the string constant is now escaped according to character Y, instead of its own character set X. mysql-test/r/ctype_cp932_binlog.result: Fixing test results. sql/log_event.cc: Using character set "csinfo" instead of the string character set. sql/sp_head.cc: - adding "thd" argument to sp_get_item_value() to have access to thd->variables.character_set_client - using character_set_client for escaping, instead of the string character set mysql-test/r/rpl_charset_sjis.result: Adding test case mysql-test/t/rpl_charset_sjis.test: Adding test case
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc11
1 files changed, 6 insertions, 5 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index a06bfe28a6f..88f9d4dece4 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -93,7 +93,7 @@ sp_map_item_type(enum enum_field_types type)
*/
static String *
-sp_get_item_value(Item *item, String *str)
+sp_get_item_value(THD *thd, Item *item, String *str)
{
Item_result result_type= item->result_type();
@@ -113,15 +113,16 @@ sp_get_item_value(Item *item, String *str)
{
char buf_holder[STRING_BUFFER_USUAL_SIZE];
String buf(buf_holder, sizeof(buf_holder), result->charset());
+ CHARSET_INFO *cs= thd->variables.character_set_client;
/* We must reset length of the buffer, because of String specificity. */
buf.length(0);
buf.append('_');
buf.append(result->charset()->csname);
- if (result->charset()->escape_with_backslash_is_dangerous)
+ if (cs->escape_with_backslash_is_dangerous)
buf.append(' ');
- append_query_string(result->charset(), result, &buf);
+ append_query_string(cs, result, &buf);
str->copy(buf);
return str;
@@ -862,7 +863,7 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
val= (*splocal)->this_item();
DBUG_PRINT("info", ("print %p", val));
- str_value= sp_get_item_value(val, &str_value_holder);
+ str_value= sp_get_item_value(thd, val, &str_value_holder);
if (str_value)
res|= qbuf.append(*str_value);
else
@@ -1456,7 +1457,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
if (arg_no)
binlog_buf.append(',');
- str_value= sp_get_item_value(nctx->get_item(arg_no),
+ str_value= sp_get_item_value(thd, nctx->get_item(arg_no),
&str_value_holder);
if (str_value)