From f5ce37d7fec7443542d4d6d7ee0a224c525ce877 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Aug 2004 20:18:59 +0400 Subject: [PATCH] Fix for bug #4340: find_in_set is case insensitive even on binary operators(for 4.1) --- mysql-test/r/func_set.result | 9 ++++++ mysql-test/t/func_set.test | 8 ++++++ sql/item_func.cc | 55 ++++++++++++++++++++++-------------- 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/mysql-test/r/func_set.result b/mysql-test/r/func_set.result index 4918617f85f..9c1cac790ff 100644 --- a/mysql-test/r/func_set.result +++ b/mysql-test/r/func_set.result @@ -56,3 +56,12 @@ id elt(two.val,'one','two') 2 one 4 two drop table t1,t2; +select find_in_set(binary 'a',binary 'A,B,C'); +find_in_set(binary 'a',binary 'A,B,C') +0 +select find_in_set('a',binary 'A,B,C'); +find_in_set('a',binary 'A,B,C') +0 +select find_in_set(binary 'a', 'A,B,C'); +find_in_set(binary 'a', 'A,B,C') +0 diff --git a/mysql-test/t/func_set.test b/mysql-test/t/func_set.test index 03843fd3da5..fb733a173bb 100644 --- a/mysql-test/t/func_set.test +++ b/mysql-test/t/func_set.test @@ -39,3 +39,11 @@ insert into t2 values (1,1),(2,1),(3,1),(4,2); select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id; select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id order by one.id; drop table t1,t2; + +# +# Bug4340: find_in_set is case insensitive even on binary operators +# + +select find_in_set(binary 'a',binary 'A,B,C'); +select find_in_set('a',binary 'A,B,C'); +select find_in_set(binary 'a', 'A,B,C'); diff --git a/sql/item_func.cc b/sql/item_func.cc index c90a70a6bb6..adcba34d56b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1435,30 +1435,43 @@ longlong Item_func_find_in_set::val_int() int diff; if ((diff=buffer->length() - find->length()) >= 0) { - const char *f_pos=find->ptr(); - const char *f_end=f_pos+find->length(); - const char *str=buffer->ptr(); - const char *end=str+diff+1; - const char *real_end=str+buffer->length(); - uint position=1; - do + my_wc_t wc; + CHARSET_INFO *cs= cmp_collation.collation; + const char *str_begin= buffer->ptr(); + const char *str_end= buffer->ptr(); + const char *real_end= str_end+buffer->length(); + const uchar *find_str= (const uchar *) find->ptr(); + uint find_str_len= find->length(); + int position= 0; + while (1) { - const char *pos= f_pos; - while (pos != f_end) + int symbol_len; + if ((symbol_len= cs->cset->mb_wc(cs, &wc, (uchar*) str_end, + (uchar*) real_end)) > 0) { - if (my_toupper(cmp_collation.collation,*str) != - my_toupper(cmp_collation.collation,*pos)) - goto not_found; - str++; - pos++; + const char *substr_end= str_end + symbol_len; + bool is_last_item= (substr_end == real_end); + if (wc == (my_wc_t) separator || is_last_item) + { + position++; + if (is_last_item) + str_end= substr_end; + if (!my_strnncoll(cs, (const uchar *) str_begin, + str_end - str_begin, + find_str, find_str_len)) + return (longlong) position; + else + str_begin= substr_end; + } + str_end= substr_end; } - if (str == real_end || str[0] == separator) - return (longlong) position; - not_found: - while (str < end && str[0] != separator) - str++; - position++; - } while (++str <= end); + else if (str_end - str_begin == 0 && + find_str_len == 0 && + wc == (my_wc_t) separator) + return (longlong) ++position; + else + return (longlong) 0; + } } return 0; }