Loading mysql-test/r/func_set.result +9 −0 Original line number Diff line number Diff line Loading @@ -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 mysql-test/t/func_set.test +8 −0 Original line number Diff line number Diff line Loading @@ -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'); sql/item_func.cc +34 −21 Original line number Diff line number Diff line Loading @@ -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 { const char *pos= f_pos; while (pos != f_end) { if (my_toupper(cmp_collation.collation,*str) != my_toupper(cmp_collation.collation,*pos)) goto not_found; str++; pos++; } if (str == real_end || str[0] == separator) return (longlong) position; not_found: while (str < end && str[0] != separator) str++; 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) { int symbol_len; if ((symbol_len= cs->cset->mb_wc(cs, &wc, (uchar*) str_end, (uchar*) real_end)) > 0) { 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++; } while (++str <= end); 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; } 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; } Loading Loading
mysql-test/r/func_set.result +9 −0 Original line number Diff line number Diff line Loading @@ -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
mysql-test/t/func_set.test +8 −0 Original line number Diff line number Diff line Loading @@ -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');
sql/item_func.cc +34 −21 Original line number Diff line number Diff line Loading @@ -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 { const char *pos= f_pos; while (pos != f_end) { if (my_toupper(cmp_collation.collation,*str) != my_toupper(cmp_collation.collation,*pos)) goto not_found; str++; pos++; } if (str == real_end || str[0] == separator) return (longlong) position; not_found: while (str < end && str[0] != separator) str++; 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) { int symbol_len; if ((symbol_len= cs->cset->mb_wc(cs, &wc, (uchar*) str_end, (uchar*) real_end)) > 0) { 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++; } while (++str <= end); 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; } 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; } Loading