List:Commits« Previous MessageNext Message »
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
View as plain text  
 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<Create_field> 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).
Thread
bzr push into mysql-trunk-wl5534 branch (jon.hauglid:3418 to 3420) WL#5534Jon Olav Hauglid14 Nov