From: Jon Olav Hauglid Date: July 22 2010 10:37am Subject: bzr commit into mysql-5.1-bugteam branch (jon.hauglid:3500) Bug#54106 List-Archive: http://lists.mysql.com/commits/114126 X-Bug: 54106 Message-Id: <201007221038.o6LIj4Km017488@rcsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============6173557119500945498==" --===============6173557119500945498== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///export/home/x/mysql-5.1-bugteam-bug54106/ based on revid:georgi.kodinov@stripped 3500 Jon Olav Hauglid 2010-07-22 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_select.cc sql/sql_update.cc === modified file 'mysql-test/r/insert.result' --- a/mysql-test/r/insert.result 2009-07-10 23:12:13 +0000 +++ b/mysql-test/r/insert.result 2010-07-22 10:37:51 +0000 @@ -639,3 +639,18 @@ CREATE TABLE t2(f1 CHAR(1)); INSERT INTO t2 SELECT f1 FROM t1; DROP TABLE t1, t2; End of 5.0 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 2009-07-10 23:12:13 +0000 +++ b/mysql-test/t/insert.test 2010-07-22 10:37:51 +0000 @@ -499,3 +499,28 @@ DROP TABLE t1, t2; --echo End of 5.0 tests. + +--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-03-29 02:32:30 +0000 +++ b/sql/sql_insert.cc 2010-07-22 10:37:51 +0000 @@ -2961,6 +2961,9 @@ 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. */ + lex->current_select->no_error= FALSE; res= check_insert_fields(thd, table_list, *fields, values, !insert_into_view, &map) || setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0); === modified file 'sql/sql_select.cc' --- a/sql/sql_select.cc 2010-07-19 18:34:28 +0000 +++ b/sql/sql_select.cc 2010-07-22 10:37:51 +0000 @@ -6819,6 +6819,8 @@ bool error_if_full_join(JOIN *join) { if (tab->type == JT_ALL && (!tab->select || !tab->select->quick)) { + /* This error should not be ignored. */ + join->select_lex->no_error= FALSE; my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); return(1); === modified file 'sql/sql_update.cc' --- a/sql/sql_update.cc 2010-07-19 09:03:52 +0000 +++ b/sql/sql_update.cc 2010-07-22 10:37:51 +0000 @@ -1199,56 +1199,6 @@ reopen_tables: } -/** - 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_error(uint sql_errno, - const char *message, - MYSQL_ERROR::enum_warning_level level, - THD *thd) - { - if (level == MYSQL_ERROR::WARN_LEVEL_ERROR && - sql_errno == ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE) - - { - thd->main_da.set_error_status(thd, sql_errno, message); - 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 */ @@ -1278,11 +1228,6 @@ bool mysql_multi_update(THD *thd, List total_list; - Safe_dml_handler handler; - bool using_handler= thd->options & 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, @@ -1292,21 +1237,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)); --===============6173557119500945498== 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-5.1-bugteam-bug54106/ # testament_sha1: 7800fed5af57f6249af3d90aeb5128a23b73cdf4 # timestamp: 2010-07-22 12:37:55 +0200 # base_revision_id: georgi.kodinov@stripped\ # a7ots7um5qzzarxc # # Begin bundle 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 --===============6173557119500945498==--