diff options
author | Igor Babaev <igor@askmonty.org> | 2011-12-31 03:36:20 -0800 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2011-12-31 03:36:20 -0800 |
commit | ec2828e4f7f973361a9fd6c06bd913103b5115bd (patch) | |
tree | 2aa5cce450b1a5e6017b3427af80b8968d3ff62c /sql/table.cc | |
parent | 7714496dc1c72d01fd214cb7737ca4216a982e0f (diff) | |
parent | b6b5f9fabe4866a8753e81e1f80593b645f35d8e (diff) | |
download | mariadb-git-ec2828e4f7f973361a9fd6c06bd913103b5115bd.tar.gz |
Merged MWL#247 into the latest 5.3.
Diffstat (limited to 'sql/table.cc')
-rw-r--r-- | sql/table.cc | 238 |
1 files changed, 217 insertions, 21 deletions
diff --git a/sql/table.cc b/sql/table.cc index 7b417b95319..fd1cb4b3ebd 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -707,6 +707,13 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, enum legacy_db_type legacy_db_type; my_bitmap_map *bitmaps; bool null_bits_are_used; + KEY first_keyinfo; + uint len; + KEY_PART_INFO *first_key_part= NULL; + uint ext_key_parts= 0; + uint first_key_parts= 0; + keyinfo= &first_keyinfo; + share->ext_key_parts= 0; DBUG_ENTER("open_binary_frm"); LINT_INIT(options); @@ -800,18 +807,28 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, share->keys_for_keyread.init(0); share->keys_in_use.init(keys); - n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO); - if (!(keyinfo = (KEY*) alloc_root(&share->mem_root, - n_length + uint2korr(disk_buff+4)))) - goto err; /* purecov: inspected */ - bzero((char*) keyinfo,n_length); - share->key_info= keyinfo; - key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys); - strpos=disk_buff+6; + /* Currently only InnoDB can use extended keys */ + share->set_use_ext_keys_flag(legacy_db_type == DB_TYPE_INNODB); - if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root, - sizeof(ulong)*key_parts))) - goto err; + len= (uint) uint2korr(disk_buff+4); + if (!keys) + { + if (!(keyinfo = (KEY*) alloc_root(&share->mem_root, len))) + goto err; + bzero((char*) keyinfo, len); + key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys); + } + strpos= disk_buff+6; + + /* + If share->use_ext_keys is set to TRUE we assume that any key + can be extended by the components of the primary key whose + definition is read first from the frm file. + For each key only those fields of the assumed primary key are + added that are not included in the proper key definition. + If after all it turns out that there is no primary key the + added components are removed from each key. + */ for (i=0 ; i < keys ; i++, keyinfo++) { @@ -833,6 +850,32 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, strpos+=4; } + if (i == 0) + { + ext_key_parts= key_parts + + (share->use_ext_keys ? first_keyinfo.key_parts*(keys-1) : 0); + + n_length=keys*sizeof(KEY)+ext_key_parts*sizeof(KEY_PART_INFO); + if (!(keyinfo= (KEY*) alloc_root(&share->mem_root, + n_length + len))) + goto err; /* purecov: inspected */ + bzero((char*) keyinfo,n_length); + share->key_info= keyinfo; + key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys); + + if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root, + sizeof(ulong)*ext_key_parts))) + goto err; + first_key_part= key_part; + first_key_parts= first_keyinfo.key_parts; + keyinfo->flags= first_keyinfo.flags; + keyinfo->key_length= first_keyinfo.key_length; + keyinfo->key_parts= first_keyinfo.key_parts; + keyinfo->algorithm= first_keyinfo.algorithm; + if (new_frm_ver >= 3) + keyinfo->block_size= first_keyinfo.block_size; + } + keyinfo->key_part= key_part; keyinfo->rec_per_key= rec_per_key; for (j=keyinfo->key_parts ; j-- ; key_part++) @@ -861,6 +904,31 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, } key_part->store_length=key_part->length; } + keyinfo->ext_key_parts= keyinfo->key_parts; + if (share->use_ext_keys && i) + { + keyinfo->ext_key_flags= keyinfo->flags | HA_NOSAME; + keyinfo->ext_key_part_map= 0; + for (j= 0; j<first_key_parts && keyinfo->ext_key_parts<MAX_REF_PARTS; j++) + { + uint key_parts= keyinfo->key_parts; + KEY_PART_INFO* curr_key_part= keyinfo->key_part; + KEY_PART_INFO* curr_key_part_end= curr_key_part+key_parts; + for ( ; curr_key_part < curr_key_part_end; curr_key_part++) + { + if (curr_key_part->fieldnr == first_key_part[j].fieldnr) + break; + } + if (curr_key_part == curr_key_part_end) + { + *key_part++= first_key_part[j]; + *rec_per_key++= 0; + keyinfo->ext_key_parts++; + keyinfo->ext_key_part_map|= 1 << j; + } + } + } + share->ext_key_parts+= keyinfo->ext_key_parts; } keynames=(char*) key_part; strpos+= (strmov(keynames, (char *) strpos) - keynames)+1; @@ -1423,11 +1491,38 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, /* Fix key->name and key_part->field */ if (key_parts) { + uint add_first_key_parts= 0; uint primary_key=(uint) (find_type((char*) primary_key_name, &share->keynames, 3) - 1); longlong ha_option= handler_file->ha_table_flags(); keyinfo= share->key_info; - key_part= keyinfo->key_part; + + if (share->use_ext_keys) + { + if (primary_key >= MAX_KEY) + { + add_first_key_parts= 0; + share->set_use_ext_keys_flag(FALSE); + } + else + { + add_first_key_parts= first_key_parts; + /* + Do not add components of the primary key starting from + the major component defined over the beginning of a field. + */ + for (i= 0; i < first_key_parts; i++) + { + uint fieldnr= keyinfo[0].key_part[i].fieldnr; + if (share->field[fieldnr-1]->key_length() != + keyinfo[0].key_part[i].length) + { + add_first_key_parts= i; + break; + } + } + } + } for (uint key=0 ; key < share->keys ; key++,keyinfo++) { @@ -1446,6 +1541,51 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, keyinfo->name_length+1); } + if (ext_key_parts > share->key_parts && key) + { + KEY_PART_INFO *new_key_part= (keyinfo-1)->key_part+ + (keyinfo-1)->ext_key_parts; + + /* + Do not extend the key that contains a component + defined over the beginning of a field. + */ + for (i= 0; i < keyinfo->key_parts; i++) + { + uint fieldnr= keyinfo->key_part[i].fieldnr; + if (share->field[fieldnr-1]->key_length() != + keyinfo->key_part[i].length) + { + add_first_key_parts= 0; + break; + } + } + + if (add_first_key_parts < keyinfo->ext_key_parts-keyinfo->key_parts) + { + share->ext_key_parts-= keyinfo->ext_key_parts; + key_part_map ext_key_part_map= keyinfo->ext_key_part_map; + keyinfo->ext_key_parts= keyinfo->key_parts; + keyinfo->ext_key_flags= keyinfo->flags; + keyinfo->ext_key_part_map= 0; + for (i= 0; i < add_first_key_parts; i++) + { + if (ext_key_part_map & 1<<i) + { + keyinfo->ext_key_part_map|= 1<<i; + keyinfo->ext_key_parts++; + } + } + share->ext_key_parts+= keyinfo->ext_key_parts; + } + if (new_key_part != keyinfo->key_part) + { + memmove(new_key_part, keyinfo->key_part, + sizeof(KEY_PART_INFO) * keyinfo->ext_key_parts); + keyinfo->key_part= new_key_part; + } + } + /* Fix fulltext keys for old .frm files */ if (share->key_info[key].flags & HA_FULLTEXT) share->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT; @@ -1457,6 +1597,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, declare this as a primary key. */ primary_key=key; + key_part= keyinfo->key_part; for (i=0 ; i < keyinfo->key_parts ;i++) { uint fieldnr= key_part[i].fieldnr; @@ -1471,7 +1612,10 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, } } - for (i=0 ; i < keyinfo->key_parts ; key_part++,i++) + key_part= keyinfo->key_part; + uint key_parts= share->use_ext_keys ? keyinfo->ext_key_parts : + keyinfo->key_parts; + for (i=0; i < key_parts; key_part++, i++) { Field *field; if (new_field_pack_flag <= 1) @@ -1523,7 +1667,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, { share->keys_for_keyread.set_bit(key); field->part_of_key.set_bit(key); - field->part_of_key_not_clustered.set_bit(key); + if (i < keyinfo->key_parts) + field->part_of_key_not_clustered.set_bit(key); } if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER) field->part_of_sortkey.set_bit(key); @@ -2198,15 +2343,15 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, KEY *key_info, *key_info_end; KEY_PART_INFO *key_part; uint n_length; - n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO); + n_length= share->keys*sizeof(KEY) + share->ext_key_parts*sizeof(KEY_PART_INFO); if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length))) goto err; outparam->key_info= key_info; key_part= (my_reinterpret_cast(KEY_PART_INFO*) (key_info+share->keys)); - + memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys); memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) * - share->key_parts)); + share->ext_key_parts)); for (key_info_end= key_info + share->keys ; key_info < key_info_end ; @@ -2217,9 +2362,9 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, key_info->table= outparam; key_info->key_part= key_part; - for (key_part_end= key_part+ key_info->key_parts ; - key_part < key_part_end ; - key_part++) + key_part_end= key_part + (share->use_ext_keys ? key_info->ext_key_parts : + key_info->key_parts) ; + for ( ; key_part < key_part_end; key_part++) { Field *field= key_part->field= outparam->field[key_part->fieldnr-1]; @@ -2235,6 +2380,8 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, field->field_length= key_part->length; } } + if (!share->use_ext_keys) + key_part+= key_info->ext_key_parts-key_info->key_parts; } } @@ -3140,7 +3287,7 @@ uint calculate_key_len(TABLE *table, uint key, const uchar *buf, KEY *key_info= table->s->key_info+key; KEY_PART_INFO *key_part= key_info->key_part; - KEY_PART_INFO *end_key_part= key_part + key_info->key_parts; + KEY_PART_INFO *end_key_part= key_part + table->actual_n_key_parts(key_info); uint length= 0; while (key_part < end_key_part && keypart_map) @@ -5419,6 +5566,47 @@ bool st_table::is_filled_at_execution() } +/** + @brief + Get actual number of key components + + @param keyinfo + + @details + The function calculates actual number of key components, possibly including + components of extended keys, taken into consideration by the optimizer for the + key described by the parameter keyinfo. + + @return number of considered key components +*/ + +inline uint st_table::actual_n_key_parts(KEY *keyinfo) +{ + return optimizer_flag(in_use, OPTIMIZER_SWITCH_EXTENDED_KEYS) ? + keyinfo->ext_key_parts : keyinfo->key_parts; +} + + +/** + @brief + Get actual key flags for a table key + + @param keyinfo + + @details + The function finds out actual key flags taken into consideration by the + optimizer for the key described by the parameter keyinfo. + + @return actual key flags +*/ + +ulong st_table::actual_key_flags(KEY *keyinfo) +{ + return optimizer_flag(in_use, OPTIMIZER_SWITCH_EXTENDED_KEYS) ? + keyinfo->ext_key_flags : keyinfo->flags; +} + + /* Cleanup this table for re-execution. @@ -6014,6 +6202,14 @@ bool TABLE_LIST::change_refs_to_fields() } +uint TABLE_SHARE::actual_n_key_parts(THD *thd) +{ + return use_ext_keys && + optimizer_flag(thd, OPTIMIZER_SWITCH_EXTENDED_KEYS) ? + ext_key_parts : key_parts; +} + + /***************************************************************************** ** Instansiate templates *****************************************************************************/ |