summaryrefslogtreecommitdiff
path: root/sql/ha_partition.cc
diff options
context:
space:
mode:
authorMattias Jonsson <mattias.jonsson@oracle.com>2012-02-02 12:47:17 +0100
committerMattias Jonsson <mattias.jonsson@oracle.com>2012-02-02 12:47:17 +0100
commit7ebeb1433e567dece2601651d306448408656da8 (patch)
tree2954bdaac8f88095fc3a3d0ebf2b9980bf022cda /sql/ha_partition.cc
parent225f0cd53d547927dc6d528a4e78c1be5e07cbc6 (diff)
downloadmariadb-git-7ebeb1433e567dece2601651d306448408656da8.tar.gz
Bug#13593865 - 64037: CRASH IN HA_PARTITION::CREATE_HANDLERS ON
ALTER TABLE AFTER DROP PARTITION Bug#13608188 - 64038: CRASH IN HANDLER::HA_THD ON ALTER TABLE AFTER REPAIR NON-EXISTING PARTITION Backport of bug#13357766 from -trunk to -5.5. The state of some partitions was not reset on failure, leading to invalid states of partitions in consequent statements. Fixed by reverting back to original state for all partitions if not all partition names was resolved. Also adding extra security by forcing tables to be reopened in case of error in mysql_alter_table. (There is also removal of \r at the end of some lines.)
Diffstat (limited to 'sql/ha_partition.cc')
-rw-r--r--sql/ha_partition.cc76
1 files changed, 36 insertions, 40 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index fdaa1b0cda6..b78e2be9664 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -3607,14 +3607,14 @@ int ha_partition::truncate_partition(Alter_info *alter_info, bool *binlog_stmt)
uint num_parts= m_part_info->num_parts;
uint num_subparts= m_part_info->num_subparts;
uint i= 0;
- uint num_parts_set= alter_info->partition_names.elements;
- uint num_parts_found= set_part_state(alter_info, m_part_info,
- PART_ADMIN);
DBUG_ENTER("ha_partition::truncate_partition");
/* Only binlog when it starts any call to the partitions handlers */
*binlog_stmt= false;
+ if (set_part_state(alter_info, m_part_info, PART_ADMIN))
+ DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
+
/*
TRUNCATE also means resetting auto_increment. Hence, reset
it so that it will be initialized again at the next use.
@@ -3624,10 +3624,6 @@ int ha_partition::truncate_partition(Alter_info *alter_info, bool *binlog_stmt)
table_share->ha_part_data->auto_inc_initialized= FALSE;
unlock_auto_increment();
- if (num_parts_set != num_parts_found &&
- (!(alter_info->flags & ALTER_ALL_PARTITION)))
- DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
-
*binlog_stmt= true;
do
@@ -6059,7 +6055,7 @@ int ha_partition::extra(enum ha_extra_function operation)
0 Success
DESCRIPTION
- Called at end of each statement to reste buffers
+ Called at end of each statement to reset buffers
*/
int ha_partition::reset(void)
@@ -6792,8 +6788,8 @@ int ha_partition::final_add_index(handler_add_index *add, bool commit)
DBUG_RETURN(ret);
err:
uint j;
- uint *key_numbers= NULL;
- KEY *old_key_info= NULL;
+ uint *key_numbers= NULL;
+ KEY *old_key_info= NULL;
uint num_of_keys= 0;
int error;
@@ -6803,27 +6799,27 @@ err:
if (i > 0)
{
num_of_keys= part_add_index->num_of_keys;
- key_numbers= (uint*) ha_thd()->alloc(sizeof(uint) * num_of_keys);
- if (!key_numbers)
- {
- sql_print_error("Failed with error handling of adding index:\n"
- "committing index failed, and when trying to revert "
- "already committed partitions we failed allocating\n"
- "memory for the index for table '%s'",
- table_share->table_name.str);
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- }
- old_key_info= table->key_info;
- /*
- Use the newly added key_info as table->key_info to remove them.
- Note that this requires the subhandlers to use name lookup of the
- index. They must use given table->key_info[key_number], they cannot
- use their local view of the keys, since table->key_info only include
- the indexes to be removed here.
- */
- for (j= 0; j < num_of_keys; j++)
- key_numbers[j]= j;
- table->key_info= part_add_index->key_info;
+ key_numbers= (uint*) ha_thd()->alloc(sizeof(uint) * num_of_keys);
+ if (!key_numbers)
+ {
+ sql_print_error("Failed with error handling of adding index:\n"
+ "committing index failed, and when trying to revert "
+ "already committed partitions we failed allocating\n"
+ "memory for the index for table '%s'",
+ table_share->table_name.str);
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+ old_key_info= table->key_info;
+ /*
+ Use the newly added key_info as table->key_info to remove them.
+ Note that this requires the subhandlers to use name lookup of the
+ index. They must use given table->key_info[key_number], they cannot
+ use their local view of the keys, since table->key_info only include
+ the indexes to be removed here.
+ */
+ for (j= 0; j < num_of_keys; j++)
+ key_numbers[j]= j;
+ table->key_info= part_add_index->key_info;
}
for (j= 0; j < m_tot_parts; j++)
@@ -6831,15 +6827,15 @@ err:
if (j < i)
{
/* Remove the newly added index */
- error= m_file[j]->prepare_drop_index(table, key_numbers, num_of_keys);
- if (error || m_file[j]->final_drop_index(table))
- {
- sql_print_error("Failed with error handling of adding index:\n"
- "committing index failed, and when trying to revert "
- "already committed partitions we failed removing\n"
- "the index for table '%s' partition nr %d",
- table_share->table_name.str, j);
- }
+ error= m_file[j]->prepare_drop_index(table, key_numbers, num_of_keys);
+ if (error || m_file[j]->final_drop_index(table))
+ {
+ sql_print_error("Failed with error handling of adding index:\n"
+ "committing index failed, and when trying to revert "
+ "already committed partitions we failed removing\n"
+ "the index for table '%s' partition nr %d",
+ table_share->table_name.str, j);
+ }
}
else if (j > i)
{