Loading mysql-test/r/ndb_index_unique.result +14 −0 Original line number Diff line number Diff line Loading @@ -612,3 +612,17 @@ a b c 3 NULL NULL 4 4 NULL drop table t1, t8; create table t1( id integer not null auto_increment, month integer not null, year integer not null, code varchar( 2) not null, primary key ( id), unique idx_t1( month, code, year) ) engine=ndb; INSERT INTO t1 (month, year, code) VALUES (4,2004,'12'); INSERT INTO t1 (month, year, code) VALUES (5,2004,'12'); select * from t1 where code = '12' and month = 4 and year = 2004 ; id month year code 1 4 2004 12 drop table t1; mysql-test/t/ndb_index_unique.test +21 −0 Original line number Diff line number Diff line Loading @@ -286,3 +286,24 @@ select * from t8 order by a; select * from t1 order by a; drop table t1, t8; ############################### # Bug 8101 # # Unique index not specified in the same order as in table # create table t1( id integer not null auto_increment, month integer not null, year integer not null, code varchar( 2) not null, primary key ( id), unique idx_t1( month, code, year) ) engine=ndb; INSERT INTO t1 (month, year, code) VALUES (4,2004,'12'); INSERT INTO t1 (month, year, code) VALUES (5,2004,'12'); select * from t1 where code = '12' and month = 4 and year = 2004 ; drop table t1; sql/ha_ndbcluster.cc +50 −9 Original line number Diff line number Diff line Loading @@ -765,6 +765,42 @@ int ha_ndbcluster::get_metadata(const char *path) DBUG_RETURN(build_index_list(table, ILBP_OPEN)); } static int fix_unique_index_attr_order(NDB_INDEX_DATA &data, const NDBINDEX *index, KEY *key_info) { DBUG_ENTER("fix_unique_index_attr_order"); unsigned sz= index->getNoOfIndexColumns(); if (data.unique_index_attrid_map) my_free((char*)data.unique_index_attrid_map, MYF(0)); data.unique_index_attrid_map= (unsigned char*)my_malloc(sz,MYF(MY_WME)); KEY_PART_INFO* key_part= key_info->key_part; KEY_PART_INFO* end= key_part+key_info->key_parts; DBUG_ASSERT(key_info->key_parts == sz); for (unsigned i= 0; key_part != end; key_part++, i++) { const char *field_name= key_part->field->field_name; unsigned name_sz= strlen(field_name); if (name_sz >= NDB_MAX_ATTR_NAME_SIZE) name_sz= NDB_MAX_ATTR_NAME_SIZE-1; #ifndef DBUG_OFF data.unique_index_attrid_map[i]= 255; #endif for (unsigned j= 0; j < sz; j++) { const NdbDictionary::Column *c= index->getColumn(j); if (strncmp(field_name, c->getName(), name_sz) == 0) { data.unique_index_attrid_map[i]= j; break; } } DBUG_ASSERT(data.unique_index_attrid_map[i] != 255); } DBUG_RETURN(0); } int ha_ndbcluster::build_index_list(TABLE *tab, enum ILBP phase) { Loading Loading @@ -839,6 +875,7 @@ int ha_ndbcluster::build_index_list(TABLE *tab, enum ILBP phase) const NDBINDEX *index= dict->getIndex(unique_index_name, m_tabname); if (!index) DBUG_RETURN(1); m_index[i].unique_index= (void *) index; error= fix_unique_index_attr_order(m_index[i], index, key_info); } } Loading Loading @@ -897,6 +934,11 @@ void ha_ndbcluster::release_metadata() { m_index[i].unique_index= NULL; m_index[i].index= NULL; if (m_index[i].unique_index_attrid_map) { my_free((char *)m_index[i].unique_index_attrid_map, MYF(0)); m_index[i].unique_index_attrid_map= NULL; } } DBUG_VOID_RETURN; Loading Loading @@ -1209,7 +1251,8 @@ int ha_ndbcluster::unique_index_read(const byte *key, for (i= 0; key_part != end; key_part++, i++) { if (set_ndb_key(op, key_part->field, i, if (set_ndb_key(op, key_part->field, m_index[active_index].unique_index_attrid_map[i], key_part->null_bit ? key_ptr + 1 : key_ptr)) ERR_RETURN(trans->getNdbError()); key_ptr+= key_part->store_length; Loading Loading @@ -1476,10 +1519,7 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op, // Set bound if not cancelled via type -1 if (p.bound_type != -1) { char truncated_field_name[NDB_MAX_ATTR_NAME_SIZE]; strnmov(truncated_field_name,field->field_name,sizeof(truncated_field_name)); truncated_field_name[sizeof(truncated_field_name)-1]= '\0'; if (op->setBound(truncated_field_name, p.bound_type, p.bound_ptr)) if (op->setBound(i, p.bound_type, p.bound_ptr)) ERR_RETURN(op->getNdbError()); } } Loading Loading @@ -3842,6 +3882,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): m_index[i].type= UNDEFINED_INDEX; m_index[i].unique_index= NULL; m_index[i].index= NULL; m_index[i].unique_index_attrid_map= NULL; } DBUG_VOID_RETURN; Loading sql/ha_ndbcluster.h +1 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ typedef struct ndb_index_data { NDB_INDEX_TYPE type; void *index; void *unique_index; unsigned char *unique_index_attrid_map; } NDB_INDEX_DATA; typedef struct st_ndbcluster_share { Loading Loading
mysql-test/r/ndb_index_unique.result +14 −0 Original line number Diff line number Diff line Loading @@ -612,3 +612,17 @@ a b c 3 NULL NULL 4 4 NULL drop table t1, t8; create table t1( id integer not null auto_increment, month integer not null, year integer not null, code varchar( 2) not null, primary key ( id), unique idx_t1( month, code, year) ) engine=ndb; INSERT INTO t1 (month, year, code) VALUES (4,2004,'12'); INSERT INTO t1 (month, year, code) VALUES (5,2004,'12'); select * from t1 where code = '12' and month = 4 and year = 2004 ; id month year code 1 4 2004 12 drop table t1;
mysql-test/t/ndb_index_unique.test +21 −0 Original line number Diff line number Diff line Loading @@ -286,3 +286,24 @@ select * from t8 order by a; select * from t1 order by a; drop table t1, t8; ############################### # Bug 8101 # # Unique index not specified in the same order as in table # create table t1( id integer not null auto_increment, month integer not null, year integer not null, code varchar( 2) not null, primary key ( id), unique idx_t1( month, code, year) ) engine=ndb; INSERT INTO t1 (month, year, code) VALUES (4,2004,'12'); INSERT INTO t1 (month, year, code) VALUES (5,2004,'12'); select * from t1 where code = '12' and month = 4 and year = 2004 ; drop table t1;
sql/ha_ndbcluster.cc +50 −9 Original line number Diff line number Diff line Loading @@ -765,6 +765,42 @@ int ha_ndbcluster::get_metadata(const char *path) DBUG_RETURN(build_index_list(table, ILBP_OPEN)); } static int fix_unique_index_attr_order(NDB_INDEX_DATA &data, const NDBINDEX *index, KEY *key_info) { DBUG_ENTER("fix_unique_index_attr_order"); unsigned sz= index->getNoOfIndexColumns(); if (data.unique_index_attrid_map) my_free((char*)data.unique_index_attrid_map, MYF(0)); data.unique_index_attrid_map= (unsigned char*)my_malloc(sz,MYF(MY_WME)); KEY_PART_INFO* key_part= key_info->key_part; KEY_PART_INFO* end= key_part+key_info->key_parts; DBUG_ASSERT(key_info->key_parts == sz); for (unsigned i= 0; key_part != end; key_part++, i++) { const char *field_name= key_part->field->field_name; unsigned name_sz= strlen(field_name); if (name_sz >= NDB_MAX_ATTR_NAME_SIZE) name_sz= NDB_MAX_ATTR_NAME_SIZE-1; #ifndef DBUG_OFF data.unique_index_attrid_map[i]= 255; #endif for (unsigned j= 0; j < sz; j++) { const NdbDictionary::Column *c= index->getColumn(j); if (strncmp(field_name, c->getName(), name_sz) == 0) { data.unique_index_attrid_map[i]= j; break; } } DBUG_ASSERT(data.unique_index_attrid_map[i] != 255); } DBUG_RETURN(0); } int ha_ndbcluster::build_index_list(TABLE *tab, enum ILBP phase) { Loading Loading @@ -839,6 +875,7 @@ int ha_ndbcluster::build_index_list(TABLE *tab, enum ILBP phase) const NDBINDEX *index= dict->getIndex(unique_index_name, m_tabname); if (!index) DBUG_RETURN(1); m_index[i].unique_index= (void *) index; error= fix_unique_index_attr_order(m_index[i], index, key_info); } } Loading Loading @@ -897,6 +934,11 @@ void ha_ndbcluster::release_metadata() { m_index[i].unique_index= NULL; m_index[i].index= NULL; if (m_index[i].unique_index_attrid_map) { my_free((char *)m_index[i].unique_index_attrid_map, MYF(0)); m_index[i].unique_index_attrid_map= NULL; } } DBUG_VOID_RETURN; Loading Loading @@ -1209,7 +1251,8 @@ int ha_ndbcluster::unique_index_read(const byte *key, for (i= 0; key_part != end; key_part++, i++) { if (set_ndb_key(op, key_part->field, i, if (set_ndb_key(op, key_part->field, m_index[active_index].unique_index_attrid_map[i], key_part->null_bit ? key_ptr + 1 : key_ptr)) ERR_RETURN(trans->getNdbError()); key_ptr+= key_part->store_length; Loading Loading @@ -1476,10 +1519,7 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op, // Set bound if not cancelled via type -1 if (p.bound_type != -1) { char truncated_field_name[NDB_MAX_ATTR_NAME_SIZE]; strnmov(truncated_field_name,field->field_name,sizeof(truncated_field_name)); truncated_field_name[sizeof(truncated_field_name)-1]= '\0'; if (op->setBound(truncated_field_name, p.bound_type, p.bound_ptr)) if (op->setBound(i, p.bound_type, p.bound_ptr)) ERR_RETURN(op->getNdbError()); } } Loading Loading @@ -3842,6 +3882,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): m_index[i].type= UNDEFINED_INDEX; m_index[i].unique_index= NULL; m_index[i].index= NULL; m_index[i].unique_index_attrid_map= NULL; } DBUG_VOID_RETURN; Loading
sql/ha_ndbcluster.h +1 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ typedef struct ndb_index_data { NDB_INDEX_TYPE type; void *index; void *unique_index; unsigned char *unique_index_attrid_map; } NDB_INDEX_DATA; typedef struct st_ndbcluster_share { Loading