Commit 187a163c authored by Sergei Golubchik's avatar Sergei Golubchik

cleanup: ha_partition::update_row/delete_row

implement log-term TODO item, convert redundant if()-s into asserts.
parent 221d010f
...@@ -4303,29 +4303,15 @@ int ha_partition::write_row(uchar * buf) ...@@ -4303,29 +4303,15 @@ int ha_partition::write_row(uchar * buf)
int ha_partition::update_row(const uchar *old_data, const uchar *new_data) int ha_partition::update_row(const uchar *old_data, const uchar *new_data)
{ {
THD *thd= ha_thd(); THD *thd= ha_thd();
uint32 new_part_id, old_part_id; uint32 new_part_id, old_part_id= m_last_part;
int error= 0; int error= 0;
longlong func_value;
DBUG_ENTER("ha_partition::update_row"); DBUG_ENTER("ha_partition::update_row");
m_err_rec= NULL; m_err_rec= NULL;
// Need to read partition-related columns, to locate the row's partition: // Need to read partition-related columns, to locate the row's partition:
DBUG_ASSERT(bitmap_is_subset(&m_part_info->full_part_field_set, DBUG_ASSERT(bitmap_is_subset(&m_part_info->full_part_field_set,
table->read_set)); table->read_set));
if ((error= get_parts_for_update(old_data, new_data, table->record[0], #ifndef DBUG_OFF
m_part_info, &old_part_id, &new_part_id,
&func_value)))
{
m_part_info->err_value= func_value;
goto exit;
}
DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), old_part_id));
if (!bitmap_is_set(&(m_part_info->lock_partitions), new_part_id))
{
error= HA_ERR_NOT_IN_LOCK_PARTITIONS;
goto exit;
}
/* /*
The protocol for updating a row is: The protocol for updating a row is:
1) position the handler (cursor) on the row to be updated, 1) position the handler (cursor) on the row to be updated,
...@@ -4343,12 +4329,21 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data) ...@@ -4343,12 +4329,21 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data)
Notice that HA_READ_BEFORE_WRITE_REMOVAL does not require this protocol, Notice that HA_READ_BEFORE_WRITE_REMOVAL does not require this protocol,
so this is not supported for this engine. so this is not supported for this engine.
*/ */
if (old_part_id != m_last_part) error= get_part_for_buf(old_data, m_rec0, m_part_info, &old_part_id);
DBUG_ASSERT(!error);
DBUG_ASSERT(old_part_id == m_last_part);
DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), old_part_id));
#endif
if ((error= get_part_for_buf(new_data, m_rec0, m_part_info, &new_part_id)))
goto exit;
if (!bitmap_is_set(&(m_part_info->lock_partitions), new_part_id))
{ {
m_err_rec= old_data; error= HA_ERR_NOT_IN_LOCK_PARTITIONS;
DBUG_RETURN(HA_ERR_ROW_IN_WRONG_PARTITION); goto exit;
} }
m_last_part= new_part_id; m_last_part= new_part_id;
start_part_bulk_insert(thd, new_part_id); start_part_bulk_insert(thd, new_part_id);
if (new_part_id == old_part_id) if (new_part_id == old_part_id)
...@@ -4395,13 +4390,8 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data) ...@@ -4395,13 +4390,8 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data)
error= m_file[old_part_id]->ha_delete_row(old_data); error= m_file[old_part_id]->ha_delete_row(old_data);
reenable_binlog(thd); reenable_binlog(thd);
if (error) if (error)
{
#ifdef IN_THE_FUTURE
(void) m_file[new_part_id]->delete_last_inserted_row(new_data);
#endif
goto exit; goto exit;
} }
}
exit: exit:
/* /*
...@@ -4460,7 +4450,6 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data) ...@@ -4460,7 +4450,6 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data)
int ha_partition::delete_row(const uchar *buf) int ha_partition::delete_row(const uchar *buf)
{ {
uint32 part_id;
int error; int error;
THD *thd= ha_thd(); THD *thd= ha_thd();
DBUG_ENTER("ha_partition::delete_row"); DBUG_ENTER("ha_partition::delete_row");
...@@ -4468,16 +4457,7 @@ int ha_partition::delete_row(const uchar *buf) ...@@ -4468,16 +4457,7 @@ int ha_partition::delete_row(const uchar *buf)
DBUG_ASSERT(bitmap_is_subset(&m_part_info->full_part_field_set, DBUG_ASSERT(bitmap_is_subset(&m_part_info->full_part_field_set,
table->read_set)); table->read_set));
if ((error= get_part_for_delete(buf, m_rec0, m_part_info, &part_id))) #ifndef DBUG_OFF
{
DBUG_RETURN(error);
}
/* Should never call delete_row on a partition which is not read */
DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), part_id));
DBUG_ASSERT(bitmap_is_set(&(m_part_info->lock_partitions), part_id));
if (!bitmap_is_set(&(m_part_info->lock_partitions), part_id))
DBUG_RETURN(HA_ERR_NOT_IN_LOCK_PARTITIONS);
/* /*
The protocol for deleting a row is: The protocol for deleting a row is:
1) position the handler (cursor) on the row to be deleted, 1) position the handler (cursor) on the row to be deleted,
...@@ -4494,19 +4474,20 @@ int ha_partition::delete_row(const uchar *buf) ...@@ -4494,19 +4474,20 @@ int ha_partition::delete_row(const uchar *buf)
Notice that HA_READ_BEFORE_WRITE_REMOVAL does not require this protocol, Notice that HA_READ_BEFORE_WRITE_REMOVAL does not require this protocol,
so this is not supported for this engine. so this is not supported for this engine.
TODO: change the assert in InnoDB into an error instead and make this one
an assert instead and remove the get_part_for_delete()!
*/ */
if (part_id != m_last_part) uint32 part_id;
{ error= get_part_for_buf(buf, m_rec0, m_part_info, &part_id);
m_err_rec= buf; DBUG_ASSERT(!error);
DBUG_RETURN(HA_ERR_ROW_IN_WRONG_PARTITION); DBUG_ASSERT(part_id == m_last_part);
} DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), m_last_part));
DBUG_ASSERT(bitmap_is_set(&(m_part_info->lock_partitions), m_last_part));
#endif
if (!bitmap_is_set(&(m_part_info->lock_partitions), m_last_part))
DBUG_RETURN(HA_ERR_NOT_IN_LOCK_PARTITIONS);
m_last_part= part_id;
tmp_disable_binlog(thd); tmp_disable_binlog(thd);
error= m_file[part_id]->ha_delete_row(buf); error= m_file[m_last_part]->ha_delete_row(buf);
reenable_binlog(thd); reenable_binlog(thd);
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -5178,7 +5159,7 @@ int ha_partition::rnd_pos_by_record(uchar *record) ...@@ -5178,7 +5159,7 @@ int ha_partition::rnd_pos_by_record(uchar *record)
{ {
DBUG_ENTER("ha_partition::rnd_pos_by_record"); DBUG_ENTER("ha_partition::rnd_pos_by_record");
if (unlikely(get_part_for_delete(record, m_rec0, m_part_info, &m_last_part))) if (unlikely(get_part_for_buf(record, m_rec0, m_part_info, &m_last_part)))
DBUG_RETURN(1); DBUG_RETURN(1);
DBUG_RETURN(handler::rnd_pos_by_record(record)); DBUG_RETURN(handler::rnd_pos_by_record(record));
...@@ -9687,7 +9668,7 @@ void ha_partition::print_error(int error, myf errflag) ...@@ -9687,7 +9668,7 @@ void ha_partition::print_error(int error, myf errflag)
str.append("("); str.append("(");
str.append_ulonglong(m_last_part); str.append_ulonglong(m_last_part);
str.append(" != "); str.append(" != ");
if (get_part_for_delete(m_err_rec, m_rec0, m_part_info, &part_id)) if (get_part_for_buf(m_err_rec, m_rec0, m_part_info, &part_id))
str.append("?"); str.append("?");
else else
str.append_ulonglong(part_id); str.append_ulonglong(part_id);
......
...@@ -246,82 +246,11 @@ bool partition_default_handling(THD *thd, TABLE *table, partition_info *part_inf ...@@ -246,82 +246,11 @@ bool partition_default_handling(THD *thd, TABLE *table, partition_info *part_inf
/* /*
A useful routine used by update_row for partition handlers to calculate A useful routine used by update/delete_row for partition handlers to
the partition ids of the old and the new record. calculate the partition id.
SYNOPSIS
get_part_for_update()
old_data Buffer of old record
new_data Buffer of new record
rec0 Reference to table->record[0]
part_info Reference to partition information
out:old_part_id The returned partition id of old record
out:new_part_id The returned partition id of new record
RETURN VALUE
0 Success
> 0 Error code
*/
int get_parts_for_update(const uchar *old_data, const uchar *new_data,
const uchar *rec0, partition_info *part_info,
uint32 *old_part_id, uint32 *new_part_id,
longlong *new_func_value)
{
Field **part_field_array= part_info->full_part_field_array;
int error;
longlong old_func_value;
DBUG_ENTER("get_parts_for_update");
DBUG_ASSERT(new_data == rec0); // table->record[0]
part_info->table->move_fields(part_field_array, old_data, rec0);
error= part_info->get_partition_id(part_info, old_part_id,
&old_func_value);
part_info->table->move_fields(part_field_array, rec0, old_data);
if (unlikely(error)) // Should never happen
{
DBUG_ASSERT(0);
DBUG_RETURN(error);
}
#ifdef NOT_NEEDED
if (new_data == rec0)
#endif
{
if (unlikely(error= part_info->get_partition_id(part_info,
new_part_id,
new_func_value)))
{
DBUG_RETURN(error);
}
}
#ifdef NOT_NEEDED
else
{
/*
This branch should never execute but it is written anyways for
future use. It will be tested by ensuring that the above
condition is false in one test situation before pushing the code.
*/
part_info->table->move_fields(part_field_array, new_data, rec0);
error= part_info->get_partition_id(part_info, new_part_id,
new_func_value);
part_info->table->move_fields(part_field_array, rec0, new_data);
if (unlikely(error))
{
DBUG_RETURN(error);
}
}
#endif
DBUG_RETURN(0);
}
/*
A useful routine used by delete_row for partition handlers to calculate
the partition id.
SYNOPSIS SYNOPSIS
get_part_for_delete() get_part_for_buf()
buf Buffer of old record buf Buffer of old record
rec0 Reference to table->record[0] rec0 Reference to table->record[0]
part_info Reference to partition information part_info Reference to partition information
...@@ -337,21 +266,19 @@ int get_parts_for_update(const uchar *old_data, const uchar *new_data, ...@@ -337,21 +266,19 @@ int get_parts_for_update(const uchar *old_data, const uchar *new_data,
calculate the partition id. calculate the partition id.
*/ */
int get_part_for_delete(const uchar *buf, const uchar *rec0, int get_part_for_buf(const uchar *buf, const uchar *rec0,
partition_info *part_info, uint32 *part_id) partition_info *part_info, uint32 *part_id)
{ {
int error; int error;
longlong func_value; longlong func_value;
DBUG_ENTER("get_part_for_delete"); DBUG_ENTER("get_part_for_buf");
if (likely(buf == rec0)) if (buf == rec0)
{
if (unlikely((error= part_info->get_partition_id(part_info, part_id,
&func_value))))
{ {
DBUG_RETURN(error); error= part_info->get_partition_id(part_info, part_id, &func_value);
} if (unlikely((error)))
DBUG_PRINT("info", ("Delete from partition %d", *part_id)); goto err;
DBUG_PRINT("info", ("Partition %d", *part_id));
} }
else else
{ {
...@@ -360,12 +287,13 @@ int get_part_for_delete(const uchar *buf, const uchar *rec0, ...@@ -360,12 +287,13 @@ int get_part_for_delete(const uchar *buf, const uchar *rec0,
error= part_info->get_partition_id(part_info, part_id, &func_value); error= part_info->get_partition_id(part_info, part_id, &func_value);
part_info->table->move_fields(part_field_array, rec0, buf); part_info->table->move_fields(part_field_array, rec0, buf);
if (unlikely(error)) if (unlikely(error))
{ goto err;
DBUG_RETURN(error); DBUG_PRINT("info", ("Partition %d (path2)", *part_id));
}
DBUG_PRINT("info", ("Delete from partition %d (path2)", *part_id));
} }
DBUG_RETURN(0); DBUG_RETURN(0);
err:
part_info->err_value= func_value;
DBUG_RETURN(error);
} }
......
...@@ -87,11 +87,7 @@ bool check_reorganise_list(partition_info *new_part_info, ...@@ -87,11 +87,7 @@ bool check_reorganise_list(partition_info *new_part_info,
partition_info *old_part_info, partition_info *old_part_info,
List<char> list_part_names); List<char> list_part_names);
handler *get_ha_partition(partition_info *part_info); handler *get_ha_partition(partition_info *part_info);
int get_parts_for_update(const uchar *old_data, const uchar *new_data, int get_part_for_buf(const uchar *buf, const uchar *rec0,
const uchar *rec0, partition_info *part_info,
uint32 *old_part_id, uint32 *new_part_id,
longlong *func_value);
int get_part_for_delete(const uchar *buf, const uchar *rec0,
partition_info *part_info, uint32 *part_id); partition_info *part_info, uint32 *part_id);
void prune_partition_set(const TABLE *table, part_id_range *part_spec); void prune_partition_set(const TABLE *table, part_id_range *part_spec);
bool check_partition_info(partition_info *part_info,handlerton **eng_type, bool check_partition_info(partition_info *part_info,handlerton **eng_type,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment