Commit 444587d8 authored by Sergei Golubchik's avatar Sergei Golubchik

BIT field woes

* get_rec_bits() was always reading two bytes, even if the
  bit field contained only of one byte
* In various places the code used field->pack_length() bytes
  starting from field->ptr, while it should be field->pack_length_in_rec()
* Field_bit::key_cmp and Field_bit::cmp_max passed field_length as
  an argument to memcmp(), but field_length is the number of bits!
parent 5e7593ad
...@@ -91,17 +91,19 @@ typedef struct st_HA_KEYSEG /* Key-portion */ ...@@ -91,17 +91,19 @@ typedef struct st_HA_KEYSEG /* Key-portion */
#define size_to_store_key_length(length) ((length) < 255 ? 1 : 3) #define size_to_store_key_length(length) ((length) < 255 ? 1 : 3)
#define get_rec_bits(bit_ptr, bit_ofs, bit_len) \ static inline uint16 get_rec_bits(const uchar *ptr, uchar ofs, uint len)
(((((uint16) (bit_ptr)[1] << 8) | (uint16) (bit_ptr)[0]) >> (bit_ofs)) & \ {
((1 << (bit_len)) - 1)) uint16 val= ptr[0];
if (ofs + len > 8)
#define set_rec_bits(bits, bit_ptr, bit_ofs, bit_len) \ val|= (uint16)(ptr[1]) << 8;
{ \ return (val >> ofs) & ((1 << len) - 1);
(bit_ptr)[0]= ((bit_ptr)[0] & ~(((1 << (bit_len)) - 1) << (bit_ofs))) | \ }
((bits) << (bit_ofs)); \
if ((bit_ofs) + (bit_len) > 8) \ static inline void set_rec_bits(uint16 bits, uchar *ptr, uchar ofs, uint len)
(bit_ptr)[1]= ((bit_ptr)[1] & ~((1 << ((bit_len) - 8 + (bit_ofs))) - 1)) | \ {
((bits) >> (8 - (bit_ofs))); \ ptr[0]= (ptr[0] & ~(((1 << len) - 1) << ofs)) | (bits << ofs);
if (ofs + len > 8)
ptr[1]= (ptr[1] & ~((1 << (len - 8 + ofs)) - 1)) | (bits >> (8 - ofs));
} }
#define clr_rec_bits(bit_ptr, bit_ofs, bit_len) \ #define clr_rec_bits(bit_ptr, bit_ofs, bit_len) \
......
...@@ -1758,7 +1758,7 @@ uint Field::fill_cache_field(CACHE_FIELD *copy) ...@@ -1758,7 +1758,7 @@ uint Field::fill_cache_field(CACHE_FIELD *copy)
{ {
uint store_length; uint store_length;
copy->str= ptr; copy->str= ptr;
copy->length= pack_length(); copy->length= pack_length_in_rec();
copy->field= this; copy->field= this;
if (flags & BLOB_FLAG) if (flags & BLOB_FLAG)
{ {
...@@ -8422,7 +8422,7 @@ int Field_bit::cmp_max(const uchar *a, const uchar *b, uint max_len) ...@@ -8422,7 +8422,7 @@ int Field_bit::cmp_max(const uchar *a, const uchar *b, uint max_len)
if ((flag= (int) (bits_a - bits_b))) if ((flag= (int) (bits_a - bits_b)))
return flag; return flag;
} }
return memcmp(a, b, field_length); return memcmp(a, b, bytes_in_rec);
} }
...@@ -8437,7 +8437,7 @@ int Field_bit::key_cmp(const uchar *str, uint length) ...@@ -8437,7 +8437,7 @@ int Field_bit::key_cmp(const uchar *str, uint length)
str++; str++;
length--; length--;
} }
return memcmp(ptr, str, length); return memcmp(ptr, str, bytes_in_rec);
} }
......
...@@ -589,7 +589,7 @@ void Copy_field::set(uchar *to,Field *from) ...@@ -589,7 +589,7 @@ void Copy_field::set(uchar *to,Field *from)
{ {
from_ptr=from->ptr; from_ptr=from->ptr;
to_ptr=to; to_ptr=to;
from_length=from->pack_length(); from_length=from->pack_length_in_rec();
if (from->maybe_null()) if (from->maybe_null())
{ {
from_null_ptr=from->null_ptr; from_null_ptr=from->null_ptr;
...@@ -640,9 +640,9 @@ void Copy_field::set(Field *to,Field *from,bool save) ...@@ -640,9 +640,9 @@ void Copy_field::set(Field *to,Field *from,bool save)
from_field=from; from_field=from;
to_field=to; to_field=to;
from_ptr=from->ptr; from_ptr=from->ptr;
from_length=from->pack_length(); from_length=from->pack_length_in_rec();
to_ptr= to->ptr; to_ptr= to->ptr;
to_length=to_field->pack_length(); to_length=to_field->pack_length_in_rec();
// set up null handling // set up null handling
from_null_ptr=to_null_ptr=0; from_null_ptr=to_null_ptr=0;
......
...@@ -15537,7 +15537,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, ...@@ -15537,7 +15537,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
else else
{ {
field->set_notnull(); field->set_notnull();
memcpy(field->ptr, orig_field->ptr, field->pack_length()); memcpy(field->ptr, orig_field->ptr, field->pack_length_in_rec());
} }
orig_field->move_field_offset(-diff); // Back to record[0] orig_field->move_field_offset(-diff); // Back to record[0]
} }
......
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