summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgluh@gluh.mysql.r18.ru <>2004-08-24 20:18:59 +0400
committergluh@gluh.mysql.r18.ru <>2004-08-24 20:18:59 +0400
commit510cacbb7728d49aa683d09dc14f15fdadf8e816 (patch)
tree508e2f34a5fbf61714047ba000167ed722c5d2fb
parentb1847f471c88233db5e768316156989ca0b263ce (diff)
downloadmariadb-git-510cacbb7728d49aa683d09dc14f15fdadf8e816.tar.gz
Fix for bug #4340: find_in_set is case insensitive even on binary operators(for 4.1)
-rw-r--r--mysql-test/r/func_set.result9
-rw-r--r--mysql-test/t/func_set.test8
-rw-r--r--sql/item_func.cc55
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;
}