Commit fad1d153 authored by Rucha Deodhar's avatar Rucha Deodhar

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.
parent 4daf9d7c
......@@ -1921,3 +1921,28 @@ let $MYSQLD_DATADIR= `select @@datadir`;
DROP TABLE t1;
--echo #
--echo # Beginning of 10.2 test
--echo #
--echo # MDEV-25460: Assertion `!is_set() || (m_status == DA_OK_BULK &&
--echo # is_bulk_op())' failed in Diagnostics_area::set_ok_status in my_ok
--echo # from mysql_sql_stmt_prepare
--echo #
CREATE TEMPORARY TABLE a (c INT) ENGINE=InnoDB;
CREATE TABLE b (c INT) ENGINE=InnoDB;
--error ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR
PREPARE s FROM 'SET STATEMENT binlog_format=ROW FOR SELECT * FROM b';
DROP TABLE b;
DROP TEMPORARY TABLE a;
CREATE TEMPORARY TABLE t (c INT);
--error ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR
PREPARE s FROM 'SET STATEMENT binlog_format=ROW FOR SELECT 1';
DROP TEMPORARY TABLE t;
--echo #
--echo # End of 10.2 test
--echo #
......@@ -6352,3 +6352,23 @@ ROLLBACK /* added by mysqlbinlog */;
# Cleanup.
#
DROP TABLE t1;
#
# Beginning of 10.2 test
#
# 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
#
CREATE TEMPORARY TABLE a (c INT) ENGINE=InnoDB;
CREATE TABLE b (c INT) ENGINE=InnoDB;
PREPARE s FROM 'SET STATEMENT binlog_format=ROW FOR SELECT * FROM b';
ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables
DROP TABLE b;
DROP TEMPORARY TABLE a;
CREATE TEMPORARY TABLE t (c INT);
PREPARE s FROM 'SET STATEMENT binlog_format=ROW FOR SELECT 1';
ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables
DROP TEMPORARY TABLE t;
#
# End of 10.2 test
#
......@@ -6393,3 +6393,29 @@ ROLLBACK /* added by mysqlbinlog */;
# Cleanup.
#
DROP TABLE t1;
#
# Beginning of 10.2 test
#
# 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
#
CREATE TEMPORARY TABLE a (c INT) ENGINE=InnoDB;
Warnings:
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1266 Using storage engine MyISAM for table 'a'
CREATE TABLE b (c INT) ENGINE=InnoDB;
Warnings:
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1266 Using storage engine MyISAM for table 'b'
PREPARE s FROM 'SET STATEMENT binlog_format=ROW FOR SELECT * FROM b';
ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables
DROP TABLE b;
DROP TEMPORARY TABLE a;
CREATE TEMPORARY TABLE t (c INT);
PREPARE s FROM 'SET STATEMENT binlog_format=ROW FOR SELECT 1';
ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables
DROP TEMPORARY TABLE t;
#
# End of 10.2 test
#
......@@ -4766,18 +4766,19 @@ void LEX::free_arena_for_set_stmt()
DBUG_VOID_RETURN;
}
void LEX::restore_set_statement_var()
bool LEX::restore_set_statement_var()
{
bool err= false;
DBUG_ENTER("LEX::restore_set_statement_var");
if (!old_var_list.is_empty())
{
DBUG_PRINT("info", ("vars: %d", old_var_list.elements));
sql_set_variables(thd, &old_var_list, false);
err= sql_set_variables(thd, &old_var_list, false);
old_var_list.empty();
free_arena_for_set_stmt();
}
DBUG_ASSERT(!is_arena_for_set_stmt());
DBUG_VOID_RETURN;
DBUG_RETURN(err);
}
/*
......
......@@ -3094,7 +3094,7 @@ struct LEX: public Query_tables_list
int print_explain(select_result_sink *output, uint8 explain_flags,
bool is_analyze, bool *printed_anything);
void restore_set_statement_var();
bool restore_set_statement_var();
void init_last_field(Column_definition *field, const char *name, CHARSET_INFO *cs);
void set_last_field_type(const Lex_field_type_st &type);
......
......@@ -4283,7 +4283,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
Restore original values of variables modified on handling
SET STATEMENT clause.
*/
thd->lex->restore_set_statement_var();
error|= thd->lex->restore_set_statement_var();
/* The order is important */
lex->unit.cleanup();
......
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