Thanks for the reply (Is it OK if I set you as a reviewer?)
Is it OK to just use the returned longlong variable "value" with length
"sizeof(longlong)"? (it will use more bytes in the calculation of the
hash than needed, but it will allways be correct)
Or should I use correspondent store-function to make it big-endian in a
temporary buffer and use that when calling the hash function?
(My mistake, I thought it was endian-independent, but that was after
store, and before korr, so after mi_uintNkorr it is machine dependent
again...)
And a side note:
In Field_bit::val_int() the default in the switch, should that not first
calculate the length and use it (or just use ptr directly), does it not
calculate that eight times now since it is a macro?
/Mattias
Kristian Nielsen wrote:
> mattiasj@stripped writes:
>
>> Below is the list of changes that have just been committed into a local
>> 5.1 repository of mattiasj. When mattiasj does a push these changes
>> will be propagated to the main repository and, within 24 hours after the
>> push, to the public repository.
>> For information on how to access the public repository
>> see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
>>
>> ChangeSet@stripped, 2008-02-04 12:28:42+01:00,
> mattiasj@stripped +4 -0
>> Bug#33379: valgrind error in parts/partition_bit_myisam
>>
>> Problem was that Field_bit used Field::hash() function that did not
>> know about using null-byte for storing bits.
>> Resulting in wrong length, which was caught by valgrind.
>>
>> Soluiton: created a Field_bit::hash() that uses Field_bit::val_int()
>> and my_charset_bin-collation function hash_sort.
>
>> diff -Nrup a/sql/field.cc b/sql/field.cc
>> --- a/sql/field.cc 2008-01-22 23:45:41 +01:00
>> +++ b/sql/field.cc 2008-02-04 12:28:38 +01:00
>> @@ -8793,6 +8793,24 @@ Field_bit::Field_bit(uchar *ptr_arg, uin
>> }
>>
>>
>> +void Field_bit::hash(ulong *nr, ulong *nr2)
>> +{
>> + if (is_null())
>> + {
>> + *nr^= (*nr << 1) | 1;
>> + }
>> + else
>> + {
>> + CHARSET_INFO *cs= &my_charset_bin;
>> + uint len= bytes_in_rec + (bit_len ? 1 : 0);
>> + longlong value= Field_bit::val_int();
>> + uchar *ptr2= (uchar*) &value;
>> + ptr2+= sizeof(longlong) - len;
>
> This looks wrong, it seems to assume big endian?
>
> Ie. on little-endian, if len<=4, then ptr2 will point to all zeroes,
> regardless of the actual value, so all values will get the same hash() ... ?
>
>> + cs->coll->hash_sort(cs, ptr2, len, nr, nr2);
>> + }
>> +}
>
> - Kristian.
>
>
--
Mattias Jonsson, Software Engineer
MySQL AB, www.mysql.com
Are you MySQL certified? www.mysql.com/certification