From: Jon Olav Hauglid Date: July 22 2010 10:35am Subject: bzr commit into mysql-5.1-bugteam branch (jon.hauglid:3500) Bug#54106 List-Archive: http://lists.mysql.com/commits/114125 X-Bug: 54106 Message-Id: <201007221036.o6M6DuJU019781@rcsinet13.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============3366827702702210149==" --===============3366827702702210149== 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. 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. 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. 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:34: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-07-22 10:34: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-07-22 10:34: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-07-22 10:34: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-07-22 10:34: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)); --===============3366827702702210149== 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: 7cee569925e7d9f9b7c6f6ab639899c88e58fff3 # timestamp: 2010-07-22 12:35:06 +0200 # base_revision_id: georgi.kodinov@stripped\ # a7ots7um5qzzarxc # # Begin bundle IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWZ+1gg4ABn9fgBCQWPf//3/9 38C////wYA23X2gBQBltqqKYwBpQCqAAAABoKMcNNMjEYTTAQwCaYRgmJkNMjQ0AlIIwjUw00TQ1 SfpqYUNNAyMajeqBk0NGhw00yMRhNMBDAJphGCYmQ0yNDQCRRqT1GRpT2pPZRPU09QD1PUaNH6hA aAAAHDTTIxGE0wEMAmmEYJiZDTI0NAFShAgARpNkBE8JomkjyankmZJiZomyjAMK56h8FXgGeeej tjF61KT3fCvr4r2OWFvLiGmzL51a9RSHER+I9zzCtvne76rFPNhZXEBUG+G23OBIcrsFIiNCuQOC 4ydiTURwsWjcHt6h/IR6hQNp2iYpwUnYczMfgbEcCn8+L+CaUoUGLP3EfBG1DbQ22xhZ8ktkWXBm DhiMHsnJzpMr6X4MLUXr7fxMbnupMFMKVo7LufPk6D5H1Hgb+s+18vo/12OIdo/UyHwXNZ4ms1m4 7ZP4pgnoVVJ+TWo8iw30Tm6sinE8RvKmsrsNh/Y23HJMCpiayi8qaC4ZH6GJMTD9CpY6KmJFsSxX MYF5QYnSWjSfp7vXPehtNNkzFDq3mPIuMjAyHrGY1n8zOWbsjeWKF5llGBgXlDeXJeWLyV6NJ9xo Nsn9KUo+bgaEUzjOYmg0m83koYFjUVNpu4lC4Zy8mguM5cNBvMRiXFD6p6vpdhjOh5F4zkcuStFN 0o7W9BNpI28rY22MNBQJDebqyHRTvzYD74w7jz66Sn2szpRcZDE6jUchefY3I6EzHokeUv4q8n6x MKeHOZaPwj7SkY4U+Bjek2PbsrL00uGDn1nYfM0lFJmKUUFUlS47CwOaJ8Nmf35udKKHVK8KIUC6 XI+tm/6pF/RjG6OF8iU6ileY8k2F5FngsVbsaxFkvShTIobvJVLqJLUxffa9pXi0wkOpWYs9e+9W yZ1kzphTKUaf9quxnamWOWHi3SasNt9K8UXsbVv12wtb1XnmUOfy2TMifv4upZNKTL+WqTudfdhK 23MXJmKy9hyi0JZi733t3lIY2BAsMRRIxO56I3go1ET40jjxSYXZ1Qzx329szvEnKxWxsoVkha0q MOOSEzXkwQgfG2rppTPptZbYWKNutUi/oc0l822YLJKFXm0qXG0azhrmjKVGMRobzhIyxXSSjgwk BeajZxjSCfF5gdMEsPkfI3SLsFJGRIjUMLRFjsBbKQC6tkmCi5hHSucnBVm7LLMJe1MlzGrOxmy/ VPsu34XVokjQfbaXImBRr78gXarm5cN2FYiPH3HlPe6WdJh1Vz02skvyWYLLnkr+0v4LMtTPswbb Y7LRpdrZQm1ZlKZa64PrMU9QnCyziTgR4S7M9wZEBjRN0uMySjpWbulqWaOn3PF2Mvg9J0YNFc6q a+A1otGYsG34qVqMChWT4QrNJGxVZmOO/SKBIsI7t8kSPcOODShfTKhJOwf06OYxlBGjhRJSAUPS j8PtJPDGOIuAtHYolZYZDx+o8gcEUInFMjQszaGG1fGila1ihpVVw2LKacOKzjjtqs+PbEquLWSr HRndA3YixTC9thu8FcZuVMEH1NKlDR1tW7zCIy4i+BXIUbdKhIpASphzbphMkVjCfjgt/gM7BKgR hJFYvWE9MJ6TCWoWe2pSopSSgKTSeR1CrApleJkI8xKbJuS5hYbjdcZGNtM2IvSJLi50YYNJVHbf Emkq+cXsP2HAZ1qBtgz5in1rTgn6RLollESxU/1EtE/uf/FD+iLmpaqyUVKn5qNP9Il6JoRL0TOU STREzlJcopE/aJQit5+sTciWaYlCP6lD/CUMBQnoP2VHDAnCJ8koidKWGo2D/ZFUHF+xnJYdQ1EW yOiJVKibn6mBqQZykFHFiiZkk4xNCxmTIoSiJeqLJsWVNLGJwLFBSKGJmLJM8TQuiaUT8EnP4Ujn H0n8aizx/Gt8ojxSlZe1H9l/+SwsPte30wzk+9+59fw9Bf+B50iflaeJ19RAqUenWzQPe1EBm8NA VrHRlSBgNAuPy/kzDHTGe2BQyoVP+3RqiXn5fm3zIqSZDQLSH49kSmY7ZqRaP2vCzuggF+eZDIRP RtUe2soC+ql86/dEyP1OA4Wh+52lhf8OtCih0OtJmnqeLZgeSqp3KD6Qcph51T82xbqcF70spuV7 DRBxKE+EOZezsDuPJ1v7V6jqLHiYY6Y1DG1Y+VpC4mSa5I91h/6xhh3v9/BcaKQaSzAtBuiiPB2d nNzYObwa2rnrkvZ5NNszOxka1AuTm8J0ZO9rbzU2Fd7ezJ1Tw9Xf7NTbG+PqcKM3E5x2u9jwPQ8j eVFIoShQj2L48ipRGBeXixUwOs9j6pmE5vBn8/C5m0O3D02eqvy+Y3naQ6HzFSdL+VEKIczmo0UL 0QvAUNDWdbHI4uo951GUXmEUOZUqMbdB4FxA0oRNefbFW9xzSg86IdA947lrvV5O9ZOYUQ3ZhySb PNLztMioqmVhRPfKSd07BmLjs7/JdeeZiS7R/XWfvO8coqigXwPfQ+R4m7fwhY+43QtfMRtKjikv kX5eY8T+BU8kdjy8PR5rp8Hqp6sny8+sVa08Ws2pylDn+sdsZobHi0Htc86+T0W5NPyfP0MoKFaM aaXRDwoM81k0tBL5jB8bSHGZ/rev1tj63kz+94z2dD2hpU+JPWHxPoFSfIoCh7sIsLy4qUhYwXOn vkYSvXKtV7n1/FJeXFuno6vfIqFeUVJj4dqbjNEtIeeG13nNM8kqazI0JrZ5H/J58TkOrKLGJUo3 ThP3dClGgtQ0efPRoHtpfZEyoV09IuOlyF56XupKmePd6fCrJ7Or/O/+73JSK9OOTveqnttbZXa1 8/m7Bw9fWcmk86Z9DYT6ipmk3F4vyse9L4aj8r3zdzOyoetI1SFEVWhUqeETfk+MGJPPdM7MVHlY 2N249Ps55jdqoYJGjy0SjkkurN5UvjBFh35nY7ammZaDnM+SZzRLsl37TUsaCmeiZoVFYpnpBtSU TRrjTgYxQXJjQwwLu+khn82ZMsxifckob5Ch1FJmlpjOCyTxUNYilJPBWefH1OERpKE6JVJoFkwl ffrDo7U/MpJH8in8/A2m3EKScND6O09yxqKRNxRJTtkN43FkOM8nVN5lBhjMZHd770+6cl8/E9HZ 1STdwpFJKGSTwl6drA1appcjvxN2asxaBpu8VxvybpW8617T9+xDLVPGVwOsoHOpWChah60j3Lkk 6qFhvLiosKFEWMUupJ/x8p0ccEyylM9OBMxwhse3YeOaOqY4lHxmQzaK7gn+EyZjNqkh+VBaD8Ko K6ZqVnFY2l5eaBQUolxO8oXFxUlCpfSh797dMqd9fPshpcM+dpG6hQn9ek+XuJy0SHUkxLhc+dDG LJgbBNFptuStsLQxRi22227A0LeE5DY2SLkMJCiHeakzG0Zi+e1tbpcnWaE7EdJ0l5pLqpUvOJpL C4fuyslxZZm2XxYyKmN8oTYk9b892EYY1/BFe+kjWykuscrI0HKPqk2LIpSJHEoZhQ/GY8LjZxdJ d9EmUCqaxum7feS18zVk0Gi8e93LOlSsDWVGPSHhBjrQDStLSZkyrlV4Su8XXU6Qc2yHM03wayl8 6HzW/HbKuu+d5t1X0WHFsbHKrpUy97g5EmShrKDivdJ3HwdLrbUn2NV/BJmd07i5jI9lzgUoZ80W YdDW+jwZksPqO44GZgtOZxHCFCwv2FmXrESOR5LTzn3J4H/i7kinChIT9rBBwA== --===============3366827702702210149==--