Automatic conversion into supersets (utf8, ucs2) for comparison in some cases
USER(), DATABASE() and VERSION() return in utf8 now
This commit is contained in:
parent
46c730e62c
commit
5d4fbc021a
@ -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))
|
||||
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)
|
||||
{
|
||||
/* set_cmp_charset() failed */
|
||||
@ -156,6 +210,8 @@ void Item_bool_func2::fix_length_and_dec()
|
||||
*/
|
||||
if (!args[0] || !args[1])
|
||||
return;
|
||||
|
||||
|
||||
// Make a special case of compare with fields to get nicer DATE comparisons
|
||||
if (args[0]->type() == FIELD_ITEM)
|
||||
{
|
||||
|
@ -1459,10 +1459,12 @@ String *Item_func_database::val_str(String *str)
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
if (!thd->db)
|
||||
{
|
||||
str->length(0);
|
||||
str->set_charset(system_charset_info);
|
||||
}
|
||||
else
|
||||
str->copy((const char*) thd->db,(uint) strlen(thd->db),
|
||||
system_charset_info, default_charset());
|
||||
str->copy((const char*) thd->db,(uint) strlen(thd->db),system_charset_info);
|
||||
return str;
|
||||
}
|
||||
|
||||
@ -1471,7 +1473,7 @@ String *Item_func_database::val_str(String *str)
|
||||
String *Item_func_user::val_str(String *str)
|
||||
{
|
||||
THD *thd=current_thd;
|
||||
CHARSET_INFO *cs= default_charset();
|
||||
CHARSET_INFO *cs= system_charset_info;
|
||||
const char *host= thd->host_or_ip;
|
||||
uint res_length;
|
||||
|
||||
|
@ -337,8 +337,8 @@ public:
|
||||
String *val_str(String *);
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
max_length= MAX_FIELD_NAME * default_charset()->mbmaxlen;
|
||||
set_charset(default_charset());
|
||||
max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen;
|
||||
set_charset(system_charset_info);
|
||||
}
|
||||
const char *func_name() const { return "database"; }
|
||||
};
|
||||
@ -350,8 +350,8 @@ public:
|
||||
String *val_str(String *);
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
max_length= (USERNAME_LENGTH+HOSTNAME_LENGTH+1)*default_charset()->mbmaxlen;
|
||||
set_charset(default_charset());
|
||||
max_length= (USERNAME_LENGTH+HOSTNAME_LENGTH+1)*system_charset_info->mbmaxlen;
|
||||
set_charset(system_charset_info);
|
||||
}
|
||||
const char *func_name() const { return "user"; }
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user