Merge mysql.com:/home/mydev/mysql-4.0
into mysql.com:/home/mydev/mysql-4.0-bug2686
This commit is contained in:
commit
f1257b3f91
@ -1190,6 +1190,22 @@ a
|
||||
A
|
||||
a
|
||||
drop table t1;
|
||||
create table t1(
|
||||
pk1 text not null, pk2 text not null, pk3 char(4),
|
||||
key1 int, key2 int,
|
||||
primary key(pk1(4), pk2(4), pk3), key(key1), key(key2)
|
||||
) engine=bdb;
|
||||
insert into t1 values (concat('aaa-', repeat('A', 4000)),
|
||||
concat('eee-', repeat('e', 4000)), 'a++a', 1, 1);
|
||||
insert into t1 values (concat('bbb-', repeat('B', 4000)),
|
||||
concat('ggg-', repeat('G', 4000)), 'b++b', 1, 1);
|
||||
select substring(pk1, 1, 4), substring(pk1, 4001),
|
||||
substring(pk2, 1, 4), substring(pk2, 4001), pk3, key1, key2
|
||||
from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
|
||||
substring(pk1, 1, 4) substring(pk1, 4001) substring(pk2, 1, 4) substring(pk2, 4001) pk3 key1 key2
|
||||
aaa- AAAA eee- eeee a++a 1 1
|
||||
bbb- BBBB ggg- GGGG b++b 1 1
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
pk1 varchar(8) not null default '',
|
||||
pk2 varchar(4) not null default '',
|
||||
|
@ -830,6 +830,25 @@ explain select a from t1;
|
||||
select a from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# bug#2686 - index_merge select on BerkeleyDB table with varchar PK causes mysqld to crash
|
||||
#
|
||||
|
||||
create table t1(
|
||||
pk1 text not null, pk2 text not null, pk3 char(4),
|
||||
key1 int, key2 int,
|
||||
primary key(pk1(4), pk2(4), pk3), key(key1), key(key2)
|
||||
) engine=bdb;
|
||||
insert into t1 values (concat('aaa-', repeat('A', 4000)),
|
||||
concat('eee-', repeat('e', 4000)), 'a++a', 1, 1);
|
||||
insert into t1 values (concat('bbb-', repeat('B', 4000)),
|
||||
concat('ggg-', repeat('G', 4000)), 'b++b', 1, 1);
|
||||
select substring(pk1, 1, 4), substring(pk1, 4001),
|
||||
substring(pk2, 1, 4), substring(pk2, 4001), pk3, key1, key2
|
||||
from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
|
||||
drop table t1;
|
||||
|
||||
|
||||
#
|
||||
# bug#2688 - Wrong index_merge query results for BDB table with variable length primary key
|
||||
#
|
||||
|
80
sql/field.cc
80
sql/field.cc
@ -4167,6 +4167,42 @@ uint32 Field_blob::get_length(const char *pos)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Put a blob length field into a record buffer.
|
||||
|
||||
SYNOPSIS
|
||||
Field_blob::put_length()
|
||||
pos Pointer into the record buffer.
|
||||
length The length value to put.
|
||||
|
||||
DESCRIPTION
|
||||
Depending on the maximum length of a blob, its length field is
|
||||
put into 1 to 4 bytes. This is a property of the blob object,
|
||||
described by 'packlength'.
|
||||
|
||||
RETURN
|
||||
nothing
|
||||
*/
|
||||
|
||||
void Field_blob::put_length(char *pos, uint32 length)
|
||||
{
|
||||
switch (packlength) {
|
||||
case 1:
|
||||
*pos= (char) length;
|
||||
break;
|
||||
case 2:
|
||||
int2store(pos, length);
|
||||
break;
|
||||
case 3:
|
||||
int3store(pos, length);
|
||||
break;
|
||||
case 4:
|
||||
int4store(pos, length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Field_blob::store(const char *from,uint len)
|
||||
{
|
||||
if (!len)
|
||||
@ -4525,6 +4561,50 @@ char *Field_blob::pack_key(char *to, const char *from, uint max_length)
|
||||
return to+length;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Unpack a blob key into a record buffer.
|
||||
|
||||
SYNOPSIS
|
||||
Field_blob::unpack_key()
|
||||
to Pointer into the record buffer.
|
||||
from Pointer to the packed key.
|
||||
max_length Key length limit from key description.
|
||||
|
||||
DESCRIPTION
|
||||
A blob key has a maximum size of 64K-1.
|
||||
In its packed form, the length field is one or two bytes long,
|
||||
depending on 'max_length'.
|
||||
Depending on the maximum length of a blob, its length field is
|
||||
put into 1 to 4 bytes. This is a property of the blob object,
|
||||
described by 'packlength'.
|
||||
Blobs are internally stored apart from the record buffer, which
|
||||
contains a pointer to the blob buffer.
|
||||
|
||||
RETURN
|
||||
Pointer into 'from' past the last byte copied from packed key.
|
||||
*/
|
||||
|
||||
const char *Field_blob::unpack_key(char *to, const char *from, uint max_length)
|
||||
{
|
||||
/* get length of the blob key */
|
||||
uint32 length= *((uchar*) from++);
|
||||
if (max_length > 255)
|
||||
length+= (*((uchar*) from++)) << 8;
|
||||
|
||||
/* put the length into the record buffer */
|
||||
put_length(to, length);
|
||||
|
||||
/* put the address of the blob buffer or NULL */
|
||||
if (length)
|
||||
memcpy_fixed(to + packlength, &from, sizeof(from));
|
||||
else
|
||||
bzero(to + packlength, sizeof(from));
|
||||
|
||||
/* point to first byte of next field in 'from' */
|
||||
return from + length;
|
||||
}
|
||||
|
||||
/* Create a packed key that will be used for storage from a MySQL key */
|
||||
|
||||
char *Field_blob::pack_key_from_key_image(char *to, const char *from,
|
||||
|
@ -189,6 +189,10 @@ public:
|
||||
{
|
||||
return pack(to,from,max_length);
|
||||
}
|
||||
virtual const char *unpack_key(char* to, const char *from, uint max_length)
|
||||
{
|
||||
return unpack(to,from);
|
||||
}
|
||||
virtual uint packed_col_length(const char *to, uint length)
|
||||
{ return length;}
|
||||
virtual uint max_packed_col_length(uint max_length)
|
||||
@ -890,6 +894,7 @@ public:
|
||||
inline uint32 get_length(uint row_offset=0)
|
||||
{ return get_length(ptr+row_offset); }
|
||||
uint32 get_length(const char *ptr);
|
||||
void put_length(char *pos, uint32 length);
|
||||
bool binary() const { return binary_flag; }
|
||||
inline void get_ptr(char **str)
|
||||
{
|
||||
@ -923,6 +928,7 @@ public:
|
||||
const char *unpack(char *to, const char *from);
|
||||
char *pack_key(char *to, const char *from, uint max_length);
|
||||
char *pack_key_from_key_image(char* to, const char *from, uint max_length);
|
||||
const char *unpack_key(char* to, const char *from, uint max_length);
|
||||
int pack_cmp(const char *a, const char *b, uint key_length);
|
||||
int pack_cmp(const char *b, uint key_length);
|
||||
uint packed_col_length(const char *col_ptr, uint length);
|
||||
|
@ -720,8 +720,8 @@ void ha_berkeley::unpack_key(char *record, DBT *key, uint index)
|
||||
}
|
||||
record[key_part->null_offset]&= ~key_part->null_bit;
|
||||
}
|
||||
pos= (char*) key_part->field->unpack(record + key_part->field->offset(),
|
||||
pos);
|
||||
pos= (char*) key_part->field->unpack_key(record + key_part->field->offset(),
|
||||
pos, key_part->length);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user