summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/ha_partition.cc83
-rw-r--r--sql/ha_partition.h18
-rw-r--r--sql/handler.h2
-rw-r--r--sql/sql_partition.cc3
-rw-r--r--sql/sql_table.cc6
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);