mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 10:14:19 +01:00
Fix for bug #4340: find_in_set is case insensitive even on binary operators(for 4.1)
This commit is contained in:
parent
614414682f
commit
f5ce37d7fe
3 changed files with 51 additions and 21 deletions
|
@ -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
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue