From 387fe5ecc3a697dd0e59fb4e4ff02fcc0385c467 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 25 Jan 2026 13:20:51 +0100 Subject: [PATCH] MDEV-36787 Error 153: No savepoint with that name upon ROLLBACK TO SAVEPOINT, assertion failure 1. InnoDB should return HA_ERR_ROLLBACK if it aborts a transaction internally 2. the server should recognize it and perform an automatic rollback --- .../r/binlog_row_mix_innodb_myisam.result | 2 -- .../r/binlog_stm_mix_innodb_myisam.result | 2 -- .../suite/innodb/r/alter_copy_bulk.result | 23 +++++++++++++++++-- .../suite/innodb/t/alter_copy_bulk.test | 20 ++++++++++++++-- sql/sql_insert.cc | 3 ++- storage/innobase/handler/ha_innodb.cc | 1 + 6 files changed, 42 insertions(+), 9 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result index ce6847d59d3..ed4a7cb4698 100644 --- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result @@ -363,8 +363,6 @@ INSERT INTO t1 values (3,3); CREATE TEMPORARY TABLE t2 (primary key (a)) engine=innodb select * from t1; ERROR 23000: Duplicate entry '1' for key 'PRIMARY' ROLLBACK; -Warnings: -Warning 1196 Some non-transactional changed tables couldn't be rolled back DROP TABLE IF EXISTS t2; Warnings: Note 1051 Unknown table 'test.t2' diff --git a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result index 30dd08e33eb..d27f8bf705d 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result @@ -329,8 +329,6 @@ INSERT INTO t1 values (3,3); CREATE TEMPORARY TABLE t2 (primary key (a)) engine=innodb select * from t1; ERROR 23000: Duplicate entry '1' for key 'PRIMARY' ROLLBACK; -Warnings: -Warning 1196 Some non-transactional changed tables couldn't be rolled back DROP TABLE IF EXISTS t2; Warnings: Note 1051 Unknown table 'test.t2' diff --git a/mysql-test/suite/innodb/r/alter_copy_bulk.result b/mysql-test/suite/innodb/r/alter_copy_bulk.result index 9be8e98539e..e2bbb2c46cc 100644 --- a/mysql-test/suite/innodb/r/alter_copy_bulk.result +++ b/mysql-test/suite/innodb/r/alter_copy_bulk.result @@ -113,8 +113,7 @@ DROP TABLE t1; DROP TABLE IF EXISTS t2; # restart # -# MDEV-37296 ALTER TABLE allows adding unique hash key -# with duplicate values +# MDEV-37296 ALTER TABLE allows adding unique hash key with duplicate values # CREATE TABLE t (pk INT PRIMARY KEY, a INT, b TEXT) ENGINE=InnoDB; INSERT INTO t VALUES (5,3,'foo'), (1,NULL,'bar'), (3,3,'foo'); @@ -134,3 +133,23 @@ pk a b 3 3 foo 5 3 foo DROP TABLE t; +# +# MDEV-36787 Error 153: No savepoint with that name upon ROLLBACK TO SAVEPOINT, assertion failure +# +CREATE TABLE t (a INT) ENGINE=InnoDB; +START TRANSACTION; +SELECT * FROM t; +a +SAVEPOINT A; +select @@in_transaction; +@@in_transaction +1 +CREATE TEMPORARY TABLE tmp (a TINYINT) ENGINE=InnoDB AS SELECT 256 AS a; +ERROR 22003: Out of range value for column 'a' at row 1 +select @@in_transaction; +@@in_transaction +0 +ROLLBACK TO SAVEPOINT A; +ERROR 42000: SAVEPOINT A does not exist +DROP TABLE t; +# End of 10.11 tests diff --git a/mysql-test/suite/innodb/t/alter_copy_bulk.test b/mysql-test/suite/innodb/t/alter_copy_bulk.test index ffa8e70f77e..fb95cfda908 100644 --- a/mysql-test/suite/innodb/t/alter_copy_bulk.test +++ b/mysql-test/suite/innodb/t/alter_copy_bulk.test @@ -132,8 +132,7 @@ DROP TABLE IF EXISTS t2; --source include/restart_mysqld.inc --echo # ---echo # MDEV-37296 ALTER TABLE allows adding unique hash key ---echo # with duplicate values +--echo # MDEV-37296 ALTER TABLE allows adding unique hash key with duplicate values --echo # CREATE TABLE t (pk INT PRIMARY KEY, a INT, b TEXT) ENGINE=InnoDB; INSERT INTO t VALUES (5,3,'foo'), (1,NULL,'bar'), (3,3,'foo'); @@ -142,3 +141,20 @@ ALTER TABLE t ADD UNIQUE (a,b); SHOW CREATE TABLE t; SELECT * FROM t; DROP TABLE t; + +--echo # +--echo # MDEV-36787 Error 153: No savepoint with that name upon ROLLBACK TO SAVEPOINT, assertion failure +--echo # +CREATE TABLE t (a INT) ENGINE=InnoDB; +START TRANSACTION; +SELECT * FROM t; +SAVEPOINT A; +select @@in_transaction; +--error ER_WARN_DATA_OUT_OF_RANGE +CREATE TEMPORARY TABLE tmp (a TINYINT) ENGINE=InnoDB AS SELECT 256 AS a; +select @@in_transaction; +--error ER_SP_DOES_NOT_EXIST +ROLLBACK TO SAVEPOINT A; +DROP TABLE t; + +--echo # End of 10.11 tests diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index e59f5ba596f..9f8366dc0d6 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -4685,7 +4685,8 @@ void select_insert::abort_result_set() finalize_replace(table, info.handle_duplicates, info.ignore); table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); - table->file->extra(HA_EXTRA_ABORT_ALTER_COPY); + if (table->file->extra(HA_EXTRA_ABORT_ALTER_COPY) == HA_ERR_ROLLBACK) + thd->transaction_rollback_request= true; /* If at least one row has been inserted/modified and will stay in the table (the table doesn't have transactions) we must write to diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index ecd98ebc631..e93d3d3f58d 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -15938,6 +15938,7 @@ ha_innobase::extra( trx = check_trx_exists(ha_thd()); m_prebuilt->table->skip_alter_undo = 0; trx->rollback(); + return(HA_ERR_ROLLBACK); } break; default:/* Do nothing */