|
|
|
@ -6916,86 +6916,6 @@ int Field_string::do_save_field_metadata(uchar *metadata_ptr) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Compare two packed keys |
|
|
|
|
|
|
|
SYNOPSIS |
|
|
|
pack_cmp() |
|
|
|
a New key |
|
|
|
b Original key |
|
|
|
length Key length |
|
|
|
insert_or_update 1 if this is an insert or update |
|
|
|
|
|
|
|
RETURN |
|
|
|
< 0 a < b |
|
|
|
0 a = b |
|
|
|
> 0 a > b |
|
|
|
*/ |
|
|
|
|
|
|
|
int Field_string::pack_cmp(const uchar *a, const uchar *b, uint length, |
|
|
|
my_bool insert_or_update) |
|
|
|
{ |
|
|
|
uint a_length, b_length; |
|
|
|
if (length > 255) |
|
|
|
{ |
|
|
|
a_length= uint2korr(a); |
|
|
|
b_length= uint2korr(b); |
|
|
|
a+= 2; |
|
|
|
b+= 2; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
a_length= (uint) *a++; |
|
|
|
b_length= (uint) *b++; |
|
|
|
} |
|
|
|
return field_charset->coll->strnncollsp(field_charset, |
|
|
|
a, a_length, |
|
|
|
b, b_length, |
|
|
|
insert_or_update); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Compare a packed key against row. |
|
|
|
|
|
|
|
@param key Original key |
|
|
|
@param length Key length. (May be less than field length) |
|
|
|
@param insert_or_update 1 if this is an insert or update |
|
|
|
|
|
|
|
@return |
|
|
|
< 0 row < key |
|
|
|
@return |
|
|
|
0 row = key |
|
|
|
@return |
|
|
|
> 0 row > key |
|
|
|
*/ |
|
|
|
|
|
|
|
int Field_string::pack_cmp(const uchar *key, uint length, |
|
|
|
my_bool insert_or_update) |
|
|
|
{ |
|
|
|
uint row_length, local_key_length; |
|
|
|
uchar *end; |
|
|
|
if (length > 255) |
|
|
|
{ |
|
|
|
local_key_length= uint2korr(key); |
|
|
|
key+= 2; |
|
|
|
} |
|
|
|
else |
|
|
|
local_key_length= (uint) *key++; |
|
|
|
|
|
|
|
/* Only use 'length' of key, not field_length */ |
|
|
|
end= ptr + length; |
|
|
|
while (end > ptr && end[-1] == ' ') |
|
|
|
end--; |
|
|
|
row_length= (uint) (end - ptr); |
|
|
|
|
|
|
|
return field_charset->coll->strnncollsp(field_charset, |
|
|
|
ptr, row_length, |
|
|
|
key, local_key_length, |
|
|
|
insert_or_update); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint Field_string::packed_col_length(const uchar *data_ptr, uint length) |
|
|
|
{ |
|
|
|
if (length > 255) |
|
|
|
@ -7355,90 +7275,6 @@ uchar *Field_varstring::pack(uchar *to, const uchar *from, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uchar * |
|
|
|
Field_varstring::pack_key(uchar *to, const uchar *key, uint max_length, |
|
|
|
bool low_byte_first __attribute__((unused))) |
|
|
|
{ |
|
|
|
uint length= length_bytes == 1 ? (uint) *key : uint2korr(key); |
|
|
|
uint local_char_length= ((field_charset->mbmaxlen > 1) ? |
|
|
|
max_length/field_charset->mbmaxlen : max_length); |
|
|
|
key+= length_bytes; |
|
|
|
if (length > local_char_length) |
|
|
|
{ |
|
|
|
local_char_length= my_charpos(field_charset, key, key+length, |
|
|
|
local_char_length); |
|
|
|
set_if_smaller(length, local_char_length); |
|
|
|
} |
|
|
|
*to++= (char) (length & 255); |
|
|
|
if (max_length > 255) |
|
|
|
*to++= (char) (length >> 8); |
|
|
|
if (length) |
|
|
|
memcpy(to, key, length); |
|
|
|
return to+length; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Unpack a key into a record buffer. |
|
|
|
|
|
|
|
A VARCHAR 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'. |
|
|
|
|
|
|
|
@param to Pointer into the record buffer. |
|
|
|
@param key Pointer to the packed key. |
|
|
|
@param max_length Key length limit from key description. |
|
|
|
|
|
|
|
@return |
|
|
|
Pointer to end of 'key' (To the next key part if multi-segment key) |
|
|
|
*/ |
|
|
|
|
|
|
|
const uchar * |
|
|
|
Field_varstring::unpack_key(uchar *to, const uchar *key, uint max_length, |
|
|
|
bool low_byte_first __attribute__((unused))) |
|
|
|
{ |
|
|
|
/* get length of the blob key */ |
|
|
|
uint32 length= *key++; |
|
|
|
if (max_length > 255) |
|
|
|
length+= (*key++) << 8; |
|
|
|
|
|
|
|
/* put the length into the record buffer */ |
|
|
|
if (length_bytes == 1) |
|
|
|
*ptr= (uchar) length; |
|
|
|
else |
|
|
|
int2store(ptr, length); |
|
|
|
memcpy(ptr + length_bytes, key, length); |
|
|
|
return key + length; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
Create a packed key that will be used for storage in the index tree. |
|
|
|
|
|
|
|
@param to Store packed key segment here |
|
|
|
@param from Key segment (as given to index_read()) |
|
|
|
@param max_length Max length of key |
|
|
|
|
|
|
|
@return |
|
|
|
end of key storage |
|
|
|
*/ |
|
|
|
|
|
|
|
uchar * |
|
|
|
Field_varstring::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length, |
|
|
|
bool low_byte_first __attribute__((unused))) |
|
|
|
{ |
|
|
|
/* Key length is always stored as 2 bytes */ |
|
|
|
uint length= uint2korr(from); |
|
|
|
if (length > max_length) |
|
|
|
length= max_length; |
|
|
|
*to++= (char) (length & 255); |
|
|
|
if (max_length > 255) |
|
|
|
*to++= (char) (length >> 8); |
|
|
|
if (length) |
|
|
|
memcpy(to, from+HA_KEY_BLOB_LENGTH, length); |
|
|
|
return to+length; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Unpack a varstring field from row data. |
|
|
|
|
|
|
|
@ -7481,59 +7317,6 @@ Field_varstring::unpack(uchar *to, const uchar *from, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int Field_varstring::pack_cmp(const uchar *a, const uchar *b, |
|
|
|
uint key_length_arg, |
|
|
|
my_bool insert_or_update) |
|
|
|
{ |
|
|
|
uint a_length, b_length; |
|
|
|
if (key_length_arg > 255) |
|
|
|
{ |
|
|
|
a_length=uint2korr(a); a+= 2; |
|
|
|
b_length=uint2korr(b); b+= 2; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
a_length= (uint) *a++; |
|
|
|
b_length= (uint) *b++; |
|
|
|
} |
|
|
|
return field_charset->coll->strnncollsp(field_charset, |
|
|
|
a, a_length, |
|
|
|
b, b_length, |
|
|
|
insert_or_update); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int Field_varstring::pack_cmp(const uchar *b, uint key_length_arg, |
|
|
|
my_bool insert_or_update) |
|
|
|
{ |
|
|
|
uchar *a= ptr+ length_bytes; |
|
|
|
uint a_length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr); |
|
|
|
uint b_length; |
|
|
|
uint local_char_length= ((field_charset->mbmaxlen > 1) ? |
|
|
|
key_length_arg / field_charset->mbmaxlen : |
|
|
|
key_length_arg); |
|
|
|
|
|
|
|
if (key_length_arg > 255) |
|
|
|
{ |
|
|
|
b_length=uint2korr(b); b+= HA_KEY_BLOB_LENGTH; |
|
|
|
} |
|
|
|
else |
|
|
|
b_length= (uint) *b++; |
|
|
|
|
|
|
|
if (a_length > local_char_length) |
|
|
|
{ |
|
|
|
local_char_length= my_charpos(field_charset, a, a+a_length, |
|
|
|
local_char_length); |
|
|
|
set_if_smaller(a_length, local_char_length); |
|
|
|
} |
|
|
|
|
|
|
|
return field_charset->coll->strnncollsp(field_charset, |
|
|
|
a, a_length, |
|
|
|
b, b_length, |
|
|
|
insert_or_update); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint Field_varstring::packed_col_length(const uchar *data_ptr, uint length) |
|
|
|
{ |
|
|
|
if (length > 255) |
|
|
|
@ -8232,139 +8015,6 @@ const uchar *Field_blob::unpack(uchar *to, |
|
|
|
DBUG_RETURN(from + master_packlength + length); |
|
|
|
} |
|
|
|
|
|
|
|
/* Keys for blobs are like keys on varchars */ |
|
|
|
|
|
|
|
int Field_blob::pack_cmp(const uchar *a, const uchar *b, uint key_length_arg, |
|
|
|
my_bool insert_or_update) |
|
|
|
{ |
|
|
|
uint a_length, b_length; |
|
|
|
if (key_length_arg > 255) |
|
|
|
{ |
|
|
|
a_length=uint2korr(a); a+=2; |
|
|
|
b_length=uint2korr(b); b+=2; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
a_length= (uint) *a++; |
|
|
|
b_length= (uint) *b++; |
|
|
|
} |
|
|
|
return field_charset->coll->strnncollsp(field_charset, |
|
|
|
a, a_length, |
|
|
|
b, b_length, |
|
|
|
insert_or_update); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int Field_blob::pack_cmp(const uchar *b, uint key_length_arg, |
|
|
|
my_bool insert_or_update) |
|
|
|
{ |
|
|
|
uchar *a; |
|
|
|
uint a_length, b_length; |
|
|
|
memcpy_fixed(&a,ptr+packlength,sizeof(char*)); |
|
|
|
if (!a) |
|
|
|
return key_length_arg > 0 ? -1 : 0; |
|
|
|
|
|
|
|
a_length= get_length(ptr); |
|
|
|
if (key_length_arg > 255) |
|
|
|
{ |
|
|
|
b_length= uint2korr(b); b+=2; |
|
|
|
} |
|
|
|
else |
|
|
|
b_length= (uint) *b++; |
|
|
|
return field_charset->coll->strnncollsp(field_charset, |
|
|
|
a, a_length, |
|
|
|
b, b_length, |
|
|
|
insert_or_update); |
|
|
|
} |
|
|
|
|
|
|
|
/** Create a packed key that will be used for storage from a MySQL row. */ |
|
|
|
|
|
|
|
uchar * |
|
|
|
Field_blob::pack_key(uchar *to, const uchar *from, uint max_length, |
|
|
|
bool low_byte_first __attribute__((unused))) |
|
|
|
{ |
|
|
|
uchar *save= ptr; |
|
|
|
ptr= (uchar*) from; |
|
|
|
uint32 length=get_length(); // Length of from string
|
|
|
|
uint local_char_length= ((field_charset->mbmaxlen > 1) ? |
|
|
|
max_length/field_charset->mbmaxlen : max_length); |
|
|
|
if (length) |
|
|
|
get_ptr((uchar**) &from); |
|
|
|
if (length > local_char_length) |
|
|
|
local_char_length= my_charpos(field_charset, from, from+length, |
|
|
|
local_char_length); |
|
|
|
set_if_smaller(length, local_char_length); |
|
|
|
*to++= (uchar) length; |
|
|
|
if (max_length > 255) // 2 byte length
|
|
|
|
*to++= (uchar) (length >> 8); |
|
|
|
memcpy(to, from, length); |
|
|
|
ptr=save; // Restore org row pointer
|
|
|
|
return to+length; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Unpack a blob key into a record buffer. |
|
|
|
|
|
|
|
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. |
|
|
|
|
|
|
|
|
|
|
|
@param to Pointer into the record buffer. |
|
|
|
@param from Pointer to the packed key. |
|
|
|
@param max_length Key length limit from key description. |
|
|
|
|
|
|
|
@return |
|
|
|
Pointer into 'from' past the last byte copied from packed key. |
|
|
|
*/ |
|
|
|
|
|
|
|
const uchar * |
|
|
|
Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length, |
|
|
|
bool low_byte_first __attribute__((unused))) |
|
|
|
{ |
|
|
|
/* get length of the blob key */ |
|
|
|
uint32 length= *from++; |
|
|
|
if (max_length > 255) |
|
|
|
length+= *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. */ |
|
|
|
|
|
|
|
uchar * |
|
|
|
Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length, |
|
|
|
bool low_byte_first __attribute__((unused))) |
|
|
|
{ |
|
|
|
uint length=uint2korr(from); |
|
|
|
if (length > max_length) |
|
|
|
length=max_length; |
|
|
|
*to++= (char) (length & 255); |
|
|
|
if (max_length > 255) |
|
|
|
*to++= (char) (length >> 8); |
|
|
|
if (length) |
|
|
|
memcpy(to, from+HA_KEY_BLOB_LENGTH, length); |
|
|
|
return to+length; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint Field_blob::packed_col_length(const uchar *data_ptr, uint length) |
|
|
|
{ |
|
|
|
if (length > 255) |
|
|
|
|