Commit 5d4fbc02 authored by unknown's avatar unknown

Automatic conversion into supersets (utf8, ucs2) for comparison in some cases

USER(), DATABASE() and VERSION() return in utf8 now

parent 46c730e6
...@@ -133,6 +133,60 @@ bool Item_bool_func2::fix_fields(THD *thd, struct st_table_list *tables, ...@@ -133,6 +133,60 @@ bool Item_bool_func2::fix_fields(THD *thd, struct st_table_list *tables,
{ {
if (Item_int_func::fix_fields(thd, tables, ref)) if (Item_int_func::fix_fields(thd, tables, ref))
return 1; return 1;
/*
We allow to convert to Unicode character sets in some cases.
The conditions when conversion is possible are:
- arguments A and B have different charsets
- A wins according to coercibility rules
- character set of A is superset for character set of B
If all of the above is true, then it's possible to convert
B into the character set of A, and then compare according
to the collation of A.
*/
if (args[0] && args[1])
{
uint strong= 0;
uint weak= 0;
if ((args[0]->coercibility < args[1]->coercibility) &&
!my_charset_same(args[0]->charset(), args[1]->charset()) &&
(args[0]->charset()->state & MY_CS_UNICODE))
{
weak= 1;
}
else if ((args[1]->coercibility < args[0]->coercibility) &&
!my_charset_same(args[0]->charset(), args[1]->charset()) &&
(args[1]->charset()->state & MY_CS_UNICODE))
{
strong= 1;
}
if (strong || weak)
{
Item* conv= 0;
if (args[weak]->type() == STRING_ITEM)
{
String tmp, cstr;
String *ostr= args[weak]->val_str(&tmp);
cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(),
args[strong]->charset());
conv= new Item_string(cstr.ptr(),cstr.length(),cstr.charset(),
args[weak]->coercibility);
((Item_string*)conv)->str_value.copy();
}
else
{
conv= new Item_func_conv_charset(args[weak],args[strong]->charset());
conv->coercibility= args[weak]->coercibility;
}
args[weak]= conv ? conv : args[weak];
set_cmp_charset(args[0]->charset(), args[0]->coercibility,
args[1]->charset(), args[1]->coercibility);
}
}
if (!cmp_charset) if (!cmp_charset)
{ {
/* set_cmp_charset() failed */ /* set_cmp_charset() failed */
...@@ -156,6 +210,8 @@ void Item_bool_func2::fix_length_and_dec() ...@@ -156,6 +210,8 @@ void Item_bool_func2::fix_length_and_dec()
*/ */
if (!args[0] || !args[1]) if (!args[0] || !args[1])
return; return;
// Make a special case of compare with fields to get nicer DATE comparisons // Make a special case of compare with fields to get nicer DATE comparisons
if (args[0]->type() == FIELD_ITEM) if (args[0]->type() == FIELD_ITEM)
{ {
......
...@@ -1459,10 +1459,12 @@ String *Item_func_database::val_str(String *str) ...@@ -1459,10 +1459,12 @@ String *Item_func_database::val_str(String *str)
{ {
THD *thd= current_thd; THD *thd= current_thd;
if (!thd->db) if (!thd->db)
{
str->length(0); str->length(0);
str->set_charset(system_charset_info);
}
else else
str->copy((const char*) thd->db,(uint) strlen(thd->db), str->copy((const char*) thd->db,(uint) strlen(thd->db),system_charset_info);
system_charset_info, default_charset());
return str; return str;
} }
...@@ -1471,7 +1473,7 @@ String *Item_func_database::val_str(String *str) ...@@ -1471,7 +1473,7 @@ String *Item_func_database::val_str(String *str)
String *Item_func_user::val_str(String *str) String *Item_func_user::val_str(String *str)
{ {
THD *thd=current_thd; THD *thd=current_thd;
CHARSET_INFO *cs= default_charset(); CHARSET_INFO *cs= system_charset_info;
const char *host= thd->host_or_ip; const char *host= thd->host_or_ip;
uint res_length; uint res_length;
......
...@@ -337,8 +337,8 @@ public: ...@@ -337,8 +337,8 @@ public:
String *val_str(String *); String *val_str(String *);
void fix_length_and_dec() void fix_length_and_dec()
{ {
max_length= MAX_FIELD_NAME * default_charset()->mbmaxlen; max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen;
set_charset(default_charset()); set_charset(system_charset_info);
} }
const char *func_name() const { return "database"; } const char *func_name() const { return "database"; }
}; };
...@@ -350,8 +350,8 @@ public: ...@@ -350,8 +350,8 @@ public:
String *val_str(String *); String *val_str(String *);
void fix_length_and_dec() void fix_length_and_dec()
{ {
max_length= (USERNAME_LENGTH+HOSTNAME_LENGTH+1)*default_charset()->mbmaxlen; max_length= (USERNAME_LENGTH+HOSTNAME_LENGTH+1)*system_charset_info->mbmaxlen;
set_charset(default_charset()); set_charset(system_charset_info);
} }
const char *func_name() const { return "user"; } const char *func_name() const { return "user"; }
}; };
......
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