From: Jon Olav Hauglid Date: March 28 2012 11:26am Subject: bzr push into mysql-trunk branch (jon.hauglid:3864 to 3865) WL#5534 List-Archive: http://lists.mysql.com/commits/143340 Message-Id: <201203281126.q2SBQSZg022851@acsmt357.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3865 Jon Olav Hauglid 2012-03-28 WL#5534 Online ALTER, Phase 1 Follow-up patch that removes old code no longer needed with WL#5526 since InnoDB now utilizes the new handler API for in-place/online ALTER TABLE. The following parts are removed: *) Old handler API functions used for in-place add/drop index: add_index(), final_add_index(), prepare_drop_index(), final_drop_index() and prepare_for_alter(). *) The compatibility layer implementation of handler::inplace_alter_table() and handler::commit_inplace_alter_table() that converted from the new API function calls to the old API function calls. *) HA_INPLACE_* capability flags used to indicate a storage engines capability for executing in-place/online ALTER TABLE operations. Engines should now override handler::check_if_supported_inplace_alter(). *) handler_add_index class. *) FIELD_IN_ADD_INDEX flag. *) Parts of the compatibility layer implementation of handler::check_if_supported_inplace_alter() that concerned add/drop index. Note that handler::check_if_incompatible_data() is not removed. It is used by the compatibility layer implementation of handler::check_if_supported_inplace_alter(). modified: include/mysql_com.h sql/ha_ndbcluster.cc sql/ha_ndbcluster.h sql/ha_partition.cc sql/handler.cc sql/handler.h 3864 Praveenkumar Hulakund 2012-03-28 [merge] merge from 5.5 to 5.6 (trunk) modified: mysql-test/r/sp-bugs.result mysql-test/r/sp-code.result mysql-test/r/sp_notembedded.result mysql-test/t/sp-bugs.test mysql-test/t/sp-code.test mysql-test/t/sp_notembedded.test === modified file 'include/mysql_com.h' --- a/include/mysql_com.h 2012-03-14 13:12:36 +0000 +++ b/include/mysql_com.h 2012-03-28 11:25:37 +0000 @@ -114,9 +114,10 @@ enum enum_server_command #define BINCMP_FLAG 131072 /* Intern: Used by sql_yacc */ #define GET_FIXED_FIELDS_FLAG (1 << 18) /* Used to get fields in item tree */ #define FIELD_IN_PART_FUNC_FLAG (1 << 19)/* Field part of partition func */ -#define FIELD_IN_ADD_INDEX (1<< 20) /* Intern: Field used in ADD INDEX. - Deprecated. Used by old in-place - ALTER TABLE API only. */ +/* + #define FIELD_IN_ADD_INDEX (1<< 20) + Was part of old online ALTER API, flag is now unused. +*/ #define FIELD_IS_RENAMED (1<< 21) /* Intern: Field is being renamed */ #define FIELD_FLAGS_STORAGE_MEDIA 22 /* Field storage media, bit 22-23, reserved by MySQL Cluster */ === modified file 'sql/ha_ndbcluster.cc' --- a/sql/ha_ndbcluster.cc 2012-03-08 15:58:08 +0000 +++ b/sql/ha_ndbcluster.cc 2012-03-28 11:25:37 +0000 @@ -353,18 +353,6 @@ static uint ndbcluster_alter_table_flags(uint flags) { const uint f= - HA_INPLACE_ADD_INDEX_NO_READ_WRITE | - HA_INPLACE_DROP_INDEX_NO_READ_WRITE | - HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE | - HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE | - HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE | - HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE | - HA_INPLACE_ADD_INDEX_NO_WRITE | - HA_INPLACE_DROP_INDEX_NO_WRITE | - HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE | - HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE | - HA_INPLACE_ADD_PK_INDEX_NO_WRITE | - HA_INPLACE_DROP_PK_INDEX_NO_WRITE | HA_PARTITION_FUNCTION_SUPPORTED | 0; @@ -9926,31 +9914,6 @@ int ha_ndbcluster::create_ndb_index(THD DBUG_RETURN(0); } -/* - Prepare for an on-line alter table -*/ -void ha_ndbcluster::prepare_for_alter() -{ - /* ndb_share reference schema */ - ndbcluster_get_share(m_share); // Increase ref_count - DBUG_PRINT("NDB_SHARE", ("%s binlog schema use_count: %u", - m_share->key, m_share->use_count)); - set_ndb_share_state(m_share, NSS_ALTERED); -} - -/* - Add an index on-line to a table -*/ -int ha_ndbcluster::add_index(TABLE *table_arg, - KEY *key_info, uint num_of_keys, - handler_add_index **add) -{ - // TODO: As we don't yet implement ::final_add_index(), - // we don't need a handler_add_index object either..? - *add= NULL; // new handler_add_index(table_arg, key_info, num_of_keys); - return add_index_impl(current_thd, table_arg, key_info, num_of_keys); -} - int ha_ndbcluster::add_index_impl(THD *thd, TABLE *table_arg, KEY *key_info, uint num_of_keys) { @@ -9978,46 +9941,6 @@ int ha_ndbcluster::add_index_impl(THD *t DBUG_RETURN(error); } -/* - Mark one or several indexes for deletion. and - renumber the remaining indexes -*/ -int ha_ndbcluster::prepare_drop_index(TABLE *table_arg, - uint *key_num, uint num_of_keys) -{ - DBUG_ENTER("ha_ndbcluster::prepare_drop_index"); - DBUG_ASSERT(m_share->state == NSS_ALTERED); - // Mark indexes for deletion - uint idx; - for (idx= 0; idx < num_of_keys; idx++) - { - DBUG_PRINT("info", ("ha_ndbcluster::prepare_drop_index %u", *key_num)); - m_index[*key_num++].status= TO_BE_DROPPED; - } - // Renumber indexes - THD *thd= current_thd; - Thd_ndb *thd_ndb= get_thd_ndb(thd); - Ndb *ndb= thd_ndb->ndb; - renumber_indexes(ndb, table_arg); - DBUG_RETURN(0); -} - -/* - Really drop all indexes marked for deletion -*/ -int ha_ndbcluster::final_drop_index(TABLE *table_arg) -{ - int error; - DBUG_ENTER("ha_ndbcluster::final_drop_index"); - DBUG_PRINT("info", ("ha_ndbcluster::final_drop_index")); - // Really drop indexes - THD *thd= current_thd; - Thd_ndb *thd_ndb= get_thd_ndb(thd); - Ndb *ndb= thd_ndb->ndb; - error= drop_indexes(ndb, table_arg); - DBUG_RETURN(error); -} - /** Rename a table in NDB Cluster. */ === modified file 'sql/ha_ndbcluster.h' --- a/sql/ha_ndbcluster.h 2012-03-06 14:29:42 +0000 +++ b/sql/ha_ndbcluster.h 2012-03-28 11:25:37 +0000 @@ -319,12 +319,6 @@ class ha_ndbcluster: public handler const char * table_type() const; const char ** bas_ext() const; ulonglong table_flags(void) const; - void prepare_for_alter(); - int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys, - handler_add_index **add); -//int final_add_index(handler_add_index *add, bool commit); // TODO - int prepare_drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys); - int final_drop_index(TABLE *table_arg); void set_part_info(partition_info *part_info, bool early); ulong index_flags(uint idx, uint part, bool all_parts) const; virtual const key_map *keys_to_use_for_scanning() { return &btree_keys; } === modified file 'sql/ha_partition.cc' --- a/sql/ha_partition.cc 2012-03-22 01:52:59 +0000 +++ b/sql/ha_partition.cc 2012-03-28 11:25:37 +0000 @@ -7073,41 +7073,12 @@ bool ha_partition::get_error_message(int */ uint ha_partition::alter_table_flags(uint flags) { - uint flags_to_return, flags_to_check; + uint flags_to_return; DBUG_ENTER("ha_partition::alter_table_flags"); flags_to_return= ht->alter_table_flags(flags); - flags_to_return|= m_file[0]->alter_table_flags(flags); + flags_to_return|= m_file[0]->alter_table_flags(flags); - /* - If one partition fails we must be able to revert the change for the other, - already altered, partitions. So both ADD and DROP can only be supported in - pairs. - */ - flags_to_check= HA_INPLACE_ADD_INDEX_NO_READ_WRITE; - flags_to_check|= HA_INPLACE_DROP_INDEX_NO_READ_WRITE; - if ((flags_to_return & flags_to_check) != flags_to_check) - flags_to_return&= ~flags_to_check; - flags_to_check= HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE; - flags_to_check|= HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE; - if ((flags_to_return & flags_to_check) != flags_to_check) - flags_to_return&= ~flags_to_check; - flags_to_check= HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE; - flags_to_check|= HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE; - if ((flags_to_return & flags_to_check) != flags_to_check) - flags_to_return&= ~flags_to_check; - flags_to_check= HA_INPLACE_ADD_INDEX_NO_WRITE; - flags_to_check|= HA_INPLACE_DROP_INDEX_NO_WRITE; - if ((flags_to_return & flags_to_check) != flags_to_check) - flags_to_return&= ~flags_to_check; - flags_to_check= HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE; - flags_to_check|= HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE; - if ((flags_to_return & flags_to_check) != flags_to_check) - flags_to_return&= ~flags_to_check; - flags_to_check= HA_INPLACE_ADD_PK_INDEX_NO_WRITE; - flags_to_check|= HA_INPLACE_DROP_PK_INDEX_NO_WRITE; - if ((flags_to_return & flags_to_check) != flags_to_check) - flags_to_return&= ~flags_to_check; DBUG_RETURN(flags_to_return); } === modified file 'sql/handler.cc' --- a/sql/handler.cc 2012-03-21 21:12:45 +0000 +++ b/sql/handler.cc 2012-03-28 11:25:37 +0000 @@ -3686,6 +3686,17 @@ handler::ha_discard_or_import_tablespace } +bool handler::ha_prepare_inplace_alter_table(TABLE *altered_table, + Alter_inplace_info *ha_alter_info) +{ + DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE || + m_lock_type != F_UNLCK); + mark_trx_read_write(); + + return prepare_inplace_alter_table(altered_table, ha_alter_info); +} + + bool handler::ha_commit_inplace_alter_table(TABLE *altered_table, Alter_inplace_info *ha_alter_info, bool commit) @@ -3706,77 +3717,6 @@ bool handler::ha_commit_inplace_alter_ta } -/** - @brief Check if both DROP and CREATE are present for an index in ALTER TABLE - - @details Checks if any index is being modified (present as both DROP INDEX - and ADD INDEX) in the current ALTER TABLE statement. Needed for disabling - in-place ALTER TABLE. - - @param ha_alter_info Structure holding data used during in-place alter. - - @return presence of index being altered - @retval FALSE No such index - @retval TRUE Have at least 1 index modified -*/ - -static bool is_index_maintenance_unique(const Alter_inplace_info *ha_alter_info) -{ - const KEY *add_key; - const KEY *drop_key; - const uint *idx_add_p; - uint idx_drop; - - for (idx_add_p= ha_alter_info->index_add_buffer; - idx_add_p < ha_alter_info->index_add_buffer + - ha_alter_info->index_add_count; idx_add_p++) - { - add_key= ha_alter_info->key_info_buffer + *idx_add_p; - for (idx_drop= 0; idx_drop < ha_alter_info->index_drop_count; idx_drop++) - { - drop_key= ha_alter_info->index_drop_buffer[idx_drop]; - if (!my_strcasecmp(system_charset_info, add_key->name, drop_key->name)) - return true; - } - } - return false; -} - - -/** - Check if engine supports in-place operation for this type of index and - update enum_alter_inplace_result accordingly. - - @param[in] handler_alter_flags Flags specifying handler support for - in-place alter. - @param[in,out] result Current level of in-place alter support. - @param[in] no_write_flag *_NO_WRITE flag to check. - @param[in] no_read_write_flag *_NO_READ_WRITE flag to check. -*/ - -static void check_alter_index_flags(ulong handler_alter_flags, - enum_alter_inplace_result *result, - ulong no_write_flag, - ulong no_read_write_flag) -{ - /* - If we already know that the operation must be done using copy algorithm, - there's nothing left to check. - */ - if (*result == HA_ALTER_INPLACE_NOT_SUPPORTED) - return; - if (handler_alter_flags & no_write_flag) - { - if (*result != HA_ALTER_INPLACE_EXCLUSIVE_LOCK) - *result= HA_ALTER_INPLACE_SHARED_LOCK; - } - else if (handler_alter_flags & no_read_write_flag) - *result= HA_ALTER_INPLACE_EXCLUSIVE_LOCK; - else - *result= HA_ALTER_INPLACE_NOT_SUPPORTED; -} - - /* Default implementation to support in-place alter table and old online add/drop index API @@ -3790,34 +3730,15 @@ handler::check_if_supported_inplace_alte HA_CREATE_INFO *create_info= ha_alter_info->create_info; - ulong handler_alter_flags= table->file->alter_table_flags(0); - DBUG_PRINT("info", ("handler_alter_flags: %lu", handler_alter_flags)); - - Alter_inplace_info::HA_ALTER_FLAGS inplace_online_operations= - Alter_inplace_info::ADD_INDEX | - Alter_inplace_info::DROP_INDEX | - Alter_inplace_info::ADD_UNIQUE_INDEX | - Alter_inplace_info::DROP_UNIQUE_INDEX | - Alter_inplace_info::ADD_PK_INDEX | - Alter_inplace_info::DROP_PK_INDEX; Alter_inplace_info::HA_ALTER_FLAGS inplace_offline_operations= Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH | Alter_inplace_info::ALTER_COLUMN_NAME | Alter_inplace_info::ALTER_COLUMN_DEFAULT | Alter_inplace_info::CHANGE_CREATE_OPTION | Alter_inplace_info::ALTER_RENAME; - Alter_inplace_info::HA_ALTER_FLAGS copy_operations= - ~(inplace_online_operations) & ~(inplace_offline_operations); /* Is there at least one operation that requires copy algorithm? */ - if (ha_alter_info->handler_flags & copy_operations) - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - - /* - Bug #49838 DROP INDEX and ADD UNIQUE INDEX for same index may - corrupt definition at engine - */ - if (is_index_maintenance_unique(ha_alter_info)) + if (ha_alter_info->handler_flags & ~inplace_offline_operations) DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); /* @@ -3836,286 +3757,14 @@ handler::check_if_supported_inplace_alte (table->s->row_type != create_info->row_type)) DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - /* - At this point we know that we won't be adding, dropping or - reordering columns so we can use simple algorithm to properly - set FIELD_IN_ADD_INDEX flag needed by old version of in-place - API. - */ - DBUG_ASSERT(!(ha_alter_info->handler_flags & - (Alter_inplace_info::ADD_COLUMN | - Alter_inplace_info::DROP_COLUMN | - Alter_inplace_info::ALTER_COLUMN_ORDER))); - /* Start by clearing this marker for all fields. */ - for (uint i= 0; i < table->s->fields; i++) - table->field[i]->flags&= ~FIELD_IN_ADD_INDEX; - /* - Then go through all new indexes and use the fact that - fields position has not changed to mark fields belonging - to newly added indexes. - */ - for (uint i= 0; i < ha_alter_info->index_add_count; i++) - { - KEY *k= ha_alter_info->key_info_buffer + ha_alter_info->index_add_buffer[i]; - KEY_PART_INFO *key_part, *end; - for(key_part= k->key_part, end= key_part + k->key_parts; - key_part != end; key_part++) - table->field[key_part->fieldnr]->flags|= FIELD_IN_ADD_INDEX; - } - - /* We now know that it's only inplace_online_operations. */ - enum_alter_inplace_result result= HA_ALTER_ERROR; - - /* Is there at least one in-place operation that must be done offline? */ - if (ha_alter_info->handler_flags & inplace_offline_operations) - { - uint table_changes= (ha_alter_info->handler_flags & - Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH) ? - IS_EQUAL_PACK_LENGTH : IS_EQUAL_YES; - if (table->file->check_if_incompatible_data(create_info, table_changes) - == COMPATIBLE_DATA_YES) - result= HA_ALTER_INPLACE_EXCLUSIVE_LOCK; - else - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - } - - /* - Bug#11750045 - 40344: ALTER IGNORE TABLE T ADD INDEX DOES NOT IGNORE - IN FAST INDEX CREATION. - Supporting IGNORE for in-place ALTER is problematic as IGNORE requires - that offending rows are deleted, which complicates locking. - Use copy instead. - */ - if (ha_alter_info->ignore) - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - - /* - Bug#13411182 ASSERTION PREBUILT->TABLE->N_REF_COUNT == 2 ON ADD FULLTEXT - Creating a fulltext index in InnoDB has the same locking requirements - as adding a primary index since it may require a rebuild of the primary - index. - */ - if (ha_alter_info->handler_flags & (Alter_inplace_info::ADD_INDEX | - Alter_inplace_info::ADD_UNIQUE_INDEX)) - { - for (uint i= 0; i < ha_alter_info->index_add_count; i++) - { - KEY *key= - &ha_alter_info->key_info_buffer[ha_alter_info->index_add_buffer[i]]; - if (key->flags & HA_FULLTEXT) - { - check_alter_index_flags(handler_alter_flags, &result, - HA_INPLACE_ADD_PK_INDEX_NO_WRITE, - HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE); - break; - } - } - } - - /* Add index */ - if (ha_alter_info->handler_flags & Alter_inplace_info::ADD_INDEX) - { - check_alter_index_flags(handler_alter_flags, &result, - HA_INPLACE_ADD_INDEX_NO_WRITE, - HA_INPLACE_ADD_INDEX_NO_READ_WRITE); - } - /* Drop index */ - if (ha_alter_info->handler_flags & Alter_inplace_info::DROP_INDEX) - { - check_alter_index_flags(handler_alter_flags, &result, - HA_INPLACE_DROP_INDEX_NO_WRITE, - HA_INPLACE_DROP_INDEX_NO_READ_WRITE); - } - /* Add unique index */ - if (ha_alter_info->handler_flags & Alter_inplace_info::ADD_UNIQUE_INDEX) - { - check_alter_index_flags(handler_alter_flags, &result, - HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE, - HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE); - } - /* Drop unique index */ - if (ha_alter_info->handler_flags & Alter_inplace_info::DROP_UNIQUE_INDEX) - { - check_alter_index_flags(handler_alter_flags, &result, - HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE, - HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE); - } - /* Add primary key */ - if (ha_alter_info->handler_flags & Alter_inplace_info::ADD_PK_INDEX) - { - check_alter_index_flags(handler_alter_flags, &result, - HA_INPLACE_ADD_PK_INDEX_NO_WRITE, - HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE); - } - /* Drop primary key */ - if (ha_alter_info->handler_flags & Alter_inplace_info::DROP_PK_INDEX) - { - check_alter_index_flags(handler_alter_flags, &result, - HA_INPLACE_DROP_PK_INDEX_NO_WRITE, - HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE); - } - - /* At least one ha_alter_info->handler_flags check should be hit. */ - DBUG_ASSERT(result != HA_ALTER_ERROR); - - DBUG_RETURN(result); -} - - -bool handler::ha_prepare_inplace_alter_table(TABLE *altered_table, - Alter_inplace_info *ha_alter_info) -{ - DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE || - m_lock_type != F_UNLCK); - mark_trx_read_write(); - - prepare_for_alter(); - - return prepare_inplace_alter_table(altered_table, ha_alter_info); -} - - -/* - Default implementation to support in-place alter table - and old online add/drop index API -*/ - -bool handler::inplace_alter_table(TABLE *altered_table, - Alter_inplace_info *ha_alter_info) -{ - DBUG_ENTER("inplace_alter_table"); - int error= 0; - Alter_inplace_info::HA_ALTER_FLAGS adding= - Alter_inplace_info::ADD_INDEX | - Alter_inplace_info::ADD_UNIQUE_INDEX | - Alter_inplace_info::ADD_PK_INDEX; - Alter_inplace_info::HA_ALTER_FLAGS dropping= - Alter_inplace_info::DROP_INDEX | - Alter_inplace_info::DROP_UNIQUE_INDEX | - Alter_inplace_info::DROP_PK_INDEX; - - if (ha_alter_info->handler_flags & adding) - { - KEY *key_info; - KEY *key; - uint *idx_p; - uint *idx_end_p; - KEY_PART_INFO *key_part; - KEY_PART_INFO *part_end; - key_info= (KEY*) ha_thd()->alloc(sizeof(KEY) * ha_alter_info->index_add_count); - key= key_info; - for (idx_p= ha_alter_info->index_add_buffer, - idx_end_p= idx_p + ha_alter_info->index_add_count; - idx_p < idx_end_p; - idx_p++, key++) - { - /* Copy the KEY struct. */ - *key= ha_alter_info->key_info_buffer[*idx_p]; - /* - Fix the key parts. - Note that this is only safe since we know at this point that - we're not adding new columns or reordering columns. - */ - part_end= key->key_part + key->key_parts; - for (key_part= key->key_part; key_part < part_end; key_part++) - key_part->field= table->field[key_part->fieldnr]; - } - /* Add the indexes. */ - if ((error= add_index(table, key_info, - ha_alter_info->index_add_count, - &ha_alter_info->handler_ctx))) - { - /* - Exchange the key_info for the error message. If we exchange - key number by key name in the message later, we need correct info. - */ - KEY *save_key_info= table->key_info; - table->key_info= key_info; - table->file->print_error(error, MYF(0)); - table->key_info= save_key_info; - DBUG_RETURN(true); - } - DBUG_ASSERT(ha_alter_info->handler_ctx); - ha_alter_info->handler_ctx->pending_add_index= true; - } - - if (ha_alter_info->handler_flags & dropping) - { - /* Currently we must finalize add index if we also drop indexes */ - if (ha_alter_info->handler_ctx && - ha_alter_info->handler_ctx->pending_add_index) - { - /* Committing index changes needs exclusive metadata lock. */ - DBUG_ASSERT(ha_thd()->mdl_context.is_lock_owner(MDL_key::TABLE, - table->s->db.str, - table->s->table_name.str, - MDL_EXCLUSIVE)); - if ((error= final_add_index(ha_alter_info->handler_ctx, true))) - { - print_error(error, MYF(0)); - DBUG_RETURN(true); - } - ha_alter_info->handler_ctx->pending_add_index= false; - } - - DBUG_PRINT("info", ("Renumbering indexes")); - /* The prepare_drop_index() method takes an array of keys. */ - if ((error= prepare_drop_index(ha_alter_info->index_drop_buffer, - ha_alter_info->index_drop_count))) - { - table->file->print_error(error, MYF(0)); - DBUG_RETURN(true); - } - } - - DBUG_RETURN(false); -} - - -/* - Default implementation to support in-place alter table - and old online add/drop index API -*/ - -bool handler::commit_inplace_alter_table(TABLE *altered_table, - Alter_inplace_info *ha_alter_info, - bool commit) -{ - DBUG_ENTER("commit_inplace_alter_table"); - int error= 0; - Alter_inplace_info::HA_ALTER_FLAGS dropping= - Alter_inplace_info::DROP_INDEX | - Alter_inplace_info::DROP_UNIQUE_INDEX | - Alter_inplace_info::DROP_PK_INDEX; - - // Do not call final_drop_index() if commit= false. - if (commit && (ha_alter_info->handler_flags & dropping)) - { - if ((error= final_drop_index())) - { - print_error(error, MYF(0)); - DBUG_RETURN(true); - } - } - - if (ha_alter_info->handler_ctx && - ha_alter_info->handler_ctx->pending_add_index) - { - ha_alter_info->handler_ctx->pending_add_index= false; - if ((error= final_add_index(ha_alter_info->handler_ctx, commit))) - { - print_error(error, MYF(0)); - DBUG_RETURN(true); - } - } - - /* - For safety. With old API this object was deleted by the handler. - With new API the deletion is done by the SQL layer. - */ - ha_alter_info->handler_ctx= NULL; + uint table_changes= (ha_alter_info->handler_flags & + Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH) ? + IS_EQUAL_PACK_LENGTH : IS_EQUAL_YES; + if (table->file->check_if_incompatible_data(create_info, table_changes) + == COMPATIBLE_DATA_YES) + DBUG_RETURN(HA_ALTER_INPLACE_EXCLUSIVE_LOCK); - DBUG_RETURN(false); + DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } === modified file 'sql/handler.h' --- a/sql/handler.h 2012-03-15 13:43:21 +0000 +++ b/sql/handler.h 2012-03-28 11:25:37 +0000 @@ -208,36 +208,6 @@ enum enum_alter_inplace_result { /** bits in alter_table_flags: - @deprecated with WL#5534: Online ALTER TABLE. - @see check_if_supported_inplace_alter() -*/ -/* - These bits are set if different kinds of indexes can be created or dropped - in-place without re-creating the table using a temporary table. - NO_READ_WRITE indicates that the handler needs concurrent reads and writes - of table data to be blocked. - Partitioning needs both ADD and DROP to be supported by its underlying - handlers, due to error handling, see bug#57778. -*/ -#define HA_INPLACE_ADD_INDEX_NO_READ_WRITE (1L << 0) -#define HA_INPLACE_DROP_INDEX_NO_READ_WRITE (1L << 1) -#define HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE (1L << 2) -#define HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE (1L << 3) -#define HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE (1L << 4) -#define HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE (1L << 5) -/* - These are set if different kinds of indexes can be created or dropped - in-place while still allowing concurrent reads (but not writes) of table - data. If a handler is capable of one or more of these, it should also set - the corresponding *_NO_READ_WRITE bit(s). -*/ -#define HA_INPLACE_ADD_INDEX_NO_WRITE (1L << 6) -#define HA_INPLACE_DROP_INDEX_NO_WRITE (1L << 7) -#define HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE (1L << 8) -#define HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE (1L << 9) -#define HA_INPLACE_ADD_PK_INDEX_NO_WRITE (1L << 10) -#define HA_INPLACE_DROP_PK_INDEX_NO_WRITE (1L << 11) -/* HA_PARTITION_FUNCTION_SUPPORTED indicates that the function is supported at all. HA_FAST_CHANGE_PARTITION means that optimised variants of the changes @@ -262,9 +232,9 @@ enum enum_alter_inplace_result { the storage engine. A typical engine to support this is NDB (through WL #2498). */ -#define HA_PARTITION_FUNCTION_SUPPORTED (1L << 12) -#define HA_FAST_CHANGE_PARTITION (1L << 13) -#define HA_PARTITION_ONE_PHASE (1L << 14) +#define HA_PARTITION_FUNCTION_SUPPORTED (1L << 0) +#define HA_FAST_CHANGE_PARTITION (1L << 1) +#define HA_PARTITION_ONE_PHASE (1L << 2) /* operations for disable/enable indexes */ #define HA_KEY_SWITCH_NONUNIQ 0 @@ -951,11 +921,8 @@ typedef struct st_ha_create_information class inplace_alter_handler_ctx : public Sql_alloc { public: - bool pending_add_index; + inplace_alter_handler_ctx() {} - inplace_alter_handler_ctx() - :pending_add_index(false) - {} virtual ~inplace_alter_handler_ctx() {} }; @@ -1081,8 +1048,8 @@ public: array. @todo This is mainly due to the fact that we need to keep compatibility - with deprecated handler::add_index() call. We plan to switch to - TABLE::key_info numbering once the deprecated API is removed. + with removed handler::add_index() call. We plan to switch to + TABLE::key_info numbering later. KEYs are sorted - see sort_keys(). */ @@ -1507,29 +1474,6 @@ uint calculate_key_len(TABLE *, uint, co #define make_prev_keypart_map(N) (((key_part_map)1 << (N)) - 1) -/** - Index creation context. - Created by handler::add_index() and destroyed by handler::final_add_index(). - And finally freed at the end of the statement. - (Sql_alloc does not free in delete). -*/ - -class handler_add_index : public Sql_alloc -{ -public: - /* Table where the indexes are added */ - TABLE* const table; - /* Indexes being created */ - KEY* const key_info; - /* Size of key_info[] */ - const uint num_of_keys; - handler_add_index(TABLE *table_arg, KEY *key_info_arg, uint num_of_keys_arg) - : table (table_arg), key_info (key_info_arg), num_of_keys (num_of_keys_arg) - {} - virtual ~handler_add_index() {} -}; - - /** Base class to be used by handlers different shares */ class Handler_share { @@ -2287,47 +2231,6 @@ public: virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0; - /** - First phase of in-place add index in old, deprecated in-place ALTER API. - Handlers are supposed to create new indexes here but not make them visible. - - @param table_arg Table to add index to - @param key_info Information about new indexes - @param num_of_key Number of new indexes - @param add[out] Context of handler specific information needed - for final_add_index(). - - @note This function can be called with less than exclusive metadata - lock depending on which flags are listed in alter_table_flags. - */ - virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys, - inplace_alter_handler_ctx **add) - { return (HA_ERR_WRONG_COMMAND); } - - /** - Second and last phase of in-place add index in old, deprecated in-place - ALTER API. Commit or rollback pending new indexes. - - @param add Context of handler specific information from add_index(). - @param commit If true, commit. If false, rollback index changes. - - @note This function is called with exclusive metadata lock. - */ - virtual int final_add_index(inplace_alter_handler_ctx *add, bool commit) - { return (HA_ERR_WRONG_COMMAND); } - - /** - First phase of in-place drop index in old, deprecated in-place ALTER API. - */ - virtual int prepare_drop_index(KEY **keys, uint num_of_keys) - { return (HA_ERR_WRONG_COMMAND); } - /** - Second and last phase of in-place drop index in old, deprecated in-place - ALTER API. - */ - virtual int final_drop_index() - { return (HA_ERR_WRONG_COMMAND); } - uint max_record_length() const { using std::min; @@ -2724,7 +2627,8 @@ protected: @retval false Success */ virtual bool inplace_alter_table(TABLE *altered_table, - Alter_inplace_info *ha_alter_info); + Alter_inplace_info *ha_alter_info) + { return false; } /** @@ -2757,7 +2661,8 @@ protected: */ virtual bool commit_inplace_alter_table(TABLE *altered_table, Alter_inplace_info *ha_alter_info, - bool commit); + bool commit) + { return false; } /** @@ -2970,7 +2875,6 @@ public: virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; } virtual int discard_or_import_tablespace(my_bool discard) { return (my_errno=HA_ERR_WRONG_COMMAND); } - virtual void prepare_for_alter() { return; } virtual void drop_table(const char *name); virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0; No bundle (reason: useless for push emails).