mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Bug 6206: ENUMs are not case sensitive even if declared BINARY
The same problem with SET columns: find_set() now executes find_type2() to do charset aware search, instead of always using system_charset_info comparison.
This commit is contained in:
@ -15,3 +15,36 @@ t1 CREATE TABLE `t1` (
|
|||||||
drop 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;
|
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;
|
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 ('<27>'),('<27>'),('<27>'),('<27>');
|
||||||
|
INSERT INTO t1 VALUES ('ae'),('oe'),('ue'),('ss');
|
||||||
|
INSERT INTO t1 VALUES ('<27>,<2C>,<2C>,<2C>');
|
||||||
|
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;
|
||||||
|
@ -14,3 +14,24 @@ show create table t1;
|
|||||||
drop 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;
|
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;
|
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 ('<27>'),('<27>'),('<27>'),('<27>');
|
||||||
|
INSERT INTO t1 VALUES ('ae'),('oe'),('ue'),('ss');
|
||||||
|
INSERT INTO t1 VALUES ('<27>,<2C>,<2C>,<2C>');
|
||||||
|
INSERT INTO t1 VALUES ('ae,oe,ue,ss');
|
||||||
|
SELECT c FROM t1 ORDER BY c;
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -5692,8 +5692,8 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||||||
from= tmpstr.ptr();
|
from= tmpstr.ptr();
|
||||||
length= tmpstr.length();
|
length= tmpstr.length();
|
||||||
}
|
}
|
||||||
ulonglong tmp= find_set(typelib, from, length, ¬_used, ¬_used2,
|
ulonglong tmp= find_set(typelib, from, length, field_charset,
|
||||||
&got_warning);
|
¬_used, ¬_used2, &got_warning);
|
||||||
if (!tmp && length && length < 22)
|
if (!tmp && length && length < 22)
|
||||||
{
|
{
|
||||||
/* This is for reading numbers with LOAD DATA INFILE */
|
/* This is for reading numbers with LOAD DATA INFILE */
|
||||||
|
@ -809,7 +809,7 @@ extern void yyerror(const char*);
|
|||||||
extern bool check_reserved_words(LEX_STRING *name);
|
extern bool check_reserved_words(LEX_STRING *name);
|
||||||
|
|
||||||
/* strfunc.cc */
|
/* 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);
|
char **err_pos, uint *err_len, bool *set_warning);
|
||||||
uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match);
|
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);
|
uint find_type2(TYPELIB *lib, const char *find, uint length, CHARSET_INFO *cs);
|
||||||
|
@ -1460,7 +1460,9 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
|
|||||||
goto err;
|
goto err;
|
||||||
var->save_result.ulong_value= ((ulong)
|
var->save_result.ulong_value= ((ulong)
|
||||||
find_set(enum_names, res->c_ptr(),
|
find_set(enum_names, res->c_ptr(),
|
||||||
res->length(), &error, &error_len,
|
res->length(),
|
||||||
|
NULL,
|
||||||
|
&error, &error_len,
|
||||||
¬_used));
|
¬_used));
|
||||||
if (error_len)
|
if (error_len)
|
||||||
{
|
{
|
||||||
|
@ -4444,8 +4444,9 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
|||||||
thd->cuted_fields=0;
|
thd->cuted_fields=0;
|
||||||
String str,*res;
|
String str,*res;
|
||||||
res=default_value->val_str(&str);
|
res=default_value->val_str(&str);
|
||||||
(void) find_set(interval, res->ptr(), res->length(), ¬_used,
|
(void) find_set(interval, res->ptr(), res->length(),
|
||||||
¬_used2, ¬_used3);
|
&my_charset_bin,
|
||||||
|
¬_used, ¬_used2, ¬_used3);
|
||||||
if (thd->cuted_fields)
|
if (thd->cuted_fields)
|
||||||
{
|
{
|
||||||
net_printf(thd,ER_INVALID_DEFAULT,field_name);
|
net_printf(thd,ER_INVALID_DEFAULT,field_name);
|
||||||
|
@ -39,16 +39,13 @@
|
|||||||
|
|
||||||
static const char field_separator=',';
|
static const char field_separator=',';
|
||||||
|
|
||||||
ulonglong find_set(TYPELIB *lib, const char *str, uint length, char **err_pos,
|
ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs,
|
||||||
uint *err_len, bool *set_warning)
|
char **err_pos, uint *err_len, bool *set_warning)
|
||||||
{
|
{
|
||||||
const char *end= str + length;
|
CHARSET_INFO *strip= cs ? cs : &my_charset_latin1;
|
||||||
*err_pos= 0; // No error yet
|
const char *end= str + strip->cset->lengthsp(strip, str, length);
|
||||||
while (end > str && my_isspace(system_charset_info, end[-1]))
|
|
||||||
end--;
|
|
||||||
|
|
||||||
*err_len= 0;
|
|
||||||
ulonglong found= 0;
|
ulonglong found= 0;
|
||||||
|
*err_pos= 0; // No error yet
|
||||||
if (str != end)
|
if (str != end)
|
||||||
{
|
{
|
||||||
const char *start= str;
|
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++) ;
|
for (; pos != end && *pos != field_separator; pos++) ;
|
||||||
var_len= (uint) (pos - start);
|
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)
|
if (!find)
|
||||||
{
|
{
|
||||||
*err_pos= (char*) start;
|
*err_pos= (char*) start;
|
||||||
|
Reference in New Issue
Block a user