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
|
||||||
a
|
a
|
||||||
drop table t1;
|
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 (
|
create table t1 (
|
||||||
pk1 varchar(8) not null default '',
|
pk1 varchar(8) not null default '',
|
||||||
pk2 varchar(4) not null default '',
|
pk2 varchar(4) not null default '',
|
||||||
|
@ -830,6 +830,25 @@ explain select a from t1;
|
|||||||
select a from t1;
|
select a from t1;
|
||||||
drop table 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
|
# 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)
|
void Field_blob::store(const char *from,uint len)
|
||||||
{
|
{
|
||||||
if (!len)
|
if (!len)
|
||||||
@ -4525,6 +4561,50 @@ char *Field_blob::pack_key(char *to, const char *from, uint max_length)
|
|||||||
return to+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 */
|
/* 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,
|
char *Field_blob::pack_key_from_key_image(char *to, const char *from,
|
||||||
|
@ -189,6 +189,10 @@ public:
|
|||||||
{
|
{
|
||||||
return pack(to,from,max_length);
|
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)
|
virtual uint packed_col_length(const char *to, uint length)
|
||||||
{ return length;}
|
{ return length;}
|
||||||
virtual uint max_packed_col_length(uint max_length)
|
virtual uint max_packed_col_length(uint max_length)
|
||||||
@ -890,6 +894,7 @@ public:
|
|||||||
inline uint32 get_length(uint row_offset=0)
|
inline uint32 get_length(uint row_offset=0)
|
||||||
{ return get_length(ptr+row_offset); }
|
{ return get_length(ptr+row_offset); }
|
||||||
uint32 get_length(const char *ptr);
|
uint32 get_length(const char *ptr);
|
||||||
|
void put_length(char *pos, uint32 length);
|
||||||
bool binary() const { return binary_flag; }
|
bool binary() const { return binary_flag; }
|
||||||
inline void get_ptr(char **str)
|
inline void get_ptr(char **str)
|
||||||
{
|
{
|
||||||
@ -923,6 +928,7 @@ public:
|
|||||||
const char *unpack(char *to, const char *from);
|
const char *unpack(char *to, const char *from);
|
||||||
char *pack_key(char *to, const char *from, uint max_length);
|
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);
|
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 *a, const char *b, uint key_length);
|
||||||
int pack_cmp(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);
|
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;
|
record[key_part->null_offset]&= ~key_part->null_bit;
|
||||||
}
|
}
|
||||||
pos= (char*) key_part->field->unpack(record + key_part->field->offset(),
|
pos= (char*) key_part->field->unpack_key(record + key_part->field->offset(),
|
||||||
pos);
|
pos, key_part->length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user