Commit 2b5a657a authored by jan@hundin.mysql.fi's avatar jan@hundin.mysql.fi

Merge jlindstrom@build.mysql.com:/home/bk/mysql-4.1

into hundin.mysql.fi:/home/jan/mysql-4.1
parents 1fa0817b 73a3e555
...@@ -245,7 +245,15 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) ...@@ -245,7 +245,15 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
} }
if (seg->type == HA_KEYTYPE_TEXT) if (seg->type == HA_KEYTYPE_TEXT)
{ {
seg->charset->coll->hash_sort(seg->charset,pos,((uchar*)key)-pos,&nr,&nr2); CHARSET_INFO *cs= seg->charset;
uint length= ((uchar*)key) - pos;
uint char_length= length / cs->mbmaxlen;
if (length > char_length)
{
char_length= my_charpos(cs, pos, pos + length, char_length);
set_if_smaller(char_length, length);
}
cs->coll->hash_sort(cs, pos, char_length, &nr, &nr2);
} }
else else
{ {
...@@ -280,7 +288,14 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) ...@@ -280,7 +288,14 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
} }
if (seg->type == HA_KEYTYPE_TEXT) if (seg->type == HA_KEYTYPE_TEXT)
{ {
seg->charset->coll->hash_sort(seg->charset,pos,end-pos,&nr,&nr2); CHARSET_INFO *cs= seg->charset;
uint char_length= seg->length / cs->mbmaxlen;
if (seg->length > char_length)
{
char_length= my_charpos(cs, pos, pos + seg->length, char_length);
set_if_smaller(char_length, seg->length);
}
cs->coll->hash_sort(cs, pos, char_length, &nr, &nr2);
} }
else else
{ {
...@@ -401,9 +416,26 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2) ...@@ -401,9 +416,26 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2)
} }
if (seg->type == HA_KEYTYPE_TEXT) if (seg->type == HA_KEYTYPE_TEXT)
{ {
CHARSET_INFO *cs= seg->charset;
uint char_length= seg->length / cs->mbmaxlen;
uint char_length1;
uint char_length2;
uchar *pos1= (uchar*)rec1 + seg->start;
uchar *pos2= (uchar*)rec2 + seg->start;
if (seg->length > char_length)
{
char_length1= my_charpos(cs, pos1, pos1 + seg->length, char_length);
set_if_smaller(char_length1, seg->length);
char_length2= my_charpos(cs, pos2, pos2 + seg->length, char_length);
set_if_smaller(char_length2, seg->length);
}
else
{
char_length1= char_length2= seg->length;
}
if (seg->charset->coll->strnncollsp(seg->charset, if (seg->charset->coll->strnncollsp(seg->charset,
(uchar*) rec1+seg->start,seg->length, pos1,char_length1,
(uchar*) rec2+seg->start,seg->length)) pos2,char_length2))
return 1; return 1;
} }
else else
...@@ -435,9 +467,27 @@ int hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key) ...@@ -435,9 +467,27 @@ int hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key)
} }
if (seg->type == HA_KEYTYPE_TEXT) if (seg->type == HA_KEYTYPE_TEXT)
{ {
CHARSET_INFO *cs= seg->charset;
uint char_length= seg->length / cs->mbmaxlen;
uint char_length_key;
uint char_length_rec;
uchar *pos= (uchar*) rec + seg->start;
if (seg->length > char_length)
{
char_length_key= my_charpos(cs, key, key + seg->length, char_length);
set_if_smaller(char_length_key, seg->length);
char_length_rec= my_charpos(cs, pos, pos + seg->length, char_length);
set_if_smaller(char_length_rec, seg->length);
}
else
{
char_length_key= seg->length;
char_length_rec= seg->length;
}
if (seg->charset->coll->strnncollsp(seg->charset, if (seg->charset->coll->strnncollsp(seg->charset,
(uchar*) rec+seg->start, seg->length, (uchar*) pos, char_length_rec,
(uchar*) key, seg->length)) (uchar*) key, char_length_key))
return 1; return 1;
} }
else else
...@@ -458,10 +508,19 @@ void hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec) ...@@ -458,10 +508,19 @@ void hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec)
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
{ {
CHARSET_INFO *cs= seg->charset;
uint char_length= (cs && cs->mbmaxlen > 1) ? seg->length / cs->mbmaxlen :
seg->length;
uchar *pos= (uchar*) rec + seg->start;
if (seg->null_bit) if (seg->null_bit)
*key++= test(rec[seg->null_pos] & seg->null_bit); *key++= test(rec[seg->null_pos] & seg->null_bit);
memcpy(key,rec+seg->start,(size_t) seg->length); if (seg->length > char_length)
key+=seg->length; {
char_length= my_charpos(cs, pos, pos + seg->length, char_length);
set_if_smaller(char_length, seg->length);
}
memcpy(key,rec+seg->start,(size_t) char_length);
key+= char_length;
} }
} }
...@@ -473,6 +532,7 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key, ...@@ -473,6 +532,7 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key,
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++) for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
{ {
uint char_length;
if (seg->null_bit) if (seg->null_bit)
{ {
if (!(*key++= 1 - test(rec[seg->null_pos] & seg->null_bit))) if (!(*key++= 1 - test(rec[seg->null_pos] & seg->null_bit)))
...@@ -515,7 +575,18 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key, ...@@ -515,7 +575,18 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key,
} }
continue; continue;
} }
memcpy(key, rec + seg->start, (size_t) seg->length); char_length= seg->length / (seg->charset ? seg->charset->mbmaxlen : 1);
if (seg->length > char_length)
{
char_length= my_charpos(seg->charset,
rec + seg->start, rec + seg->start + seg->length,
char_length);
set_if_smaller(char_length, seg->length);
if (char_length < seg->length)
seg->charset->cset->fill(seg->charset, key + char_length,
seg->length - char_length, ' ');
}
memcpy(key, rec + seg->start, (size_t) char_length);
key+= seg->length; key+= seg->length;
} }
memcpy(key, &recpos, sizeof(byte*)); memcpy(key, &recpos, sizeof(byte*));
...@@ -530,6 +601,7 @@ uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len) ...@@ -530,6 +601,7 @@ uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len)
for (seg= keydef->seg, endseg= seg + keydef->keysegs; for (seg= keydef->seg, endseg= seg + keydef->keysegs;
seg < endseg && (int) k_len > 0; old+= seg->length, seg++) seg < endseg && (int) k_len > 0; old+= seg->length, seg++)
{ {
uint char_length;
if (seg->null_bit) if (seg->null_bit)
{ {
k_len--; k_len--;
...@@ -551,7 +623,16 @@ uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len) ...@@ -551,7 +623,16 @@ uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len)
} }
continue; continue;
} }
memcpy((byte*) key, old, seg->length); char_length= seg->length / (seg->charset ? seg->charset->mbmaxlen : 1);
if (seg->length > char_length)
{
char_length= my_charpos(seg->charset, old, old+seg->length, char_length);
set_if_smaller(char_length, seg->length);
if (char_length < seg->length)
seg->charset->cset->fill(seg->charset, key + char_length,
seg->length - char_length, ' ');
}
memcpy(key, old, (size_t) char_length);
key+= seg->length; key+= seg->length;
k_len-= seg->length; k_len-= seg->length;
} }
......
...@@ -325,3 +325,75 @@ insert into t1 values ('ꪪꪪ'); ...@@ -325,3 +325,75 @@ insert into t1 values ('ꪪꪪ');
insert into t1 values ('ꪪꪪꪪ'); insert into t1 values ('ꪪꪪꪪ');
ERROR 23000: Duplicate entry 'ꪪꪪ' for key 1 ERROR 23000: Duplicate entry 'ꪪꪪ' for key 1
drop table t1; drop table t1;
create table t1 (
c char(10) character set utf8,
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 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;
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` 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;
...@@ -317,6 +317,7 @@ NDBCLUSTER YES/NO Clustered, fault-tolerant, memory-based tables ...@@ -317,6 +317,7 @@ NDBCLUSTER YES/NO Clustered, fault-tolerant, memory-based tables
NDB YES/NO Alias for NDBCLUSTER NDB YES/NO Alias for NDBCLUSTER
EXAMPLE YES/NO Example storage engine EXAMPLE YES/NO Example storage engine
ARCHIVE YES/NO Archive storage engine ARCHIVE YES/NO Archive storage engine
CSV YES/NO CSV storage engine
drop table if exists tx; drop table if exists tx;
prepare stmt1 from ' drop table if exists tx ' ; prepare stmt1 from ' drop table if exists tx ' ;
execute stmt1 ; execute stmt1 ;
......
...@@ -236,3 +236,50 @@ insert into t1 values ('ꪪꪪ'); ...@@ -236,3 +236,50 @@ insert into t1 values ('ꪪꪪ');
insert into t1 values ('ꪪꪪꪪ'); insert into t1 values ('ꪪꪪꪪ');
drop table t1; drop table t1;
#
# Bug 4531: unique key prefix interacts poorly with utf8
# Check HEAP+HASH, case insensitive collation
#
create table t1 (
c char(10) character set utf8,
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, case insensitive collation
#
create table t1 (
c char(10) character set utf8 collate utf8_bin,
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;
...@@ -189,7 +189,6 @@ sub new ...@@ -189,7 +189,6 @@ sub new
$self->{'transactions'} = 1; # Transactions enabled $self->{'transactions'} = 1; # Transactions enabled
$limits{'max_columns'} = 90; # Max number of columns in table $limits{'max_columns'} = 90; # Max number of columns in table
$limits{'max_tables'} = 32; # No comments $limits{'max_tables'} = 32; # No comments
$limits{'working_blobs'} = 0; # NDB tables can't handle BLOB's
} }
if (defined($main::opt_create_options) && if (defined($main::opt_create_options) &&
$main::opt_create_options =~ /type=bdb/i) $main::opt_create_options =~ /type=bdb/i)
......
...@@ -34,6 +34,12 @@ ...@@ -34,6 +34,12 @@
- If the variable should show up in 'show variables' add it to the - If the variable should show up in 'show variables' add it to the
init_vars[] struct in this file init_vars[] struct in this file
NOTES:
- Be careful with var->save_result: sys_var::check() only updates
ulonglong_value; so other members of the union are garbage then; to use
them you must first assign a value to them (in specific ::check() for
example).
TODO: TODO:
- Add full support for the variable character_set (for 4.1) - Add full support for the variable character_set (for 4.1)
...@@ -2332,7 +2338,7 @@ bool sys_var_slave_skip_counter::update(THD *thd, set_var *var) ...@@ -2332,7 +2338,7 @@ bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
bool sys_var_sync_binlog_period::update(THD *thd, set_var *var) bool sys_var_sync_binlog_period::update(THD *thd, set_var *var)
{ {
pthread_mutex_t *lock_log= mysql_bin_log.get_log_lock(); pthread_mutex_t *lock_log= mysql_bin_log.get_log_lock();
sync_binlog_period= var->save_result.ulong_value; sync_binlog_period= (ulong) var->save_result.ulonglong_value;
/* /*
Must reset the counter otherwise it may already be beyond the new period Must reset the counter otherwise it may already be beyond the new period
and so the new period will not be taken into account. Need mutex otherwise and so the new period will not be taken into account. Need mutex otherwise
......
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