Commit 58efae92 authored by unknown's avatar unknown

Fix for bug #4340: find_in_set is case insensitive even on binary operators(for 4.1)

parent 20b3f6c5
...@@ -56,3 +56,12 @@ id elt(two.val,'one','two') ...@@ -56,3 +56,12 @@ id elt(two.val,'one','two')
2 one 2 one
4 two 4 two
drop table t1,t2; 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
...@@ -39,3 +39,11 @@ insert into t2 values (1,1),(2,1),(3,1),(4,2); ...@@ -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;
select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id order by 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; 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');
...@@ -1435,30 +1435,43 @@ longlong Item_func_find_in_set::val_int() ...@@ -1435,30 +1435,43 @@ longlong Item_func_find_in_set::val_int()
int diff; int diff;
if ((diff=buffer->length() - find->length()) >= 0) if ((diff=buffer->length() - find->length()) >= 0)
{ {
const char *f_pos=find->ptr(); my_wc_t wc;
const char *f_end=f_pos+find->length(); CHARSET_INFO *cs= cmp_collation.collation;
const char *str=buffer->ptr(); const char *str_begin= buffer->ptr();
const char *end=str+diff+1; const char *str_end= buffer->ptr();
const char *real_end=str+buffer->length(); const char *real_end= str_end+buffer->length();
uint position=1; const uchar *find_str= (const uchar *) find->ptr();
do uint find_str_len= find->length();
int position= 0;
while (1)
{ {
const char *pos= f_pos; int symbol_len;
while (pos != f_end) if ((symbol_len= cs->cset->mb_wc(cs, &wc, (uchar*) str_end,
(uchar*) real_end)) > 0)
{ {
if (my_toupper(cmp_collation.collation,*str) != const char *substr_end= str_end + symbol_len;
my_toupper(cmp_collation.collation,*pos)) bool is_last_item= (substr_end == real_end);
goto not_found; if (wc == (my_wc_t) separator || is_last_item)
str++; {
pos++; 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) else if (str_end - str_begin == 0 &&
return (longlong) position; find_str_len == 0 &&
not_found: wc == (my_wc_t) separator)
while (str < end && str[0] != separator) return (longlong) ++position;
str++; else
position++; return (longlong) 0;
} while (++str <= end); }
} }
return 0; return 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