Commit 1ff701ee authored by unknown's avatar unknown

Several problems were fixed (mostly BLOB+charset related)

Fixed that MyISAM were not working properly with non-8bit charsets in some cases
CONVERT() function now works properly


myisam/mi_unique.c:
  Fix for non-8bit charsets
sql/field.cc:
  Initialize blobs with charset
sql/field.h:
  Initialize blobs with charset
sql/field_conv.cc:
  Initialize blobs with charset
sql/item_strfunc.cc:
  CONVERT() function now has working fix_lenght_and_dec(), and it's own 
  fix_fields()
sql/item_strfunc.h:
  CONVERT() function now has working fix_lenght_and_dec(), and it's own 
  fix_fields()
sql/sql_select.cc:
  Fixes for BLOBs
  Fixed that wrong charset was used in some cases
parent 96991914
...@@ -99,11 +99,20 @@ ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const byte *record) ...@@ -99,11 +99,20 @@ ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const byte *record)
end= pos+length; end= pos+length;
if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT) if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT)
{ {
uchar *sort_order=keyseg->charset->sort_order; if (keyseg->charset->hash_sort)
while (pos != end) {
crc=((crc << 8) + ulong nr=1, nr2=4;
(((uchar) sort_order[*(uchar*) pos++]))) + keyseg->charset->hash_sort(keyseg->charset,(const uchar*)pos,length,&nr, &nr2);
(crc >> (8*sizeof(ha_checksum)-8)); 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 else
while (pos != end) while (pos != end)
...@@ -173,11 +182,19 @@ int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b, ...@@ -173,11 +182,19 @@ int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b,
end= pos_a+length; end= pos_a+length;
if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT) if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT)
{ {
uchar *sort_order=keyseg->charset->sort_order; if (use_strcoll(keyseg->charset))
while (pos_a != end) {
if (sort_order[*(uchar*) pos_a++] != if (my_strnncoll(keyseg->charset,pos_a,length,pos_b,length))
sort_order[*(uchar*) pos_b++])
return 1; 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 else
while (pos_a != end) while (pos_a != end)
......
...@@ -3782,10 +3782,10 @@ uint Field_varstring::max_packed_col_length(uint max_length) ...@@ -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, 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, enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,uint blob_pack_length, 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, :Field_str(ptr_arg, (1L << min(blob_pack_length,3)*8)-1L,
null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, 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) packlength(blob_pack_length),binary_flag(binary_arg), geom_flag(true)
{ {
flags|= BLOB_FLAG; flags|= BLOB_FLAG;
...@@ -3967,9 +3967,9 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)), ...@@ -3967,9 +3967,9 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
char *blob; char *blob;
memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob) 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 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; return val_ptr;
} }
...@@ -4782,7 +4782,8 @@ Field *make_field(char *ptr, uint32 field_length, ...@@ -4782,7 +4782,8 @@ Field *make_field(char *ptr, uint32 field_length,
if (f_is_blob(pack_flag)) if (f_is_blob(pack_flag))
return new Field_blob(ptr,null_pos,null_bit, return new Field_blob(ptr,null_pos,null_bit,
unireg_check, field_name, table, 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)) if (f_is_geom(pack_flag))
return new Field_geom(ptr,null_pos,null_bit, return new Field_geom(ptr,null_pos,null_bit,
unireg_check, field_name, table, unireg_check, field_name, table,
......
...@@ -842,11 +842,11 @@ class Field_blob :public Field_str { ...@@ -842,11 +842,11 @@ class Field_blob :public Field_str {
Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg, enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,uint blob_pack_length, 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, 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, :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) packlength(3),binary_flag(binary_arg), geom_flag(true)
{ {
flags|= BLOB_FLAG; flags|= BLOB_FLAG;
...@@ -930,11 +930,12 @@ class Field_geom :public Field_blob { ...@@ -930,11 +930,12 @@ class Field_geom :public Field_blob {
struct st_table *table_arg,uint blob_pack_length, struct st_table *table_arg,uint blob_pack_length,
bool binary_arg) bool binary_arg)
:Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_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, Field_geom(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)
:Field_blob(len_arg, maybe_null_arg, field_name_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; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY; }
void get_key_image(char *buff,uint length, imagetype type); void get_key_image(char *buff,uint length, imagetype type);
......
...@@ -508,7 +508,8 @@ void field_conv(Field *to,Field *from) ...@@ -508,7 +508,8 @@ void field_conv(Field *to,Field *from)
if (!blob->value.is_alloced() && if (!blob->value.is_alloced() &&
from->real_type() != FIELD_TYPE_STRING) from->real_type() != FIELD_TYPE_STRING)
blob->value.copy(); 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; return;
} }
if ((from->result_type() == STRING_RESULT && if ((from->result_type() == STRING_RESULT &&
......
...@@ -1799,7 +1799,7 @@ String *Item_func_conv_charset::val_str(String *str) ...@@ -1799,7 +1799,7 @@ String *Item_func_conv_charset::val_str(String *str)
s=(const uchar*)arg->ptr(); s=(const uchar*)arg->ptr();
se=s+arg->length(); 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); str->alloc(dmaxlen);
d0=d=(unsigned char*)str->ptr(); d0=d=(unsigned char*)str->ptr();
de=d+dmaxlen; de=d+dmaxlen;
...@@ -1841,7 +1841,7 @@ String *Item_func_conv_charset::val_str(String *str) ...@@ -1841,7 +1841,7 @@ String *Item_func_conv_charset::val_str(String *str)
void Item_func_conv_charset::fix_length_and_dec() 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 @@ String *Item_func_conv_charset3::val_str(String *str) ...@@ -1911,23 +1911,41 @@ String *Item_func_conv_charset3::val_str(String *str)
return str; 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()))) bool Item_func_conv_charset::fix_fields(THD *thd,struct st_table_list *tables)
return 0; {
str->copy(res->charset()->name,strlen(res->charset()->name)); char buff[STACK_BUFF_ALLOC]; // Max argument in function
return str; 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() 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) String *Item_func_hex::val_str(String *str)
......
...@@ -40,7 +40,8 @@ class Item_str_func :public Item_func ...@@ -40,7 +40,8 @@ class Item_str_func :public Item_func
if (!t_arg) if (!t_arg)
return result_field; return result_field;
return (max_length > 255) ? 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, (Field *) new Field_string(max_length,maybe_null, name,t_arg, binary,
default_charset_info); default_charset_info);
} }
...@@ -488,6 +489,7 @@ class Item_func_conv_charset :public Item_str_func ...@@ -488,6 +489,7 @@ class Item_func_conv_charset :public Item_str_func
{ {
conv_charset=cs; conv_charset=cs;
} }
bool fix_fields(THD *thd,struct st_table_list *tables);
String *val_str(String *); String *val_str(String *);
void fix_length_and_dec(); void fix_length_and_dec();
const char *func_name() const { return "conv_charset"; } const char *func_name() const { return "conv_charset"; }
......
...@@ -3523,7 +3523,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, ...@@ -3523,7 +3523,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
case STRING_RESULT: case STRING_RESULT:
if (item_sum->max_length > 255) if (item_sum->max_length > 255)
return new Field_blob(item_sum->max_length,maybe_null, 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, return new Field_string(item_sum->max_length,maybe_null,
item->name,table,item->binary,default_charset_info); 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, ...@@ -3576,7 +3576,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
case STRING_RESULT: case STRING_RESULT:
if (item->max_length > 255) if (item->max_length > 255)
new_field= new Field_blob(item->max_length,maybe_null, 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 else
new_field= new Field_string(item->max_length,maybe_null, new_field= new Field_string(item->max_length,maybe_null,
item->name,table,item->binary, item->name,table,item->binary,
...@@ -4104,7 +4105,9 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, ...@@ -4104,7 +4105,9 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
{ {
Field *field=keyinfo->key_part[i].field; Field *field=keyinfo->key_part[i].field;
seg->flag= 0; 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->length= keyinfo->key_part[i].length;
seg->start= keyinfo->key_part[i].offset; seg->start= keyinfo->key_part[i].offset;
if (field->flags & BLOB_FLAG) if (field->flags & BLOB_FLAG)
......
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