Skip to content

Commit fad1d15

Browse files
MDEV-25460: Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())'
failed in Diagnostics_area::set_ok_status in my_ok from mysql_sql_stmt_prepare Analysis: Before PREPARE is executed, binlog_format is STATEMENT. This PREPARE had SET STATEMENT which sets binlog_format to ROW. Now after PREPARE is done we reset the binlog_format (back to STATEMENT). But we have temporary table, it doesn't let changing binlog_format=ROW to binlog_format=STATEMENT and gives error which goes unreported. This unreported error eventually causes assertion failure. Fix: Change return type for LEX::restore_set_statement_var() to bool and make it return error state.
1 parent 4daf9d7 commit fad1d15

File tree

6 files changed

+77
-5
lines changed

6 files changed

+77
-5
lines changed

mysql-test/extra/binlog_tests/mysqlbinlog_row_engine.inc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,3 +1921,28 @@ let $MYSQLD_DATADIR= `select @@datadir`;
19211921
DROP TABLE t1;
19221922

19231923

1924+
--echo #
1925+
--echo # Beginning of 10.2 test
1926+
--echo #
1927+
--echo # MDEV-25460: Assertion `!is_set() || (m_status == DA_OK_BULK &&
1928+
--echo # is_bulk_op())' failed in Diagnostics_area::set_ok_status in my_ok
1929+
--echo # from mysql_sql_stmt_prepare
1930+
--echo #
1931+
1932+
CREATE TEMPORARY TABLE a (c INT) ENGINE=InnoDB;
1933+
CREATE TABLE b (c INT) ENGINE=InnoDB;
1934+
1935+
--error ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR
1936+
PREPARE s FROM 'SET STATEMENT binlog_format=ROW FOR SELECT * FROM b';
1937+
1938+
DROP TABLE b;
1939+
DROP TEMPORARY TABLE a;
1940+
1941+
CREATE TEMPORARY TABLE t (c INT);
1942+
--error ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR
1943+
PREPARE s FROM 'SET STATEMENT binlog_format=ROW FOR SELECT 1';
1944+
DROP TEMPORARY TABLE t;
1945+
1946+
--echo #
1947+
--echo # End of 10.2 test
1948+
--echo #

mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6352,3 +6352,23 @@ ROLLBACK /* added by mysqlbinlog */;
63526352
# Cleanup.
63536353
#
63546354
DROP TABLE t1;
6355+
#
6356+
# Beginning of 10.2 test
6357+
#
6358+
# MDEV-25460: Assertion `!is_set() || (m_status == DA_OK_BULK &&
6359+
# is_bulk_op())' failed in Diagnostics_area::set_ok_status in my_ok
6360+
# from mysql_sql_stmt_prepare
6361+
#
6362+
CREATE TEMPORARY TABLE a (c INT) ENGINE=InnoDB;
6363+
CREATE TABLE b (c INT) ENGINE=InnoDB;
6364+
PREPARE s FROM 'SET STATEMENT binlog_format=ROW FOR SELECT * FROM b';
6365+
ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables
6366+
DROP TABLE b;
6367+
DROP TEMPORARY TABLE a;
6368+
CREATE TEMPORARY TABLE t (c INT);
6369+
PREPARE s FROM 'SET STATEMENT binlog_format=ROW FOR SELECT 1';
6370+
ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables
6371+
DROP TEMPORARY TABLE t;
6372+
#
6373+
# End of 10.2 test
6374+
#

mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6393,3 +6393,29 @@ ROLLBACK /* added by mysqlbinlog */;
63936393
# Cleanup.
63946394
#
63956395
DROP TABLE t1;
6396+
#
6397+
# Beginning of 10.2 test
6398+
#
6399+
# MDEV-25460: Assertion `!is_set() || (m_status == DA_OK_BULK &&
6400+
# is_bulk_op())' failed in Diagnostics_area::set_ok_status in my_ok
6401+
# from mysql_sql_stmt_prepare
6402+
#
6403+
CREATE TEMPORARY TABLE a (c INT) ENGINE=InnoDB;
6404+
Warnings:
6405+
Warning 1286 Unknown storage engine 'InnoDB'
6406+
Warning 1266 Using storage engine MyISAM for table 'a'
6407+
CREATE TABLE b (c INT) ENGINE=InnoDB;
6408+
Warnings:
6409+
Warning 1286 Unknown storage engine 'InnoDB'
6410+
Warning 1266 Using storage engine MyISAM for table 'b'
6411+
PREPARE s FROM 'SET STATEMENT binlog_format=ROW FOR SELECT * FROM b';
6412+
ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables
6413+
DROP TABLE b;
6414+
DROP TEMPORARY TABLE a;
6415+
CREATE TEMPORARY TABLE t (c INT);
6416+
PREPARE s FROM 'SET STATEMENT binlog_format=ROW FOR SELECT 1';
6417+
ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables
6418+
DROP TEMPORARY TABLE t;
6419+
#
6420+
# End of 10.2 test
6421+
#

sql/sql_lex.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4766,18 +4766,19 @@ void LEX::free_arena_for_set_stmt()
47664766
DBUG_VOID_RETURN;
47674767
}
47684768

4769-
void LEX::restore_set_statement_var()
4769+
bool LEX::restore_set_statement_var()
47704770
{
4771+
bool err= false;
47714772
DBUG_ENTER("LEX::restore_set_statement_var");
47724773
if (!old_var_list.is_empty())
47734774
{
47744775
DBUG_PRINT("info", ("vars: %d", old_var_list.elements));
4775-
sql_set_variables(thd, &old_var_list, false);
4776+
err= sql_set_variables(thd, &old_var_list, false);
47764777
old_var_list.empty();
47774778
free_arena_for_set_stmt();
47784779
}
47794780
DBUG_ASSERT(!is_arena_for_set_stmt());
4780-
DBUG_VOID_RETURN;
4781+
DBUG_RETURN(err);
47814782
}
47824783

47834784
/*

sql/sql_lex.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3094,7 +3094,7 @@ struct LEX: public Query_tables_list
30943094

30953095
int print_explain(select_result_sink *output, uint8 explain_flags,
30963096
bool is_analyze, bool *printed_anything);
3097-
void restore_set_statement_var();
3097+
bool restore_set_statement_var();
30983098

30993099
void init_last_field(Column_definition *field, const char *name, CHARSET_INFO *cs);
31003100
void set_last_field_type(const Lex_field_type_st &type);

sql/sql_prepare.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4283,7 +4283,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
42834283
Restore original values of variables modified on handling
42844284
SET STATEMENT clause.
42854285
*/
4286-
thd->lex->restore_set_statement_var();
4286+
error|= thd->lex->restore_set_statement_var();
42874287

42884288
/* The order is important */
42894289
lex->unit.cleanup();

0 commit comments

Comments
 (0)