Commit 7671bc00 authored by bar@mysql.com's avatar bar@mysql.com

Bug#12371: executing prepared statement fails (illegal mix of collations)

ctype_utf8.test, ctype_utf8.result:
  Adding test case.
item.h:
item.cc:
  Adding Item_param::safe_charset_converter
parent 6c258beb
...@@ -1131,3 +1131,20 @@ a ...@@ -1131,3 +1131,20 @@ a
i i
drop table t1,t2; drop table t1,t2;
set names utf8;
create table t1 (a char(10), b varchar(10));
insert into t1 values ('bar','kostja');
insert into t1 values ('kostja','bar');
prepare my_stmt from "select * from t1 where a=?";
set @a:='bar';
execute my_stmt using @a;
a b
bar kostja
set @a:='kostja';
execute my_stmt using @a;
a b
kostja bar
set @a:=null;
execute my_stmt using @a;
a b
drop table if exists t1;
...@@ -916,3 +916,20 @@ insert into t1 values('a'),('a'),(0xE38182),(0xE38182); ...@@ -916,3 +916,20 @@ insert into t1 values('a'),('a'),(0xE38182),(0xE38182);
insert into t1 values('i'),('i'),(0xE38184),(0xE38184); insert into t1 values('i'),('i'),(0xE38184),(0xE38184);
select * from t1 union distinct select * from t2; select * from t1 union distinct select * from t2;
drop table t1,t2; drop table t1,t2;
#
# Bug#12371: executing prepared statement fails (illegal mix of collations)
#
set names utf8;
create table t1 (a char(10), b varchar(10));
insert into t1 values ('bar','kostja');
insert into t1 values ('kostja','bar');
prepare my_stmt from "select * from t1 where a=?";
set @a:='bar';
execute my_stmt using @a;
set @a:='kostja';
execute my_stmt using @a;
set @a:=null;
execute my_stmt using @a;
drop table if exists t1;
...@@ -696,6 +696,32 @@ Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs) ...@@ -696,6 +696,32 @@ Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs)
} }
Item *Item_param::safe_charset_converter(CHARSET_INFO *tocs)
{
if (const_item())
{
Item_string *conv;
uint cnv_errors;
char buf[MAX_FIELD_WIDTH];
String tmp(buf, sizeof(buf), &my_charset_bin);
String cstr, *ostr= val_str(&tmp);
/*
As safe_charset_converter is not executed for
a parameter bound to NULL, ostr should never be 0.
*/
cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &cnv_errors);
if (cnv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(),
cstr.charset(),
collation.derivation)))
return NULL;
conv->str_value.copy();
conv->str_value.mark_as_const();
return conv;
}
return NULL;
}
Item *Item_static_string_func::safe_charset_converter(CHARSET_INFO *tocs) Item *Item_static_string_func::safe_charset_converter(CHARSET_INFO *tocs)
{ {
Item_string *conv; Item_string *conv;
...@@ -1351,7 +1377,7 @@ bool agg_item_charsets(DTCollation &coll, const char *fname, ...@@ -1351,7 +1377,7 @@ bool agg_item_charsets(DTCollation &coll, const char *fname,
been created in prepare. In this case register the change for been created in prepare. In this case register the change for
rollback. rollback.
*/ */
if (arena) if (arena && arena->is_conventional())
*arg= conv; *arg= conv;
else else
thd->change_item_tree(arg, conv); thd->change_item_tree(arg, conv);
......
...@@ -1194,6 +1194,7 @@ public: ...@@ -1194,6 +1194,7 @@ public:
constant, assert otherwise. This method is called only if constant, assert otherwise. This method is called only if
basic_const_item returned TRUE. basic_const_item returned TRUE.
*/ */
Item *safe_charset_converter(CHARSET_INFO *tocs);
Item *new_item(); Item *new_item();
/* /*
Implement by-value equality evaluation if parameter value Implement by-value equality evaluation if parameter value
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment