Bug #37292 KEY array passed into handler::add_index has incomplete information
Submitted: 9 Jun 2008 18:29 Modified: 10 Jun 2008 15:09
Reporter: Zardosht Kasheff (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: General Severity:S3 (Non-critical)
Version:5.1.23-rc OS:Any
Assigned to: CPU Architecture:Any
Tags: add_index, handler::add_index

[9 Jun 2008 18:29] Zardosht Kasheff
Description:
Although I filed the severity as an S3, it is possible that it may be an S4.

While implementing handler::add_index on 5.1.23-rc for the tokutek
storage engine, I noticed that the parameter KEY* key_info had some
missing information. It did not seem to take the null bytes into
account.

For a given key, here is the dump of its two key_part elements, as passed
in add_index:
(gdb) inspect key_part[0]
$9 = {field = 0x1a2aff0, offset = 12, null_offset = 0, length = 4,
  store_length = 0, key_type = 32795, fieldnr = 3, key_part_flag = 0,
  type = 0 '\0', null_bit = 0 '\0'}
(gdb) inspect key_part[1]
$10 = {field = 0x1a2b1f0, offset = 28, null_offset = 0, length = 4,
  store_length = 0, key_type = 32795, fieldnr = 7, key_part_flag = 0,
  type = 0 '\0', null_bit = 0 '\0'}

Here is a dump of its two key_part elements, as passed in the subsequent
handler::open call:
(gdb) inspect table->key_info[3]->key_part[0]
  $15 = {field = 0x1faea90, offset = 14, null_offset = 0, length = 4,
  store_length = 5, key_type = 32795, fieldnr = 4, key_part_flag = 16,
  type = 4 '\004', null_bit = 2 '\002'}
(gdb) inspect table->key_info[3]->key_part[1]
$16 = {field = 0x1faec90, offset = 30, null_offset = 0, length = 4,
  store_length = 5, key_type = 32795, fieldnr = 8, key_part_flag = 16,
  type = 4 '\004', null_bit = 32 ' '}

The number of null bytes at the beginning of each row is 2. Note that for
the data passed into handler::add_index, the offsets are off by 2, the
null_bit, key_part_flag, and store_length are all 0, instead of their
proper values.

How to repeat:
set a breakpoint in handler::add_index and inspect KEY array. Then set a breakpoint in handler::open and inspect the KEY array. Notice discrepancies in the key objects that are in common with teh two arrays.

Suggested fix:
The data in the two keys should be consistent.
[10 Jun 2008 14:55] Sergei Golubchik
Right, the fix should be in sql_table.cc:

        /* Fix the key parts. */
        part_end= key->key_part + key->key_parts;
        for (key_part= key->key_part; key_part < part_end; key_part++)
        {
          key_part->field= table->field[key_part->fieldnr];
+         key_part->null_bit= key_part->field->null_bit;
        }

and probably other fixes for key_part copied from open_binary_frm() are also appropriate here.

Until it's done, you can use find the correct value in key_part->field->null_bit.