diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index f32ed667864daf0cf2754be554be4f08d75f21d8..5fdc6f6f3dc8cb6291acbf820383e6ef9b5030a9 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -24,4 +24,4 @@ subselect : Bug#15706 type_time : Bug#15805 rpl000002 : Bug#15920 Temporary tables are not binlogged in SBR ps_7ndb : Bug#15923 Core dump in RBR mode when executing test suite -sp_trans : Bug#15924 Code dump in RBR mode when executing test suite +#sp_trans : Bug#15924 Code dump in RBR mode when executing test suite diff --git a/sql/log.cc b/sql/log.cc index 44d3869e9d56ff71cd60f067b75771e98f14a34a..dd08ca7b9b5c5afc6148622241b5f7f8d17d5f5e 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -241,13 +241,15 @@ static int binlog_savepoint_set(THD *thd, void *sv) DBUG_ENTER("binlog_savepoint_set"); binlog_trx_data *const trx_data= (binlog_trx_data*) thd->ha_data[binlog_hton.slot]; - IO_CACHE *trans_log= &trx_data->trans_log; - DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(trans_log)); + DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(&trx_data->trans_log)); - *(my_off_t *)sv= my_b_tell(trans_log); + *(my_off_t *)sv= my_b_tell(&trx_data->trans_log); /* Write it to the binary log */ - Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE); - DBUG_RETURN(mysql_bin_log.write(&qinfo)); + + int const error= + thd->binlog_query(THD::STMT_QUERY_TYPE, + thd->query, thd->query_length, TRUE, FALSE); + DBUG_RETURN(error); } static int binlog_savepoint_rollback(THD *thd, void *sv) @@ -265,8 +267,10 @@ static int binlog_savepoint_rollback(THD *thd, void *sv) */ if (unlikely(thd->options & OPTION_STATUS_NO_TRANS_UPDATE)) { - Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE); - DBUG_RETURN(mysql_bin_log.write(&qinfo)); + int const error= + thd->binlog_query(THD::STMT_QUERY_TYPE, + thd->query, thd->query_length, TRUE, FALSE); + DBUG_RETURN(error); } reinit_io_cache(trans_log, WRITE_CACHE, *(my_off_t *)sv, 0, 0); DBUG_RETURN(0); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 08d89228a7203a2f882b4b6b295715f33f2b335f..2bc0d8d59ab69ef8ccd33b18a64c82465208bcb9 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1969,6 +1969,23 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, backup->client_capabilities= client_capabilities; backup->savepoints= transaction.savepoints; + /* + For row-based replication and before executing a function/trigger, + the pending rows event has to be flushed. The function/trigger + might execute statement that require the pending event to be + flushed. A simple example: + + CREATE FUNCTION foo() RETURNS INT + BEGIN + SAVEPOINT x; + RETURN 0; + END + + INSERT INTO t1 VALUES (1), (foo()), (2); + */ + if (binlog_row_based) + thd->binlog_flush_pending_rows_event(false); + if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) && !binlog_row_based) options&= ~OPTION_BIN_LOG;