From: Jon Olav Hauglid Date: July 21 2010 10:35am Subject: bzr commit into mysql-trunk-runtime branch (jon.hauglid:3081) Bug#54106 List-Archive: http://lists.mysql.com/commits/114027 X-Bug: 54106 Message-Id: <201007211036.o6L8Ketd024755@acsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1363467130573968176==" --===============1363467130573968176== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///export/home/x/mysql-trunk-runtime-bug54106/ based on revid:jon.hauglid@stripped 3081 Jon Olav Hauglid 2010-07-21 Bug #54106 assert in Protocol::end_statement, INSERT IGNORE ... SELECT ... UNION SELECT ... This assert was triggered by INSERT IGNORE ... SELECT. The assert checks that a statement either sends OK or an error to the client. If the bug was triggered on release builds, it caused OK to be sent to the client instead of the correct error message (in this case ER_FIELD_SPECIFIED_TWICE). The reason the assert was triggered, was that lex->no_error was set to TRUE during JOIN::optimize() because of IGNORE. This causes all errors to be ignored. However, not all errors can be ignored. Some, such as ER_FIELD_SPECIFIED_TWICE will cause the INSERT to fail no matter what. But since lex->no_error was set, the critical errors were ignored, the INSERT failed and neither OK nor the error message was sent to the client. This patch fixes the problem by temporarily turning off lex->no_error in places where errors cannot be ignored during processing of INSERT ... SELECT. Test case added to insert.test. modified: mysql-test/r/insert.result mysql-test/t/insert.test sql/sql_insert.cc sql/sql_update.cc === modified file 'mysql-test/r/insert.result' --- a/mysql-test/r/insert.result 2010-04-11 06:52:42 +0000 +++ b/mysql-test/r/insert.result 2010-07-21 10:35:04 +0000 @@ -671,3 +671,18 @@ drop table t1; # # End of 5.4 tests # +# +# Bug#54106 assert in Protocol::end_statement, +# INSERT IGNORE ... SELECT ... UNION SELECT ... +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 (a, a) VALUES (1, 1); +ERROR 42000: Column 'a' specified twice +INSERT IGNORE t1 (a, a) VALUES (1, 1); +ERROR 42000: Column 'a' specified twice +INSERT IGNORE t1 (a, a) SELECT 1,1; +ERROR 42000: Column 'a' specified twice +INSERT IGNORE t1 (a, a) SELECT 1,1 UNION SELECT 2,2; +ERROR 42000: Column 'a' specified twice +DROP TABLE t1; === modified file 'mysql-test/t/insert.test' --- a/mysql-test/t/insert.test 2010-04-11 06:52:42 +0000 +++ b/mysql-test/t/insert.test 2010-07-21 10:35:04 +0000 @@ -525,3 +525,29 @@ drop table t1; --echo # --echo # End of 5.4 tests --echo # + + +--echo # +--echo # Bug#54106 assert in Protocol::end_statement, +--echo # INSERT IGNORE ... SELECT ... UNION SELECT ... +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (a INT); + +--error ER_FIELD_SPECIFIED_TWICE +INSERT INTO t1 (a, a) VALUES (1, 1); +# Verify that ER_FIELD_SPECIFIED_TWICE is not ignorable +--error ER_FIELD_SPECIFIED_TWICE +INSERT IGNORE t1 (a, a) VALUES (1, 1); + +--error ER_FIELD_SPECIFIED_TWICE +INSERT IGNORE t1 (a, a) SELECT 1,1; +# Used to cause an assert +--error ER_FIELD_SPECIFIED_TWICE +INSERT IGNORE t1 (a, a) SELECT 1,1 UNION SELECT 2,2; + +DROP TABLE t1; === modified file 'sql/sql_insert.cc' --- a/sql/sql_insert.cc 2010-07-08 21:20:08 +0000 +++ b/sql/sql_insert.cc 2010-07-21 10:35:04 +0000 @@ -3057,9 +3057,14 @@ select_insert::prepare(List &value we are fixing fields from insert list. */ lex->current_select= &lex->select_lex; + + /* Errors during check_insert_fields() should not be ignored. */ + bool no_error_save= lex->current_select->no_error; + lex->current_select->no_error= FALSE; res= (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0) || check_insert_fields(thd, table_list, *fields, values, !insert_into_view, 1, &map)); + lex->current_select->no_error= no_error_save; if (!res && fields->elements) { === modified file 'sql/sql_update.cc' --- a/sql/sql_update.cc 2010-06-22 20:32:29 +0000 +++ b/sql/sql_update.cc 2010-07-21 10:35:04 +0000 @@ -1137,57 +1137,6 @@ int mysql_multi_update_prepare(THD *thd) } -/** - Implementation of the safe update options during UPDATE IGNORE. This syntax - causes an UPDATE statement to ignore all errors. In safe update mode, - however, we must never ignore the ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE. There - is a special hook in my_message_sql that will otherwise delete all errors - when the IGNORE option is specified. - - In the future, all IGNORE handling should be used with this class and all - traces of the hack outlined below should be removed. - - - The parser detects IGNORE option and sets thd->lex->ignore= 1 - - - In JOIN::optimize, if this is set, then - thd->lex->current_select->no_error gets set. - - - In my_message_sql(), if the flag above is set then any error is - unconditionally converted to a warning. - - We are moving in the direction of using Internal_error_handler subclasses - to do all such error tweaking, please continue this effort if new bugs - appear. - */ -class Safe_dml_handler : public Internal_error_handler { - -private: - bool m_handled_error; - -public: - explicit Safe_dml_handler() : m_handled_error(FALSE) {} - - 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 (level == MYSQL_ERROR::WARN_LEVEL_ERROR && - sql_errno == ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE) - { - thd->stmt_da->set_error_status(thd, sql_errno, msg, sqlstate); - m_handled_error= TRUE; - return TRUE; - } - return FALSE; - } - - bool handled_error() { return m_handled_error; } - -}; - /* Setup multi-update handling and call SELECT to do the join */ @@ -1221,11 +1170,6 @@ bool mysql_multi_update(THD *thd, List total_list; - Safe_dml_handler handler; - bool using_handler= thd->variables.option_bits & OPTION_SAFE_UPDATES; - if (using_handler) - thd->push_internal_handler(&handler); - res= mysql_select(thd, &select_lex->ref_pointer_array, table_list, select_lex->with_wild, total_list, @@ -1235,21 +1179,9 @@ bool mysql_multi_update(THD *thd, OPTION_SETUP_TABLES_DONE, *result, unit, select_lex); - if (using_handler) - { - Internal_error_handler *top_handler; - top_handler= thd->pop_internal_handler(); - DBUG_ASSERT(&handler == top_handler); - } - DBUG_PRINT("info",("res: %d report_error: %d", res, (int) thd->is_error())); res|= thd->is_error(); - /* - Todo: remove below code and make Safe_dml_handler do error processing - instead. That way we can return the actual error instead of - ER_UNKNOWN_ERROR. - */ - if (unlikely(res) && (!using_handler || !handler.handled_error())) + if (unlikely(res)) { /* If we had a another error reported earlier then this will be ignored */ (*result)->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR)); @@ -1513,8 +1445,16 @@ multi_update::initialize_tables(JOIN *jo TABLE_LIST *table_ref; DBUG_ENTER("initialize_tables"); - if ((thd->variables.option_bits & OPTION_SAFE_UPDATES) && error_if_full_join(join)) - DBUG_RETURN(1); + if (thd->variables.option_bits & OPTION_SAFE_UPDATES) + { + /* This error should not be ignored. */ + bool no_error_save= thd->lex->current_select->no_error; + thd->lex->current_select->no_error= FALSE; + bool error= error_if_full_join(join); + thd->lex->current_select->no_error= no_error_save; + if (error) + DBUG_RETURN(TRUE); + } main_table=join->join_tab->table; table_to_update= 0; --===============1363467130573968176== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/jon.hauglid@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: jon.hauglid@stripped # target_branch: file:///export/home/x/mysql-trunk-runtime-bug54106/ # testament_sha1: c526c2de86b22a3e1209dbac4191e77bcf0f9610 # timestamp: 2010-07-21 12:35:09 +0200 # base_revision_id: jon.hauglid@stripped\ # xn93j8pwxa1lvca5 # # Begin bundle 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 --===============1363467130573968176==--