From: Jon Olav Hauglid Date: August 9 2010 11:40am Subject: bzr commit into mysql-5.1-bugteam branch (jon.hauglid:3479) Bug#54106 List-Archive: http://lists.mysql.com/commits/115309 X-Bug: 54106 Message-Id: <201008091141.o79BfBNs018189@rcsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============6309503838182690120==" --===============6309503838182690120== 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 3479 Jon Olav Hauglid 2010-08-09 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-08-09 11:39:59 +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-08-09 11:39:59 +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-08-09 11:39:59 +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-08-09 11:39:59 +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-08-09 11:39:59 +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)); --===============6309503838182690120== 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: 64bb8772cd9bcd1d0d4f8cd6b1d94d632cc5c76b # timestamp: 2010-08-09 13:40:04 +0200 # base_revision_id: georgi.kodinov@stripped\ # wu8dpos5rtoglro3 # # Begin bundle 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 --===============6309503838182690120==--