summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNayuta Yanagisawa <nayuta.yanagisawa@hey.com>2021-10-13 22:45:26 +0900
committerNayuta Yanagisawa <nayuta.yanagisawa@hey.com>2022-06-29 22:40:56 +0900
commit0bc343ad201431923615b2dbf8fc1f6fcf887299 (patch)
tree1e2a96118ba6545198b0c37b093f95bf21741e5d
parentf339ef3f9793d5de8f825f1ec6489550b98e7e9a (diff)
downloadmariadb-git-bb-10.3-mdev-26544_3.tar.gz
MDEV-26544 Assertion `part_share->auto_inc_initialized' failed in ha_partition::get_auto_increment on INSERTbb-10.3-mdev-26544_3
The partition storage engine ignores return (error) values of handler::info(). As a result, a query that should be aborted is not aborted and then the server violates the assertion.
-rw-r--r--sql/ha_partition.cc38
-rw-r--r--sql/ha_partition.h2
-rw-r--r--storage/spider/mysql-test/spider/bugfix/r/mdev_26544.result23
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_26544.cnf2
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_26544.test32
5 files changed, 82 insertions, 15 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 5c08c934dde..fd52fc42904 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -4339,7 +4339,7 @@ void ha_partition::try_semi_consistent_read(bool yes)
int ha_partition::write_row(uchar * buf)
{
uint32 part_id;
- int error;
+ int error= 0;
longlong func_value;
bool have_auto_increment= table->next_number_field && buf == table->record[0];
MY_BITMAP *old_map;
@@ -4356,15 +4356,15 @@ int ha_partition::write_row(uchar * buf)
if (have_auto_increment)
{
if (!table_share->next_number_keypart)
- update_next_auto_inc_val();
- error= update_auto_increment();
+ if (unlikely(error= update_next_auto_inc_val()))
+ goto exit;
/*
If we have failed to set the auto-increment value for this row,
it is highly likely that we will not be able to insert it into
the correct partition. We must check and fail if necessary.
*/
- if (unlikely(error))
+ if (unlikely(error= update_auto_increment()))
goto exit;
/*
@@ -8304,6 +8304,7 @@ int ha_partition::compare_number_of_records(ha_partition *me,
int ha_partition::info(uint flag)
{
+ int error= 0;
uint no_lock_flag= flag & HA_STATUS_NO_LOCK;
uint extra_var_flag= flag & HA_STATUS_VARIABLE_EXTRA;
DBUG_ENTER("ha_partition::info");
@@ -8356,7 +8357,11 @@ int ha_partition::info(uint flag)
break;
}
file= *file_array;
- file->info(HA_STATUS_AUTO | no_lock_flag);
+ if ((error= file->info(HA_STATUS_AUTO | no_lock_flag)))
+ {
+ unlock_auto_increment();
+ DBUG_RETURN(error);
+ }
set_if_bigger(auto_increment_value,
file->stats.auto_increment_value);
} while (*(++file_array));
@@ -8412,7 +8417,8 @@ int ha_partition::info(uint flag)
i= bitmap_get_next_set(&m_part_info->read_partitions, i))
{
file= m_file[i];
- file->info(HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag);
+ if ((error= file->info(HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag)))
+ DBUG_RETURN(error);
stats.records+= file->stats.records;
stats.deleted+= file->stats.deleted;
stats.data_file_length+= file->stats.data_file_length;
@@ -8497,7 +8503,8 @@ int ha_partition::info(uint flag)
if (!(flag & HA_STATUS_VARIABLE) ||
!bitmap_is_set(&(m_part_info->read_partitions),
(uint) (file_array - m_file)))
- file->info(HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag);
+ if ((error= file->info(HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag)))
+ DBUG_RETURN(error);
if (file->stats.records > max_records || !handler_instance_set)
{
handler_instance_set= 1;
@@ -8518,7 +8525,8 @@ int ha_partition::info(uint flag)
this);
file= m_file[handler_instance];
- file->info(HA_STATUS_CONST | no_lock_flag);
+ if ((error= file->info(HA_STATUS_CONST | no_lock_flag)))
+ DBUG_RETURN(error);
stats.block_size= file->stats.block_size;
stats.create_time= file->stats.create_time;
ref_length= m_ref_length;
@@ -8534,7 +8542,8 @@ int ha_partition::info(uint flag)
Note: all engines does not support HA_STATUS_ERRKEY, so set errkey.
*/
file->errkey= errkey;
- file->info(HA_STATUS_ERRKEY | no_lock_flag);
+ if ((error= file->info(HA_STATUS_ERRKEY | no_lock_flag)))
+ DBUG_RETURN(error);
errkey= file->errkey;
}
if (flag & HA_STATUS_TIME)
@@ -8551,7 +8560,8 @@ int ha_partition::info(uint flag)
do
{
file= *file_array;
- file->info(HA_STATUS_TIME | no_lock_flag);
+ if ((error= file->info(HA_STATUS_TIME | no_lock_flag)))
+ DBUG_RETURN(error);
if (file->stats.update_time > stats.update_time)
stats.update_time= file->stats.update_time;
} while (*(++file_array));
@@ -10526,11 +10536,11 @@ int ha_partition::cmp_ref(const uchar *ref1, const uchar *ref2)
the underlying partitions require that the value should be re-calculated
*/
-void ha_partition::update_next_auto_inc_val()
+int ha_partition::update_next_auto_inc_val()
{
- if (!part_share->auto_inc_initialized ||
- need_info_for_auto_inc())
- info(HA_STATUS_AUTO);
+ if (!part_share->auto_inc_initialized || need_info_for_auto_inc())
+ return info(HA_STATUS_AUTO);
+ return 0;
}
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 6c0e4ef6cf2..590ec73cc69 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -1361,7 +1361,7 @@ public:
virtual void release_auto_increment();
private:
virtual int reset_auto_increment(ulonglong value);
- void update_next_auto_inc_val();
+ int update_next_auto_inc_val();
virtual void lock_auto_increment()
{
/* lock already taken */
diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_26544.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_26544.result
new file mode 100644
index 00000000000..b3d5facc202
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_26544.result
@@ -0,0 +1,23 @@
+#
+# MDEV-26544 Assertion `part_share->auto_inc_initialized' failed in ha_partition::get_auto_increment on INSERT
+#
+for master_1
+for child2
+for child3
+connection master_1;
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+CREATE TABLE `tbl_a` (
+`a` INT AUTO_INCREMENT, KEY(`a`)
+) ENGINE=Spider DEFAULT CHARSET=utf8
+PARTITION BY LIST COLUMNS (`a`) (
+PARTITION `pt1` DEFAULT
+);
+INSERT INTO tbl_a (a) VALUES (0);
+ERROR HY000: Unable to connect to foreign data source: localhost
+INSERT INTO tbl_a () VALUES ();
+ERROR HY000: Unable to connect to foreign data source: localhost
+DROP DATABASE IF EXISTS auto_test_remote;
+for master_1
+for child2
+for child3
diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_26544.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_26544.cnf
new file mode 100644
index 00000000000..b0853e32654
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_26544.cnf
@@ -0,0 +1,2 @@
+!include include/default_mysqld.cnf
+!include ../my_1_1.cnf
diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_26544.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_26544.test
new file mode 100644
index 00000000000..ac2b68988c0
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_26544.test
@@ -0,0 +1,32 @@
+--echo #
+--echo # MDEV-26544 Assertion `part_share->auto_inc_initialized' failed in ha_partition::get_auto_increment on INSERT
+--echo #
+
+--disable_query_log
+--disable_result_log
+--source ../../t/test_init.inc
+--enable_result_log
+--enable_query_log
+
+--connection master_1
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+
+eval CREATE TABLE `tbl_a` (
+ `a` INT AUTO_INCREMENT, KEY(`a`)
+) $MASTER_1_ENGINE $MASTER_1_CHARSET
+PARTITION BY LIST COLUMNS (`a`) (
+ PARTITION `pt1` DEFAULT
+);
+--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
+INSERT INTO tbl_a (a) VALUES (0);
+--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
+INSERT INTO tbl_a () VALUES ();
+
+DROP DATABASE IF EXISTS auto_test_remote;
+
+--disable_query_log
+--disable_result_log
+--source ../../t/test_deinit.inc
+--enable_result_log
+--enable_query_log