From: Jon Olav Hauglid Date: November 14 2011 3:18pm Subject: bzr push into mysql-trunk-wl5534 branch (jon.hauglid:3418 to 3420) WL#5534 List-Archive: http://lists.mysql.com/commits/141938 Message-Id: <201111141518.pAEFIX0n014092@acsmt357.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3420 Jon Olav Hauglid 2011-11-04 WL#5534 Online ALTER, Phase 1. Patch #45: Review fixes, part 3. - Simplified handler::check_if_supported_inplace_alter() logic, added more code comments. - Added check_alter_index_flags() helper function to remove duplicated code. - Moved pending_add_index from Alter_inplace_information to inplace_alter_handler_ctx. modified: sql/handler.cc sql/handler.h 3419 Jon Olav Hauglid 2011-11-02 WL#5534 Online ALTER, Phase 1. Patch #44: Review fixes, part 2. - Made is_index_maintenance_unique() a static helper function rather than a member function of handler. - Moved tmp table check from default implementation of handler::check_if_supported_inplace_alter() to SQL layer as this is a general restriction. - Moved HA_ALTER_STORAGE_ENGINE check to default implementation of handler::check_if_supported_inplace_alter(). - Removed the 'table_changes' parameter from handler::check_if_supported_inplace_alter(). Instead rely on HA_ALTER_FLAGS. - Removed Alter_info::has_new_or_reordered_columns(). Instead rely on HA_ALTER_FLAGS. - Added more HA_ALTER_FLAGS checks to default implementation of handler::check_if_supported_inplace_alter(). Also made parser set ALTER_COLUMN_ORDER flag. - Removed unused members from inplace_alter_handler_ctx. - Made a few parameters const. modified: sql/ha_partition.cc sql/ha_partition.h sql/handler.cc sql/handler.h sql/sql_alter.cc sql/sql_alter.h sql/sql_lex.h sql/sql_table.cc sql/sql_yacc.yy storage/innobase/handler/handler0alter.cc 3418 Jon Olav Hauglid 2011-11-01 [merge] Merge from mysql-trunk to mysql-trunk-wl5534. No conflicts. removed: mysql-test/suite/rpl/r/rpl_mixed_crash_safe.result.THIS mysql-test/suite/rpl/t/rpl_mixed_crash_safe.test.THIS storage/perfschema/table_file_summary.cc storage/perfschema/table_file_summary.h added: mysql-test/suite/rpl/r/rpl_rotate_purge_deadlock.result mysql-test/suite/rpl/t/rpl_rotate_purge_deadlock-master.opt mysql-test/suite/rpl/t/rpl_rotate_purge_deadlock.test storage/perfschema/table_file_summary_by_event_name.cc storage/perfschema/table_file_summary_by_event_name.h storage/perfschema/table_file_summary_by_instance.cc storage/perfschema/table_file_summary_by_instance.h modified: cmd-line-utils/libedit/README cmd-line-utils/libedit/chared.c mysql-test/extra/rpl_tests/rpl_parallel_load.test mysql-test/include/subquery_mat.inc mysql-test/include/subquery_sj.inc mysql-test/r/archive.result mysql-test/r/compare.result mysql-test/r/derived.result mysql-test/r/func_rollback.result mysql-test/r/index_merge_innodb.result mysql-test/r/mysqld--help-notwin.result mysql-test/r/mysqld--help-win.result mysql-test/r/optimizer_switch.result mysql-test/r/plugin.result mysql-test/r/signal.result mysql-test/r/sp-error.result mysql-test/r/sp.result mysql-test/r/subquery_all.result mysql-test/r/subquery_all_bka.result mysql-test/r/subquery_all_bka_nixbnl.result mysql-test/r/subquery_mat.result mysql-test/r/subquery_mat_all.result mysql-test/r/subquery_sj_all.result mysql-test/r/subquery_sj_all_bka.result mysql-test/r/subquery_sj_all_bka_nixbnl.result mysql-test/r/subquery_sj_all_bkaunique.result mysql-test/r/subquery_sj_dupsweed.result mysql-test/r/subquery_sj_dupsweed_bka.result mysql-test/r/subquery_sj_dupsweed_bka_nixbnl.result mysql-test/r/subquery_sj_dupsweed_bkaunique.result mysql-test/r/subquery_sj_firstmatch.result mysql-test/r/subquery_sj_firstmatch_bka.result mysql-test/r/subquery_sj_firstmatch_bka_nixbnl.result mysql-test/r/subquery_sj_firstmatch_bkaunique.result mysql-test/r/subquery_sj_loosescan.result mysql-test/r/subquery_sj_loosescan_bka.result mysql-test/r/subquery_sj_loosescan_bka_nixbnl.result mysql-test/r/subquery_sj_loosescan_bkaunique.result mysql-test/r/subquery_sj_mat.result mysql-test/r/subquery_sj_mat_bka.result mysql-test/r/subquery_sj_mat_bka_nixbnl.result mysql-test/r/subquery_sj_mat_bkaunique.result mysql-test/r/subquery_sj_mat_nosj.result mysql-test/r/subquery_sj_none.result mysql-test/r/subquery_sj_none_bka.result mysql-test/r/subquery_sj_none_bka_nixbnl.result mysql-test/r/subquery_sj_none_bkaunique.result mysql-test/r/user_var.result mysql-test/r/view_grant.result mysql-test/suite/funcs_1/r/storedproc.result mysql-test/suite/opt_trace/r/bugs_no_prot_all.result mysql-test/suite/opt_trace/r/bugs_ps_prot_all.result mysql-test/suite/opt_trace/r/general_no_prot_all.result mysql-test/suite/opt_trace/r/general_ps_prot_all.result mysql-test/suite/opt_trace/r/range_no_prot.result mysql-test/suite/opt_trace/r/range_ps_prot.result mysql-test/suite/perfschema/r/func_file_io.result mysql-test/suite/perfschema/r/pfs_upgrade.result mysql-test/suite/perfschema/r/relaylog.result mysql-test/suite/perfschema/r/schema.result mysql-test/suite/perfschema/r/start_server_nothing.result mysql-test/suite/perfschema/r/table_schema.result mysql-test/suite/rpl/r/rpl_alter_repository.result mysql-test/suite/rpl/r/rpl_checksum.result mysql-test/suite/rpl/r/rpl_log_pos.result mysql-test/suite/rpl/r/rpl_manual_change_index_file.result mysql-test/suite/rpl/t/rpl_alter_repository.test mysql-test/suite/rpl/t/rpl_checksum.test mysql-test/suite/rpl/t/rpl_log_pos.test mysql-test/suite/rpl/t/rpl_manual_change_index_file.test mysql-test/suite/rpl/t/rpl_packet.test mysql-test/suite/rpl/t/rpl_row_event_max_size.test mysql-test/suite/sys_vars/r/sort_buffer_size_basic_32.result* mysql-test/suite/sys_vars/r/sort_buffer_size_basic_64.result mysql-test/t/archive.test mysql-test/t/compare.test mysql-test/t/derived.test mysql-test/t/index_merge_innodb.test mysql-test/t/plugin.test mysql-test/t/signal.test mysql-test/t/sp-error.test mysql-test/t/user_var.test scripts/mysql_system_tables.sql sql/binlog.cc sql/binlog.h sql/event_db_repository.cc sql/events.cc sql/item_cmpfunc.cc sql/log.cc sql/log.h sql/opt_range.cc sql/records.cc sql/records.h sql/rpl_master.cc sql/rpl_slave.cc sql/sp_head.cc sql/sp_rcontext.cc sql/sql_acl.cc sql/sql_base.cc sql/sql_class.h sql/sql_const.h sql/sql_delete.cc sql/sql_help.cc sql/sql_join_cache.cc sql/sql_parse.cc sql/sql_plugin.cc sql/sql_reload.cc sql/sql_select.cc sql/sql_select.h sql/sql_servers.cc sql/sql_table.cc sql/sql_udf.cc sql/sql_update.cc sql/sys_vars.cc storage/archive/ha_archive.cc storage/innobase/buf/buf0buf.c storage/innobase/dict/dict0dict.c storage/innobase/fil/fil0fil.c storage/innobase/fsp/fsp0fsp.c storage/innobase/handler/ha_innodb.cc storage/innobase/include/buf0buf.h storage/innobase/include/fil0fil.h storage/innobase/include/fsp0fsp.h storage/innobase/include/sync0rw.ic storage/innobase/lock/lock0lock.c storage/innobase/row/row0mysql.c storage/innobase/row/row0umod.c storage/innobase/srv/srv0start.c storage/perfschema/CMakeLists.txt storage/perfschema/pfs.cc storage/perfschema/pfs_engine_table.cc storage/perfschema/pfs_events.h storage/perfschema/pfs_instr.cc storage/perfschema/pfs_instr.h storage/perfschema/pfs_stat.h storage/perfschema/pfs_visitor.cc storage/perfschema/pfs_visitor.h storage/perfschema/table_events_stages.cc storage/perfschema/table_events_stages.h storage/perfschema/table_events_statements.cc storage/perfschema/table_events_statements.h storage/perfschema/table_events_waits.cc storage/perfschema/table_events_waits.h storage/perfschema/table_helper.h storage/perfschema/table_socket_summary_by_instance.cc === modified file 'sql/ha_partition.cc' --- a/sql/ha_partition.cc 2011-10-31 15:42:48 +0000 +++ b/sql/ha_partition.cc 2011-11-02 09:55:44 +0000 @@ -6908,12 +6908,11 @@ bool ha_partition::check_if_incompatible Support of in-place alter table. */ enum_alter_inplace_result -ha_partition::check_if_supported_inplace_alter(TABLE *table, +ha_partition::check_if_supported_inplace_alter(const TABLE *table, HA_CREATE_INFO *create_info, - Alter_info *alter_info, - Alter_inplace_information *ha_alter_info, - HA_ALTER_FLAGS *alter_flags, - uint table_changes) + const Alter_info *alter_info, + const Alter_inplace_information *ha_alter_info, + HA_ALTER_FLAGS *alter_flags) { uint index= 0; enum_alter_inplace_result result= HA_ALTER_INPLACE_NO_LOCK; @@ -6924,8 +6923,7 @@ ha_partition::check_if_supported_inplace { enum_alter_inplace_result p_result= m_file[index]->check_if_supported_inplace_alter(table, create_info, alter_info, - ha_alter_info, alter_flags, - table_changes); + ha_alter_info, alter_flags); if (p_result < result) result= p_result; if (result == HA_ALTER_ERROR) @@ -6945,7 +6943,7 @@ class ha_partition_inplace_ctx : public public: inplace_alter_handler_ctx **handler_ctx_array; ha_partition_inplace_ctx() - : inplace_alter_handler_ctx(NULL, 0) + : inplace_alter_handler_ctx() {} ~ha_partition_inplace_ctx() {} }; === modified file 'sql/ha_partition.h' --- a/sql/ha_partition.h 2011-10-21 18:00:03 +0000 +++ b/sql/ha_partition.h 2011-11-02 09:55:44 +0000 @@ -1056,12 +1056,11 @@ public: ------------------------------------------------------------------------- */ virtual enum_alter_inplace_result - check_if_supported_inplace_alter(TABLE *table, + check_if_supported_inplace_alter(const TABLE *table, HA_CREATE_INFO *create_info, - Alter_info *alter_info, - Alter_inplace_information *ha_alter_info, - HA_ALTER_FLAGS *alter_flags, - uint table_changes); + const Alter_info *alter_info, + const Alter_inplace_information *ha_alter_info, + HA_ALTER_FLAGS *alter_flags); virtual bool prepare_inplace_alter_table(HA_CREATE_INFO *create_info, Alter_inplace_information *ha_alter_info, HA_ALTER_FLAGS *alter_flags); === modified file 'sql/handler.cc' --- a/sql/handler.cc 2011-10-27 10:58:28 +0000 +++ b/sql/handler.cc 2011-11-04 16:14:46 +0000 @@ -3700,21 +3700,38 @@ handler::ha_prepare_for_alter() } -bool Alter_inplace_information::is_index_maintenance_unique (const TABLE *table) +/** + @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. + @param table The table being altered + + @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_information *ha_alter_info, + const TABLE *table) { const KEY *add_key; const KEY *drop_key; const uint *idx_add_p; uint idx_drop; - for (idx_add_p= index_add_buffer; - idx_add_p < index_add_buffer + - index_add_count; idx_add_p++) + 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= key_info_buffer + *idx_add_p; - for (idx_drop= 0; idx_drop < index_drop_count; idx_drop++) + 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= index_drop_buffer[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; } @@ -3722,20 +3739,52 @@ bool Alter_inplace_information::is_index return false; } + +/** + Check if *_NO_WRITE or *_NO_READ_WRITE flags are set 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 interface + and old online add/drop index API */ + enum_alter_inplace_result -handler::check_if_supported_inplace_alter(TABLE *table, +handler::check_if_supported_inplace_alter(const TABLE *table, HA_CREATE_INFO *create_info, - Alter_info *alter_info, - Alter_inplace_information *ha_alter_info, - HA_ALTER_FLAGS *alter_flags, - uint table_changes) + const Alter_info *alter_info, + const Alter_inplace_information *ha_alter_info, + HA_ALTER_FLAGS *alter_flags) { DBUG_ENTER("check_if_supported_alter"); - enum_alter_inplace_result result= HA_ALTER_INPLACE_NOT_SUPPORTED; ulong handler_alter_flags= table->file->alter_table_flags(0); HA_ALTER_FLAGS inplace_online_operations; inplace_online_operations= @@ -3752,141 +3801,119 @@ handler::check_if_supported_inplace_alte HA_ALTER_FLAGS copy_operations; copy_operations= copy_operations | + HA_ADD_COLUMN | + HA_DROP_COLUMN | + HA_ALTER_COLUMN_TYPE | + HA_ALTER_COLUMN_ORDER | + HA_ALTER_COLUMN_NULLABLE | HA_ADD_FOREIGN_KEY | HA_DROP_FOREIGN_KEY | HA_ALTER_FOREIGN_KEY | - HA_ADD_CONSTRAINT; - HA_ALTER_FLAGS offline_operations= ~(inplace_online_operations); - HA_ALTER_FLAGS inplace_offline_operations= offline_operations & ~(copy_operations); + HA_ADD_CONSTRAINT | + HA_CHANGE_CHARACTER_SET | + HA_SET_DEFAULT_CHARACTER_SET | + HA_ALTER_STORAGE_ENGINE | + HA_RECREATE | + HA_ALTER_TABLE_REORG; + HA_ALTER_FLAGS inplace_offline_operations= + ~(inplace_online_operations) & ~(copy_operations); DBUG_PRINT("info", ("handler_alter_flags: %lu", handler_alter_flags)); #ifndef DBUG_OFF { char dbug_string[HA_MAX_ALTER_FLAGS+1]; alter_flags->print(dbug_string); DBUG_PRINT("info", ("alter_flags: %s", dbug_string)); - offline_operations.print(dbug_string); - DBUG_PRINT("info", ("offline_operations: %s", dbug_string)); inplace_offline_operations.print(dbug_string); DBUG_PRINT("info", ("inplace_offline_operations: %s", dbug_string)); } #endif - /* Bug #49838 DROP INDEX and ADD UNIQUE INDEX for same index may corrupt definition at engine */ - if (ha_alter_info->is_index_maintenance_unique(table)) + /* Is there at least one operation that requires copy algorithm? */ + if ((*alter_flags & copy_operations).is_set()) DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); /* - ALTER TABLE which adds new columns (e.g. replacing columns being - removed) or changes their order can't be executed using in-place - algorithm even if table structure stays the same. + Bug #49838 DROP INDEX and ADD UNIQUE INDEX for same index may + corrupt definition at engine */ - if (alter_info->has_new_or_reordered_columns()) + if (is_index_maintenance_unique(ha_alter_info, table)) DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - /* In-place ALTER TABLE is not supported for temporary tables. */ - if (table->s->tmp_table) - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - - /* Check the old alter table flags */ - if ((*alter_flags & inplace_offline_operations).is_set() && - table_changes == IS_EQUAL_YES) + /* Is there at least one in-place operation that must be done offline? */ + if ((*alter_flags & inplace_offline_operations).is_set()) { - /* Not adding/dropping index check if supported as fast alter */ if (table->file->check_if_incompatible_data(create_info, IS_EQUAL_YES) == COMPATIBLE_DATA_YES) DBUG_RETURN(HA_ALTER_INPLACE_EXCLUSIVE_LOCK); else DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } - else if ((*alter_flags & offline_operations).is_set()) - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - else + + /* We now know that it's only inplace_online_operations. */ + enum_alter_inplace_result result= HA_ALTER_ERROR; + + /* Add index */ + if (alter_flags->is_set(HA_ADD_INDEX) || + alter_flags->is_set(HA_ALTER_INDEX)) { - /* Add index */ - if ((*alter_flags & HA_ADD_INDEX).is_set() || - (*alter_flags & HA_ALTER_INDEX).is_set()) - { - if (handler_alter_flags & HA_INPLACE_ADD_INDEX_NO_WRITE) - result= (result == HA_ALTER_INPLACE_EXCLUSIVE_LOCK)? - HA_ALTER_INPLACE_EXCLUSIVE_LOCK - : HA_ALTER_INPLACE_SHARED_LOCK; - else if (handler_alter_flags & HA_INPLACE_ADD_INDEX_NO_READ_WRITE) - result= HA_ALTER_INPLACE_EXCLUSIVE_LOCK; - else - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - } - /* Drop index */ - if ((*alter_flags & HA_DROP_INDEX).is_set() || - (*alter_flags & HA_ALTER_INDEX).is_set()) - { - if (handler_alter_flags & HA_INPLACE_DROP_INDEX_NO_WRITE) - result= (result == HA_ALTER_INPLACE_EXCLUSIVE_LOCK)? - HA_ALTER_INPLACE_EXCLUSIVE_LOCK - : HA_ALTER_INPLACE_SHARED_LOCK; - else if (handler_alter_flags & HA_INPLACE_DROP_INDEX_NO_READ_WRITE) - result= HA_ALTER_INPLACE_EXCLUSIVE_LOCK; - else - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - } - /* Add unique index */ - if ((*alter_flags & HA_ADD_UNIQUE_INDEX).is_set() || - (*alter_flags & HA_ALTER_UNIQUE_INDEX).is_set()) - { - if (handler_alter_flags & HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE) - result= (result == HA_ALTER_INPLACE_EXCLUSIVE_LOCK)? - HA_ALTER_INPLACE_EXCLUSIVE_LOCK - : HA_ALTER_INPLACE_SHARED_LOCK; - else if (handler_alter_flags & HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE) - result= HA_ALTER_INPLACE_EXCLUSIVE_LOCK; - else - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - } - /* Drop unique index */ - if ((*alter_flags & HA_DROP_UNIQUE_INDEX).is_set() || - (*alter_flags & HA_ALTER_UNIQUE_INDEX).is_set()) - { - if (handler_alter_flags &HA_INPLACE_DROP_PK_INDEX_NO_WRITE) - result= (result == HA_ALTER_INPLACE_EXCLUSIVE_LOCK)? - HA_ALTER_INPLACE_EXCLUSIVE_LOCK - : HA_ALTER_INPLACE_SHARED_LOCK; - else if (handler_alter_flags & HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE) - result= HA_ALTER_INPLACE_EXCLUSIVE_LOCK; - else - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - } - /* Add primary key */ - if ((*alter_flags & HA_ADD_PK_INDEX).is_set() || - (*alter_flags & HA_ALTER_PK_INDEX).is_set()) - { - if (handler_alter_flags & HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE) - result= HA_ALTER_INPLACE_EXCLUSIVE_LOCK; - else if (handler_alter_flags & HA_INPLACE_ADD_PK_INDEX_NO_WRITE) - result= (result == HA_ALTER_INPLACE_EXCLUSIVE_LOCK)? - HA_ALTER_INPLACE_EXCLUSIVE_LOCK - : HA_ALTER_INPLACE_NO_LOCK; - else - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - } - /* Drop primary key */ - if ((*alter_flags & HA_DROP_PK_INDEX).is_set() || - (*alter_flags & HA_ALTER_PK_INDEX).is_set()) - { - if (handler_alter_flags &HA_INPLACE_DROP_PK_INDEX_NO_WRITE) - result= (result == HA_ALTER_INPLACE_EXCLUSIVE_LOCK)? - HA_ALTER_INPLACE_EXCLUSIVE_LOCK - : HA_ALTER_INPLACE_SHARED_LOCK; - else if (handler_alter_flags & HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE) - result= HA_ALTER_INPLACE_EXCLUSIVE_LOCK; - else - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); - } + check_alter_index_flags(handler_alter_flags, &result, + HA_INPLACE_ADD_INDEX_NO_WRITE, + HA_INPLACE_ADD_INDEX_NO_READ_WRITE); + } + /* Drop index */ + if (alter_flags->is_set(HA_DROP_INDEX) || + alter_flags->is_set(HA_ALTER_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 (alter_flags->is_set(HA_ADD_UNIQUE_INDEX) || + alter_flags->is_set(HA_ALTER_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 (alter_flags->is_set(HA_DROP_UNIQUE_INDEX) || + alter_flags->is_set(HA_ALTER_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 (alter_flags->is_set(HA_ADD_PK_INDEX) || + alter_flags->is_set(HA_ALTER_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 (alter_flags->is_set(HA_DROP_PK_INDEX) || + alter_flags->is_set(HA_ALTER_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); + } + + /* Check if no alter_flags checks were hit. If so, use copy. */ + if (result == HA_ALTER_ERROR) + result= HA_ALTER_INPLACE_NOT_SUPPORTED; + DBUG_RETURN(result); } + /* - Default implementation to support old online add/drop index - */ + Default implementation to support in-place alter table + and old online add/drop index API +*/ + bool handler::inplace_alter_table(HA_CREATE_INFO *create_info, Alter_inplace_information *ha_alter_info, HA_ALTER_FLAGS *alter_flags) @@ -3932,13 +3959,15 @@ bool handler::inplace_alter_table(HA_CRE table->key_info= save_key_info; DBUG_RETURN(true); } - ha_alter_info->pending_add_index= true; + DBUG_ASSERT(ha_alter_info->handler_ctx); + ha_alter_info->handler_ctx->pending_add_index= true; } if ((*alter_flags & dropping).is_set()) { /* Currently we must finalize add index if we also drop indexes */ - if (ha_alter_info->pending_add_index) + 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, @@ -3950,7 +3979,7 @@ bool handler::inplace_alter_table(HA_CRE print_error(error, MYF(0)); DBUG_RETURN(true); } - ha_alter_info->pending_add_index= false; + ha_alter_info->handler_ctx->pending_add_index= false; } DBUG_PRINT("info", ("Renumbering indexes")); @@ -3966,6 +3995,12 @@ bool handler::inplace_alter_table(HA_CRE DBUG_RETURN(false); } + +/* + Default implementation to support in-place alter table + and old online add/drop index API +*/ + bool handler::commit_inplace_alter_table(HA_CREATE_INFO *create_info, Alter_inplace_information *ha_alter_info, HA_ALTER_FLAGS *alter_flags, @@ -3987,9 +4022,10 @@ bool handler::commit_inplace_alter_table } } - if (ha_alter_info->pending_add_index) + if (ha_alter_info->handler_ctx && + ha_alter_info->handler_ctx->pending_add_index) { - ha_alter_info->pending_add_index= false; + 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)); === modified file 'sql/handler.h' --- a/sql/handler.h 2011-10-31 15:42:48 +0000 +++ b/sql/handler.h 2011-11-04 16:14:46 +0000 @@ -962,12 +962,10 @@ typedef struct st_ha_create_information class inplace_alter_handler_ctx : public Sql_alloc { public: - /* Indexes being created */ - KEY* const key_info; - /* Size of key_info[] */ - const uint num_of_keys; - inplace_alter_handler_ctx(KEY *key_info_arg, uint num_of_keys_arg) - : key_info (key_info_arg), num_of_keys (num_of_keys_arg) + bool pending_add_index; + + inplace_alter_handler_ctx() + :pending_add_index(false) {} virtual ~inplace_alter_handler_ctx() {} }; @@ -983,7 +981,6 @@ public: uint index_add_count; uint *index_add_buffer; inplace_alter_handler_ctx *handler_ctx; - bool pending_add_index; Alter_inplace_information() :key_info_buffer(NULL), @@ -992,24 +989,8 @@ public: index_drop_buffer(NULL), index_add_count(0), index_add_buffer(NULL), - handler_ctx(NULL), - pending_add_index(false) + handler_ctx(NULL) {} - - /** - @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 table The table being altered - - @return presence of index being altered - @retval FALSE No such index - @retval TRUE Have at least 1 index modified - */ - bool is_index_maintenance_unique (const TABLE *table); }; @@ -2276,9 +2257,6 @@ public: @param alter_info Data related to detected changes. @param ha_alter_info Structure holding data used during in-place alter. @param alter_flags Bitmask that shows what will be changed. - @param table_changes Shows if table layout has changed (for - backwards compatibility with - check_if_incompatible_data). @retval HA_ALTER_ERROR Unexpected error @retval HA_ALTER_INPLACE_NOT_SUPPORTED Not supported @@ -2296,12 +2274,11 @@ public: implementation. */ virtual enum_alter_inplace_result - check_if_supported_inplace_alter(TABLE *table, + check_if_supported_inplace_alter(const TABLE *table, HA_CREATE_INFO *create_info, - Alter_info *alter_info, - Alter_inplace_information *ha_alter_info, - HA_ALTER_FLAGS *alter_flags, - uint table_changes); + const Alter_info *alter_info, + const Alter_inplace_information *ha_alter_info, + HA_ALTER_FLAGS *alter_flags); /** === modified file 'sql/sql_alter.cc' --- a/sql/sql_alter.cc 2011-09-13 11:15:34 +0000 +++ b/sql/sql_alter.cc 2011-11-02 09:55:44 +0000 @@ -83,23 +83,6 @@ bool Alter_info::set_requested_lock(cons } -bool Alter_info::has_new_or_reordered_columns() -{ - List_iterator_fast new_field_it(create_list); - Create_field *new_field; - uint new_field_idx; - - for (new_field_idx= 0, new_field= new_field_it++; new_field; - new_field_idx++, new_field= new_field_it++) - { - if (! new_field->field || - new_field->field->field_index != new_field_idx) - return true; - } - return false; -} - - bool Sql_cmd_alter_table::execute(THD *thd) { LEX *lex= thd->lex; === modified file 'sql/sql_alter.h' --- a/sql/sql_alter.h 2011-09-13 11:15:34 +0000 +++ b/sql/sql_alter.h 2011-11-02 09:55:44 +0000 @@ -149,16 +149,6 @@ public: bool set_requested_lock(const LEX_STRING *str); - - /** - Check if ALTER TABLE statement changes position of any column - in the table or adds new columns. - - @retval True - some column is added or changes its position. - @retval False - no columns are added nor their positions change. - */ - - bool has_new_or_reordered_columns(); private: Alter_info &operator=(const Alter_info &rhs); // not implemented Alter_info(const Alter_info &rhs); // not implemented === modified file 'sql/sql_lex.h' --- a/sql/sql_lex.h 2011-10-15 17:28:15 +0000 +++ b/sql/sql_lex.h 2011-11-02 09:55:44 +0000 @@ -940,6 +940,7 @@ inline bool st_select_lex_unit::is_union #define ALTER_FOREIGN_KEY (1L << 22) #define ALTER_EXCHANGE_PARTITION (1L << 23) #define ALTER_TRUNCATE_PARTITION (1L << 24) +#define ALTER_COLUMN_ORDER (1L << 25) struct st_sp_chistics { === modified file 'sql/sql_table.cc' --- a/sql/sql_table.cc 2011-11-01 09:19:26 +0000 +++ b/sql/sql_table.cc 2011-11-02 09:55:44 +0000 @@ -5027,8 +5027,8 @@ static void setup_ha_alter_flags(TABLE * *alter_flags|= HA_CHANGE_COLUMN; if (ALTER_CHANGE_COLUMN_DEFAULT & flags) *alter_flags|= HA_COLUMN_DEFAULT_VALUE; -// if (ALTER_COLUMN_ORDER & flags) -// *alter_flags|= HA_ALTER_COLUMN_ORDER; + if (ALTER_COLUMN_ORDER & flags) + *alter_flags|= HA_ALTER_COLUMN_ORDER; // if (ALTER_ROW_FORMAT & flags) // *alter_flags|= HA_ALTER_ROW_FORMAT; if (ALTER_RECREATE & flags) @@ -7266,10 +7266,10 @@ bool mysql_alter_table(THD *thd,char *ne if ((thd->variables.old_alter_table && alter_info->requested_algorithm != Alter_info::ALTER_TABLE_ALGORITHM_INPLACE) - || (table->s->db_type() != create_info->db_type) + || table->s->tmp_table // In-place not supported for tmp tables || ignore #ifdef WITH_PARTITION_STORAGE_ENGINE - || (partition_changed && + || (partition_changed && create_info->db_type == partition_hton && !(create_info->db_type->partition_flags() & HA_USE_AUTO_PARTITION)) #endif ) @@ -7324,8 +7324,7 @@ bool mysql_alter_table(THD *thd,char *ne create_info, alter_info, &ha_alter_info, - &ha_alter_flags, - table_changes); + &ha_alter_flags); switch (inplace_supported) { case HA_ALTER_INPLACE_EXCLUSIVE_LOCK: === modified file 'sql/sql_yacc.yy' --- a/sql/sql_yacc.yy 2011-10-22 20:19:50 +0000 +++ b/sql/sql_yacc.yy 2011-11-02 09:55:44 +0000 @@ -7181,8 +7181,16 @@ opt_restrict: opt_place: /* empty */ {} - | AFTER_SYM ident { store_position_for_column($2.str); } - | FIRST_SYM { store_position_for_column(first_keyword); } + | AFTER_SYM ident + { + store_position_for_column($2.str); + Lex->alter_info.flags |= ALTER_COLUMN_ORDER; + } + | FIRST_SYM + { + store_position_for_column(first_keyword); + Lex->alter_info.flags |= ALTER_COLUMN_ORDER; + } ; opt_to: === modified file 'storage/innobase/handler/handler0alter.cc' --- a/storage/innobase/handler/handler0alter.cc 2011-10-31 15:42:48 +0000 +++ b/storage/innobase/handler/handler0alter.cc 2011-11-02 09:55:44 +0000 @@ -647,9 +647,8 @@ class ha_innobase_add_index : public inp public: /** table where the indexes are being created */ dict_table_t* indexed_table; - ha_innobase_add_index(KEY* key_info, uint num_of_keys, - dict_table_t* indexed_table_arg) : - inplace_alter_handler_ctx(key_info, num_of_keys), + ha_innobase_add_index(dict_table_t* indexed_table_arg) : + inplace_alter_handler_ctx(), indexed_table (indexed_table_arg) {} ~ha_innobase_add_index() {} }; @@ -942,8 +941,7 @@ error_handling: ut_d(mutex_enter(&dict_sys->mutex)); ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE)); ut_d(mutex_exit(&dict_sys->mutex)); - *add = new ha_innobase_add_index(key_info, num_of_keys, - indexed_table); + *add = new ha_innobase_add_index(indexed_table); dict_table_close(prebuilt->table, dict_locked); break; No bundle (reason: useless for push emails).