summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--myisam/mi_unique.c35
-rw-r--r--sql/field.cc11
-rw-r--r--sql/field.h11
-rw-r--r--sql/field_conv.cc3
-rw-r--r--sql/item_strfunc.cc38
-rw-r--r--sql/item_strfunc.h4
-rw-r--r--sql/sql_select.cc9
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)