2687 Mattias Jonsson 2008-10-29 [merge]
merge
modified:
mysql-test/r/partition_innodb.result
mysql-test/t/partition_innodb.test
sql/ha_partition.cc
sql/ha_partition.h
sql/key.cc
2686 Mattias Jonsson 2008-10-29 [merge]
merge
modified:
sql/ha_partition.cc
sql/ha_partition.h
sql/handler.h
sql/sql_partition.cc
sql/sql_table.cc
2685 Alexey Botchkov 2008-10-27 [merge]
merging
modified:
mysql-test/r/explain.result
mysql-test/r/view.result
mysql-test/t/explain.test
mysql-test/t/view.test
sql/item_cmpfunc.cc
sql/sql_view.cc
=== modified file 'mysql-test/r/partition_innodb.result'
--- a/mysql-test/r/partition_innodb.result 2008-03-07 21:46:29 +0000
+++ b/mysql-test/r/partition_innodb.result 2008-10-10 10:01:01 +0000
@@ -1,3 +1,68 @@
+# Bug#37721, test of ORDER BY on PK and WHERE on INDEX
+CREATE TABLE t1 (
+a INT,
+b INT,
+PRIMARY KEY (a),
+INDEX (b))
+ENGINE InnoDB
+PARTITION BY HASH(a)
+PARTITIONS 3;
+INSERT INTO t1 VALUES (0,0),(4,0),(2,0);
+SELECT a FROM t1 WHERE b = 0 ORDER BY a ASC;
+a
+0
+2
+4
+SELECT a FROM t1 WHERE b = 0 ORDER BY a DESC;
+a
+4
+2
+0
+ALTER TABLE t1 DROP INDEX b;
+SELECT a FROM t1 WHERE b = 0 ORDER BY a ASC;
+a
+0
+2
+4
+SELECT a FROM t1 WHERE b = 0 ORDER BY a DESC;
+a
+4
+2
+0
+DROP TABLE t1;
+CREATE TABLE t1 (
+a VARCHAR(600),
+b VARCHAR(600),
+PRIMARY KEY (a),
+INDEX (b))
+ENGINE InnoDB
+PARTITION BY KEY(a)
+PARTITIONS 3;
+INSERT INTO t1 VALUES (concat(repeat('MySQL',100),'1'),repeat('0',257));
+INSERT INTO t1 VALUES (concat(repeat('MySQL',100),'3'),repeat('0',257));
+INSERT INTO t1 VALUES (concat(repeat('MySQL',100),'2'),repeat('0',257));
+SELECT right(a,1) FROM t1 WHERE b = repeat('0',257) ORDER BY a ASC;
+right(a,1)
+1
+2
+3
+SELECT right(a,1) FROM t1 WHERE b = repeat('0',257) ORDER BY a DESC;
+right(a,1)
+3
+2
+1
+ALTER TABLE t1 DROP INDEX b;
+SELECT right(a,1) FROM t1 WHERE b = repeat('0',257) ORDER BY a ASC;
+right(a,1)
+1
+2
+3
+SELECT right(a,1) FROM t1 WHERE b = repeat('0',257) ORDER BY a DESC;
+right(a,1)
+3
+2
+1
+DROP TABLE t1;
# Bug#32948
CREATE TABLE t1 (c1 INT, PRIMARY KEY (c1)) ENGINE=INNODB;
CREATE TABLE t2 (c1 INT, PRIMARY KEY (c1),
=== modified file 'mysql-test/t/partition_innodb.test'
--- a/mysql-test/t/partition_innodb.test 2008-03-07 21:46:29 +0000
+++ b/mysql-test/t/partition_innodb.test 2008-10-10 10:01:01 +0000
@@ -1,6 +1,46 @@
--source include/have_partition.inc
--source include/have_innodb.inc
+#
+# Bug37721: ORDER BY when WHERE contains non-partitioned index column
+# wrong order since it did not use pk as second compare
+--echo # Bug#37721, test of ORDER BY on PK and WHERE on INDEX
+CREATE TABLE t1 (
+ a INT,
+ b INT,
+ PRIMARY KEY (a),
+ INDEX (b))
+ENGINE InnoDB
+PARTITION BY HASH(a)
+PARTITIONS 3;
+# This will give the middle partition the highest value
+INSERT INTO t1 VALUES (0,0),(4,0),(2,0);
+SELECT a FROM t1 WHERE b = 0 ORDER BY a ASC;
+SELECT a FROM t1 WHERE b = 0 ORDER BY a DESC;
+ALTER TABLE t1 DROP INDEX b;
+SELECT a FROM t1 WHERE b = 0 ORDER BY a ASC;
+SELECT a FROM t1 WHERE b = 0 ORDER BY a DESC;
+DROP TABLE t1;
+CREATE TABLE t1 (
+ a VARCHAR(600),
+ b VARCHAR(600),
+ PRIMARY KEY (a),
+ INDEX (b))
+ENGINE InnoDB
+PARTITION BY KEY(a)
+PARTITIONS 3;
+# This will give the middle partition the highest value
+INSERT INTO t1 VALUES (concat(repeat('MySQL',100),'1'),repeat('0',257));
+INSERT INTO t1 VALUES (concat(repeat('MySQL',100),'3'),repeat('0',257));
+INSERT INTO t1 VALUES (concat(repeat('MySQL',100),'2'),repeat('0',257));
+SELECT right(a,1) FROM t1 WHERE b = repeat('0',257) ORDER BY a ASC;
+SELECT right(a,1) FROM t1 WHERE b = repeat('0',257) ORDER BY a DESC;
+ALTER TABLE t1 DROP INDEX b;
+SELECT right(a,1) FROM t1 WHERE b = repeat('0',257) ORDER BY a ASC;
+SELECT right(a,1) FROM t1 WHERE b = repeat('0',257) ORDER BY a DESC;
+DROP TABLE t1;
+
+#
# Bug#32948 - FKs allowed to reference partitioned table
#
-- echo # Bug#32948
=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc 2008-10-06 13:14:20 +0000
+++ b/sql/ha_partition.cc 2008-10-29 22:01:41 +0000
@@ -239,7 +239,8 @@ void ha_partition::init_handler_variable
m_rec_length= 0;
m_last_part= 0;
m_rec0= 0;
- m_curr_key_info= 0;
+ m_curr_key_info[0]= NULL;
+ m_curr_key_info[1]= NULL;
/*
this allows blackhole to work properly
*/
@@ -3604,11 +3605,24 @@ int ha_partition::index_init(uint inx, b
handler **file;
DBUG_ENTER("ha_partition::index_init");
+ DBUG_PRINT("info", ("inx %u sorted %u", inx, sorted));
active_index= inx;
m_part_spec.start_part= NO_CURRENT_PART_ID;
m_start_key.length= 0;
m_ordered= sorted;
- m_curr_key_info= table->key_info+inx;
+ m_curr_key_info[0]= table->key_info+inx;
+ if (m_pkey_is_clustered && table->s->primary_key != MAX_KEY)
+ {
+ /*
+ if PK is clustered, then the key cmp must use the pk to
+ differentiate between equal key in given index.
+ */
+ DBUG_PRINT("info", ("Clustered pk, using pk as secondary cmp"));
+ m_curr_key_info[1]= table->key_info+table->s->primary_key;
+ m_curr_key_info[2]= NULL;
+ }
+ else
+ m_curr_key_info[1]= NULL;
/*
Some handlers only read fields as specified by the bitmap for the
read set. For partitioned handlers we always require that the
@@ -3633,9 +3647,13 @@ int ha_partition::index_init(uint inx, b
TODO: handle COUNT(*) queries via unordered scan.
*/
uint i;
- for (i= 0; i < m_curr_key_info->key_parts; i++)
- bitmap_set_bit(table->read_set,
- m_curr_key_info->key_part[i].field->field_index);
+ KEY **key_info= m_curr_key_info;
+ do
+ {
+ for (i= 0; i < (*key_info)->key_parts; i++)
+ bitmap_set_bit(table->read_set,
+ (*key_info)->key_part[i].field->field_index);
+ } while (*(++key_info));
}
file= m_file;
do
@@ -3692,10 +3710,10 @@ int ha_partition::index_end()
Read one record in an index scan and start an index scan
SYNOPSIS
- index_read()
+ index_read_map()
buf Read row in MySQL Row Format
key Key parts in consecutive order
- key_len Total length of key parts
+ keypart_map Which part of key is used
find_flag What type of key condition is used
RETURN VALUE
@@ -3703,12 +3721,12 @@ int ha_partition::index_end()
0 Success
DESCRIPTION
- index_read starts a new index scan using a start key. The MySQL Server
+ index_read_map starts a new index scan using a start key. The MySQL Server
will check the end key on its own. Thus to function properly the
partitioned handler need to ensure that it delivers records in the sort
order of the MySQL Server.
- index_read can be restarted without calling index_end on the previous
- index scan and without calling index_init. In this case the index_read
+ index_read_map can be restarted without calling index_end on the previous
+ index scan and without calling index_init. In this case the index_read_map
is on the same index as the previous index_scan. This is particularly
used in conjuntion with multi read ranges.
*/
@@ -3765,11 +3783,15 @@ int ha_partition::common_index_read(ucha
DBUG_ENTER("ha_partition::common_index_read");
LINT_INIT(key_len); /* used if have_start_key==TRUE */
+ DBUG_PRINT("info", ("m_ordered %u m_ordered_scan_ong %u have_start_key %u",
+ m_ordered, m_ordered_scan_ongoing, have_start_key));
+
if (have_start_key)
{
m_start_key.length= key_len= calculate_key_len(table, active_index,
m_start_key.key,
m_start_key.keypart_map);
+ DBUG_ASSERT(key_len);
}
if ((error= partition_scan_set_up(buf, have_start_key)))
{
@@ -3784,9 +3806,12 @@ int ha_partition::common_index_read(ucha
reverse_order= TRUE;
m_ordered_scan_ongoing= TRUE;
}
+ DBUG_PRINT("info", ("m_ordered %u m_o_scan_ong %u have_start_key %u",
+ m_ordered, m_ordered_scan_ongoing, have_start_key));
if (!m_ordered_scan_ongoing ||
(have_start_key && m_start_key.flag == HA_READ_KEY_EXACT &&
- (key_len >= m_curr_key_info->key_length || key_len == 0)))
+ !m_pkey_is_clustered &&
+ key_len >= m_curr_key_info[0]->key_length))
{
/*
We use unordered index scan either when read_range is used and flag
@@ -3799,6 +3824,8 @@ int ha_partition::common_index_read(ucha
Need to set unordered scan ongoing since we can come here even when
it isn't set.
*/
+ DBUG_PRINT("info", ("key_len %lu (%lu), doing unordered scan",
+ key_len, m_curr_key_info[0]->key_length));
m_ordered_scan_ongoing= FALSE;
error= handle_unordered_scan_next_partition(buf);
}
@@ -3900,7 +3927,7 @@ int ha_partition::common_first_last(ucha
Read last using key
SYNOPSIS
- index_read_last()
+ index_read_last_map()
buf Read row in MySQL Row Format
key Key
keypart_map Which part of key is used
@@ -4057,7 +4084,7 @@ int ha_partition::read_range_first(const
(end_key->flag == HA_READ_AFTER_KEY) ? -1 : 0);
}
- range_key_part= m_curr_key_info->key_part;
+ range_key_part= m_curr_key_info[0]->key_part;
if (start_key)
m_start_key= *start_key;
else
@@ -5760,6 +5787,89 @@ bool ha_partition::get_error_message(int
/****************************************************************************
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
=== modified file 'sql/ha_partition.h'
--- a/sql/ha_partition.h 2008-10-01 10:14:55 +0000
+++ b/sql/ha_partition.h 2008-10-29 22:01:41 +0000
@@ -74,9 +74,16 @@ private:
handler **m_added_file; // Added parts kept for errors
partition_info *m_part_info; // local reference to partition
Field **m_part_field_array; // Part field array locally to save acc
- uchar *m_ordered_rec_buffer; // Row and key buffer for ord. idx scan
- KEY *m_curr_key_info; // Current index
- uchar *m_rec0; // table->record[0]
+ uchar *m_ordered_rec_buffer; // Row and key buffer for ord. idx scan
+ /*
+ Current index.
+ When used in key_rec_cmp: If clustered pk, index compare
+ must compare pk if given index is same for two rows.
+ So normally m_curr_key_info[0]= current index and m_curr_key[1]= NULL,
+ and if clustered pk, [0]= current index, [1]= pk, [2]= NULL
+ */
+ KEY *m_curr_key_info[3]; // Current index
+ uchar *m_rec0; // table->record[0]
QUEUE m_queue; // Prio queue used by sorted read
/*
Since the partition handler is a handler on top of other handlers, it
@@ -224,6 +231,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 +783,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 +963,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);
/*
-------------------------------------------------------------------------
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2008-10-08 13:52:57 +0000
+++ b/sql/handler.h 2008-10-29 20:30:04 +0000
@@ -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. */
=== modified file 'sql/key.cc'
--- a/sql/key.cc 2008-02-07 14:09:59 +0000
+++ b/sql/key.cc 2008-10-10 10:01:01 +0000
@@ -448,84 +448,104 @@ int key_cmp(KEY_PART_INFO *key_part, con
}
-/*
- Compare two records in index order
- SYNOPSIS
- key_rec_cmp()
- key Index information
- rec0 Pointer to table->record[0]
- first_rec Pointer to record compare with
- second_rec Pointer to record compare against first_rec
-
- DESCRIPTION
- This method is set-up such that it can be called directly from the
- priority queue and it is attempted to be optimised as much as possible
- since this will be called O(N * log N) times while performing a merge
- sort in various places in the code.
-
- We retrieve the pointer to table->record[0] using the fact that key_parts
- have an offset making it possible to calculate the start of the record.
- We need to get the diff to the compared record since none of the records
- being compared are stored in table->record[0].
-
- We first check for NULL values, if there are no NULL values we use
- a compare method that gets two field pointers and a max length
- and return the result of the comparison.
+/**
+ Compare two records in index order.
+
+ This method is set-up such that it can be called directly from the
+ priority queue and it is attempted to be optimised as much as possible
+ since this will be called O(N * log N) times while performing a merge
+ sort in various places in the code.
+
+ We retrieve the pointer to table->record[0] using the fact that key_parts
+ have an offset making it possible to calculate the start of the record.
+ We need to get the diff to the compared record since none of the records
+ being compared are stored in table->record[0].
+
+ We first check for NULL values, if there are no NULL values we use
+ a compare method that gets two field pointers and a max length
+ and return the result of the comparison.
+
+ key is a null terminated array, since in some cases (clustered
+ primary key) it must compare more than one index.
+
+ @param key Null terminated array of index information
+ @param first_rec Pointer to record compare with
+ @param second_rec Pointer to record compare against first_rec
+
+ @return Return value is SIGN(first_rec - second_rec)
+ @retval 0 Keys are equal
+ @retval -1 second_rec is greater than first_rec
+ @retval +1 first_rec is greater than second_rec
*/
-int key_rec_cmp(void *key, uchar *first_rec, uchar *second_rec)
+int key_rec_cmp(void *key_p, uchar *first_rec, uchar *second_rec)
{
- KEY *key_info= (KEY*)key;
- uint key_parts= key_info->key_parts, i= 0;
+ KEY **key= (KEY**) key_p;
+ KEY *key_info= *(key++); // Start with first key
+ uint key_parts, key_part_num;
KEY_PART_INFO *key_part= key_info->key_part;
uchar *rec0= key_part->field->ptr - key_part->offset;
my_ptrdiff_t first_diff= first_rec - rec0, sec_diff= second_rec - rec0;
int result= 0;
+ Field *field;
DBUG_ENTER("key_rec_cmp");
+ /* loop over all given keys */
do
{
- Field *field= key_part->field;
+ key_parts= key_info->key_parts;
+ key_part= key_info->key_part;
+ key_part_num= 0;
- if (key_part->null_bit)
+ /* loop over every key part */
+ do
{
- /* The key_part can contain NULL values */
- bool first_is_null= field->is_null_in_record_with_offset(first_diff);
- bool sec_is_null= field->is_null_in_record_with_offset(sec_diff);
- /*
- NULL is smaller then everything so if first is NULL and the other
- not then we know that we should return -1 and for the opposite
- we should return +1. If both are NULL then we call it equality
- although it is a strange form of equality, we have equally little
- information of the real value.
- */
- if (!first_is_null)
+ field= key_part->field;
+
+ if (key_part->null_bit)
{
- if (!sec_is_null)
- ; /* Fall through, no NULL fields */
- else
+ /* The key_part can contain NULL values */
+ bool first_is_null= field->is_null_in_record_with_offset(first_diff);
+ bool sec_is_null= field->is_null_in_record_with_offset(sec_diff);
+ /*
+ NULL is smaller then everything so if first is NULL and the other
+ not then we know that we should return -1 and for the opposite
+ we should return +1. If both are NULL then we call it equality
+ although it is a strange form of equality, we have equally little
+ information of the real value.
+ */
+ if (!first_is_null)
{
- DBUG_RETURN(+1);
+ if (!sec_is_null)
+ ; /* Fall through, no NULL fields */
+ else
+ {
+ DBUG_RETURN(+1);
+ }
}
+ else if (!sec_is_null)
+ {
+ DBUG_RETURN(-1);
+ }
+ else
+ goto next_loop; /* Both were NULL */
}
- else if (!sec_is_null)
- {
- DBUG_RETURN(-1);
- }
- else
- goto next_loop; /* Both were NULL */
- }
- /*
- No null values in the fields
- We use the virtual method cmp_max with a max length parameter.
- For most field types this translates into a cmp without
- max length. The exceptions are the BLOB and VARCHAR field types
- that take the max length into account.
- */
- result= field->cmp_max(field->ptr+first_diff, field->ptr+sec_diff,
- key_part->length);
+ /*
+ No null values in the fields
+ We use the virtual method cmp_max with a max length parameter.
+ For most field types this translates into a cmp without
+ max length. The exceptions are the BLOB and VARCHAR field types
+ that take the max length into account.
+ */
+ if ((result= field->cmp_max(field->ptr+first_diff, field->ptr+sec_diff,
+ key_part->length)))
+ DBUG_RETURN(result);
next_loop:
- key_part++;
- } while (!result && ++i < key_parts);
- DBUG_RETURN(result);
+ key_part++;
+ key_part_num++;
+ } while (key_part_num < key_parts); /* this key is done */
+
+ key_info= *(key++);
+ } while (key_info); /* no more keys to test */
+ DBUG_RETURN(0);
}
=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc 2008-10-07 15:19:32 +0000
+++ b/sql/sql_partition.cc 2008-10-29 20:30:04 +0000
@@ -4251,8 +4251,7 @@ uint prep_alter_part_table(THD *thd, TAB
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);
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2008-10-13 10:22:36 +0000
+++ b/sql/sql_table.cc 2008-10-29 20:30:04 +0000
@@ -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);
| Thread |
|---|
| • bzr push into mysql-5.1 branch (mattias.jonsson:2685 to 2687) | Mattias Jonsson | 30 Oct |