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)
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)
......
......@@ -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,
......
......@@ -842,11 +842,11 @@ class Field_blob :public Field_str {
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 @@ class Field_geom :public Field_blob {
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);
......
......@@ -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 &&
......
......@@ -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 @@ String *Item_func_conv_charset::val_str(String *str)
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)
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)
......
......@@ -40,7 +40,8 @@ class Item_str_func :public Item_func
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 @@ class Item_func_conv_charset :public Item_str_func
{
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"; }
......
......@@ -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)
......
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