From: Alexander Nozdrin Date: January 19 2011 12:50pm Subject: bzr commit into mysql-trunk branch (alexander.nozdrin:3532) Bug#55847 List-Archive: http://lists.mysql.com/commits/129185 X-Bug: 55847 Message-Id: <201101191251.p0JCpcWC008082@acsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============6708179492156345776==" --===============6708179492156345776== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/alik/MySQL/bzr/00/bug55847/mysql-trunk-bug55847/ based on revid:anders.song@stripped 3532 Alexander Nozdrin 2011-01-19 A patch for Bug#55847: SHOW WARNINGS returns empty result set when SQLEXCEPTION is active. The problem was in a hackish THD::no_warnings_for_error attribute. When it was set, an error was not written to Warning_info -- only Diagnostics_area state was changed. That means, Diagnostics_area might contain error state, which is not present in Warning_info. The fix is to remove that hack. This patch is needed to fix Bug 55843. modified: mysql-test/r/warnings.result mysql-test/t/warnings.test sql/sql_admin.cc sql/sql_class.cc sql/sql_class.h sql/sql_error.cc sql/sql_error.h sql/sql_parse.cc sql/sql_show.cc sql/sql_trigger.cc === modified file 'mysql-test/r/warnings.result' --- a/mysql-test/r/warnings.result 2010-08-30 06:38:09 +0000 +++ b/mysql-test/r/warnings.result 2011-01-19 12:50:36 +0000 @@ -316,3 +316,25 @@ SHOW ERRORS; Level Code Message Error 1051 Unknown table 'test.t1' End of 5.0 tests + +-- Bug#55847 + +DROP TABLE IF EXISTS t1; +DROP FUNCTION IF EXISTS f1; +CREATE TABLE t1(a INT UNIQUE); +CREATE FUNCTION f1(x INT) RETURNS INT +BEGIN +INSERT INTO t1 VALUES(x); +INSERT INTO t1 VALUES(x); +RETURN x; +END| + +SHOW TABLES WHERE f1(11) = 11; +ERROR 23000: Duplicate entry '11' for key 'a' + +SHOW WARNINGS; +Level Code Message +Error 1062 Duplicate entry '11' for key 'a' + +DROP TABLE t1; +DROP FUNCTION f1; === modified file 'mysql-test/t/warnings.test' --- a/mysql-test/t/warnings.test 2009-11-13 10:17:53 +0000 +++ b/mysql-test/t/warnings.test 2011-01-19 12:50:36 +0000 @@ -228,3 +228,43 @@ DROP TABLE t1; SHOW ERRORS; --echo End of 5.0 tests + +# +# Bug#55847: SHOW WARNINGS returns empty result set when SQLEXCEPTION is active +# + +--echo +--echo -- Bug#55847 +--echo + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP FUNCTION IF EXISTS f1; +--enable_warnings + +CREATE TABLE t1(a INT UNIQUE); + +delimiter |; + +CREATE FUNCTION f1(x INT) RETURNS INT +BEGIN + INSERT INTO t1 VALUES(x); + INSERT INTO t1 VALUES(x); + RETURN x; +END| + +delimiter ;| + +--echo + +--error ER_DUP_ENTRY +SHOW TABLES WHERE f1(11) = 11; + +--echo + +SHOW WARNINGS; + +--echo + +DROP TABLE t1; +DROP FUNCTION f1; === modified file 'sql/sql_admin.cc' --- a/sql/sql_admin.cc 2011-01-10 13:26:13 +0000 +++ b/sql/sql_admin.cc 2011-01-19 12:50:36 +0000 @@ -336,13 +336,20 @@ static bool mysql_admin_table(THD* thd, so any errors opening the table are logical errors. In these cases it makes sense to report them. */ - if (!thd->locked_tables_mode) - thd->no_warnings_for_error= no_warnings_for_error; + Warning_info wi(thd->query_id); + Warning_info *wi_saved= thd->warning_info; + + if (!thd->locked_tables_mode && no_warnings_for_error) + thd->warning_info= &wi; + if (view_operator_func == NULL) table->required_type=FRMTYPE_TABLE; open_error= open_and_lock_tables(thd, table, TRUE, 0); - thd->no_warnings_for_error= 0; + + if (!thd->locked_tables_mode && no_warnings_for_error) + thd->warning_info= wi_saved; + table->next_global= save_next_global; table->next_local= save_next_local; thd->open_options&= ~extra_open_options; === modified file 'sql/sql_class.cc' --- a/sql/sql_class.cc 2010-12-17 16:14:15 +0000 +++ b/sql/sql_class.cc 2011-01-19 12:50:36 +0000 @@ -584,7 +584,7 @@ THD::THD() client_capabilities= 0; // minimalistic client ull=0; system_thread= NON_SYSTEM_THREAD; - cleanup_done= abort_on_warning= no_warnings_for_error= 0; + cleanup_done= abort_on_warning= 0; peer_port= 0; // For SHOW PROCESSLIST transaction.m_pending_rows_event= 0; transaction.on= 1; @@ -857,10 +857,6 @@ MYSQL_ERROR* THD::raise_condition(uint s query_cache_abort(&query_cache_tls); - /* FIXME: broken special case */ - if (no_warnings_for_error && (level == MYSQL_ERROR::WARN_LEVEL_ERROR)) - DBUG_RETURN(NULL); - /* When simulating OOM, skip writing to error log to avoid mtr errors */ DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(NULL);); === modified file 'sql/sql_class.h' --- a/sql/sql_class.h 2010-12-29 00:38:59 +0000 +++ b/sql/sql_class.h 2011-01-19 12:50:36 +0000 @@ -2147,7 +2147,6 @@ public: bool enable_slow_log; /* enable slow log for current statement */ bool abort_on_warning; bool got_warning; /* Set on call to push_warning() */ - bool no_warnings_for_error; /* no warnings on call to my_error() */ /* set during loop of derived table processing */ bool derived_tables_processing; my_bool tablespace_op; /* This is TRUE in DISCARD/IMPORT TABLESPACE */ === modified file 'sql/sql_error.cc' --- a/sql/sql_error.cc 2010-11-18 16:34:56 +0000 +++ b/sql/sql_error.cc 2011-01-19 12:50:36 +0000 @@ -558,6 +558,20 @@ MYSQL_ERROR *Warning_info::push_warning( return cond; } +MYSQL_ERROR *Warning_info::push_warning(THD *thd, const MYSQL_ERROR *sql_condition) +{ + MYSQL_ERROR *new_condition= push_warning(thd, + sql_condition->get_sql_errno(), + sql_condition->get_sqlstate(), + sql_condition->get_level(), + sql_condition->get_message_text()); + + if (new_condition) + new_condition->copy_opt_attributes(sql_condition); + + return new_condition; +} + /* Push the warning to error list if there is still room in the list === modified file 'sql/sql_error.h' --- a/sql/sql_error.h 2010-11-18 16:34:56 +0000 +++ b/sql/sql_error.h 2011-01-19 12:50:36 +0000 @@ -383,19 +383,13 @@ public: void append_warnings(THD *thd, List *src) { MYSQL_ERROR *err; - MYSQL_ERROR *copy; List_iterator_fast it(*src); /* Don't use ::push_warning() to avoid invocation of condition handlers or escalation of warnings to errors. */ while ((err= it++)) - { - copy= Warning_info::push_warning(thd, err->get_sql_errno(), err->get_sqlstate(), - err->get_level(), err->get_message_text()); - if (copy) - copy->copy_opt_attributes(err); - } + Warning_info::push_warning(thd, err); } /** @@ -461,6 +455,9 @@ public: MYSQL_ERROR::enum_warning_level level, const char* msg); + /** Add a new condition to the current list. */ + MYSQL_ERROR *push_warning(THD *thd, const MYSQL_ERROR *sql_condition); + /** Set the read only status for this statement area. This is a privileged operation, reserved for the implementation of === modified file 'sql/sql_parse.cc' --- a/sql/sql_parse.cc 2011-01-15 05:56:24 +0000 +++ b/sql/sql_parse.cc 2011-01-19 12:50:36 +0000 @@ -7274,9 +7274,16 @@ bool parse_sql(THD *thd, bool mysql_parse_status= MYSQLparse(thd) != 0; - /* Check that if MYSQLparse() failed, thd->is_error() is set. */ + /* + Check that if MYSQLparse() failed either thd->is_error() is set, or an + internal error handler is set. + + If there is an internal error handler, it might be used to catch + parsing error, so thd->is_error() is not set. + */ DBUG_ASSERT(!mysql_parse_status || + (mysql_parse_status && thd->get_internal_handler()) || (mysql_parse_status && thd->is_error())); /* Reset parser state. */ === modified file 'sql/sql_show.cc' --- a/sql/sql_show.cc 2011-01-07 12:03:21 +0000 +++ b/sql/sql_show.cc 2011-01-19 12:50:36 +0000 @@ -3412,6 +3412,27 @@ end: } +class Trigger_error_handler : public Internal_error_handler +{ +public: + bool handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl) + { + if (sql_errno == ER_PARSE_ERROR || + sql_errno == ER_TRG_NO_DEFINER || + sql_errno == ER_TRG_NO_CREATION_CTX) + return true; + + return false; + } +}; + + + /** @brief Fill I_S tables whose data are retrieved from frm files and storage engine @@ -3561,7 +3582,6 @@ int get_all_tables(THD *thd, TABLE_LIST acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0)) #endif { - thd->no_warnings_for_error= 1; List table_names; int res= make_table_name_list(thd, &table_names, lex, &lookup_field_vals, @@ -3610,9 +3630,23 @@ int get_all_tables(THD *thd, TABLE_LIST if (!(table_open_method & ~OPEN_FRM_ONLY) && !with_i_schema) { - if (!fill_schema_table_from_frm(thd, tables, schema_table, db_name, - table_name, schema_table_idx, - can_deadlock)) + /* + Here we need to filter out warnings, which can happen + during loading of triggers in fill_schema_table_from_frm(), + because we don't need those warnings to pollute output of + SELECT from I_S / SHOW-statements. + */ + + Trigger_error_handler err_handler; + thd->push_internal_handler(&err_handler); + + int res= fill_schema_table_from_frm(thd, tables, schema_table, db_name, + table_name, schema_table_idx, + can_deadlock); + + thd->pop_internal_handler(); + + if (!res) continue; } @@ -3622,7 +3656,6 @@ int get_all_tables(THD *thd, TABLE_LIST Set the parent lex of 'sel' because it is needed by sel.init_query() which is called inside make_table_list. */ - thd->no_warnings_for_error= 1; sel.parent_lex= lex; /* db_name can be changed in make_table_list() func */ if (!thd->make_lex_string(&orig_db_name, db_name->str, @@ -6664,6 +6697,51 @@ int make_schema_select(THD *thd, SELECT_ } +static bool do_fill_table(THD *thd, + TABLE_LIST *table_list, + JOIN_TAB *join_table) +{ + Warning_info wi(thd->query_id); + Warning_info *wi_saved= thd->warning_info; + + thd->warning_info= &wi; + + bool res= table_list->schema_table->fill_table( + thd, table_list, join_table->select_cond); + + thd->warning_info= wi_saved; + + // Pass an error if any. + + if (thd->stmt_da->is_error()) + { + thd->warning_info->push_warning(thd, + thd->stmt_da->sql_errno(), + thd->stmt_da->get_sqlstate(), + MYSQL_ERROR::WARN_LEVEL_ERROR, + thd->stmt_da->message()); + } + + // Pass warnings (if any). + + List_iterator_fast it(wi.warn_list()); + while (true) + { + MYSQL_ERROR *err = it++; + + if (!err) + break; + + if (err->get_level() == MYSQL_ERROR::WARN_LEVEL_ERROR) + continue; + + thd->warning_info->push_warning(thd, err); + } + + return res; +} + + /* Fill temporary schema tables before SELECT @@ -6686,7 +6764,6 @@ bool get_schema_tables_result(JOIN *join bool result= 0; DBUG_ENTER("get_schema_tables_result"); - thd->no_warnings_for_error= 1; for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++) { if (!tab->table || !tab->table->pos_in_table_list) @@ -6737,8 +6814,7 @@ bool get_schema_tables_result(JOIN *join else table_list->table->file->stats.records= 0; - if (table_list->schema_table->fill_table(thd, table_list, - tab->select_cond)) + if (do_fill_table(thd, table_list, tab)) { result= 1; join->error= 1; @@ -6750,7 +6826,6 @@ bool get_schema_tables_result(JOIN *join table_list->schema_table_state= executed_place; } } - thd->no_warnings_for_error= 0; DBUG_RETURN(result); } === modified file 'sql/sql_trigger.cc' --- a/sql/sql_trigger.cc 2010-11-29 16:27:58 +0000 +++ b/sql/sql_trigger.cc 2011-01-19 12:50:36 +0000 @@ -1219,13 +1219,12 @@ bool Table_triggers_list::check_n_load(T DBUG_RETURN(1); // EOM } - - if (!thd->no_warnings_for_error) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TRG_NO_CREATION_CTX, - ER(ER_TRG_NO_CREATION_CTX), - (const char*) db, - (const char*) table_name); + + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRG_NO_CREATION_CTX, + ER(ER_TRG_NO_CREATION_CTX), + (const char*) db, + (const char*) table_name); if (!(trg_client_cs_name= alloc_lex_string(&table->mem_root)) || !(trg_connection_cl_name= alloc_lex_string(&table->mem_root)) || @@ -1356,12 +1355,12 @@ bool Table_triggers_list::check_n_load(T MySQL, which does not support triggers definers. We should emit warning here. */ - if (!thd->no_warnings_for_error) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TRG_NO_DEFINER, ER(ER_TRG_NO_DEFINER), - (const char*) db, - (const char*) sp->m_name.str); - + + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRG_NO_DEFINER, ER(ER_TRG_NO_DEFINER), + (const char*) db, + (const char*) sp->m_name.str); + /* Set definer to the '' to correct displaying in the information schema. --===============6708179492156345776== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/alexander.nozdrin@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: alexander.nozdrin@stripped\ # 1i9rl6gunxvu9va0 # target_branch: file:///home/alik/MySQL/bzr/00/bug55847/mysql-trunk-\ # bug55847/ # testament_sha1: 37da04eda8c5ba541f8df785b4108d2534819feb # timestamp: 2011-01-19 15:50:42 +0300 # base_revision_id: anders.song@stripped\ # qiu8ubqy5j88wk70 # # Begin bundle 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 xMJjT/8XckU4UJCfvdVA --===============6708179492156345776==--