diff options
Diffstat (limited to 'sql/table.cc')
-rw-r--r-- | sql/table.cc | 88 |
1 files changed, 87 insertions, 1 deletions
diff --git a/sql/table.cc b/sql/table.cc index 92e3d2e4800..a7142db17bd 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -61,6 +61,7 @@ struct extra2_fields LEX_CUSTRING application_period; LEX_CUSTRING field_data_type_info; LEX_CUSTRING without_overlaps; + LEX_CUSTRING index_flags; void reset() { bzero((void*)this, sizeof(*this)); } }; @@ -1407,6 +1408,39 @@ void TABLE_SHARE::set_overlapped_keys() } +/* + @brief + Set of indexes that are marked as IGNORE. +*/ + +void TABLE_SHARE::set_ignored_indexes() +{ + KEY *keyinfo= key_info; + for (uint i= 0; i < keys; i++, keyinfo++) + { + if (keyinfo->is_ignored) + ignored_indexes.set_bit(i); + } +} + + +/* + @brief + Set of indexes that the optimizer may use when creating an execution plan. +*/ + +key_map TABLE_SHARE::usable_indexes(THD *thd) +{ + if (optimizer_flag(thd, OPTIMIZER_SWITCH_IGNORE_INDEXES)) + { + key_map usable_indexes(keys_in_use); + usable_indexes.subtract(ignored_indexes); + return usable_indexes; + } + return keys_in_use; +} + + bool Item_field::check_index_dependence(void *arg) { TABLE *table= (TABLE *)arg; @@ -1574,6 +1608,9 @@ bool read_extra2(const uchar *frm_image, size_t len, extra2_fields *fields) case EXTRA2_FIELD_DATA_TYPE_INFO: fail= read_extra2_section_once(extra2, length, &fields->field_data_type_info); break; + case EXTRA2_INDEX_FLAGS: + fail= read_extra2_section_once(extra2, length, &fields->index_flags); + break; default: /* abort frm parsing if it's an unknown but important extra2 value */ if (type >= EXTRA2_ENGINE_IMPORTANT) @@ -1729,6 +1766,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, MEM_ROOT *old_root= thd->mem_root; Virtual_column_info **table_check_constraints; extra2_fields extra2; + bool extra_index_flags_present= FALSE; DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image"); keyinfo= &first_keyinfo; @@ -1883,9 +1921,13 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, share->key_parts= key_parts= disk_buff[1]; } share->keys_for_keyread.init(0); + share->ignored_indexes.init(0); share->keys_in_use.init(keys); ext_key_parts= key_parts; + if (extra2.index_flags.str && extra2.index_flags.length != keys) + goto err; + len= (uint) uint2korr(disk_buff+4); share->reclength = uint2korr(frm_image+16); @@ -2081,9 +2123,26 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, } share->key_block_size= uint2korr(frm_image+62); keyinfo= share->key_info; + + + if (extra2.index_flags.str) + extra_index_flags_present= TRUE; + for (uint i= 0; i < share->keys; i++, keyinfo++) + { + if (extra_index_flags_present) + { + uchar flags= *extra2.index_flags.str++; + keyinfo->is_ignored= (flags & EXTRA2_IGNORED_KEY); + } + else + keyinfo->is_ignored= FALSE; + if (keyinfo->algorithm == HA_KEY_ALG_LONG_HASH) hash_fields++; + } + + share->set_ignored_indexes(); #ifdef WITH_PARTITION_STORAGE_ENGINE if (par_image && plugin_data(se_plugin, handlerton*) == partition_hton) @@ -2738,6 +2797,33 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, } } + /* + Make sure that the primary key is not marked as IGNORE + This can happen in the case + 1) when IGNORE is mentioned in the Key specification + 2) When a unique NON-NULLABLE key is promted to a primary key. + The unqiue key could have been marked as IGNORE when there + was a primary key in the table. + + Eg: + CREATE TABLE t1(a INT NOT NULL, primary key(a), UNIQUE key1(a)) + so for this table when we try to IGNORE key1 + then we run: + ALTER TABLE t1 ALTER INDEX key1 IGNORE + this runs successsfully and key1 is marked as IGNORE. + + But lets say then we drop the primary key + ALTER TABLE t1 DROP PRIMARY + then the UNIQUE key will be promoted to become the primary key + but then the UNIQUE key cannot be marked as IGNORE, so an + error is thrown + */ + if (primary_key != MAX_KEY && keyinfo && keyinfo->is_ignored) + { + my_error(ER_PK_INDEX_CANT_BE_IGNORED, MYF(0)); + goto err; + } + if (share->use_ext_keys) { if (primary_key >= MAX_KEY) @@ -8129,7 +8215,7 @@ bool TABLE_LIST::process_index_hints(TABLE *tbl) { /* initialize the result variables */ tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by= - tbl->keys_in_use_for_order_by= tbl->s->keys_in_use; + tbl->keys_in_use_for_order_by= tbl->s->usable_indexes(tbl->in_use); /* index hint list processing */ if (index_hints) |