diff --git a/VC++Files/winmysqladmin/mysql_com.h b/VC++Files/winmysqladmin/mysql_com.h index a732953a8d7..2a7eb57d745 100644 --- a/VC++Files/winmysqladmin/mysql_com.h +++ b/VC++Files/winmysqladmin/mysql_com.h @@ -159,28 +159,28 @@ enum enum_field_types { FIELD_TYPE_DECIMAL, FIELD_TYPE_TINY, /* Shutdown/kill enums and constants */ /* Bits for THD::killable. */ -#define KILLABLE_CONNECT (unsigned char)(1 << 0) -#define KILLABLE_TRANS (unsigned char)(1 << 1) -#define KILLABLE_LOCK_TABLE (unsigned char)(1 << 2) -#define KILLABLE_UPDATE (unsigned char)(1 << 3) +#define MYSQL_SHUTDOWN_KILLABLE_CONNECT (unsigned char)(1 << 0) +#define MYSQL_SHUTDOWN_KILLABLE_TRANS (unsigned char)(1 << 1) +#define MYSQL_SHUTDOWN_KILLABLE_LOCK_TABLE (unsigned char)(1 << 2) +#define MYSQL_SHUTDOWN_KILLABLE_UPDATE (unsigned char)(1 << 3) -enum enum_shutdown_level { +enum mysql_enum_shutdown_level { /* We want levels to be in growing order of hardness (because we use number comparisons). Note that DEFAULT does not respect the growing property, but it's ok. */ - SHUTDOWN_DEFAULT= 0, + DEFAULT= 0, /* wait for existing connections to finish */ - SHUTDOWN_WAIT_CONNECTIONS= KILLABLE_CONNECT, + WAIT_CONNECTIONS= MYSQL_SHUTDOWN_KILLABLE_CONNECT, /* wait for existing trans to finish */ - SHUTDOWN_WAIT_TRANSACTIONS= KILLABLE_TRANS, + WAIT_TRANSACTIONS= MYSQL_SHUTDOWN_KILLABLE_TRANS, /* wait for existing updates to finish (=> no partial MyISAM update) */ - SHUTDOWN_WAIT_UPDATES= KILLABLE_UPDATE, + WAIT_UPDATES= MYSQL_SHUTDOWN_KILLABLE_UPDATE, /* flush InnoDB buffers and other storage engines' buffers*/ - SHUTDOWN_WAIT_ALL_BUFFERS= (KILLABLE_UPDATE << 1), + WAIT_ALL_BUFFERS= (MYSQL_SHUTDOWN_KILLABLE_UPDATE << 1), /* don't flush InnoDB buffers, flush other storage engines' buffers*/ - SHUTDOWN_WAIT_CRITICAL_BUFFERS= (KILLABLE_UPDATE << 1) + 1, + WAIT_CRITICAL_BUFFERS= (MYSQL_SHUTDOWN_KILLABLE_UPDATE << 1) + 1, /* Now the 2 levels of the KILL command */ #if MYSQL_VERSION_ID >= 50000 KILL_QUERY= 254, @@ -188,10 +188,6 @@ enum enum_shutdown_level { KILL_CONNECTION= 255 }; -/* Same value and type (0, enum_shutdown_level) but not same meaning */ -#define NOT_KILLED SHUTDOWN_DEFAULT - - extern unsigned long max_allowed_packet; extern unsigned long net_buffer_length; diff --git a/include/mysql.h b/include/mysql.h index 0f3fdc90548..52187c3ff28 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -454,7 +454,7 @@ int STDCALL mysql_add_slave(MYSQL* mysql, const char* host, const char* passwd); int STDCALL mysql_shutdown(MYSQL *mysql, - enum enum_shutdown_level + enum mysql_enum_shutdown_level shutdown_level); int STDCALL mysql_dump_debug_info(MYSQL *mysql); int STDCALL mysql_refresh(MYSQL *mysql, diff --git a/include/mysql_com.h b/include/mysql_com.h index fa25db5f11a..3b65d6f3fbc 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -227,28 +227,28 @@ enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY, /* Shutdown/kill enums and constants */ /* Bits for THD::killable. */ -#define KILLABLE_CONNECT (unsigned char)(1 << 0) -#define KILLABLE_TRANS (unsigned char)(1 << 1) -#define KILLABLE_LOCK_TABLE (unsigned char)(1 << 2) -#define KILLABLE_UPDATE (unsigned char)(1 << 3) +#define MYSQL_SHUTDOWN_KILLABLE_CONNECT (unsigned char)(1 << 0) +#define MYSQL_SHUTDOWN_KILLABLE_TRANS (unsigned char)(1 << 1) +#define MYSQL_SHUTDOWN_KILLABLE_LOCK_TABLE (unsigned char)(1 << 2) +#define MYSQL_SHUTDOWN_KILLABLE_UPDATE (unsigned char)(1 << 3) -enum enum_shutdown_level { +enum mysql_enum_shutdown_level { /* We want levels to be in growing order of hardness (because we use number comparisons). Note that DEFAULT does not respect the growing property, but it's ok. */ - SHUTDOWN_DEFAULT= 0, + SHUTDOWN_DEFAULT = 0, /* wait for existing connections to finish */ - SHUTDOWN_WAIT_CONNECTIONS= KILLABLE_CONNECT, + SHUTDOWN_WAIT_CONNECTIONS= MYSQL_SHUTDOWN_KILLABLE_CONNECT, /* wait for existing trans to finish */ - SHUTDOWN_WAIT_TRANSACTIONS= KILLABLE_TRANS, + SHUTDOWN_WAIT_TRANSACTIONS= MYSQL_SHUTDOWN_KILLABLE_TRANS, /* wait for existing updates to finish (=> no partial MyISAM update) */ - SHUTDOWN_WAIT_UPDATES= KILLABLE_UPDATE, + SHUTDOWN_WAIT_UPDATES= MYSQL_SHUTDOWN_KILLABLE_UPDATE, /* flush InnoDB buffers and other storage engines' buffers*/ - SHUTDOWN_WAIT_ALL_BUFFERS= (KILLABLE_UPDATE << 1), + SHUTDOWN_WAIT_ALL_BUFFERS= (MYSQL_SHUTDOWN_KILLABLE_UPDATE << 1), /* don't flush InnoDB buffers, flush other storage engines' buffers*/ - SHUTDOWN_WAIT_CRITICAL_BUFFERS= (KILLABLE_UPDATE << 1) + 1, + SHUTDOWN_WAIT_CRITICAL_BUFFERS= (MYSQL_SHUTDOWN_KILLABLE_UPDATE << 1) + 1, /* Now the 2 levels of the KILL command */ #if MYSQL_VERSION_ID >= 50000 KILL_QUERY= 254, @@ -256,10 +256,6 @@ enum enum_shutdown_level { KILL_CONNECTION= 255 }; -/* Same value and type (0, enum_shutdown_level) but not same meaning */ -#define NOT_KILLED SHUTDOWN_DEFAULT - - /* options for mysql_set_option */ enum enum_mysql_set_option { diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index fbadfc2c76e..c95c5e3a982 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1291,7 +1291,7 @@ mysql_drop_db(MYSQL *mysql, const char *db) int STDCALL -mysql_shutdown(MYSQL *mysql, enum enum_shutdown_level shutdown_level) +mysql_shutdown(MYSQL *mysql, enum mysql_enum_shutdown_level shutdown_level) { uchar level[1]; DBUG_ENTER("mysql_shutdown"); diff --git a/myisam/mi_search.c b/myisam/mi_search.c index 2f1c37e4f21..24f5db1401d 100644 --- a/myisam/mi_search.c +++ b/myisam/mi_search.c @@ -396,9 +396,18 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, matched=prefix_len+left; - for (my_flag=0;left;left--) - if ((my_flag= (int) sort_order[*vseg++] - (int) sort_order[*k++])) - break; + if (sort_order) + { + for (my_flag=0;left;left--) + if ((my_flag= (int) sort_order[*vseg++] - (int) sort_order[*k++])) + break; + } + else + { + for (my_flag=0;left;left--) + if ((my_flag= (int) *vseg++ - (int) *k++)) + break; + } if (my_flag>0) /* mismatch */ break; diff --git a/mysql-test/r/binary.result b/mysql-test/r/binary.result index 000c0c16d77..a4ced14bb12 100644 --- a/mysql-test/r/binary.result +++ b/mysql-test/r/binary.result @@ -59,8 +59,10 @@ concat("-",a,"-",b,"-") -hello-hello- select concat("-",a,"-",b,"-") from t1 where b="hello "; concat("-",a,"-",b,"-") +-hello-hello- select concat("-",a,"-",b,"-") from t1 ignore index (b) where b="hello "; concat("-",a,"-",b,"-") +-hello-hello- alter table t1 modify b tinytext not null, drop key b, add key (b(100)); select concat("-",a,"-",b,"-") from t1; concat("-",a,"-",b,"-") diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 793e2ceff19..6c6e5114cf8 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -79,6 +79,21 @@ SELECT 'a\t' < 'a'; SELECT 'a\t' < 'a '; 'a\t' < 'a ' 1 +SELECT 'a' = 'a ' collate utf8_bin; +'a' = 'a ' collate utf8_bin +1 +SELECT 'a\0' < 'a' collate utf8_bin; +'a\0' < 'a' collate utf8_bin +1 +SELECT 'a\0' < 'a ' collate utf8_bin; +'a\0' < 'a ' collate utf8_bin +1 +SELECT 'a\t' < 'a' collate utf8_bin; +'a\t' < 'a' collate utf8_bin +1 +SELECT 'a\t' < 'a ' collate utf8_bin; +'a\t' < 'a ' collate utf8_bin +1 CREATE TABLE t1 (a char(10) character set utf8 not null); INSERT INTO t1 VALUES ('a'),('a\0'),('a\t'),('a '); SELECT hex(a),STRCMP(a,'a'), STRCMP(a,'a ') FROM t1; @@ -362,6 +377,134 @@ c_a б drop table t1; create table t1 ( +c char(10) character set utf8, +unique key a using btree (c(1)) +) engine=heap; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` char(10) character set utf8 default NULL, + UNIQUE KEY `a` TYPE BTREE (`c`(1)) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); +insert into t1 values ('aa'); +ERROR 23000: Duplicate entry 'aa' for key 1 +insert into t1 values ('aaa'); +ERROR 23000: Duplicate entry 'aaa' for key 1 +insert into t1 values ('б'); +insert into t1 values ('бб'); +ERROR 23000: Duplicate entry 'бÐ' for key 1 +insert into t1 values ('ббб'); +ERROR 23000: Duplicate entry 'бÐ' for key 1 +select c as c_all from t1 order by c; +c_all +a +b +c +d +e +f +б +select c as c_a from t1 where c='a'; +c_a +a +select c as c_a from t1 where c='б'; +c_a +б +drop table t1; +create table t1 (c varchar(30) character set utf8 collate utf8_bin, unique(c(10))); +insert into t1 values ('1'),('2'),('3'),('x'),('y'),('z'); +insert into t1 values ('aaaaaaaaaa'); +insert into t1 values ('aaaaaaaaaaa'); +ERROR 23000: Duplicate entry 'aaaaaaaaaaa' for key 1 +insert into t1 values ('aaaaaaaaaaaa'); +ERROR 23000: Duplicate entry 'aaaaaaaaaaaa' for key 1 +insert into t1 values (repeat('b',20)); +select c c1 from t1 where c='1'; +c1 +1 +select c c2 from t1 where c='2'; +c2 +2 +select c c3 from t1 where c='3'; +c3 +3 +select c cx from t1 where c='x'; +cx +x +select c cy from t1 where c='y'; +cy +y +select c cz from t1 where c='z'; +cz +z +select c ca10 from t1 where c='aaaaaaaaaa'; +ca10 +aaaaaaaaaa +select c cb20 from t1 where c=repeat('b',20); +cb20 +bbbbbbbbbbbbbbbbbbbb +drop table t1; +create table t1 (c char(3) character set utf8 collate utf8_bin, unique (c(2))); +insert into t1 values ('1'),('2'),('3'),('4'),('x'),('y'),('z'); +insert into t1 values ('a'); +insert into t1 values ('aa'); +insert into t1 values ('aaa'); +ERROR 23000: Duplicate entry 'aaa' for key 1 +insert into t1 values ('b'); +insert into t1 values ('bb'); +insert into t1 values ('bbb'); +ERROR 23000: Duplicate entry 'bbb' for key 1 +insert into t1 values ('а'); +insert into t1 values ('аа'); +insert into t1 values ('ааа'); +ERROR 23000: Duplicate entry 'ааа' for key 1 +insert into t1 values ('б'); +insert into t1 values ('бб'); +insert into t1 values ('ббб'); +ERROR 23000: Duplicate entry 'ббб' for key 1 +insert into t1 values ('ꪪ'); +insert into t1 values ('ꪪꪪ'); +insert into t1 values ('ꪪꪪꪪ'); +ERROR 23000: Duplicate entry 'ꪪꪪ' for key 1 +drop table t1; +create table t1 ( +c char(10) character set utf8 collate utf8_bin, +unique key a using hash (c(1)) +) engine=heap; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` char(10) character set utf8 collate utf8_bin default NULL, + UNIQUE KEY `a` (`c`(1)) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); +insert into t1 values ('aa'); +ERROR 23000: Duplicate entry 'aa' for key 1 +insert into t1 values ('aaa'); +ERROR 23000: Duplicate entry 'aaa' for key 1 +insert into t1 values ('б'); +insert into t1 values ('бб'); +ERROR 23000: Duplicate entry 'бÐ' for key 1 +insert into t1 values ('ббб'); +ERROR 23000: Duplicate entry 'бÐ' for key 1 +select c as c_all from t1 order by c; +c_all +a +b +c +d +e +f +б +select c as c_a from t1 where c='a'; +c_a +a +select c as c_a from t1 where c='б'; +c_a +б +drop table t1; +create table t1 ( c char(10) character set utf8 collate utf8_bin, unique key a using btree (c(1)) ) engine=heap; diff --git a/mysql-test/r/endspace.result b/mysql-test/r/endspace.result index 4800bbf4ecb..167adea6674 100644 --- a/mysql-test/r/endspace.result +++ b/mysql-test/r/endspace.result @@ -19,7 +19,7 @@ select 'a a' > 'a', 'a \0' < 'a'; 1 1 select binary 'a a' > 'a', binary 'a \0' > 'a', binary 'a\0' > 'a'; binary 'a a' > 'a' binary 'a \0' > 'a' binary 'a\0' > 'a' -1 1 1 +1 0 0 create table t1 (text1 varchar(32) not NULL, KEY key1 (text1)); insert into t1 values ('teststring'), ('nothing'), ('teststring\t'); check table t1; diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 354675cd4d4..0109097d3a1 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -412,6 +412,7 @@ aaa. aaa . select concat(a,'.') from t1 where binary a='aaa'; concat(a,'.') +aaa . aaa. update t1 set a='bbb' where a='aaa'; select concat(a,'.') from t1; diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 808e04c56d8..21880732e47 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -46,6 +46,15 @@ SELECT 'a\0' < 'a '; SELECT 'a\t' < 'a'; SELECT 'a\t' < 'a '; +# +# The same for binary collation +# +SELECT 'a' = 'a ' collate utf8_bin; +SELECT 'a\0' < 'a' collate utf8_bin; +SELECT 'a\0' < 'a ' collate utf8_bin; +SELECT 'a\t' < 'a' collate utf8_bin; +SELECT 'a\t' < 'a ' collate utf8_bin; + CREATE TABLE t1 (a char(10) character set utf8 not null); INSERT INTO t1 VALUES ('a'),('a\0'),('a\t'),('a '); SELECT hex(a),STRCMP(a,'a'), STRCMP(a,'a ') FROM t1; @@ -189,7 +198,7 @@ drop table t2; # # Bug 4521: unique key prefix interacts poorly with utf8 -# Check keys with prefix compression +# MYISAM: keys with prefix compression, case insensitive collation. # create table t1 (c varchar(30) character set utf8, unique(c(10))); insert into t1 values ('1'),('2'),('3'),('x'),('y'),('z'); @@ -211,7 +220,8 @@ drop table t1; # # Bug 4521: unique key prefix interacts poorly with utf8 -# Check fixed length keys +# MYISAM: fixed length keys, case insensitive collation +# create table t1 (c char(3) character set utf8, unique (c(2))); insert into t1 values ('1'),('2'),('3'),('4'),('x'),('y'),('z'); insert into t1 values ('a'); @@ -265,6 +275,105 @@ drop table t1; # Check HEAP+BTREE, case insensitive collation # create table t1 ( +c char(10) character set utf8, +unique key a using btree (c(1)) +) engine=heap; +show create table t1; +insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); +--error 1062 +insert into t1 values ('aa'); +--error 1062 +insert into t1 values ('aaa'); +insert into t1 values ('б'); +--error 1062 +insert into t1 values ('бб'); +--error 1062 +insert into t1 values ('ббб'); +select c as c_all from t1 order by c; +select c as c_a from t1 where c='a'; +select c as c_a from t1 where c='б'; +drop table t1; + + +# +# Bug 4521: unique key prefix interacts poorly with utf8 +# MYISAM: keys with prefix compression, binary collation. +# +create table t1 (c varchar(30) character set utf8 collate utf8_bin, unique(c(10))); +insert into t1 values ('1'),('2'),('3'),('x'),('y'),('z'); +insert into t1 values ('aaaaaaaaaa'); +--error 1062 +insert into t1 values ('aaaaaaaaaaa'); +--error 1062 +insert into t1 values ('aaaaaaaaaaaa'); +insert into t1 values (repeat('b',20)); +select c c1 from t1 where c='1'; +select c c2 from t1 where c='2'; +select c c3 from t1 where c='3'; +select c cx from t1 where c='x'; +select c cy from t1 where c='y'; +select c cz from t1 where c='z'; +select c ca10 from t1 where c='aaaaaaaaaa'; +select c cb20 from t1 where c=repeat('b',20); +drop table t1; + +# +# Bug 4521: unique key prefix interacts poorly with utf8 +# MYISAM: fixed length keys, binary collation +# +create table t1 (c char(3) character set utf8 collate utf8_bin, unique (c(2))); +insert into t1 values ('1'),('2'),('3'),('4'),('x'),('y'),('z'); +insert into t1 values ('a'); +insert into t1 values ('aa'); +--error 1062 +insert into t1 values ('aaa'); +insert into t1 values ('b'); +insert into t1 values ('bb'); +--error 1062 +insert into t1 values ('bbb'); +insert into t1 values ('а'); +insert into t1 values ('аа'); +--error 1062 +insert into t1 values ('ааа'); +insert into t1 values ('б'); +insert into t1 values ('бб'); +--error 1062 +insert into t1 values ('ббб'); +insert into t1 values ('ꪪ'); +insert into t1 values ('ꪪꪪ'); +--error 1062 +insert into t1 values ('ꪪꪪꪪ'); +drop table t1; + +# +# Bug 4531: unique key prefix interacts poorly with utf8 +# Check HEAP+HASH, binary collation +# +create table t1 ( +c char(10) character set utf8 collate utf8_bin, +unique key a using hash (c(1)) +) engine=heap; +show create table t1; +insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); +--error 1062 +insert into t1 values ('aa'); +--error 1062 +insert into t1 values ('aaa'); +insert into t1 values ('б'); +--error 1062 +insert into t1 values ('бб'); +--error 1062 +insert into t1 values ('ббб'); +select c as c_all from t1 order by c; +select c as c_a from t1 where c='a'; +select c as c_a from t1 where c='б'; +drop table t1; + +# +# Bug 4531: unique key prefix interacts poorly with utf8 +# Check HEAP+BTREE, binary collation +# +create table t1 ( c char(10) character set utf8 collate utf8_bin, unique key a using btree (c(1)) ) engine=heap; diff --git a/sql/field.h b/sql/field.h index fe06cd96f1a..83c5a71f07f 100644 --- a/sql/field.h +++ b/sql/field.h @@ -357,7 +357,7 @@ public: uint size_of() const { return sizeof(*this); } CHARSET_INFO *charset(void) const { return field_charset; } void set_charset(CHARSET_INFO *charset) { field_charset=charset; } - bool binary() const { return field_charset->state & MY_CS_BINSORT ? 1 : 0; } + bool binary() const { return field_charset == &my_charset_bin; } uint32 max_length() { return field_length; } friend class create_field; }; diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 39ef6ca855a..7cd534d60b3 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -357,9 +357,11 @@ ulong ha_berkeley::index_flags(uint idx, uint part, bool all_parts) const case HA_KEYTYPE_VARTEXT: /* As BDB stores only one copy of equal strings, we can't use key read - on these + on these. Binary collations do support key read though. */ - flags&= ~HA_KEYREAD_ONLY; + if (!(table->key_info[idx].key_part[i].field->charset()->state + & MY_CS_BINSORT)) + flags&= ~HA_KEYREAD_ONLY; break; default: // Keep compiler happy break; diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index a7f6cc45831..d7327362286 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -430,7 +430,7 @@ int ha_heap::create(const char *name, TABLE *table_arg, { if (!f_is_packed(flag) && f_packtype(flag) == (int) FIELD_TYPE_DECIMAL && - !(flag & FIELDFLAG_BINARY)) + !(field->charset() == &my_charset_bin)) seg->type= (int) HA_KEYTYPE_TEXT; else seg->type= (int) HA_KEYTYPE_BINARY; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 23bdad1aae5..3c75dba42da 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -303,10 +303,10 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type) my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name()); return 1; } - if (my_binary_compare(cmp_collation.collation)) + if (cmp_collation.collation == &my_charset_bin) { /* - We are using binary collation, change to compare byte by byte, + We are using BLOB/BINARY/VARBINARY, change to compare byte by byte, without removing end space */ if (func == &Arg_comparator::compare_string) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 57e4022719e..5aa4a8de156 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1643,8 +1643,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in packet[0]. */ - enum enum_shutdown_level level= - (enum enum_shutdown_level) (uchar) packet[0]; + enum mysql_enum_shutdown_level level= + (enum mysql_enum_shutdown_level) (uchar) packet[0]; DBUG_PRINT("quit",("Got shutdown command for level %u", level)); if (level == SHUTDOWN_DEFAULT) level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index cc83471f264..e759a5654f1 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -68,31 +68,10 @@ static uchar bin_char_array[] = -/* - Compare two strings. Result is sign(first_argument - second_argument) - - SYNOPSIS - my_strnncoll_binary() - cs Chararacter set - s String to compare - slen Length of 's' - t String to compare - tlen Length of 't' - - NOTE - This is used also when comparing with end space removal, as end space - is significant for binary strings - - RETURN - < 0 s < t - 0 s == t - > 0 s > t -*/ - static int my_strnncoll_binary(CHARSET_INFO * cs __attribute__((unused)), - const uchar *s, uint slen, - const uchar *t, uint tlen, - my_bool t_is_prefix) + const uchar *s, uint slen, + const uchar *t, uint tlen, + my_bool t_is_prefix) { uint len=min(slen,tlen); int cmp= memcmp(s,t,len); @@ -100,14 +79,105 @@ static int my_strnncoll_binary(CHARSET_INFO * cs __attribute__((unused)), } +/* + Compare two strings. Result is sign(first_argument - second_argument) + + SYNOPSIS + my_strnncollsp_binary() + cs Chararacter set + s String to compare + slen Length of 's' + t String to compare + tlen Length of 't' + + NOTE + This function is used for real binary strings, i.e. for + BLOB, BINARY(N) and VARBINARY(N). + It does not ignore trailing spaces. + + RETURN + < 0 s < t + 0 s == t + > 0 s > t +*/ + static int my_strnncollsp_binary(CHARSET_INFO * cs __attribute__((unused)), - const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *s, uint slen, + const uchar *t, uint tlen) { return my_strnncoll_binary(cs,s,slen,t,tlen,0); } +static int my_strnncoll_8bit_bin(CHARSET_INFO * cs __attribute__((unused)), + const uchar *s, uint slen, + const uchar *t, uint tlen, + my_bool t_is_prefix) +{ + uint len=min(slen,tlen); + int cmp= memcmp(s,t,len); + return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen); +} + + +/* + Compare two strings. Result is sign(first_argument - second_argument) + + SYNOPSIS + my_strnncollsp_8bit_bin() + cs Chararacter set + s String to compare + slen Length of 's' + t String to compare + tlen Length of 't' + + NOTE + This function is used for character strings with binary collations. + It ignores trailing spaces. + + RETURN + < 0 s < t + 0 s == t + > 0 s > t +*/ + +static int my_strnncollsp_8bit_bin(CHARSET_INFO * cs __attribute__((unused)), + const uchar *a, uint a_length, + const uchar *b, uint b_length) +{ + const uchar *end; + uint length; + + end= a + (length= min(a_length, b_length)); + while (a < end) + { + if (*a++ != *b++) + return ((int) a[-1] - (int) b[-1]); + } + if (a_length != b_length) + { + int swap= 0; + /* + Check the next not space character of the longer key. If it's < ' ', + then it's smaller than the other key. + */ + if (a_length < b_length) + { + /* put shorter key in s */ + a_length= b_length; + a= b; + swap= -1; /* swap sign of result */ + } + for (end= a + a_length-length; a < end ; a++) + { + if (*a != ' ') + return ((int) *a - (int) ' ') ^ swap; + } + } + return 0; +} + + /* This function is used for all conversion functions */ static void my_case_str_bin(CHARSET_INFO *cs __attribute__((unused)), @@ -342,6 +412,20 @@ skip: MY_COLLATION_HANDLER my_collation_8bit_bin_handler = +{ + NULL, /* init */ + my_strnncoll_8bit_bin, + my_strnncollsp_8bit_bin, + my_strnxfrm_bin, + my_like_range_simple, + my_wildcmp_bin, + my_strcasecmp_bin, + my_instr_bin, + my_hash_sort_bin +}; + + +static MY_COLLATION_HANDLER my_collation_binary_handler = { NULL, /* init */ my_strnncoll_binary, @@ -407,5 +491,5 @@ CHARSET_INFO my_charset_bin = 0, /* min_sort_char */ 255, /* max_sort_char */ &my_charset_handler, - &my_collation_8bit_bin_handler + &my_collation_binary_handler }; diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 7b0dadcfa19..ecafa6356d5 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -360,11 +360,62 @@ static int my_strnncoll_mb_bin(CHARSET_INFO * cs __attribute__((unused)), return cmp ? cmp : (int) ((t_is_prefix ? len : slen) - tlen); } + +/* + Compare two strings. + + SYNOPSIS + my_strnncollsp_mb_bin() + cs Chararacter set + s String to compare + slen Length of 's' + t String to compare + tlen Length of 't' + + NOTE + This function is used for character strings with binary collations. + It ignores trailing spaces. + + RETURN + A negative number if s < t + A positive number if s > t + 0 if strings are equal +*/ + static int my_strnncollsp_mb_bin(CHARSET_INFO * cs __attribute__((unused)), - const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *a, uint a_length, + const uchar *b, uint b_length) { - return my_strnncoll_mb_bin(cs,s,slen,t,tlen,0); + const uchar *end; + uint length; + + end= a + (length= min(a_length, b_length)); + while (a < end) + { + if (*a++ != *b++) + return ((int) a[-1] - (int) b[-1]); + } + if (a_length != b_length) + { + int swap= 0; + /* + Check the next not space character of the longer key. If it's < ' ', + then it's smaller than the other key. + */ + if (a_length < b_length) + { + /* put shorter key in s */ + a_length= b_length; + a= b; + swap= -1; /* swap sign of result */ + } + for (end= a + a_length-length; a < end ; a++) + { + if (*a != ' ') + return ((int) *a - (int) ' ') ^ swap; + } + } + return 0; }