Commit f95eb829 authored by bar@bar.mysql.r18.ru's avatar bar@bar.mysql.r18.ru

stringcmp() and sortcmp() have been unified

into the only one sortcmp() with additional
CHARSET_INFO *cmp_charset argument.
parent 143c8505
...@@ -120,8 +120,8 @@ bool Item_string::eq(const Item *item, bool binary_cmp) const ...@@ -120,8 +120,8 @@ bool Item_string::eq(const Item *item, bool binary_cmp) const
if (type() == item->type()) if (type() == item->type())
{ {
if (binary_cmp) if (binary_cmp)
return !stringcmp(&str_value, &item->str_value); return !sortcmp(&str_value, &item->str_value, &my_charset_bin);
return !sortcmp(&str_value, &item->str_value); return !sortcmp(&str_value, &item->str_value, charset());
} }
return 0; return 0;
} }
...@@ -1355,7 +1355,7 @@ bool field_is_equal_to_item(Field *field,Item *item) ...@@ -1355,7 +1355,7 @@ bool field_is_equal_to_item(Field *field,Item *item)
if (item->null_value) if (item->null_value)
return 1; // This must be true return 1; // This must be true
field->val_str(&field_tmp,&field_tmp); field->val_str(&field_tmp,&field_tmp);
return !stringcmp(&field_tmp,item_result); return !sortcmp(&field_tmp,item_result,&my_charset_bin);
} }
if (res_type == INT_RESULT) if (res_type == INT_RESULT)
return 1; // Both where of type int return 1; // Both where of type int
......
...@@ -56,10 +56,8 @@ bool Item_str_buff::cmp(void) ...@@ -56,10 +56,8 @@ bool Item_str_buff::cmp(void)
} }
else if (null_value) else if (null_value)
return 0; // new and old value was null return 0; // new and old value was null
else if (!item->binary())
tmp= sortcmp(&value,res) != 0;
else else
tmp= stringcmp(&value,res) != 0; tmp= sortcmp(&value,res,item->charset()) != 0;
if (tmp) if (tmp)
value.copy(*res); // Remember for next cmp value.copy(*res); // Remember for next cmp
return tmp; return tmp;
......
...@@ -125,7 +125,9 @@ void Item_bool_func2::fix_length_and_dec() ...@@ -125,7 +125,9 @@ void Item_bool_func2::fix_length_and_dec()
} }
} }
set_cmp_func(); set_cmp_func();
binary_cmp= args[0]->binary() || args[1]->binary(); /* QQ: COERCIBILITY */
cmp_charset= (args[0]->binary() || args[1]->binary()) ?
&my_charset_bin : args[0]->charset();
} }
...@@ -167,7 +169,7 @@ int Arg_comparator::compare_string() ...@@ -167,7 +169,7 @@ int Arg_comparator::compare_string()
if ((res2= (*b)->val_str(&owner->tmp_value2))) if ((res2= (*b)->val_str(&owner->tmp_value2)))
{ {
owner->null_value= 0; owner->null_value= 0;
return owner->binary_cmp ? stringcmp(res1,res2) : sortcmp(res1,res2); return sortcmp(res1,res2,owner->cmp_charset);
} }
} }
owner->null_value= 1; owner->null_value= 1;
...@@ -181,8 +183,7 @@ int Arg_comparator::compare_e_string() ...@@ -181,8 +183,7 @@ int Arg_comparator::compare_e_string()
res2= (*b)->val_str(&owner->tmp_value2); res2= (*b)->val_str(&owner->tmp_value2);
if (!res1 || !res2) if (!res1 || !res2)
return test(res1 == res2); return test(res1 == res2);
return (owner->binary_cmp ? test(stringcmp(res1, res2) == 0) : return test(sortcmp(res1, res2, owner->cmp_charset) == 0);
test(sortcmp(res1, res2) == 0));
} }
...@@ -402,7 +403,7 @@ longlong Item_func_strcmp::val_int() ...@@ -402,7 +403,7 @@ longlong Item_func_strcmp::val_int()
null_value=1; null_value=1;
return 0; return 0;
} }
int value= binary_cmp ? stringcmp(a,b) : sortcmp(a,b); int value= sortcmp(a,b,cmp_charset);
null_value=0; null_value=0;
return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1); return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1);
} }
...@@ -482,10 +483,11 @@ void Item_func_between::fix_length_and_dec() ...@@ -482,10 +483,11 @@ void Item_func_between::fix_length_and_dec()
cmp_type=item_cmp_type(args[0]->result_type(), cmp_type=item_cmp_type(args[0]->result_type(),
item_cmp_type(args[1]->result_type(), item_cmp_type(args[1]->result_type(),
args[2]->result_type())); args[2]->result_type()));
/* QQ: COERCIBILITY */
if (args[0]->binary() | args[1]->binary() | args[2]->binary()) if (args[0]->binary() | args[1]->binary() | args[2]->binary())
string_compare=stringcmp; cmp_charset= &my_charset_bin;
else else
string_compare=sortcmp; cmp_charset= args[0]->charset();
/* /*
Make a special case of compare with date/time and longlong fields. Make a special case of compare with date/time and longlong fields.
...@@ -517,17 +519,17 @@ longlong Item_func_between::val_int() ...@@ -517,17 +519,17 @@ longlong Item_func_between::val_int()
a=args[1]->val_str(&value1); a=args[1]->val_str(&value1);
b=args[2]->val_str(&value2); b=args[2]->val_str(&value2);
if (!args[1]->null_value && !args[2]->null_value) if (!args[1]->null_value && !args[2]->null_value)
return (string_compare(value,a) >= 0 && string_compare(value,b) <= 0) ? return (sortcmp(value,a,cmp_charset) >= 0 &&
1 : 0; sortcmp(value,b,cmp_charset) <= 0) ? 1 : 0;
if (args[1]->null_value && args[2]->null_value) if (args[1]->null_value && args[2]->null_value)
null_value=1; null_value=1;
else if (args[1]->null_value) else if (args[1]->null_value)
{ {
null_value= string_compare(value,b) <= 0; // not null if false range. null_value= sortcmp(value,b,cmp_charset) <= 0; // not null if false range.
} }
else else
{ {
null_value= string_compare(value,a) >= 0; // not null if false range. null_value= sortcmp(value,a,cmp_charset) >= 0; // not null if false range.
} }
} }
else if (cmp_type == INT_RESULT) else if (cmp_type == INT_RESULT)
...@@ -809,12 +811,13 @@ Item *Item_func_case::find_item(String *str) ...@@ -809,12 +811,13 @@ Item *Item_func_case::find_item(String *str)
} }
if ((tmp=args[i]->val_str(str))) // If not null if ((tmp=args[i]->val_str(str))) // If not null
{ {
/* QQ: COERCIBILITY */
if (first_expr_is_binary || args[i]->binary()) if (first_expr_is_binary || args[i]->binary())
{ {
if (stringcmp(tmp,first_expr_str)==0) if (sortcmp(tmp,first_expr_str,&my_charset_bin)==0)
return args[i+1]; return args[i+1];
} }
else if (sortcmp(tmp,first_expr_str)==0) else if (sortcmp(tmp,first_expr_str,tmp->charset())==0)
return args[i+1]; return args[i+1];
} }
break; break;
...@@ -1211,10 +1214,7 @@ cmp_item* cmp_item::get_comparator(Item *item) ...@@ -1211,10 +1214,7 @@ cmp_item* cmp_item::get_comparator(Item *item)
{ {
switch (item->result_type()) { switch (item->result_type()) {
case STRING_RESULT: case STRING_RESULT:
if (item->binary()) return new cmp_item_sort_string(item->charset());
return new cmp_item_binary_string;
else
return new cmp_item_sort_string;
break; break;
case INT_RESULT: case INT_RESULT:
return new cmp_item_int; return new cmp_item_int;
...@@ -1234,12 +1234,7 @@ cmp_item* cmp_item::get_comparator(Item *item) ...@@ -1234,12 +1234,7 @@ cmp_item* cmp_item::get_comparator(Item *item)
cmp_item* cmp_item_sort_string::make_same() cmp_item* cmp_item_sort_string::make_same()
{ {
return new cmp_item_sort_string_in_static(); return new cmp_item_sort_string_in_static(cmp_charset);
}
cmp_item* cmp_item_binary_string::make_same()
{
return new cmp_item_binary_string_in_static();
} }
cmp_item* cmp_item_int::make_same() cmp_item* cmp_item_int::make_same()
...@@ -1346,6 +1341,22 @@ bool Item_func_in::nulls_in_row() ...@@ -1346,6 +1341,22 @@ bool Item_func_in::nulls_in_row()
return 0; return 0;
} }
static int srtcmp_in(const String *x,const String *y)
{
CHARSET_INFO *cs= x->charset();
return cs->strnncollsp(cs,
(unsigned char *) x->ptr(),x->length(),
(unsigned char *) y->ptr(),y->length());
}
static int bincmp_in(const String *x,const String *y)
{
CHARSET_INFO *cs= &my_charset_bin;
return cs->strnncollsp(cs,
(unsigned char *) x->ptr(),x->length(),
(unsigned char *) y->ptr(),y->length());
}
void Item_func_in::fix_length_and_dec() void Item_func_in::fix_length_and_dec()
{ {
/* /*
...@@ -1357,9 +1368,9 @@ void Item_func_in::fix_length_and_dec() ...@@ -1357,9 +1368,9 @@ void Item_func_in::fix_length_and_dec()
switch (item->result_type()) { switch (item->result_type()) {
case STRING_RESULT: case STRING_RESULT:
if (item->binary()) if (item->binary())
array=new in_string(arg_count,(qsort_cmp) stringcmp); array=new in_string(arg_count,(qsort_cmp) srtcmp_in);
else else
array=new in_string(arg_count,(qsort_cmp) sortcmp); array=new in_string(arg_count,(qsort_cmp) bincmp_in);
break; break;
case INT_RESULT: case INT_RESULT:
array= new in_longlong(arg_count); array= new in_longlong(arg_count);
...@@ -1759,8 +1770,9 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref) ...@@ -1759,8 +1770,9 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
/* /*
Comparision is by default done according to character set of LIKE Comparision is by default done according to character set of LIKE
QQ: COERCIBILITY
*/ */
if (binary_cmp) if (cmp_charset == &my_charset_bin)
set_charset(&my_charset_bin); set_charset(&my_charset_bin);
else else
set_charset(args[1]->charset()); set_charset(args[1]->charset());
...@@ -1877,7 +1889,7 @@ longlong Item_func_regex::val_int() ...@@ -1877,7 +1889,7 @@ longlong Item_func_regex::val_int()
null_value=1; null_value=1;
return 0; return 0;
} }
if (!regex_compiled || stringcmp(res2,&prev_regexp)) if (!regex_compiled || sortcmp(res2,&prev_regexp,&my_charset_bin))
{ {
prev_regexp.copy(*res2); prev_regexp.copy(*res2);
if (regex_compiled) if (regex_compiled)
...@@ -1936,7 +1948,7 @@ void Item_func_like::turboBM_compute_suffixes(int *suff) ...@@ -1936,7 +1948,7 @@ void Item_func_like::turboBM_compute_suffixes(int *suff)
*splm1 = pattern_len; *splm1 = pattern_len;
if (binary_cmp) if (cmp_charset == &my_charset_bin)
{ {
int i; int i;
for (i = pattern_len - 2; i >= 0; i--) for (i = pattern_len - 2; i >= 0; i--)
...@@ -2039,7 +2051,7 @@ void Item_func_like::turboBM_compute_bad_character_shifts() ...@@ -2039,7 +2051,7 @@ void Item_func_like::turboBM_compute_bad_character_shifts()
for (i = bmBc; i < end; i++) for (i = bmBc; i < end; i++)
*i = pattern_len; *i = pattern_len;
if (binary_cmp) if (cmp_charset == &my_charset_bin)
{ {
for (j = 0; j < plm1; j++) for (j = 0; j < plm1; j++)
bmBc[(uint) (uchar) pattern[j]] = plm1 - j; bmBc[(uint) (uchar) pattern[j]] = plm1 - j;
...@@ -2070,7 +2082,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const ...@@ -2070,7 +2082,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
const int tlmpl= text_len - pattern_len; const int tlmpl= text_len - pattern_len;
/* Searching */ /* Searching */
if (binary_cmp) if (cmp_charset == &my_charset_bin)
{ {
while (j <= tlmpl) while (j <= tlmpl)
{ {
......
...@@ -112,7 +112,7 @@ class Item_bool_func2 :public Item_int_func ...@@ -112,7 +112,7 @@ class Item_bool_func2 :public Item_int_func
protected: protected:
Arg_comparator cmp; Arg_comparator cmp;
String tmp_value1,tmp_value2; String tmp_value1,tmp_value2;
bool binary_cmp; CHARSET_INFO *cmp_charset;
public: public:
Item_bool_func2(Item *a,Item *b): Item_bool_func2(Item *a,Item *b):
...@@ -127,7 +127,7 @@ class Item_bool_func2 :public Item_int_func ...@@ -127,7 +127,7 @@ class Item_bool_func2 :public Item_int_func
bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; } bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
void print(String *str) { Item_func::print_op(str); } void print(String *str) { Item_func::print_op(str); }
bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); } bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
virtual bool binary() const { return binary_cmp; } virtual bool binary() const { return test(cmp_charset->state & MY_CS_BINSORT); }
static Item_bool_func2* eq_creator(Item *a, Item *b); static Item_bool_func2* eq_creator(Item *a, Item *b);
static Item_bool_func2* ne_creator(Item *a, Item *b); static Item_bool_func2* ne_creator(Item *a, Item *b);
...@@ -242,7 +242,7 @@ class Item_func_ne :public Item_bool_rowready_func2 ...@@ -242,7 +242,7 @@ class Item_func_ne :public Item_bool_rowready_func2
class Item_func_between :public Item_int_func class Item_func_between :public Item_int_func
{ {
int (*string_compare)(const String *x,const String *y); CHARSET_INFO *cmp_charset;
public: public:
Item_result cmp_type; Item_result cmp_type;
String value0,value1,value2; String value0,value1,value2;
...@@ -263,7 +263,9 @@ class Item_func_strcmp :public Item_bool_func2 ...@@ -263,7 +263,9 @@ class Item_func_strcmp :public Item_bool_func2
void fix_length_and_dec() void fix_length_and_dec()
{ {
max_length=2; max_length=2;
binary_cmp= args[0]->binary() || args[1]->binary(); /* QQ: COERCIBILITY */
cmp_charset= args[0]->binary() || args[1]->binary() ?
&my_charset_bin : args[0]->charset();
} }
optimize_type select_optimize() const { return OPTIMIZE_NONE; } optimize_type select_optimize() const { return OPTIMIZE_NONE; }
const char *func_name() const { return "strcmp"; } const char *func_name() const { return "strcmp"; }
...@@ -439,7 +441,8 @@ class in_double :public in_vector ...@@ -439,7 +441,8 @@ class in_double :public in_vector
class cmp_item :public Sql_alloc class cmp_item :public Sql_alloc
{ {
public: public:
cmp_item() {} CHARSET_INFO *cmp_charset;
cmp_item() { cmp_charset= &my_charset_bin; }
virtual ~cmp_item() {} virtual ~cmp_item() {}
virtual void store_value(Item *item)= 0; virtual void store_value(Item *item)= 0;
virtual int cmp(Item *item)= 0; virtual int cmp(Item *item)= 0;
...@@ -453,18 +456,14 @@ class cmp_item :public Sql_alloc ...@@ -453,18 +456,14 @@ class cmp_item :public Sql_alloc
} }
}; };
typedef int (*str_cmp_func_pointer)(const String *, const String *);
class cmp_item_string :public cmp_item class cmp_item_string :public cmp_item
{ {
protected: protected:
str_cmp_func_pointer str_cmp_func;
String *value_res; String *value_res;
public: public:
cmp_item_string (str_cmp_func_pointer cmp): str_cmp_func(cmp) {} cmp_item_string (CHARSET_INFO *cs) { cmp_charset= cs; }
friend class cmp_item_sort_string; friend class cmp_item_sort_string;
friend class cmp_item_binary_string;
friend class cmp_item_sort_string_in_static; friend class cmp_item_sort_string_in_static;
friend class cmp_item_binary_string_in_static;
}; };
class cmp_item_sort_string :public cmp_item_string class cmp_item_sort_string :public cmp_item_string
...@@ -473,12 +472,9 @@ class cmp_item_sort_string :public cmp_item_string ...@@ -473,12 +472,9 @@ class cmp_item_sort_string :public cmp_item_string
char value_buff[80]; char value_buff[80];
String value; String value;
public: public:
cmp_item_sort_string(str_cmp_func_pointer cmp): cmp_item_sort_string(CHARSET_INFO *cs):
cmp_item_string(cmp), cmp_item_string(cs),
value(value_buff, sizeof(value_buff), default_charset_info) {} value(value_buff, sizeof(value_buff), cs) {}
cmp_item_sort_string():
cmp_item_string(&sortcmp),
value(value_buff, sizeof(value_buff), default_charset_info) {}
void store_value(Item *item) void store_value(Item *item)
{ {
value_res= item->val_str(&value); value_res= item->val_str(&value);
...@@ -489,22 +485,16 @@ class cmp_item_sort_string :public cmp_item_string ...@@ -489,22 +485,16 @@ class cmp_item_sort_string :public cmp_item_string
String tmp(buff, sizeof(buff), default_charset_info), *res; String tmp(buff, sizeof(buff), default_charset_info), *res;
if (!(res= arg->val_str(&tmp))) if (!(res= arg->val_str(&tmp)))
return 1; /* Can't be right */ return 1; /* Can't be right */
return (*str_cmp_func)(value_res, res); return sortcmp(value_res, res, cmp_charset);
} }
int compare(cmp_item *c) int compare(cmp_item *c)
{ {
cmp_item_string *cmp= (cmp_item_string *)c; cmp_item_string *cmp= (cmp_item_string *)c;
return (*str_cmp_func)(value_res, cmp->value_res); return sortcmp(value_res, cmp->value_res, cmp_charset);
} }
cmp_item *make_same(); cmp_item *make_same();
}; };
class cmp_item_binary_string :public cmp_item_sort_string {
public:
cmp_item_binary_string(): cmp_item_sort_string(&stringcmp) {}
cmp_item *make_same();
};
class cmp_item_int :public cmp_item class cmp_item_int :public cmp_item
{ {
longlong value; longlong value;
...@@ -590,9 +580,8 @@ class cmp_item_sort_string_in_static :public cmp_item_string ...@@ -590,9 +580,8 @@ class cmp_item_sort_string_in_static :public cmp_item_string
protected: protected:
String value; String value;
public: public:
cmp_item_sort_string_in_static(str_cmp_func_pointer cmp): cmp_item_sort_string_in_static(CHARSET_INFO *cs):
cmp_item_string(cmp) {} cmp_item_string(cs) {}
cmp_item_sort_string_in_static(): cmp_item_string(&sortcmp) {}
void store_value(Item *item) void store_value(Item *item)
{ {
value_res= item->val_str(&value); value_res= item->val_str(&value);
...@@ -606,21 +595,11 @@ class cmp_item_sort_string_in_static :public cmp_item_string ...@@ -606,21 +595,11 @@ class cmp_item_sort_string_in_static :public cmp_item_string
int compare(cmp_item *c) int compare(cmp_item *c)
{ {
cmp_item_string *cmp= (cmp_item_string *)c; cmp_item_string *cmp= (cmp_item_string *)c;
return (*str_cmp_func)(value_res, cmp->value_res); return sortcmp(value_res, cmp->value_res, cmp_charset);
} }
cmp_item * make_same() cmp_item * make_same()
{ {
return new cmp_item_sort_string_in_static(); return new cmp_item_sort_string_in_static(cmp_charset);
}
};
class cmp_item_binary_string_in_static :public cmp_item_sort_string_in_static {
public:
cmp_item_binary_string_in_static():
cmp_item_sort_string_in_static(&stringcmp) {}
cmp_item * make_same()
{
return new cmp_item_binary_string_in_static();
} }
}; };
......
...@@ -107,7 +107,7 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -107,7 +107,7 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 0; // Fatal error if flag is set! return 0; // Fatal error if flag is set!
if (arg_count) if (arg_count)
{ // Print purify happy { // Print purify happy
coercibility= COER_NOCOLL; bool first_coll= 1;
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++) for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
{ {
if ((*arg)->fix_fields(thd, tables, arg) || if ((*arg)->fix_fields(thd, tables, arg) ||
...@@ -122,15 +122,17 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -122,15 +122,17 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
Set return character set to first argument if we are returning a Set return character set to first argument if we are returning a
string. string.
*/ */
if ((*arg)->binary()) if (first_coll)
{ {
set_charset(&my_charset_bin); set_charset((*arg)->charset());
coercibility= COER_NOCOLL; coercibility= (*args)->coercibility;
first_coll= 0;
} }
else if (coercibility== COER_NOCOLL) else if ((*arg)->charset() == &my_charset_bin ||
charset() == &my_charset_bin)
{ {
coercibility= (*arg)->coercibility; set_charset(&my_charset_bin);
set_charset((*arg)->charset()); coercibility= COER_NOCOLL;
} }
else if ((*arg)->coercibility < coercibility) else if ((*arg)->coercibility < coercibility)
{ {
...@@ -864,6 +866,7 @@ void Item_func_min_max::fix_length_and_dec() ...@@ -864,6 +866,7 @@ void Item_func_min_max::fix_length_and_dec()
max_length=0; max_length=0;
maybe_null=1; maybe_null=1;
cmp_type=args[0]->result_type(); cmp_type=args[0]->result_type();
for (uint i=0 ; i < arg_count ; i++) for (uint i=0 ; i < arg_count ; i++)
{ {
if (max_length < args[i]->max_length) if (max_length < args[i]->max_length)
...@@ -873,11 +876,11 @@ void Item_func_min_max::fix_length_and_dec() ...@@ -873,11 +876,11 @@ void Item_func_min_max::fix_length_and_dec()
if (!args[i]->maybe_null) if (!args[i]->maybe_null)
maybe_null=0; maybe_null=0;
cmp_type=item_cmp_type(cmp_type,args[i]->result_type()); cmp_type=item_cmp_type(cmp_type,args[i]->result_type());
if (args[i]->binary()) if (i==0)
set_charset(args[i]->charset());
else if (args[i]->charset() == &my_charset_bin)
set_charset(&my_charset_bin); set_charset(&my_charset_bin);
} }
if (cmp_type == STRING_RESULT)
str_cmp_function= binary() ? stringcmp : sortcmp;
} }
...@@ -922,7 +925,7 @@ String *Item_func_min_max::val_str(String *str) ...@@ -922,7 +925,7 @@ String *Item_func_min_max::val_str(String *str)
res2= args[i]->val_str(res == str ? &tmp_value : str); res2= args[i]->val_str(res == str ? &tmp_value : str);
if (res2) if (res2)
{ {
int cmp= (*str_cmp_function)(res,res2); int cmp= sortcmp(res,res2,charset());
if ((cmp_sign < 0 ? cmp : -cmp) < 0) if ((cmp_sign < 0 ? cmp : -cmp) < 0)
res=res2; res=res2;
} }
......
...@@ -524,7 +524,6 @@ class Item_func_min_max :public Item_func ...@@ -524,7 +524,6 @@ class Item_func_min_max :public Item_func
Item_result cmp_type; Item_result cmp_type;
String tmp_value; String tmp_value;
int cmp_sign; int cmp_sign;
int (*str_cmp_function)(const String *x,const String *y);
public: public:
Item_func_min_max(List<Item> &list,int cmp_sign_arg) :Item_func(list), Item_func_min_max(List<Item> &list,int cmp_sign_arg) :Item_func(list),
cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg) {} cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg) {}
......
...@@ -183,12 +183,17 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -183,12 +183,17 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 1; return 1;
hybrid_type=item->result_type(); hybrid_type=item->result_type();
if (hybrid_type == INT_RESULT) if (hybrid_type == INT_RESULT)
{
cmp_charset= &my_charset_bin;
max_length=20; max_length=20;
}
else if (hybrid_type == REAL_RESULT) else if (hybrid_type == REAL_RESULT)
{
cmp_charset= &my_charset_bin;
max_length=float_length(decimals); max_length=float_length(decimals);
else }else
{ {
str_cmp_function= item->binary() ? stringcmp : sortcmp; cmp_charset= item->charset();
max_length=item->max_length; max_length=item->max_length;
} }
decimals=item->decimals; decimals=item->decimals;
...@@ -440,7 +445,7 @@ bool Item_sum_min::add() ...@@ -440,7 +445,7 @@ bool Item_sum_min::add()
{ {
String *result=args[0]->val_str(&tmp_value); String *result=args[0]->val_str(&tmp_value);
if (!args[0]->null_value && if (!args[0]->null_value &&
(null_value || (*str_cmp_function)(&value,result) > 0)) (null_value || sortcmp(&value,result,cmp_charset) > 0))
{ {
value.copy(*result); value.copy(*result);
null_value=0; null_value=0;
...@@ -487,7 +492,7 @@ bool Item_sum_max::add() ...@@ -487,7 +492,7 @@ bool Item_sum_max::add()
{ {
String *result=args[0]->val_str(&tmp_value); String *result=args[0]->val_str(&tmp_value);
if (!args[0]->null_value && if (!args[0]->null_value &&
(null_value || (*str_cmp_function)(&value,result) < 0)) (null_value || sortcmp(&value,result,cmp_charset) < 0))
{ {
value.copy(*result); value.copy(*result);
null_value=0; null_value=0;
...@@ -762,7 +767,7 @@ Item_sum_hybrid::min_max_update_str_field(int offset) ...@@ -762,7 +767,7 @@ Item_sum_hybrid::min_max_update_str_field(int offset)
result_field->ptr-=offset; result_field->ptr-=offset;
if (result_field->is_null() || if (result_field->is_null() ||
(cmp_sign * (*str_cmp_function)(res_str,&tmp_value)) < 0) (cmp_sign * sortcmp(res_str,&tmp_value,cmp_charset)) < 0)
result_field->store(res_str->ptr(),res_str->length(),res_str->charset()); result_field->store(res_str->ptr(),res_str->length(),res_str->charset());
else else
{ // Use old value { // Use old value
......
...@@ -369,17 +369,19 @@ class Item_sum_hybrid :public Item_sum ...@@ -369,17 +369,19 @@ class Item_sum_hybrid :public Item_sum
enum_field_types hybrid_field_type; enum_field_types hybrid_field_type;
int cmp_sign; int cmp_sign;
table_map used_table_cache; table_map used_table_cache;
int (*str_cmp_function)(const String *x,const String *y); CHARSET_INFO *cmp_charset;
public: public:
Item_sum_hybrid(Item *item_par,int sign) Item_sum_hybrid(Item *item_par,int sign)
:Item_sum(item_par), hybrid_type(INT_RESULT), cmp_sign(sign), :Item_sum(item_par), hybrid_type(INT_RESULT), cmp_sign(sign),
used_table_cache(~(table_map) 0) used_table_cache(~(table_map) 0),
cmp_charset(&my_charset_bin)
{} {}
Item_sum_hybrid(THD *thd, Item_sum_hybrid &item): Item_sum_hybrid(THD *thd, Item_sum_hybrid &item):
Item_sum(thd, item), value(item.value), tmp_value(item.tmp_value), Item_sum(thd, item), value(item.value), tmp_value(item.tmp_value),
sum(item.sum), sum_int(item.sum_int), hybrid_type(item.hybrid_type), sum(item.sum), sum_int(item.sum_int), hybrid_type(item.hybrid_type),
cmp_sign(item.cmp_sign), used_table_cache(used_table_cache) {} cmp_sign(item.cmp_sign), used_table_cache(used_table_cache),
cmp_charset(item.cmp_charset) {}
bool fix_fields(THD *, TABLE_LIST *, Item **); bool fix_fields(THD *, TABLE_LIST *, Item **);
table_map used_tables() const { return used_table_cache; } table_map used_tables() const { return used_table_cache; }
bool const_item() const { return !used_table_cache; } bool const_item() const { return !used_table_cache; }
......
...@@ -41,13 +41,13 @@ ...@@ -41,13 +41,13 @@
int sortcmp2(void* cmp_arg __attribute__((unused)), int sortcmp2(void* cmp_arg __attribute__((unused)),
const String *a,const String *b) const String *a,const String *b)
{ {
return sortcmp(a,b); return sortcmp(a,b,a->charset());
} }
int stringcmp2(void* cmp_arg __attribute__((unused)), int stringcmp2(void* cmp_arg __attribute__((unused)),
const String *a,const String *b) const String *a,const String *b)
{ {
return stringcmp(a,b); return sortcmp(a,b,&my_charset_bin);
} }
int compare_double2(void* cmp_arg __attribute__((unused)), int compare_double2(void* cmp_arg __attribute__((unused)),
...@@ -329,21 +329,11 @@ void field_str::add() ...@@ -329,21 +329,11 @@ void field_str::add()
if (length > max_length) if (length > max_length)
max_length = length; max_length = length;
if (item->binary()) if (sortcmp(res, &min_arg,item->charset()) < 0)
{
if (stringcmp(res, &min_arg) < 0)
min_arg.copy(*res);
if (stringcmp(res, &max_arg) > 0)
max_arg.copy(*res);
}
else
{
if (sortcmp(res, &min_arg) < 0)
min_arg.copy(*res); min_arg.copy(*res);
if (sortcmp(res, &max_arg) > 0) if (sortcmp(res, &max_arg,item->charset()) > 0)
max_arg.copy(*res); max_arg.copy(*res);
} }
}
if (room_in_tree) if (room_in_tree)
{ {
......
...@@ -538,30 +538,14 @@ void String::qs_append(const char &c) ...@@ -538,30 +538,14 @@ void String::qs_append(const char &c)
} }
int sortcmp(const String *x,const String *y) int sortcmp(const String *x,const String *y, CHARSET_INFO *cs)
{ {
CHARSET_INFO *cs= x->str_charset;
return cs->strnncollsp(cs, return cs->strnncollsp(cs,
(unsigned char *) x->ptr(),x->length(), (unsigned char *) x->ptr(),x->length(),
(unsigned char *) y->ptr(),y->length()); (unsigned char *) y->ptr(),y->length());
} }
int stringcmp(const String *x,const String *y)
{
const char *s= x->ptr();
const char *t= y->ptr();
uint32 x_len=x->length(),y_len=y->length(),len=min(x_len,y_len);
while (len--)
{
if (*s++ != *t++)
return ((int) (uchar) s[-1] - (int) (uchar) t[-1]);
}
return (int) (x_len-y_len);
}
String *copy_if_not_alloced(String *to,String *from,uint32 from_length) String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
{ {
if (from->Alloced_length >= from_length) if (from->Alloced_length >= from_length)
......
...@@ -25,8 +25,7 @@ ...@@ -25,8 +25,7 @@
#endif #endif
class String; class String;
int sortcmp(const String *a,const String *b); int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
int stringcmp(const String *a,const String *b);
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
class String class String
...@@ -205,8 +204,7 @@ class String ...@@ -205,8 +204,7 @@ class String
void strip_sp(); void strip_sp();
inline void caseup() { my_caseup(str_charset,Ptr,str_length); } inline void caseup() { my_caseup(str_charset,Ptr,str_length); }
inline void casedn() { my_casedn(str_charset,Ptr,str_length); } inline void casedn() { my_casedn(str_charset,Ptr,str_length); }
friend int sortcmp(const String *a,const String *b); friend int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
friend int stringcmp(const String *a,const String *b);
friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
uint32 numchars(); uint32 numchars();
int charpos(int i,uint32 offset=0); int charpos(int i,uint32 offset=0);
......
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