Commit b033e3df authored by unknown's avatar unknown

BDB: Bug#4531: unique key prefix interacts poorly with utf8,

Bug#4594 column index make = failed for gbk


myisam/mi_key.c:
  cleanup
parent a7c81531
......@@ -25,9 +25,12 @@
#define CHECK_KEYS
#define FIX_LENGTH if (length > char_length) \
char_length= my_charpos(cs, pos, pos+length, char_length); \
set_if_smaller(char_length,length); \
#define FIX_LENGTH \
do { \
if (length > char_length) \
char_length= my_charpos(cs, pos, pos+length, char_length); \
set_if_smaller(char_length,length); \
} while(0)
static int _mi_put_key_in_record(MI_INFO *info,uint keynr,byte *record);
......@@ -157,7 +160,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
FIX_LENGTH;
memcpy((byte*) key, pos, char_length);
if (length > char_length)
bfill(key+char_length, length-char_length, ' ');
cs->cset->fill(cs, key+char_length, length-char_length, ' ');
key+= length;
}
_mi_dpointer(info,key,filepos);
......@@ -267,7 +270,7 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
FIX_LENGTH;
memcpy((byte*) key, pos, char_length);
if (length > char_length)
bfill(key+char_length, length-char_length, ' ');
cs->cset->fill(cs,key+char_length, length-char_length, ' ');
key+= length;
k_length-=length;
}
......
......@@ -412,6 +412,36 @@ select c as c_a from t1 where c='б';
c_a
б
drop table t1;
create table t1 (
c char(10) character set utf8,
unique key a (c(1))
) engine=bdb;
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');
......@@ -541,6 +571,36 @@ c_a
б
drop table t1;
create table t1 (
c char(10) character set utf8 collate utf8_bin,
unique key a (c(1))
) engine=bdb;
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 (
str varchar(255) character set utf8 not null,
key str (str(2))
) engine=myisam;
......@@ -570,3 +630,13 @@ select * from t1 where str='str';
str
str
drop table t1;
create table t1 (
str varchar(255) character set utf8 not null,
key str (str(2))
) engine=bdb;
INSERT INTO t1 VALUES ('str');
INSERT INTO t1 VALUES ('str2');
select * from t1 where str='str';
str
str
drop table t1;
......@@ -294,6 +294,30 @@ 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 BDB, case insensitive collation
#
--disable_warnings
create table t1 (
c char(10) character set utf8,
unique key a (c(1))
) engine=bdb;
--enable_warnings
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
......@@ -393,6 +417,31 @@ 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 BDB, binary collation
#
--disable_warnings
create table t1 (
c char(10) character set utf8 collate utf8_bin,
unique key a (c(1))
) engine=bdb;
--enable_warnings
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#4594: column index make = failed for gbk, but like works
# Check MYISAM
......@@ -429,3 +478,18 @@ INSERT INTO t1 VALUES ('str');
INSERT INTO t1 VALUES ('str2');
select * from t1 where str='str';
drop table t1;
# the same for BDB
#
--disable_warnings
create table t1 (
str varchar(255) character set utf8 not null,
key str (str(2))
) engine=bdb;
--enable_warnings
INSERT INTO t1 VALUES ('str');
INSERT INTO t1 VALUES ('str2');
select * from t1 where str='str';
drop table t1;
......@@ -4382,7 +4382,7 @@ void Field_string::sql_type(String &res) const
(field_length > 3 &&
(table->db_options_in_use &
HA_OPTION_PACK_RECORD) ?
(has_charset() ? "varchar" : "varbinary") :
(has_charset() ? "varchar" : "varbinary") :
(has_charset() ? "char" : "binary")),
(int) field_length / charset()->mbmaxlen);
res.length(length);
......@@ -4401,6 +4401,24 @@ char *Field_string::pack(char *to, const char *from, uint max_length)
}
char *Field_string::pack_key(char *to, const char *from, uint max_length)
{
const char *end=from+min(field_length,max_length);
int length;
while (end > from && end[-1] == ' ')
end--;
length= end-from;
uint char_length= (field_charset->mbmaxlen > 1) ?
max_length/field_charset->mbmaxlen : max_length;
if (length > char_length)
char_length= my_charpos(field_charset, from, end, char_length);
set_if_smaller(length, char_length);
*to= (uchar)length;
memcpy(to+1, from, length);
return to+1+length;
}
const char *Field_string::unpack(char *to, const char *from)
{
uint length= (uint) (uchar) *from++;
......@@ -4564,6 +4582,24 @@ char *Field_varstring::pack(char *to, const char *from, uint max_length)
}
char *Field_varstring::pack_key(char *to, const char *from, uint max_length)
{
uint length=uint2korr(from);
uint char_length= (field_charset->mbmaxlen > 1) ?
max_length/field_charset->mbmaxlen : max_length;
from+=HA_KEY_BLOB_LENGTH;
if (length > char_length)
char_length= my_charpos(field_charset, from, from+length, char_length);
set_if_smaller(length, char_length);
*to++= (char) (length & 255);
if (max_length > 255)
*to++= (char) (length >> 8);
if (length)
memcpy(to, from, length);
return to+length;
}
const char *Field_varstring::unpack(char *to, const char *from)
{
uint length;
......@@ -5139,16 +5175,17 @@ char *Field_blob::pack_key(char *to, const char *from, uint max_length)
char *save=ptr;
ptr=(char*) from;
uint32 length=get_length(); // Length of from string
if (length > max_length)
length=max_length;
uint char_length= (field_charset->mbmaxlen > 1) ?
max_length/field_charset->mbmaxlen : max_length;
if (length)
get_ptr((char**) &from);
if (length > char_length)
char_length= my_charpos(field_charset, from, from+length, char_length);
set_if_smaller(length, char_length);
*to++= (uchar) length;
if (max_length > 255) // 2 byte length
*to++= (uchar) (length >> 8);
if (length)
{
get_ptr((char**) &from);
memcpy(to, from, length);
}
memcpy(to, from, length);
ptr=save; // Restore org row pointer
return to+length;
}
......
......@@ -917,6 +917,7 @@ class Field_string :public Field_str {
void sort_string(char *buff,uint length);
void sql_type(String &str) const;
char *pack(char *to, const char *from, uint max_length=~(uint) 0);
char *pack_key(char *to, const char *from, uint max_length);
const char *unpack(char* to, const char *from);
int pack_cmp(const char *a,const char *b,uint key_length);
int pack_cmp(const char *b,uint key_length);
......@@ -965,6 +966,7 @@ class Field_varstring :public Field_str {
void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
void sql_type(String &str) const;
char *pack(char *to, const char *from, uint max_length=~(uint) 0);
char *pack_key(char *to, const char *from, uint max_length);
const char *unpack(char* to, const char *from);
int pack_cmp(const char *a, const char *b, uint key_length);
int pack_cmp(const char *b, uint key_length);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment