Loading mysql-test/r/ctype_recoding.result +8 −1 Original line number Diff line number Diff line Loading @@ -181,11 +181,18 @@ select * from t1 where a=_koi8r' a select * from t1 where a=concat(_koi8r''); ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (koi8r_general_ci,COERCIBLE) for operation '=' a select * from t1 where a=_latin1''; ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation '=' drop table t1; set names latin1; create table t1 (a char(10) character set utf8 collate utf8_bin); insert into t1 values (' xxx'); select * from t1 where a=lpad('xxx',10,' '); a xxx drop table t1; set names koi8r; create table t1 (c1 char(10) character set cp1251); insert into t1 values (''); Loading mysql-test/t/ctype_recoding.test +9 −2 Original line number Diff line number Diff line Loading @@ -144,8 +144,7 @@ create table t1 (a char(10) character set cp1251); insert into t1 values (_koi8r''); # this is possible: select * from t1 where a=_koi8r''; # this is not possible, because we have a function, not just a constant: --error 1267 # this is possible, because we have a function with constant arguments: select * from t1 where a=concat(_koi8r''); # this is not posible, cannot convert _latin1'' into cp1251: --error 1267 Loading @@ -153,6 +152,14 @@ select * from t1 where a=_latin1' drop table t1; set names latin1; # # Bug#10446 Illegal mix of collations # create table t1 (a char(10) character set utf8 collate utf8_bin); insert into t1 values (' xxx'); select * from t1 where a=lpad('xxx',10,' '); drop table t1; # # Check more automatic conversion # Loading sql/item.cc +2 −10 Original line number Diff line number Diff line Loading @@ -211,16 +211,8 @@ bool Item::eq(const Item *item, bool binary_cmp) const Item *Item::safe_charset_converter(CHARSET_INFO *tocs) { /* Allow conversion from and to "binary". Don't allow automatic conversion to non-Unicode charsets, as it potentially loses data. */ if (collation.collation != &my_charset_bin && tocs != &my_charset_bin && !(tocs->state & MY_CS_UNICODE)) return NULL; // safe conversion is not possible return new Item_func_conv_charset(this, tocs); Item_func_conv_charset *conv= new Item_func_conv_charset(this, tocs, 1); return conv->safe ? conv : NULL; } Loading sql/item_strfunc.cc +2 −0 Original line number Diff line number Diff line Loading @@ -2252,6 +2252,8 @@ String *Item_func_conv::val_str(String *str) String *Item_func_conv_charset::val_str(String *str) { DBUG_ASSERT(fixed == 1); if (use_cached_value) return null_value ? 0 : &str_value; String *arg= args[0]->val_str(str); uint dummy_errors; if (!arg) Loading sql/item_strfunc.h +32 −2 Original line number Diff line number Diff line Loading @@ -614,10 +614,40 @@ class Item_func_quote :public Item_str_func class Item_func_conv_charset :public Item_str_func { bool use_cached_value; public: bool safe; CHARSET_INFO *conv_charset; // keep it public Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) { conv_charset=cs; } { conv_charset= cs; use_cached_value= 0; safe= 0; } Item_func_conv_charset(Item *a, CHARSET_INFO *cs, bool cache_if_const) :Item_str_func(a) { DBUG_ASSERT(args[0]->fixed); conv_charset= cs; if (cache_if_const && args[0]->const_item()) { uint errors= 0; String tmp, *str= args[0]->val_str(&tmp); if (!str || str_value.copy(str->ptr(), str->length(), str->charset(), conv_charset, &errors)) null_value= 1; use_cached_value= 1; safe= (errors == 0); } else { use_cached_value= 0; /* Conversion from and to "binary" is safe. Conversion to Unicode is safe. Other kind of conversions are potentially lossy. */ safe= (args[0]->collation.collation == &my_charset_bin || cs == &my_charset_bin || (cs->state & MY_CS_UNICODE)); } } String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "convert"; } Loading Loading
mysql-test/r/ctype_recoding.result +8 −1 Original line number Diff line number Diff line Loading @@ -181,11 +181,18 @@ select * from t1 where a=_koi8r' a select * from t1 where a=concat(_koi8r''); ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (koi8r_general_ci,COERCIBLE) for operation '=' a select * from t1 where a=_latin1''; ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation '=' drop table t1; set names latin1; create table t1 (a char(10) character set utf8 collate utf8_bin); insert into t1 values (' xxx'); select * from t1 where a=lpad('xxx',10,' '); a xxx drop table t1; set names koi8r; create table t1 (c1 char(10) character set cp1251); insert into t1 values (''); Loading
mysql-test/t/ctype_recoding.test +9 −2 Original line number Diff line number Diff line Loading @@ -144,8 +144,7 @@ create table t1 (a char(10) character set cp1251); insert into t1 values (_koi8r''); # this is possible: select * from t1 where a=_koi8r''; # this is not possible, because we have a function, not just a constant: --error 1267 # this is possible, because we have a function with constant arguments: select * from t1 where a=concat(_koi8r''); # this is not posible, cannot convert _latin1'' into cp1251: --error 1267 Loading @@ -153,6 +152,14 @@ select * from t1 where a=_latin1' drop table t1; set names latin1; # # Bug#10446 Illegal mix of collations # create table t1 (a char(10) character set utf8 collate utf8_bin); insert into t1 values (' xxx'); select * from t1 where a=lpad('xxx',10,' '); drop table t1; # # Check more automatic conversion # Loading
sql/item.cc +2 −10 Original line number Diff line number Diff line Loading @@ -211,16 +211,8 @@ bool Item::eq(const Item *item, bool binary_cmp) const Item *Item::safe_charset_converter(CHARSET_INFO *tocs) { /* Allow conversion from and to "binary". Don't allow automatic conversion to non-Unicode charsets, as it potentially loses data. */ if (collation.collation != &my_charset_bin && tocs != &my_charset_bin && !(tocs->state & MY_CS_UNICODE)) return NULL; // safe conversion is not possible return new Item_func_conv_charset(this, tocs); Item_func_conv_charset *conv= new Item_func_conv_charset(this, tocs, 1); return conv->safe ? conv : NULL; } Loading
sql/item_strfunc.cc +2 −0 Original line number Diff line number Diff line Loading @@ -2252,6 +2252,8 @@ String *Item_func_conv::val_str(String *str) String *Item_func_conv_charset::val_str(String *str) { DBUG_ASSERT(fixed == 1); if (use_cached_value) return null_value ? 0 : &str_value; String *arg= args[0]->val_str(str); uint dummy_errors; if (!arg) Loading
sql/item_strfunc.h +32 −2 Original line number Diff line number Diff line Loading @@ -614,10 +614,40 @@ class Item_func_quote :public Item_str_func class Item_func_conv_charset :public Item_str_func { bool use_cached_value; public: bool safe; CHARSET_INFO *conv_charset; // keep it public Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) { conv_charset=cs; } { conv_charset= cs; use_cached_value= 0; safe= 0; } Item_func_conv_charset(Item *a, CHARSET_INFO *cs, bool cache_if_const) :Item_str_func(a) { DBUG_ASSERT(args[0]->fixed); conv_charset= cs; if (cache_if_const && args[0]->const_item()) { uint errors= 0; String tmp, *str= args[0]->val_str(&tmp); if (!str || str_value.copy(str->ptr(), str->length(), str->charset(), conv_charset, &errors)) null_value= 1; use_cached_value= 1; safe= (errors == 0); } else { use_cached_value= 0; /* Conversion from and to "binary" is safe. Conversion to Unicode is safe. Other kind of conversions are potentially lossy. */ safe= (args[0]->collation.collation == &my_charset_bin || cs == &my_charset_bin || (cs->state & MY_CS_UNICODE)); } } String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "convert"; } Loading