diff options
author | unknown <bar@bar.mysql.r18.ru> | 2003-03-04 18:01:59 +0400 |
---|---|---|
committer | unknown <bar@bar.mysql.r18.ru> | 2003-03-04 18:01:59 +0400 |
commit | 3cbb978d51ce694c941671f8bc4efd673d80e4e0 (patch) | |
tree | ec01d4c8c14546cc3ecf4ff069124834d4ee8959 /sql | |
parent | 9dfa4eb60af7661e613f900d620de15d29bce54b (diff) | |
download | mariadb-git-3cbb978d51ce694c941671f8bc4efd673d80e4e0.tar.gz |
stringcmp() and sortcmp() have been unified
into the only one sortcmp() with additional
CHARSET_INFO *cmp_charset argument.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.cc | 6 | ||||
-rw-r--r-- | sql/item_buff.cc | 4 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 72 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 57 | ||||
-rw-r--r-- | sql/item_func.cc | 25 | ||||
-rw-r--r-- | sql/item_func.h | 1 | ||||
-rw-r--r-- | sql/item_sum.cc | 15 | ||||
-rw-r--r-- | sql/item_sum.h | 8 | ||||
-rw-r--r-- | sql/sql_analyse.cc | 22 | ||||
-rw-r--r-- | sql/sql_string.cc | 18 | ||||
-rw-r--r-- | sql/sql_string.h | 6 |
11 files changed, 102 insertions, 132 deletions
diff --git a/sql/item.cc b/sql/item.cc index decd0ec044b..3c6b85e933b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -120,8 +120,8 @@ bool Item_string::eq(const Item *item, bool binary_cmp) const if (type() == item->type()) { if (binary_cmp) - return !stringcmp(&str_value, &item->str_value); - return !sortcmp(&str_value, &item->str_value); + return !sortcmp(&str_value, &item->str_value, &my_charset_bin); + return !sortcmp(&str_value, &item->str_value, charset()); } return 0; } @@ -1355,7 +1355,7 @@ bool field_is_equal_to_item(Field *field,Item *item) if (item->null_value) return 1; // This must be true 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) return 1; // Both where of type int diff --git a/sql/item_buff.cc b/sql/item_buff.cc index 573d4ab17e3..c4431294dff 100644 --- a/sql/item_buff.cc +++ b/sql/item_buff.cc @@ -56,10 +56,8 @@ bool Item_str_buff::cmp(void) } else if (null_value) return 0; // new and old value was null - else if (!item->binary()) - tmp= sortcmp(&value,res) != 0; else - tmp= stringcmp(&value,res) != 0; + tmp= sortcmp(&value,res,item->charset()) != 0; if (tmp) value.copy(*res); // Remember for next cmp return tmp; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 7ff36bb32ed..3ca3a556658 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -125,7 +125,9 @@ void Item_bool_func2::fix_length_and_dec() } } 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() if ((res2= (*b)->val_str(&owner->tmp_value2))) { 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; @@ -181,8 +183,7 @@ int Arg_comparator::compare_e_string() res2= (*b)->val_str(&owner->tmp_value2); if (!res1 || !res2) return test(res1 == res2); - return (owner->binary_cmp ? test(stringcmp(res1, res2) == 0) : - test(sortcmp(res1, res2) == 0)); + return test(sortcmp(res1, res2, owner->cmp_charset) == 0); } @@ -402,7 +403,7 @@ longlong Item_func_strcmp::val_int() null_value=1; return 0; } - int value= binary_cmp ? stringcmp(a,b) : sortcmp(a,b); + int value= sortcmp(a,b,cmp_charset); null_value=0; return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1); } @@ -482,10 +483,11 @@ void Item_func_between::fix_length_and_dec() cmp_type=item_cmp_type(args[0]->result_type(), item_cmp_type(args[1]->result_type(), args[2]->result_type())); + /* QQ: COERCIBILITY */ if (args[0]->binary() | args[1]->binary() | args[2]->binary()) - string_compare=stringcmp; + cmp_charset= &my_charset_bin; else - string_compare=sortcmp; + cmp_charset= args[0]->charset(); /* Make a special case of compare with date/time and longlong fields. @@ -517,17 +519,17 @@ longlong Item_func_between::val_int() a=args[1]->val_str(&value1); b=args[2]->val_str(&value2); if (!args[1]->null_value && !args[2]->null_value) - return (string_compare(value,a) >= 0 && string_compare(value,b) <= 0) ? - 1 : 0; + return (sortcmp(value,a,cmp_charset) >= 0 && + sortcmp(value,b,cmp_charset) <= 0) ? 1 : 0; if (args[1]->null_value && args[2]->null_value) null_value=1; 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 { - 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) @@ -809,12 +811,13 @@ Item *Item_func_case::find_item(String *str) } if ((tmp=args[i]->val_str(str))) // If not null { + /* QQ: COERCIBILITY */ 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]; } - else if (sortcmp(tmp,first_expr_str)==0) + else if (sortcmp(tmp,first_expr_str,tmp->charset())==0) return args[i+1]; } break; @@ -1211,10 +1214,7 @@ cmp_item* cmp_item::get_comparator(Item *item) { switch (item->result_type()) { case STRING_RESULT: - if (item->binary()) - return new cmp_item_binary_string; - else - return new cmp_item_sort_string; + return new cmp_item_sort_string(item->charset()); break; case INT_RESULT: return new cmp_item_int; @@ -1234,12 +1234,7 @@ cmp_item* cmp_item::get_comparator(Item *item) cmp_item* cmp_item_sort_string::make_same() { - return new cmp_item_sort_string_in_static(); -} - -cmp_item* cmp_item_binary_string::make_same() -{ - return new cmp_item_binary_string_in_static(); + return new cmp_item_sort_string_in_static(cmp_charset); } cmp_item* cmp_item_int::make_same() @@ -1346,6 +1341,22 @@ bool Item_func_in::nulls_in_row() 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() { /* @@ -1357,9 +1368,9 @@ void Item_func_in::fix_length_and_dec() switch (item->result_type()) { case STRING_RESULT: if (item->binary()) - array=new in_string(arg_count,(qsort_cmp) stringcmp); + array=new in_string(arg_count,(qsort_cmp) srtcmp_in); else - array=new in_string(arg_count,(qsort_cmp) sortcmp); + array=new in_string(arg_count,(qsort_cmp) bincmp_in); break; case INT_RESULT: array= new in_longlong(arg_count); @@ -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 + QQ: COERCIBILITY */ - if (binary_cmp) + if (cmp_charset == &my_charset_bin) set_charset(&my_charset_bin); else set_charset(args[1]->charset()); @@ -1877,7 +1889,7 @@ longlong Item_func_regex::val_int() null_value=1; return 0; } - if (!regex_compiled || stringcmp(res2,&prev_regexp)) + if (!regex_compiled || sortcmp(res2,&prev_regexp,&my_charset_bin)) { prev_regexp.copy(*res2); if (regex_compiled) @@ -1936,7 +1948,7 @@ void Item_func_like::turboBM_compute_suffixes(int *suff) *splm1 = pattern_len; - if (binary_cmp) + if (cmp_charset == &my_charset_bin) { int i; for (i = pattern_len - 2; i >= 0; i--) @@ -2039,7 +2051,7 @@ void Item_func_like::turboBM_compute_bad_character_shifts() for (i = bmBc; i < end; i++) *i = pattern_len; - if (binary_cmp) + if (cmp_charset == &my_charset_bin) { for (j = 0; 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 const int tlmpl= text_len - pattern_len; /* Searching */ - if (binary_cmp) + if (cmp_charset == &my_charset_bin) { while (j <= tlmpl) { diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index c05d0317341..cc0ce455019 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -112,7 +112,7 @@ class Item_bool_func2 :public Item_int_func protected: Arg_comparator cmp; String tmp_value1,tmp_value2; - bool binary_cmp; + CHARSET_INFO *cmp_charset; public: Item_bool_func2(Item *a,Item *b): @@ -127,7 +127,7 @@ public: bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; } void print(String *str) { Item_func::print_op(str); } 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* ne_creator(Item *a, Item *b); @@ -242,7 +242,7 @@ public: class Item_func_between :public Item_int_func { - int (*string_compare)(const String *x,const String *y); + CHARSET_INFO *cmp_charset; public: Item_result cmp_type; String value0,value1,value2; @@ -263,7 +263,9 @@ public: void fix_length_and_dec() { 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; } const char *func_name() const { return "strcmp"; } @@ -439,7 +441,8 @@ public: class cmp_item :public Sql_alloc { public: - cmp_item() {} + CHARSET_INFO *cmp_charset; + cmp_item() { cmp_charset= &my_charset_bin; } virtual ~cmp_item() {} virtual void store_value(Item *item)= 0; virtual int cmp(Item *item)= 0; @@ -453,18 +456,14 @@ public: } }; -typedef int (*str_cmp_func_pointer)(const String *, const String *); class cmp_item_string :public cmp_item { protected: - str_cmp_func_pointer str_cmp_func; String *value_res; 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_binary_string; 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 @@ -473,12 +472,9 @@ protected: char value_buff[80]; String value; public: - cmp_item_sort_string(str_cmp_func_pointer cmp): - cmp_item_string(cmp), - value(value_buff, sizeof(value_buff), default_charset_info) {} - cmp_item_sort_string(): - cmp_item_string(&sortcmp), - value(value_buff, sizeof(value_buff), default_charset_info) {} + cmp_item_sort_string(CHARSET_INFO *cs): + cmp_item_string(cs), + value(value_buff, sizeof(value_buff), cs) {} void store_value(Item *item) { value_res= item->val_str(&value); @@ -489,22 +485,16 @@ public: String tmp(buff, sizeof(buff), default_charset_info), *res; if (!(res= arg->val_str(&tmp))) 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) { 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(); }; -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 { longlong value; @@ -590,9 +580,8 @@ class cmp_item_sort_string_in_static :public cmp_item_string protected: String value; public: - cmp_item_sort_string_in_static(str_cmp_func_pointer cmp): - cmp_item_string(cmp) {} - cmp_item_sort_string_in_static(): cmp_item_string(&sortcmp) {} + cmp_item_sort_string_in_static(CHARSET_INFO *cs): + cmp_item_string(cs) {} void store_value(Item *item) { value_res= item->val_str(&value); @@ -606,21 +595,11 @@ public: int compare(cmp_item *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() { - return new cmp_item_sort_string_in_static(); - } -}; - -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(); + return new cmp_item_sort_string_in_static(cmp_charset); } }; diff --git a/sql/item_func.cc b/sql/item_func.cc index e5d32042641..53d15e838b2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -107,7 +107,7 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return 0; // Fatal error if flag is set! if (arg_count) { // Print purify happy - coercibility= COER_NOCOLL; + bool first_coll= 1; for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++) { if ((*arg)->fix_fields(thd, tables, arg) || @@ -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 string. */ - if ((*arg)->binary()) + if (first_coll) { - set_charset(&my_charset_bin); - coercibility= COER_NOCOLL; + set_charset((*arg)->charset()); + 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((*arg)->charset()); + set_charset(&my_charset_bin); + coercibility= COER_NOCOLL; } else if ((*arg)->coercibility < coercibility) { @@ -864,6 +866,7 @@ void Item_func_min_max::fix_length_and_dec() max_length=0; maybe_null=1; cmp_type=args[0]->result_type(); + for (uint i=0 ; i < arg_count ; i++) { if (max_length < args[i]->max_length) @@ -873,11 +876,11 @@ void Item_func_min_max::fix_length_and_dec() if (!args[i]->maybe_null) maybe_null=0; 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); } - if (cmp_type == STRING_RESULT) - str_cmp_function= binary() ? stringcmp : sortcmp; } @@ -922,7 +925,7 @@ String *Item_func_min_max::val_str(String *str) res2= args[i]->val_str(res == str ? &tmp_value : str); if (res2) { - int cmp= (*str_cmp_function)(res,res2); + int cmp= sortcmp(res,res2,charset()); if ((cmp_sign < 0 ? cmp : -cmp) < 0) res=res2; } diff --git a/sql/item_func.h b/sql/item_func.h index fc7145705b2..860ddbbbadf 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -524,7 +524,6 @@ class Item_func_min_max :public Item_func Item_result cmp_type; String tmp_value; int cmp_sign; - int (*str_cmp_function)(const String *x,const String *y); public: Item_func_min_max(List<Item> &list,int cmp_sign_arg) :Item_func(list), cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg) {} diff --git a/sql/item_sum.cc b/sql/item_sum.cc index a0f8bc8b8a2..e303c26262e 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -183,12 +183,17 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return 1; hybrid_type=item->result_type(); if (hybrid_type == INT_RESULT) + { + cmp_charset= &my_charset_bin; max_length=20; + } else if (hybrid_type == REAL_RESULT) + { + cmp_charset= &my_charset_bin; max_length=float_length(decimals); - else + }else { - str_cmp_function= item->binary() ? stringcmp : sortcmp; + cmp_charset= item->charset(); max_length=item->max_length; } decimals=item->decimals; @@ -440,7 +445,7 @@ bool Item_sum_min::add() { String *result=args[0]->val_str(&tmp_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); null_value=0; @@ -487,7 +492,7 @@ bool Item_sum_max::add() { String *result=args[0]->val_str(&tmp_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); null_value=0; @@ -762,7 +767,7 @@ Item_sum_hybrid::min_max_update_str_field(int offset) result_field->ptr-=offset; 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()); else { // Use old value diff --git a/sql/item_sum.h b/sql/item_sum.h index db8bded9946..74c7b11a7ba 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -369,17 +369,19 @@ class Item_sum_hybrid :public Item_sum enum_field_types hybrid_field_type; int cmp_sign; table_map used_table_cache; - int (*str_cmp_function)(const String *x,const String *y); + CHARSET_INFO *cmp_charset; public: Item_sum_hybrid(Item *item_par,int 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(thd, item), value(item.value), tmp_value(item.tmp_value), 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 **); table_map used_tables() const { return used_table_cache; } bool const_item() const { return !used_table_cache; } diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 9e9d7a08925..36464126ae5 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -41,13 +41,13 @@ int sortcmp2(void* cmp_arg __attribute__((unused)), const String *a,const String *b) { - return sortcmp(a,b); + return sortcmp(a,b,a->charset()); } int stringcmp2(void* cmp_arg __attribute__((unused)), 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)), @@ -329,20 +329,10 @@ void field_str::add() if (length > max_length) max_length = length; - if (item->binary()) - { - 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); - if (sortcmp(res, &max_arg) > 0) - max_arg.copy(*res); - } + if (sortcmp(res, &min_arg,item->charset()) < 0) + min_arg.copy(*res); + if (sortcmp(res, &max_arg,item->charset()) > 0) + max_arg.copy(*res); } if (room_in_tree) diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 21e38397842..1a0366112f4 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -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, (unsigned char *) x->ptr(),x->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) { if (from->Alloced_length >= from_length) diff --git a/sql/sql_string.h b/sql/sql_string.h index 047faf3e3db..8e0705844ad 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -25,8 +25,7 @@ #endif class String; -int sortcmp(const String *a,const String *b); -int stringcmp(const String *a,const String *b); +int sortcmp(const String *a,const String *b, CHARSET_INFO *cs); String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); class String @@ -205,8 +204,7 @@ public: void strip_sp(); inline void caseup() { my_caseup(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 stringcmp(const String *a,const String *b); + friend int sortcmp(const String *a,const String *b, CHARSET_INFO *cs); friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); uint32 numchars(); int charpos(int i,uint32 offset=0); |