diff --git a/sql/item.cc b/sql/item.cc index d01a06e5eba..415fe4d72af 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -133,6 +133,9 @@ void Item_field::set_field(Field *field_par) field_name=field_par->field_name; binary=field_par->binary(); unsigned_flag=test(field_par->flags & UNSIGNED_FLAG); + /* For string fields copy character set from original field */ + if (!field_par->binary()) + str_value.set_charset(((Field_str*)field_par)->charset()); } const char *Item_ident::full_name() const diff --git a/sql/item_func.cc b/sql/item_func.cc index 0675bf81dab..b14c1b38383 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -78,6 +78,17 @@ Item_func::fix_fields(THD *thd,TABLE_LIST *tables) maybe_null=1; if ((*arg)->binary) binary=1; + /* + Change charset to arg charset if it is not equal to + default_charset_info. This will work for many cases, + but generally this should be done more carefull. Each string + function should have it's own fix_fields() method to correctly + setup it's result's character set taking in account arguments. + For example: left(a,b) should take in account only first argument, + but ignore the second one. + */ + if ((*arg)->str_value.charset() != default_charset_info) + str_value.set_charset((*arg)->str_value.charset()); with_sum_func= with_sum_func || (*arg)->with_sum_func; used_tables_cache|=(*arg)->used_tables(); const_item_cache&= (*arg)->const_item(); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 5275da95b6e..81d866bfe6d 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -759,6 +759,7 @@ String *Item_func_left::val_str(String *str) if (!res->alloced_length()) { // Don't change const str str_value= *res; // Not malloced string + str_value.set_charset(res->charset()); res= &str_value; } res->length((uint) length); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4737e068d3e..025a5c600a5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3579,7 +3579,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, item->name,table,item->binary); else new_field= new Field_string(item->max_length,maybe_null, - item->name,table,item->binary,default_charset_info); + item->name,table,item->binary, + item->str_value.charset()); break; } if (copy_func)