Commit 0f73558e authored by bar@mysql.com's avatar bar@mysql.com

Merge mysql.com:/usr/home/bar/mysql-4.1.b10446

into  mysql.com:/usr/home/bar/mysql-5.0
parents 1a391f71 5c1ba75c
...@@ -181,11 +181,18 @@ select * from t1 where a=_koi8r' ...@@ -181,11 +181,18 @@ select * from t1 where a=_koi8r'
a a
select * from t1 where a=concat(_koi8r''); 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''; select * from t1 where a=_latin1'';
ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation '=' ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation '='
drop table t1; drop table t1;
set names latin1; 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; set names koi8r;
create table t1 (c1 char(10) character set cp1251); create table t1 (c1 char(10) character set cp1251);
insert into t1 values (''); insert into t1 values ('');
......
...@@ -144,8 +144,7 @@ create table t1 (a char(10) character set cp1251); ...@@ -144,8 +144,7 @@ create table t1 (a char(10) character set cp1251);
insert into t1 values (_koi8r''); insert into t1 values (_koi8r'');
# this is possible: # this is possible:
select * from t1 where a=_koi8r''; select * from t1 where a=_koi8r'';
# this is not possible, because we have a function, not just a constant: # this is possible, because we have a function with constant arguments:
--error 1267
select * from t1 where a=concat(_koi8r''); select * from t1 where a=concat(_koi8r'');
# this is not posible, cannot convert _latin1'' into cp1251: # this is not posible, cannot convert _latin1'' into cp1251:
--error 1267 --error 1267
...@@ -153,6 +152,14 @@ select * from t1 where a=_latin1' ...@@ -153,6 +152,14 @@ select * from t1 where a=_latin1'
drop table t1; drop table t1;
set names latin1; 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 # Check more automatic conversion
# #
......
...@@ -601,16 +601,8 @@ bool Item::eq(const Item *item, bool binary_cmp) const ...@@ -601,16 +601,8 @@ bool Item::eq(const Item *item, bool binary_cmp) const
Item *Item::safe_charset_converter(CHARSET_INFO *tocs) Item *Item::safe_charset_converter(CHARSET_INFO *tocs)
{ {
/* Item_func_conv_charset *conv= new Item_func_conv_charset(this, tocs, 1);
Allow conversion from and to "binary". return conv->safe ? conv : NULL;
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);
} }
......
...@@ -2316,6 +2316,8 @@ String *Item_func_conv::val_str(String *str) ...@@ -2316,6 +2316,8 @@ String *Item_func_conv::val_str(String *str)
String *Item_func_conv_charset::val_str(String *str) String *Item_func_conv_charset::val_str(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
if (use_cached_value)
return null_value ? 0 : &str_value;
String *arg= args[0]->val_str(str); String *arg= args[0]->val_str(str);
uint dummy_errors; uint dummy_errors;
if (!arg) if (!arg)
......
...@@ -652,10 +652,40 @@ public: ...@@ -652,10 +652,40 @@ public:
class Item_func_conv_charset :public Item_str_func class Item_func_conv_charset :public Item_str_func
{ {
bool use_cached_value;
public: public:
bool safe;
CHARSET_INFO *conv_charset; // keep it public CHARSET_INFO *conv_charset; // keep it public
Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) 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 *); String *val_str(String *);
void fix_length_and_dec(); void fix_length_and_dec();
const char *func_name() const { return "convert"; } const char *func_name() const { return "convert"; }
......
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