diff options
author | unknown <evgen@moonbone.local> | 2005-12-27 20:16:59 +0300 |
---|---|---|
committer | unknown <evgen@moonbone.local> | 2005-12-27 20:16:59 +0300 |
commit | 9a128b97d13bb68449c94285b80eda22b37ecbb1 (patch) | |
tree | 3754ebf647321dd47b3b485a4756970aadbdf56f | |
parent | c2ac089167ac158aff1318cdb94c55a48fae34a5 (diff) | |
download | mariadb-git-9a128b97d13bb68449c94285b80eda22b37ecbb1.tar.gz |
Fix bug#14583
When InnoDB compares varchar field in ucs2 with given key using bin collation,
it calls my_strnncollsp_ucs2_bin() to perform comparison.
Because field length was lesser than length of key field should be padded
with trailing spaces in order to get correct result.
Because my_strnncollsp_ucs2_bin() was calling my_strnncollp_ucs2_bin(), which
doesn't pads field, wrong comparison result was returned. This results in
wrong result set.
my_strnncollsp_ucs2_bin() now compares fields like my_strnncollsp_ucs2 do,
but using binary collation.
mysql-test/t/ctype_ucs.test:
Test case for bug#14583 Wrong my_strnncollsp_ucs2_bin() behaviour results in skipping
correct records.
mysql-test/r/ctype_ucs.result:
Test case for bug#14583 Wrong my_strnncollsp_ucs2_bin() behaviour results in skipping correct records.
strings/ctype-ucs2.c:
Fix bug#14583 Wrong my_strnncollsp_ucs2_bin() behaviour results in skipping
correct records.my_strnncollsp_ucs2_bin() now compares fields like my_strnncollsp_ucs2 do,
but using binary collation.
-rw-r--r-- | mysql-test/r/ctype_ucs.result | 7 | ||||
-rw-r--r-- | mysql-test/t/ctype_ucs.test | 8 | ||||
-rw-r--r-- | strings/ctype-ucs2.c | 41 |
3 files changed, 54 insertions, 2 deletions
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 619ad750ff3..3ca56548de9 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -677,3 +677,10 @@ hex(a) 005B 803D drop table t1; +create table t1(f1 varchar(5) CHARACTER SET ucs2 COLLATE ucs2_bin NOT NULL) engine=InnoDB; +insert into t1 values('a'); +create index t1f1 on t1(f1); +select f1 from t1 where f1 like 'a%'; +f1 +a +drop table t1; diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index 2c9e71ddff5..3b3c2c70f32 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -419,4 +419,12 @@ insert into t1 values (0x005b); select hex(a) from t1; drop table t1; +# +# Bug #14583 Bug on query using a LIKE on indexed field with ucs2_bin collation +# +create table t1(f1 varchar(5) CHARACTER SET ucs2 COLLATE ucs2_bin NOT NULL) engine=InnoDB; +insert into t1 values('a'); +create index t1f1 on t1(f1); +select f1 from t1 where f1 like 'a%'; +drop table t1; # End of 4.1 tests diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index ad07fd9903c..d8985a890d9 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1352,11 +1352,48 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *cs, return t_is_prefix ? (int) (t - te) : (int) ((se-s) - (te-t)); } -static int my_strnncollsp_ucs2_bin(CHARSET_INFO *cs, +static int my_strnncollsp_ucs2_bin(CHARSET_INFO *cs __attribute__((unused)), const uchar *s, uint slen, const uchar *t, uint tlen) { - return my_strnncoll_ucs2_bin(cs,s,slen,t,tlen,0); + const uchar *se, *te; + uint minlen; + + /* extra safety to make sure the lengths are even numbers */ + slen= (slen >> 1) << 1; + tlen= (tlen >> 1) << 1; + + se= s + slen; + te= t + tlen; + + for (minlen= min(slen, tlen); minlen; minlen-= 2) + { + int s_wc= s[0] * 256 + s[1]; + int t_wc= t[0] * 256 + t[1]; + if ( s_wc != t_wc ) + return s_wc > t_wc ? 1 : -1; + + s+= 2; + t+= 2; + } + + if (slen != tlen) + { + int swap= 1; + if (slen < tlen) + { + s= t; + se= te; + swap= -1; + } + + for ( ; s < se ; s+= 2) + { + if (s[0] || s[1] != ' ') + return (s[0] == 0 && s[1] < ' ') ? -swap : swap; + } + } + return 0; } |