diff options
-rw-r--r-- | mysql-test/r/type_set.result | 33 | ||||
-rw-r--r-- | mysql-test/t/type_set.test | 21 | ||||
-rw-r--r-- | sql/field.cc | 4 | ||||
-rw-r--r-- | sql/mysql_priv.h | 2 | ||||
-rw-r--r-- | sql/set_var.cc | 4 | ||||
-rw-r--r-- | sql/sql_parse.cc | 5 | ||||
-rw-r--r-- | sql/strfunc.cc | 16 |
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, ¬_used, ¬_used2, - &got_warning); + ulonglong tmp= find_set(typelib, from, length, field_charset, + ¬_used, ¬_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, ¬_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(), ¬_used, - ¬_used2, ¬_used3); + (void) find_set(interval, res->ptr(), res->length(), + &my_charset_bin, + ¬_used, ¬_used2, ¬_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; |