Bug #49895 use of KEY_PART_INFO->fieldnr inconsistent in handler::create and add_index
Submitted: 23 Dec 2009 16:27 Modified: 23 Dec 2009 21:44
Reporter: Zardosht Kasheff (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:5.1.36, 5.1 bzr OS:Any (add_index)
Assigned to: CPU Architecture:Any

[23 Dec 2009 16:27] Zardosht Kasheff
Description:
This is another bug, on top of #37292, that makes implementing and maintaining handler::add_index INCREDIBLY painful for storage engine writers.

For keys passed into hander::create, the value of fieldnr in KEY_PART_INFO is the ith field in the table. For instance, if we have the table foo (a int, b int, c int, d int, key(d)), then fieldnr in the KEY_PART_INFO associated with column d is set to 4.

The same key, created via handler::add_index, will set fieldnr to 3 and not 4.

There is a workaround to access key_part->field->field_index to get a consistent value, but all of these workarounds for implementing add_index is starting to get messy.

How to repeat:
create tables mentioned above, inspect variables in debugger

Suggested fix:
set fieldnr in add_index to match what is set in handler::create. Both should have values of 4 in the above example.
[23 Dec 2009 21:44] Sveta Smirnova
Thank you for the report.

Verified as described.

To repeat create test for MTR:

$cat t/bug49895.test 
--source include/have_ndb.inc

create table foo (a int, b int, c int, d int, key(d)) engine=ndb;

alter table foo add index(d);

Then run it under gdb:

$./mtr --manual-gdb bug49895
Logging: ./mtr  --manual-gdb bug49895
....

In another terminal

$gdb -cd /....
Breakpoint 1, mysql_parse (thd=<incomplete type>, inBuf=0xb008e9ea "CREATE TABLE IF NOT EXISTS mysql.ndb_schema ( db VARBINARY(63) NOT NULL, name VARBINARY(63) NOT NULL, slock BINARY(32) NOT NULL, query BLOB NOT NULL, node_id INT UNSIGNED NOT NULL, epoch BIGINT UNSIGN"..., length=364, found_semicolon=0xb008e968) at sql_parse.cc:5901
5901      DBUG_ENTER("mysql_parse");
(gdb) b ha_ndbcluster::create
Breakpoint 2 at 0x2da003: file ha_ndbcluster.cc, line 5145.
(gdb) b ha_ndbcluster::add_index
Breakpoint 3 at 0x2dc41b: file ha_ndbcluster.cc, line 5755.
(gdb) c
Continuing.

Breakpoint 2, ha_ndbcluster::create (this=0x608d828, name=0xb008d2d7 "./mysql/ndb_schema", form=0xb008c9b0, create_info=0xb008dbfc) at ha_ndbcluster.cc:5145
5145      THD *thd= current_thd;
(gdb) p table_arg->key_info->key_part->fieldnr
No symbol "table_arg" in current context.
(gdb) p form->key_info->key_part->fieldnr
$1 = 1
(gdb) c
Continuing.

Breakpoint 2, ha_ndbcluster::create (this=0x609e828, name=0xb008d2d7 "./mysql/ndb_apply_status", form=0xb008c9b0, create_info=0xb008dbfc) at ha_ndbcluster.cc:5145
5145      THD *thd= current_thd;
(gdb) p form->key_info->key_part->fieldnr
$2 = 1
(gdb) c
Continuing.
091224  0:40:26 [Note] table './mysql/ndb_apply_status' opened read only
[Switching to process 17657 thread 0x2e03]

Breakpoint 2, ha_ndbcluster::create (this=0x609d228, name=0xb01207a7 "./test/foo", form=0xb011fe80, create_info=0xb01210cc) at ha_ndbcluster.cc:5145
5145      THD *thd= current_thd;
(gdb) p form->key_info->key_part->fieldnr
$3 = 4
(gdb) c
Continuing.

Breakpoint 3, ha_ndbcluster::add_index (this=0x6043228, table_arg=0x6076218, key_info=0x608a560, num_of_keys=1) at ha_ndbcluster.cc:5755
5755      int error= 0;
(gdb) p form->key_info->key_part->fieldnr
No symbol "form" in current context.
(gdb) p key_info->key_part->fieldnr
$4 = 3