diff options
author | unknown <bar@bar.mysql.r18.ru> | 2003-06-27 13:52:38 +0500 |
---|---|---|
committer | unknown <bar@bar.mysql.r18.ru> | 2003-06-27 13:52:38 +0500 |
commit | 6fd2a8585f169eac9cebd2c57a56397e9c865e9e (patch) | |
tree | 55bce2ad2b8def6ced5383c1f007ffaef3fcb6f8 /sql | |
parent | 3f810d0e906be42faeb407d1da140977725745af (diff) | |
download | mariadb-git-6fd2a8585f169eac9cebd2c57a56397e9c865e9e.tar.gz |
str0 IN (str1, str2, ...) now works according to collation rules
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_cmpfunc.cc | 47 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 15 |
2 files changed, 32 insertions, 30 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index b764bb322d3..f9c2228b33d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1196,17 +1196,17 @@ void Item_func_coalesce::fix_length_and_dec() Classes and function for the IN operator ****************************************************************************/ -static int cmp_longlong(longlong *a,longlong *b) +static int cmp_longlong(void *cmp_arg, longlong *a,longlong *b) { return *a < *b ? -1 : *a == *b ? 0 : 1; } -static int cmp_double(double *a,double *b) +static int cmp_double(void *cmp_arg, double *a,double *b) { return *a < *b ? -1 : *a == *b ? 0 : 1; } -static int cmp_row(cmp_item_row* a, cmp_item_row* b) +static int cmp_row(void *cmp_arg, cmp_item_row* a, cmp_item_row* b) { return a->compare(b); } @@ -1223,18 +1223,18 @@ int in_vector::find(Item *item) { uint mid=(start+end+1)/2; int res; - if ((res=(*compare)(base+mid*size,result)) == 0) + if ((res=(*compare)(collation, base+mid*size, result)) == 0) return 1; if (res < 0) start=mid; else end=mid-1; } - return (int) ((*compare)(base+start*size,result) == 0); + return (int) ((*compare)(collation, base+start*size, result) == 0); } -in_string::in_string(uint elements,qsort_cmp cmp_func) - :in_vector(elements, sizeof(String), cmp_func), +in_string::in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs) + :in_vector(elements, sizeof(String), cmp_func, cs), tmp(buff, sizeof(buff), &my_charset_bin) {} @@ -1273,7 +1273,7 @@ in_row::in_row(uint elements, Item * item) { base= (char*) new cmp_item_row[count= elements]; size= sizeof(cmp_item_row); - compare= (qsort_cmp) cmp_row; + compare= (qsort2_cmp) cmp_row; tmp.store_value(item); } @@ -1298,7 +1298,7 @@ void in_row::set(uint pos, Item *item) } in_longlong::in_longlong(uint elements) - :in_vector(elements,sizeof(longlong),(qsort_cmp) cmp_longlong) + :in_vector(elements,sizeof(longlong),(qsort2_cmp) cmp_longlong, 0) {} void in_longlong::set(uint pos,Item *item) @@ -1315,7 +1315,7 @@ byte *in_longlong::get_value(Item *item) } in_double::in_double(uint elements) - :in_vector(elements,sizeof(double),(qsort_cmp) cmp_double) + :in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0) {} void in_double::set(uint pos,Item *item) @@ -1462,17 +1462,8 @@ bool Item_func_in::nulls_in_row() return 0; } -static int srtcmp_in(const String *x,const String *y) +static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y) { - CHARSET_INFO *cs= x->charset(); - return cs->coll->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->coll->strnncollsp(cs, (unsigned char *) x->ptr(),x->length(), (unsigned char *) y->ptr(),y->length()); @@ -1488,10 +1479,18 @@ 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) srtcmp_in); - else - array=new in_string(arg_count,(qsort_cmp) bincmp_in); + uint i; + cmp_collation.set(item->collation); + for (i=0 ; i<arg_count; i++) + if (cmp_collation.aggregate(args[i]->collation)) + break; + if (cmp_collation.derivation == DERIVATION_NONE) + { + my_error(ER_CANT_AGGREGATE_NCOLLATIONS,MYF(0),func_name()); + return; + } + array=new in_string(arg_count,(qsort2_cmp) srtcmp_in, + cmp_collation.collation); break; case INT_RESULT: array= new in_longlong(arg_count); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 792f2e2411c..1311cae335f 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -382,21 +382,23 @@ class in_vector :public Sql_alloc protected: char *base; uint size; - qsort_cmp compare; + qsort2_cmp compare; + CHARSET_INFO *collation; uint count; public: uint used_count; in_vector() {} - in_vector(uint elements,uint element_length,qsort_cmp cmp_func) + in_vector(uint elements,uint element_length,qsort2_cmp cmp_func, + CHARSET_INFO *cmp_coll) :base((char*) sql_calloc(elements*element_length)), - size(element_length), compare(cmp_func), count(elements), - used_count(elements) {} + size(element_length), compare(cmp_func), collation(cmp_coll), + count(elements), used_count(elements) {} virtual ~in_vector() {} virtual void set(uint pos,Item *item)=0; virtual byte *get_value(Item *item)=0; void sort() { - qsort(base,used_count,size,compare); + qsort2(base,used_count,size,compare,collation); } int find(Item *item); }; @@ -406,7 +408,7 @@ class in_string :public in_vector char buff[80]; String tmp; public: - in_string(uint elements,qsort_cmp cmp_func); + in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs); ~in_string(); void set(uint pos,Item *item); byte *get_value(Item *item); @@ -605,6 +607,7 @@ class Item_func_in :public Item_int_func in_vector *array; cmp_item *in_item; bool have_null; + DTCollation cmp_collation; public: Item_func_in(Item *a,List<Item> &list) :Item_int_func(list), item(a), array(0), in_item(0), have_null(0) |