mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 02:51:44 +01:00
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.
This commit is contained in:
parent
7b049bf2cd
commit
d91cbf34ff
3 changed files with 54 additions and 2 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue