diff options
-rw-r--r-- | myisam/mi_unique.c | 35 | ||||
-rw-r--r-- | sql/field.cc | 11 | ||||
-rw-r--r-- | sql/field.h | 11 | ||||
-rw-r--r-- | sql/field_conv.cc | 3 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 38 | ||||
-rw-r--r-- | sql/item_strfunc.h | 4 | ||||
-rw-r--r-- | sql/sql_select.cc | 9 |
7 files changed, 77 insertions, 34 deletions
diff --git a/myisam/mi_unique.c b/myisam/mi_unique.c index 629523ec69a..7afaabfe75b 100644 --- a/myisam/mi_unique.c +++ b/myisam/mi_unique.c @@ -99,11 +99,20 @@ ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const byte *record) end= pos+length; if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT) { - uchar *sort_order=keyseg->charset->sort_order; - while (pos != end) - crc=((crc << 8) + - (((uchar) sort_order[*(uchar*) pos++]))) + - (crc >> (8*sizeof(ha_checksum)-8)); + if (keyseg->charset->hash_sort) + { + ulong nr=1, nr2=4; + keyseg->charset->hash_sort(keyseg->charset,(const uchar*)pos,length,&nr, &nr2); + crc=nr; + } + else + { + uchar *sort_order=keyseg->charset->sort_order; + while (pos != end) + crc=((crc << 8) + + (((uchar) sort_order[*(uchar*) pos++]))) + + (crc >> (8*sizeof(ha_checksum)-8)); + } } else while (pos != end) @@ -173,11 +182,19 @@ int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b, end= pos_a+length; if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT) { - uchar *sort_order=keyseg->charset->sort_order; - while (pos_a != end) - if (sort_order[*(uchar*) pos_a++] != - sort_order[*(uchar*) pos_b++]) + if (use_strcoll(keyseg->charset)) + { + if (my_strnncoll(keyseg->charset,pos_a,length,pos_b,length)) return 1; + } + else + { + uchar *sort_order=keyseg->charset->sort_order; + while (pos_a != end) + if (sort_order[*(uchar*) pos_a++] != + sort_order[*(uchar*) pos_b++]) + return 1; + } } else while (pos_a != end) diff --git a/sql/field.cc b/sql/field.cc index 8b1073d32f3..a475612fbb0 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3782,10 +3782,10 @@ uint Field_varstring::max_packed_col_length(uint max_length) Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg,uint blob_pack_length, - bool binary_arg) + bool binary_arg, CHARSET_INFO *cs) :Field_str(ptr_arg, (1L << min(blob_pack_length,3)*8)-1L, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, - table_arg, default_charset_info), + table_arg, cs), packlength(blob_pack_length),binary_flag(binary_arg), geom_flag(true) { flags|= BLOB_FLAG; @@ -3967,9 +3967,9 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)), char *blob; memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); if (!blob) - val_ptr->set("",0,default_charset_info); // A bit safer than ->length(0) + val_ptr->set("",0,field_charset); // A bit safer than ->length(0) else - val_ptr->set((const char*) blob,get_length(ptr),default_charset_info); + val_ptr->set((const char*) blob,get_length(ptr),field_charset); return val_ptr; } @@ -4782,7 +4782,8 @@ Field *make_field(char *ptr, uint32 field_length, if (f_is_blob(pack_flag)) return new Field_blob(ptr,null_pos,null_bit, unireg_check, field_name, table, - pack_length,f_is_binary(pack_flag) != 0); + pack_length,f_is_binary(pack_flag) != 0, + default_charset_info); if (f_is_geom(pack_flag)) return new Field_geom(ptr,null_pos,null_bit, unireg_check, field_name, table, diff --git a/sql/field.h b/sql/field.h index 5b9723654d9..5bc463af48d 100644 --- a/sql/field.h +++ b/sql/field.h @@ -842,11 +842,11 @@ public: Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg,uint blob_pack_length, - bool binary_arg); + bool binary_arg, CHARSET_INFO *cs); Field_blob(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, bool binary_arg) + struct st_table *table_arg, bool binary_arg, CHARSET_INFO *cs) :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg, default_charset_info), + NONE, field_name_arg, table_arg, cs), packlength(3),binary_flag(binary_arg), geom_flag(true) { flags|= BLOB_FLAG; @@ -930,11 +930,12 @@ public: struct st_table *table_arg,uint blob_pack_length, bool binary_arg) :Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, - field_name_arg, table_arg, blob_pack_length,binary_arg) {} + field_name_arg, table_arg, blob_pack_length,binary_arg, + default_charset_info) {} Field_geom(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, struct st_table *table_arg, bool binary_arg) :Field_blob(len_arg, maybe_null_arg, field_name_arg, - table_arg, binary_arg) {} + table_arg, binary_arg, default_charset_info) {} enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY; } void get_key_image(char *buff,uint length, imagetype type); diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 3b8a2ee791c..da7a1187a47 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -508,7 +508,8 @@ void field_conv(Field *to,Field *from) if (!blob->value.is_alloced() && from->real_type() != FIELD_TYPE_STRING) blob->value.copy(); - blob->store(blob->value.ptr(),blob->value.length(),default_charset_info); + blob->store(blob->value.ptr(),blob->value.length(), + to->binary()?default_charset_info:((Field_str*)to)->charset()); return; } if ((from->result_type() == STRING_RESULT && diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index a4f09f9103e..c2549ddc769 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1799,7 +1799,7 @@ String *Item_func_conv_charset::val_str(String *str) s=(const uchar*)arg->ptr(); se=s+arg->length(); - dmaxlen=arg->length()*(conv_charset->mbmaxlen?conv_charset->mbmaxlen:1)+1; + dmaxlen=arg->length()*(to->mbmaxlen?to->mbmaxlen:1)+1; str->alloc(dmaxlen); d0=d=(unsigned char*)str->ptr(); de=d+dmaxlen; @@ -1841,7 +1841,7 @@ outp: void Item_func_conv_charset::fix_length_and_dec() { - /* BAR TODO: What to do here??? */ + max_length = args[0]->max_length*(conv_charset->mbmaxlen?conv_charset->mbmaxlen:1); } @@ -1911,23 +1911,41 @@ outp: return str; } -String *Item_func_charset::val_str(String *str) -{ - String *res = args[0]->val_str(str); - if ((null_value=(args[0]->null_value || !res->charset()))) - return 0; - str->copy(res->charset()->name,strlen(res->charset()->name)); - return str; +bool Item_func_conv_charset::fix_fields(THD *thd,struct st_table_list *tables) +{ + char buff[STACK_BUFF_ALLOC]; // Max argument in function + binary=0; + used_tables_cache=0; + const_item_cache=1; + + if (thd && check_stack_overrun(thd,buff)) + return 0; // Fatal error if flag is set! + if (args[0]->fix_fields(thd,tables)) + return 1; + maybe_null=args[0]->maybe_null; + binary=args[0]->binary; + str_value.set_charset(conv_charset); + fix_length_and_dec(); + return 0; } void Item_func_conv_charset3::fix_length_and_dec() { - /* BAR TODO: What to do here??? */ + max_length = args[0]->max_length; } +String *Item_func_charset::val_str(String *str) +{ + String *res = args[0]->val_str(str); + + if ((null_value=(args[0]->null_value || !res->charset()))) + return 0; + str->copy(res->charset()->name,strlen(res->charset()->name)); + return str; +} String *Item_func_hex::val_str(String *str) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index a273abaf614..74ec51274fc 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -40,7 +40,8 @@ public: if (!t_arg) return result_field; return (max_length > 255) ? - (Field *)new Field_blob(max_length,maybe_null, name,t_arg, binary) : + (Field *)new Field_blob(max_length,maybe_null, name,t_arg, binary, + default_charset_info) : (Field *) new Field_string(max_length,maybe_null, name,t_arg, binary, default_charset_info); } @@ -488,6 +489,7 @@ public: { conv_charset=cs; } + bool fix_fields(THD *thd,struct st_table_list *tables); String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "conv_charset"; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 025a5c600a5..f528750341e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3523,7 +3523,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case STRING_RESULT: if (item_sum->max_length > 255) return new Field_blob(item_sum->max_length,maybe_null, - item->name,table,item->binary); + item->name,table,item->binary,default_charset_info); return new Field_string(item_sum->max_length,maybe_null, item->name,table,item->binary,default_charset_info); } @@ -3576,7 +3576,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case STRING_RESULT: if (item->max_length > 255) new_field= new Field_blob(item->max_length,maybe_null, - item->name,table,item->binary); + item->name,table,item->binary, + item->str_value.charset()); else new_field= new Field_string(item->max_length,maybe_null, item->name,table,item->binary, @@ -4104,7 +4105,9 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, { Field *field=keyinfo->key_part[i].field; seg->flag= 0; - seg->language= MY_CHARSET_CURRENT; + seg->language= field->binary() ? MY_CHARSET_CURRENT : + ((Field_str*)field)->charset()->number; + seg->length= keyinfo->key_part[i].length; seg->start= keyinfo->key_part[i].offset; if (field->flags & BLOB_FLAG) |