From 378beed0a680172d6570117c853d803e30983199 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 20 Sep 2017 20:02:01 +0200 Subject: [PATCH] MDEV-13290: Assertion Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' or `! is_set()' failed followup for 97c2a7354b6 - don't use thd->is_error(), the error could've been set before TABLE_LIST::cleanup_items. Use the error handler to count errors. This fixes rpl.rpl_row_binlog_max_cache_size - it was failing when ER_STMT_CACHE_FULL happened duing multi-table update. Because multi_update::abort_result_set() calls do_updates() to update as much as possible, so one cannot rely on thd->is_error() after that. --- sql/sql_class.h | 22 ++++++++++++++++++++++ sql/table.cc | 11 +++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/sql/sql_class.h b/sql/sql_class.h index 57ff65cb416..7429ac586ea 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1468,6 +1468,28 @@ public: }; +/** + Implements the trivial error handler which counts errors as they happen. +*/ + +class Counting_error_handler : public Internal_error_handler +{ +public: + int errors; + bool handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + Sql_condition::enum_warning_level level, + const char* msg, + Sql_condition ** cond_hdl) + { + errors++; + return false; + } + Counting_error_handler() : errors(0) {} +}; + + /** This class is an internal error handler implementation for DROP TABLE statements. The thing is that there may be warnings during diff --git a/sql/table.cc b/sql/table.cc index ff9c4217b7d..36ed9be8084 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4628,7 +4628,13 @@ void TABLE_LIST::cleanup_items() int TABLE_LIST::view_check_option(THD *thd, bool ignore_failure) { - if (check_option && check_option->val_int() == 0) + Counting_error_handler ceh; + thd->push_internal_handler(&ceh); + bool res= check_option && check_option->val_int() == 0; + thd->pop_internal_handler(); + if (ceh.errors) + return(VIEW_CHECK_ERROR); + if (res) { TABLE_LIST *main_view= top_table(); if (ignore_failure) @@ -4642,9 +4648,6 @@ int TABLE_LIST::view_check_option(THD *thd, bool ignore_failure) main_view->view_name.str); return(VIEW_CHECK_ERROR); } - /* We check thd->error() because it can be set by conversion problem. */ - if (thd->is_error()) - return(VIEW_CHECK_ERROR); return(VIEW_CHECK_OK); }