diff --git a/mysql-test/suite/parts/t/mdev_41989.test b/mysql-test/suite/parts/t/mdev_41989.test new file mode 100644 index 0000000000000..140b3b955b9ea --- /dev/null +++ b/mysql-test/suite/parts/t/mdev_41989.test @@ -0,0 +1,5 @@ +CREATE TABLE t1 (id INT PRIMARY KEY, a INT) ENGINE=MyISAM PARTITION BY HASH (id) PARTITIONS 2; +INSERT INTO t1 VALUES (1, 1), (2, 2); +--error ER_DUP_ENTRY +UPDATE t1 SET id = 2 WHERE id = 1; +DROP TABLE t1; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 3afd8f396e58d..0eb681b986a31 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -431,6 +431,7 @@ void ha_partition::init_handler_variables() m_top_entry= NO_CURRENT_PART_ID; m_rec_length= 0; m_last_part= 0; + m_err_part= NO_CURRENT_PART_ID; m_err_rec= NULL; m_curr_key_info[0]= NULL; m_curr_key_info[1]= NULL; @@ -4696,33 +4697,32 @@ 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, so this is not supported for this engine. */ - { - Abort_on_warning_instant_set old_abort_on_warning(thd, 0); - error= get_part_for_buf(old_data, table->record[0], 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 (unlikely((error= get_part_for_buf(new_data, table->record[0], - m_part_info, &new_part_id)))) - goto exit; - if (unlikely(!bitmap_is_set(&(m_part_info->lock_partitions), new_part_id))) - { - error= HA_ERR_NOT_IN_LOCK_PARTITIONS; - goto exit; - } - - - start_part_bulk_insert(thd, new_part_id); - DBUG_ASSERT(!m_file[new_part_id]->row_logging); - if (new_part_id == old_part_id) +{ + uint32 saved_last_part; + + Abort_on_warning_instant_set old_abort_on_warning(thd, 0); + + if (unlikely((error= get_part_for_buf(new_data, table->record[0], + m_part_info, &new_part_id)))) + goto exit; + if (unlikely(!bitmap_is_set(&(m_part_info->lock_partitions), new_part_id))) + { + error= HA_ERR_NOT_IN_LOCK_PARTITIONS; + goto exit; + } + + saved_last_part = m_last_part; + start_part_bulk_insert(thd, new_part_id); + DBUG_ASSERT(m_file[new_part_id]->row_logging); + if (new_part_id != old_part_id) { DBUG_PRINT("info", ("Update in partition %u", (uint) new_part_id)); error= m_file[new_part_id]->ha_update_row(old_data, new_data); + if (error) + m_last_part= saved_last_part; goto exit; } + else { Field *saved_next_number_field= table->next_number_field; diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 943f5e4279c09..07ad94d12bd83 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -359,6 +359,7 @@ class ha_partition final :public handler uint m_tot_parts; // Total number of partitions; uint m_num_locks; // For engines like ha_blackhole, which needs no locks uint m_last_part; // Last file that we update,write,read + uint m_err_part; // Partition where last error occurred part_id_range m_part_spec; // Which parts to scan uint m_scan_value; // Value passed in rnd_init // call diff --git a/sql/opt_context_store_replay.cc b/sql/opt_context_store_replay.cc index 4bea88970c6b9..f5228532ce226 100644 --- a/sql/opt_context_store_replay.cc +++ b/sql/opt_context_store_replay.cc @@ -869,7 +869,7 @@ bool Optimizer_context_recorder::dump_sql_script(THD* thd, String &sql_script) { String ddl; StringBuffer<256> full_tbl_name; - LEX_CSTRING *tbl_name_key; + LEX_CSTRING *tbl_name_key= nullptr; append_table_or_view_name(tbl, &full_tbl_name); /*