summaryrefslogtreecommitdiff
path: root/sql/ha_partition.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/ha_partition.cc')
-rw-r--r--sql/ha_partition.cc190
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
{