summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <evgen@moonbone.local>2005-12-27 20:16:59 +0300
committerunknown <evgen@moonbone.local>2005-12-27 20:16:59 +0300
commit9a128b97d13bb68449c94285b80eda22b37ecbb1 (patch)
tree3754ebf647321dd47b3b485a4756970aadbdf56f
parentc2ac089167ac158aff1318cdb94c55a48fae34a5 (diff)
downloadmariadb-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.result7
-rw-r--r--mysql-test/t/ctype_ucs.test8
-rw-r--r--strings/ctype-ucs2.c41
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;
}