diff options
Diffstat (limited to 'sql/ha_partition.cc')
-rw-r--r-- | sql/ha_partition.cc | 190 |
1 files changed, 100 insertions, 90 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 8bf35f79ba9..3d8d5ae9eb8 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -3337,113 +3337,123 @@ int ha_partition::delete_row(const uchar *buf) Called from sql_delete.cc by mysql_delete(). Called from sql_select.cc by JOIN::reinit(). Called from sql_union.cc by st_select_lex_unit::exec(). - - Also used for handle ALTER TABLE t TRUNCATE PARTITION ... - NOTE: auto increment value will be truncated in that partition as well! */ int ha_partition::delete_all_rows() { int error; - bool truncate= FALSE; handler **file; - THD *thd= ha_thd(); DBUG_ENTER("ha_partition::delete_all_rows"); - if (thd->lex->sql_command == SQLCOM_TRUNCATE) + file= m_file; + do { - Alter_info *alter_info= &thd->lex->alter_info; - /* TRUNCATE also means resetting auto_increment */ - lock_auto_increment(); - table_share->ha_part_data->next_auto_inc_val= 0; - table_share->ha_part_data->auto_inc_initialized= FALSE; - unlock_auto_increment(); - if (alter_info->flags & ALTER_ADMIN_PARTITION) - { - /* ALTER TABLE t TRUNCATE PARTITION ... */ - List_iterator<partition_element> part_it(m_part_info->partitions); - int saved_error= 0; - 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); - if (num_parts_set != num_parts_found && - (!(alter_info->flags & ALTER_ALL_PARTITION))) - DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND); + if ((error= (*file)->ha_delete_all_rows())) + DBUG_RETURN(error); + } while (*(++file)); + DBUG_RETURN(0); +} + + +/** + Manually truncate the table. + + @retval 0 Success. + @retval > 0 Error code. +*/ + +int ha_partition::truncate() +{ + int error; + handler **file; + DBUG_ENTER("ha_partition::truncate"); + + /* + TRUNCATE also means resetting auto_increment. Hence, reset + it so that it will be initialized again at the next use. + */ + lock_auto_increment(); + table_share->ha_part_data->next_auto_inc_val= 0; + table_share->ha_part_data->auto_inc_initialized= FALSE; + unlock_auto_increment(); - /* - Cannot return HA_ERR_WRONG_COMMAND here without correct pruning - since that whould delete the whole table row by row in sql_delete.cc - */ - bitmap_clear_all(&m_part_info->used_partitions); - do - { - partition_element *part_elem= part_it++; - if (part_elem->part_state == PART_ADMIN) - { - if (m_is_sub_partitioned) - { - List_iterator<partition_element> - subpart_it(part_elem->subpartitions); - partition_element *sub_elem; - uint j= 0, part; - do - { - sub_elem= subpart_it++; - part= i * num_subparts + j; - bitmap_set_bit(&m_part_info->used_partitions, part); - if (!saved_error) - { - DBUG_PRINT("info", ("truncate subpartition %u (%s)", - part, sub_elem->partition_name)); - if ((error= m_file[part]->ha_delete_all_rows())) - saved_error= error; - /* If not reset_auto_increment is supported, just accept it */ - if (!saved_error && - (error= m_file[part]->ha_reset_auto_increment(0)) && - error != HA_ERR_WRONG_COMMAND) - saved_error= error; - } - } while (++j < num_subparts); - } - else - { - DBUG_PRINT("info", ("truncate partition %u (%s)", i, - part_elem->partition_name)); - bitmap_set_bit(&m_part_info->used_partitions, i); - if (!saved_error) - { - if ((error= m_file[i]->ha_delete_all_rows()) && !saved_error) - saved_error= error; - /* If not reset_auto_increment is supported, just accept it */ - if (!saved_error && - (error= m_file[i]->ha_reset_auto_increment(0)) && - error != HA_ERR_WRONG_COMMAND) - saved_error= error; - } - } - part_elem->part_state= PART_NORMAL; - } - } while (++i < num_parts); - DBUG_RETURN(saved_error); - } - truncate= TRUE; - } file= m_file; do { - if ((error= (*file)->ha_delete_all_rows())) + if ((error= (*file)->ha_truncate())) DBUG_RETURN(error); - /* Ignore the error */ - if (truncate) - (void) (*file)->ha_reset_auto_increment(0); } while (*(++file)); DBUG_RETURN(0); } +/** + Truncate a set of specific partitions. + + @remark Auto increment value will be truncated in that partition as well! + + ALTER TABLE t TRUNCATE PARTITION ... +*/ + +int ha_partition::truncate_partition(Alter_info *alter_info) +{ + int error= 0; + List_iterator<partition_element> part_it(m_part_info->partitions); + 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"); + + /* + TRUNCATE also means resetting auto_increment. Hence, reset + it so that it will be initialized again at the next use. + */ + lock_auto_increment(); + table_share->ha_part_data->next_auto_inc_val= 0; + 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); + + do + { + partition_element *part_elem= part_it++; + if (part_elem->part_state == PART_ADMIN) + { + if (m_is_sub_partitioned) + { + List_iterator<partition_element> + subpart_it(part_elem->subpartitions); + partition_element *sub_elem; + uint j= 0, part; + do + { + sub_elem= subpart_it++; + part= i * num_subparts + j; + DBUG_PRINT("info", ("truncate subpartition %u (%s)", + part, sub_elem->partition_name)); + if ((error= m_file[part]->ha_truncate())) + break; + } while (++j < num_subparts); + } + else + { + DBUG_PRINT("info", ("truncate partition %u (%s)", i, + part_elem->partition_name)); + error= m_file[i]->ha_truncate(); + } + part_elem->part_state= PART_NORMAL; + } + } while (!error && (++i < num_parts)); + DBUG_RETURN(error); +} + + /* Start a large batch of insert rows @@ -6327,8 +6337,8 @@ void ha_partition::print_error(int error, myf errflag) /* Should probably look for my own errors first */ DBUG_PRINT("enter", ("error: %d", error)); - if (error == HA_ERR_NO_PARTITION_FOUND && - thd->lex->sql_command != SQLCOM_TRUNCATE) + if ((error == HA_ERR_NO_PARTITION_FOUND) && + ! (thd->lex->alter_info.flags & ALTER_TRUNCATE_PARTITION)) m_part_info->print_no_partition_found(table); else { |