mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-03 14:33:32 +03:00 
			
		
		
		
	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!
This commit is contained in:
		@@ -91,17 +91,19 @@ typedef struct st_HA_KEYSEG		/* Key-portion */
 | 
			
		||||
 | 
			
		||||
#define size_to_store_key_length(length) ((length) < 255 ? 1 : 3)
 | 
			
		||||
 | 
			
		||||
#define get_rec_bits(bit_ptr, bit_ofs, bit_len) \
 | 
			
		||||
  (((((uint16) (bit_ptr)[1] << 8) | (uint16) (bit_ptr)[0]) >> (bit_ofs)) & \
 | 
			
		||||
   ((1 << (bit_len)) - 1))
 | 
			
		||||
static inline uint16 get_rec_bits(const uchar *ptr, uchar ofs, uint len)
 | 
			
		||||
{
 | 
			
		||||
  uint16 val= ptr[0];
 | 
			
		||||
  if (ofs + len > 8)
 | 
			
		||||
    val|= (uint16)(ptr[1]) << 8;
 | 
			
		||||
  return (val >> ofs) & ((1 << len) - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define set_rec_bits(bits, bit_ptr, bit_ofs, bit_len) \
 | 
			
		||||
{ \
 | 
			
		||||
  (bit_ptr)[0]= ((bit_ptr)[0] & ~(((1 << (bit_len)) - 1) << (bit_ofs))) | \
 | 
			
		||||
                ((bits) << (bit_ofs)); \
 | 
			
		||||
  if ((bit_ofs) + (bit_len) > 8) \
 | 
			
		||||
    (bit_ptr)[1]= ((bit_ptr)[1] & ~((1 << ((bit_len) - 8 + (bit_ofs))) - 1)) | \
 | 
			
		||||
                  ((bits) >> (8 - (bit_ofs))); \
 | 
			
		||||
static inline void set_rec_bits(uint16 bits, uchar *ptr, uchar ofs, uint len)
 | 
			
		||||
{
 | 
			
		||||
  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) \
 | 
			
		||||
 
 | 
			
		||||
@@ -1758,7 +1758,7 @@ uint Field::fill_cache_field(CACHE_FIELD *copy)
 | 
			
		||||
{
 | 
			
		||||
  uint store_length;
 | 
			
		||||
  copy->str= ptr;
 | 
			
		||||
  copy->length= pack_length();
 | 
			
		||||
  copy->length= pack_length_in_rec();
 | 
			
		||||
  copy->field= this;
 | 
			
		||||
  if (flags & BLOB_FLAG)
 | 
			
		||||
  {
 | 
			
		||||
@@ -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)))
 | 
			
		||||
      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)
 | 
			
		||||
    str++;
 | 
			
		||||
    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)
 | 
			
		||||
{
 | 
			
		||||
  from_ptr=from->ptr;
 | 
			
		||||
  to_ptr=to;
 | 
			
		||||
  from_length=from->pack_length();
 | 
			
		||||
  from_length=from->pack_length_in_rec();
 | 
			
		||||
  if (from->maybe_null())
 | 
			
		||||
  {
 | 
			
		||||
    from_null_ptr=from->null_ptr;
 | 
			
		||||
@@ -640,9 +640,9 @@ void Copy_field::set(Field *to,Field *from,bool save)
 | 
			
		||||
  from_field=from;
 | 
			
		||||
  to_field=to;
 | 
			
		||||
  from_ptr=from->ptr;
 | 
			
		||||
  from_length=from->pack_length();
 | 
			
		||||
  from_length=from->pack_length_in_rec();
 | 
			
		||||
  to_ptr=  to->ptr;
 | 
			
		||||
  to_length=to_field->pack_length();
 | 
			
		||||
  to_length=to_field->pack_length_in_rec();
 | 
			
		||||
 | 
			
		||||
  // set up null handling
 | 
			
		||||
  from_null_ptr=to_null_ptr=0;
 | 
			
		||||
 
 | 
			
		||||
@@ -394,7 +394,7 @@ void JOIN_CACHE::create_flag_fields()
 | 
			
		||||
    TABLE *table= tab->table;
 | 
			
		||||
 | 
			
		||||
    /* Create a field for the null bitmap from table if needed */
 | 
			
		||||
    if (tab->used_null_fields || tab->used_uneven_bit_fields)			    
 | 
			
		||||
    if (tab->used_null_fields || tab->used_uneven_bit_fields)
 | 
			
		||||
      length+= add_flag_field_to_join_cache(table->null_flags,
 | 
			
		||||
                                            table->s->null_bytes,
 | 
			
		||||
                                            ©);
 | 
			
		||||
 
 | 
			
		||||
@@ -15537,7 +15537,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        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]
 | 
			
		||||
    } 
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user