diff options
author | Igor Babaev <igor@askmonty.org> | 2012-03-02 15:03:20 -0800 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2012-03-02 15:03:20 -0800 |
commit | 8bc5045ea377f39701f421cc7ae00756f79962d2 (patch) | |
tree | 751d8bbe4d3844ab9dc16d0c07855e40028cbabc /sql/table.cc | |
parent | 8b469eb5151cb1b7da00cee3a7b42c10bd7ff51e (diff) | |
parent | 2521ac0c7f2450d588fa1704a6eef785da8812a9 (diff) | |
download | mariadb-git-8bc5045ea377f39701f421cc7ae00756f79962d2.tar.gz |
Merge MWL #247 from mariadb 5.3 -> mariadb 5.5.
Diffstat (limited to 'sql/table.cc')
-rw-r--r-- | sql/table.cc | 259 |
1 files changed, 236 insertions, 23 deletions
diff --git a/sql/table.cc b/sql/table.cc index 8f4f034bf2a..016f79607d0 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -753,10 +753,12 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, uchar forminfo[288]; uchar *record; uchar *disk_buff, *strpos, *null_flags, *null_pos; - ulong pos, record_offset, *rec_per_key, rec_buff_length; + ulong pos, record_offset; + ulong *rec_per_key= NULL; + ulong rec_buff_length; handler *handler_file= 0; KEY *keyinfo; - KEY_PART_INFO *key_part; + KEY_PART_INFO *key_part= NULL; SQL_CRYPT *crypted=0; Field **field_ptr, *reg_field; const char **interval_array; @@ -767,6 +769,13 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, char *vcol_screen_pos; uchar *UNINIT_VAR(options); uchar *extra_segment_buff= 0; + 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"); new_field_pack_flag= head[27]; @@ -861,18 +870,37 @@ 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= reinterpret_cast<KEY_PART_INFO*>(keyinfo+keys); - strpos=disk_buff+6; + /* + At this point we don't have enough information read from the frm file + to get a proper handlerton for the interesting engine in order to get + properties of this engine. + */ + /* Currently only InnoDB can use extended keys */ + share->set_use_ext_keys_flag(legacy_db_type == DB_TYPE_INNODB); + + 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= reinterpret_cast<KEY_PART_INFO*> (keyinfo+keys); + } + strpos= disk_buff+6; - if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root, - sizeof(ulong)*key_parts))) - goto err; + /* + 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. + + When in the future we support others schemes of extending of + secondary keys with components of the primary key we'll have + to change the type of this flag for an enumeration type. + */ for (i=0 ; i < keys ; i++, keyinfo++) { @@ -894,6 +922,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= 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++) @@ -922,6 +976,35 @@ 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; + keyinfo->ext_key_flags= keyinfo->flags; + keyinfo->ext_key_part_map= 0; + 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; @@ -1522,11 +1605,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(primary_key_name, &share->keynames, FIND_TYPE_NO_PREFIX) - 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++) { @@ -1545,6 +1655,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; @@ -1556,6 +1711,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; @@ -1570,7 +1726,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) @@ -1622,7 +1781,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); @@ -2261,7 +2421,7 @@ 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; @@ -2269,7 +2429,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, 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 ; @@ -2280,11 +2440,11 @@ 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]; + Field *field= key_part->field= outparam->field[key_part->fieldnr - 1]; if (field->key_length() != key_part->length && !(field->flags & BLOB_FLAG)) @@ -2298,6 +2458,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; } } @@ -3225,7 +3387,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) @@ -5737,9 +5899,11 @@ bool TABLE::add_tmp_key(uint key, uint key_parts, keyinfo= key_info + key; keyinfo->key_part= key_part_info; keyinfo->usable_key_parts= keyinfo->key_parts = key_parts; + keyinfo->ext_key_parts= keyinfo->key_parts; keyinfo->key_length=0; keyinfo->algorithm= HA_KEY_ALG_UNDEF; keyinfo->flags= HA_GENERATED_KEY; + keyinfo->ext_key_flags= keyinfo->flags; if (unique) keyinfo->flags|= HA_NOSAME; sprintf(buf, "key%i", key); @@ -5808,6 +5972,47 @@ bool 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 +*/ + +uint 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 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. @@ -6477,6 +6682,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 *****************************************************************************/ |