diff options
-rw-r--r-- | sql/ha_partition.cc | 83 | ||||
-rw-r--r-- | sql/ha_partition.h | 18 | ||||
-rw-r--r-- | sql/handler.h | 2 | ||||
-rw-r--r-- | sql/sql_partition.cc | 3 | ||||
-rw-r--r-- | sql/sql_table.cc | 6 |
5 files changed, 101 insertions, 11 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 14e321218ca..360dcd300c9 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5760,6 +5760,89 @@ bool ha_partition::get_error_message(int error, String *buf) /**************************************************************************** MODULE handler characteristics ****************************************************************************/ +/** + alter_table_flags must be on handler/table level, not on hton level + due to the ha_partition hton does not know what the underlying hton is. +*/ +uint ha_partition::alter_table_flags(uint flags) +{ + DBUG_ENTER("ha_partition::alter_table_flags"); + DBUG_RETURN(ht->alter_table_flags(flags) | + m_file[0]->alter_table_flags(flags)); +} + + +/** + check if copy of data is needed in alter table. +*/ +bool ha_partition::check_if_incompatible_data(HA_CREATE_INFO *create_info, + uint table_changes) +{ + handler **file; + bool ret; + + /* + The check for any partitioning related changes have already been done + in mysql_alter_table (by fix_partition_func), so it is only up to + the underlying handlers. + */ + for (file= m_file; *file; file++) + if ((ret= (*file)->check_if_incompatible_data(create_info, + table_changes)) != + COMPATIBLE_DATA_YES) + break; + return ret; +} + + +/** + Support of fast or online add/drop index +*/ +int ha_partition::add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys) +{ + handler **file; + int ret; + + /* + There has already been a check in fix_partition_func in mysql_alter_table + before this call, which checks for unique/primary key violations of the + partitioning function. So no need for extra check here. + */ + for (file= m_file; *file; file++) + if ((ret= (*file)->add_index(table_arg, key_info, num_of_keys))) + break; + return ret; +} + + +int ha_partition::prepare_drop_index(TABLE *table_arg, uint *key_num, + uint num_of_keys) +{ + handler **file; + int ret; + + /* + DROP INDEX does not affect partitioning. + */ + for (file= m_file; *file; file++) + if ((ret= (*file)->prepare_drop_index(table_arg, key_num, num_of_keys))) + break; + return ret; +} + + +int ha_partition::final_drop_index(TABLE *table_arg) +{ + handler **file; + int ret= HA_ERR_WRONG_COMMAND; + + for (file= m_file; *file; file++) + if ((ret= (*file)->final_drop_index(table_arg))) + break; + return ret; +} + + /* If frm_error() is called then we will use this to to find out what file extensions exist for the storage engine. This is also used by the default diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 685f057dfce..601b7009434 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -224,6 +224,8 @@ public: DBUG_RETURN(0); } virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share); + virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info, + uint table_changes); private: int prepare_for_rename(); int copy_partitions(ulonglong * const copied, ulonglong * const deleted); @@ -774,6 +776,11 @@ public: return m_file[0]->index_flags(inx, part, all_parts); } + /** + wrapper function for handlerton alter_table_flags, since + the ha_partition_hton cannot know all its capabilities + */ + virtual uint alter_table_flags(uint flags); /* extensions of table handler files */ @@ -949,13 +956,14 @@ public: ------------------------------------------------------------------------- MODULE on-line ALTER TABLE ------------------------------------------------------------------------- - These methods are in the handler interface but never used (yet) - They are to be used by on-line alter table add/drop index: + These methods are in the handler interface. (used by innodb-plugin) + They are used for on-line/fast alter table add/drop index: ------------------------------------------------------------------------- - virtual ulong index_ddl_flags(KEY *wanted_index) const - virtual int add_index(TABLE *table_arg,KEY *key_info,uint num_of_keys); - virtual int drop_index(TABLE *table_arg,uint *key_num,uint num_of_keys); */ + virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys); + virtual int prepare_drop_index(TABLE *table_arg, uint *key_num, + uint num_of_keys); + virtual int final_drop_index(TABLE *table_arg); /* ------------------------------------------------------------------------- diff --git a/sql/handler.h b/sql/handler.h index b7d4d689d40..1b3945d9287 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1738,7 +1738,7 @@ public: if (ht->alter_table_flags) return ht->alter_table_flags(flags); return 0; - } + } protected: /* Service methods for use by storage engines. */ diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index a45664a9767..da80a2125e9 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -4251,8 +4251,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, alter_info->no_parts= curr_part_no - new_part_no; } } - if (table->s->db_type()->alter_table_flags && - (!(flags= table->s->db_type()->alter_table_flags(alter_info->flags)))) + if (!(flags= table->file->alter_table_flags(alter_info->flags))) { my_error(ER_PARTITION_FUNCTION_FAILURE, MYF(0)); DBUG_RETURN(1); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ff9a968f7f2..a5b7a90569d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6454,8 +6454,7 @@ view_err: uint *idx_p; uint *idx_end_p; - if (table->s->db_type()->alter_table_flags) - alter_flags= table->s->db_type()->alter_table_flags(alter_info->flags); + alter_flags= table->file->alter_table_flags(alter_info->flags); DBUG_PRINT("info", ("alter_flags: %lu", alter_flags)); /* Check dropped indexes. */ for (idx_p= index_drop_buffer, idx_end_p= idx_p + index_drop_count; @@ -6725,7 +6724,6 @@ view_err: /* Copy the data if necessary. */ thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields thd->cuted_fields=0L; - thd_proc_info(thd, "copy to tmp table"); copied=deleted=0; /* We do not copy data for MERGE tables. Only the children have data. @@ -6736,6 +6734,7 @@ view_err: /* We don't want update TIMESTAMP fields during ALTER TABLE. */ new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; new_table->next_number_field=new_table->found_next_number_field; + thd_proc_info(thd, "copy to tmp table"); error= copy_data_between_tables(table, new_table, alter_info->create_list, ignore, order_num, order, &copied, &deleted, @@ -6747,6 +6746,7 @@ view_err: VOID(pthread_mutex_lock(&LOCK_open)); wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); VOID(pthread_mutex_unlock(&LOCK_open)); + thd_proc_info(thd, "manage keys"); alter_table_manage_keys(table, table->file->indexes_are_disabled(), alter_info->keys_onoff); error= ha_autocommit_or_rollback(thd, 0); |