summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/type_set.result33
-rw-r--r--mysql-test/t/type_set.test21
-rw-r--r--sql/field.cc4
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/set_var.cc4
-rw-r--r--sql/sql_parse.cc5
-rw-r--r--sql/strfunc.cc16
7 files changed, 70 insertions, 15 deletions
diff --git a/mysql-test/r/type_set.result b/mysql-test/r/type_set.result
index 084e004cd47..9c82f59fc69 100644
--- a/mysql-test/r/type_set.result
+++ b/mysql-test/r/type_set.result
@@ -15,3 +15,36 @@ t1 CREATE TABLE `t1` (
drop table t1;
CREATE TABLE t1 ( user varchar(64) NOT NULL default '', path varchar(255) NOT NULL default '', privilege set('select','RESERVED30','RESERVED29','RESERVED28','RESERVED27','RESERVED26', 'RESERVED25','RESERVED24','data.delete','RESERVED22','RESERVED21', 'RESERVED20','data.insert.none','data.insert.approve', 'data.insert.delete','data.insert.move','data.insert.propose', 'data.insert.reject','RESERVED13','RESERVED12','RESERVED11','RESERVED10', 'RESERVED09','data.update','RESERVED07','RESERVED06','RESERVED05', 'RESERVED04','metadata.delete','metadata.put','RESERVED01','RESERVED00') NOT NULL default '', KEY user (user) ) ENGINE=MyISAM CHARSET=utf8;
DROP TABLE t1;
+set names latin1;
+create table t1 (s set ('a','A') character set latin1 collate latin1_bin);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `s` set('a','A') character set latin1 collate latin1_bin default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ('a'),('a,A'),('A,a'),('A');
+select s from t1 order by s;
+s
+a
+A
+a,A
+a,A
+drop table t1;
+CREATE TABLE t1 (c set('ae','oe','ue','ss') collate latin1_german2_ci);
+INSERT INTO t1 VALUES ('ä'),('ö'),('ü'),('ß');
+INSERT INTO t1 VALUES ('ae'),('oe'),('ue'),('ss');
+INSERT INTO t1 VALUES ('ä,ö,ü,ß');
+INSERT INTO t1 VALUES ('ae,oe,ue,ss');
+SELECT c FROM t1 ORDER BY c;
+c
+ae
+ae
+oe
+oe
+ue
+ue
+ss
+ss
+ae,oe,ue,ss
+ae,oe,ue,ss
+DROP TABLE t1;
diff --git a/mysql-test/t/type_set.test b/mysql-test/t/type_set.test
index 60aa8dcfcf2..e4aeecb2c79 100644
--- a/mysql-test/t/type_set.test
+++ b/mysql-test/t/type_set.test
@@ -14,3 +14,24 @@ show create table t1;
drop table t1;
CREATE TABLE t1 ( user varchar(64) NOT NULL default '', path varchar(255) NOT NULL default '', privilege set('select','RESERVED30','RESERVED29','RESERVED28','RESERVED27','RESERVED26', 'RESERVED25','RESERVED24','data.delete','RESERVED22','RESERVED21', 'RESERVED20','data.insert.none','data.insert.approve', 'data.insert.delete','data.insert.move','data.insert.propose', 'data.insert.reject','RESERVED13','RESERVED12','RESERVED11','RESERVED10', 'RESERVED09','data.update','RESERVED07','RESERVED06','RESERVED05', 'RESERVED04','metadata.delete','metadata.put','RESERVED01','RESERVED00') NOT NULL default '', KEY user (user) ) ENGINE=MyISAM CHARSET=utf8;
DROP TABLE t1;
+
+#
+# Check that SET is case sensitive with a binary collation
+#
+set names latin1;
+create table t1 (s set ('a','A') character set latin1 collate latin1_bin);
+show create table t1;
+insert into t1 values ('a'),('a,A'),('A,a'),('A');
+select s from t1 order by s;
+drop table t1;
+
+#
+# Check that SET honors a more complex collation correctly
+#
+CREATE TABLE t1 (c set('ae','oe','ue','ss') collate latin1_german2_ci);
+INSERT INTO t1 VALUES ('ä'),('ö'),('ü'),('ß');
+INSERT INTO t1 VALUES ('ae'),('oe'),('ue'),('ss');
+INSERT INTO t1 VALUES ('ä,ö,ü,ß');
+INSERT INTO t1 VALUES ('ae,oe,ue,ss');
+SELECT c FROM t1 ORDER BY c;
+DROP TABLE t1;
diff --git a/sql/field.cc b/sql/field.cc
index e7631fb08aa..71cc2ce3e74 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5692,8 +5692,8 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
from= tmpstr.ptr();
length= tmpstr.length();
}
- ulonglong tmp= find_set(typelib, from, length, &not_used, &not_used2,
- &got_warning);
+ ulonglong tmp= find_set(typelib, from, length, field_charset,
+ &not_used, &not_used2, &got_warning);
if (!tmp && length && length < 22)
{
/* This is for reading numbers with LOAD DATA INFILE */
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 6dac0d9a38f..18944aebad9 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -809,7 +809,7 @@ extern void yyerror(const char*);
extern bool check_reserved_words(LEX_STRING *name);
/* strfunc.cc */
-ulonglong find_set(TYPELIB *typelib,const char *x, uint length,
+ulonglong find_set(TYPELIB *lib, const char *x, uint length, CHARSET_INFO *cs,
char **err_pos, uint *err_len, bool *set_warning);
uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match);
uint find_type2(TYPELIB *lib, const char *find, uint length, CHARSET_INFO *cs);
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 60a51314742..c609c3e4793 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1460,7 +1460,9 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
goto err;
var->save_result.ulong_value= ((ulong)
find_set(enum_names, res->c_ptr(),
- res->length(), &error, &error_len,
+ res->length(),
+ NULL,
+ &error, &error_len,
&not_used));
if (error_len)
{
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 61049360b93..0750403aef5 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4444,8 +4444,9 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
thd->cuted_fields=0;
String str,*res;
res=default_value->val_str(&str);
- (void) find_set(interval, res->ptr(), res->length(), &not_used,
- &not_used2, &not_used3);
+ (void) find_set(interval, res->ptr(), res->length(),
+ &my_charset_bin,
+ &not_used, &not_used2, &not_used3);
if (thd->cuted_fields)
{
net_printf(thd,ER_INVALID_DEFAULT,field_name);
diff --git a/sql/strfunc.cc b/sql/strfunc.cc
index ea67a5a4343..b5255e9be06 100644
--- a/sql/strfunc.cc
+++ b/sql/strfunc.cc
@@ -39,16 +39,13 @@
static const char field_separator=',';
-ulonglong find_set(TYPELIB *lib, const char *str, uint length, char **err_pos,
- uint *err_len, bool *set_warning)
+ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs,
+ char **err_pos, uint *err_len, bool *set_warning)
{
- const char *end= str + length;
- *err_pos= 0; // No error yet
- while (end > str && my_isspace(system_charset_info, end[-1]))
- end--;
-
- *err_len= 0;
+ CHARSET_INFO *strip= cs ? cs : &my_charset_latin1;
+ const char *end= str + strip->cset->lengthsp(strip, str, length);
ulonglong found= 0;
+ *err_pos= 0; // No error yet
if (str != end)
{
const char *start= str;
@@ -59,7 +56,8 @@ ulonglong find_set(TYPELIB *lib, const char *str, uint length, char **err_pos,
for (; pos != end && *pos != field_separator; pos++) ;
var_len= (uint) (pos - start);
- uint find= find_type(lib, start, var_len, 0);
+ uint find= cs ? find_type2(lib, start, var_len, cs) :
+ find_type(lib, start, var_len, (bool) 0);
if (!find)
{
*err_pos= (char*) start;