From: Jorgen Loland Date: November 15 2010 3:18pm Subject: bzr commit into mysql-5.5-bugteam branch (jorgen.loland:3124) Bug#54812 List-Archive: http://lists.mysql.com/commits/123928 X-Bug: 54812 Message-Id: <20101115151809.02D221EE1@atum21.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============2304109715650336393==" --===============2304109715650336393== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///export/home/jl208045/mysql/mysql-5.5-bugteam-54812/ based on revid:vvaintroub@stripped 3124 Jorgen Loland 2010-11-15 Bug#54812: assert in Diagnostics_area::set_ok_status during EXPLAIN Before the patch, send_eof() of some subclasses of select_result (e.g., select_send::send_eof()) could handle being called after an error had occured while others could not. The methods that were not well-behaved would trigger an ASSERT on debug builds. Release builds were not affected. Consider the following query as an example for how the ASSERT could be triggered: A user without execute privilege on f() does SELECT MAX(key1) INTO @dummy FROM t1 WHERE f() < 1; resulting in "ERROR 42000: execute command denied to user..." The server would end the query by calling send_eof(). The fact that the error had occured would make the ASSERT trigger. select_dumpvar::send_eof() was the offending method in the bug report, but the problem also applied to other subclasses of select_result. This patch uniforms send_eof() of all subclasses of select_result to handle being called after an error has occured. @ mysql-test/r/not_embedded_server.result Added test for BUG#54812 @ mysql-test/t/not_embedded_server.test Added test for BUG#54812 @ sql/sql_class.cc send_eof() of all subclasses of select_result can now handle being called after an error has occured. @ sql/sql_insert.cc send_eof() of all subclasses of select_result can now handle being called after an error has occured. Also fix call to abort() in select_create::send_eof(), which was supposed to abort the result set, not terminate the server. This call to abort() should have been changed when the function was renamed from abort_result_set() but was forgotten. New test case added by BUG#54812 covered this line and terminated server. @ sql/sql_prepare.cc send_eof() of all subclasses of select_result can now handle being called after an error has occured. @ sql/sql_update.cc send_eof() of all subclasses of select_result can now handle being called after an error has occured. modified: mysql-test/r/not_embedded_server.result mysql-test/t/not_embedded_server.test sql/sql_class.cc sql/sql_insert.cc sql/sql_prepare.cc sql/sql_update.cc === modified file 'mysql-test/r/not_embedded_server.result' --- a/mysql-test/r/not_embedded_server.result 2009-12-04 23:02:48 +0000 +++ b/mysql-test/r/not_embedded_server.result 2010-11-15 15:18:04 +0000 @@ -14,3 +14,32 @@ flush privileges; ERROR HY000: Table 'host' was not locked with LOCK TABLES unlock tables; drop table t1; +# +# Bug#54812: assert in Diagnostics_area::set_ok_status during EXPLAIN +# +CREATE USER nopriv_user@localhost; +connection: default +DROP TABLE IF EXISTS t1,t2,t3; +DROP FUNCTION IF EXISTS f; +CREATE TABLE t1 (key1 INT PRIMARY KEY); +CREATE TABLE t2 (key2 INT); +INSERT INTO t1 VALUES (1),(2); +CREATE FUNCTION f() RETURNS INT RETURN 1; +GRANT FILE ON *.* TO 'nopriv_user'@'localhost'; +FLUSH PRIVILEGES; +connection: con1 +SELECT MAX(key1) FROM t1 WHERE f() < 1 INTO OUTFILE 'mytest'; +ERROR 42000: execute command denied to user 'nopriv_user'@'localhost' for routine 'test.f' +INSERT INTO t2 SELECT MAX(key1) FROM t1 WHERE f() < 1; +ERROR 42000: execute command denied to user 'nopriv_user'@'localhost' for routine 'test.f' +SELECT MAX(key1) INTO @dummy FROM t1 WHERE f() < 1; +ERROR 42000: execute command denied to user 'nopriv_user'@'localhost' for routine 'test.f' +CREATE TABLE t3 (i INT) AS SELECT MAX(key1) FROM t1 WHERE f() < 1; +ERROR 42000: execute command denied to user 'nopriv_user'@'localhost' for routine 'test.f' +connection: default +DROP TABLE t1,t2; +DROP FUNCTION f; +DROP USER nopriv_user@localhost; +# +# End Bug#54812 +# === modified file 'mysql-test/t/not_embedded_server.test' --- a/mysql-test/t/not_embedded_server.test 2009-12-04 23:02:48 +0000 +++ b/mysql-test/t/not_embedded_server.test 2010-11-15 15:18:04 +0000 @@ -54,3 +54,57 @@ lock tables t1 read; flush privileges; unlock tables; drop table t1; + +--echo # +--echo # Bug#54812: assert in Diagnostics_area::set_ok_status during EXPLAIN +--echo # + +CREATE USER nopriv_user@localhost; + +connection default; +--echo connection: default + +--disable_warnings +DROP TABLE IF EXISTS t1,t2,t3; +DROP FUNCTION IF EXISTS f; +--enable_warnings + +CREATE TABLE t1 (key1 INT PRIMARY KEY); +CREATE TABLE t2 (key2 INT); +INSERT INTO t1 VALUES (1),(2); + +CREATE FUNCTION f() RETURNS INT RETURN 1; + +GRANT FILE ON *.* TO 'nopriv_user'@'localhost'; + +FLUSH PRIVILEGES; + +connect (con1,localhost,nopriv_user,,); +connection con1; +--echo connection: con1 + +--error ER_PROCACCESS_DENIED_ERROR +SELECT MAX(key1) FROM t1 WHERE f() < 1 INTO OUTFILE 'mytest'; + +--error ER_PROCACCESS_DENIED_ERROR +INSERT INTO t2 SELECT MAX(key1) FROM t1 WHERE f() < 1; + +--error ER_PROCACCESS_DENIED_ERROR +SELECT MAX(key1) INTO @dummy FROM t1 WHERE f() < 1; + +--error ER_PROCACCESS_DENIED_ERROR +CREATE TABLE t3 (i INT) AS SELECT MAX(key1) FROM t1 WHERE f() < 1; + +disconnect con1; +--source include/wait_until_disconnected.inc + +connection default; +--echo connection: default + +DROP TABLE t1,t2; +DROP FUNCTION f; +DROP USER nopriv_user@localhost; + +--echo # +--echo # End Bug#54812 +--echo # === modified file 'sql/sql_class.cc' --- a/sql/sql_class.cc 2010-10-23 13:09:27 +0000 +++ b/sql/sql_class.cc 2010-11-15 15:18:04 +0000 @@ -1842,8 +1842,9 @@ void select_to_file::send_error(uint err bool select_to_file::send_eof() { int error= test(end_io_cache(&cache)); - if (mysql_file_close(file, MYF(MY_WME))) - error= 1; + if (mysql_file_close(file, MYF(MY_WME)) || thd->is_error()) + error= true; + if (!error) { ::my_ok(thd,row_count); @@ -2884,6 +2885,13 @@ bool select_dumpvar::send_eof() if (! row_count) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA)); + /* + Don't send EOF if we're in error condition (which implies we've already + sent or are sending an error) + */ + if (thd->is_error()) + return true; + ::my_ok(thd,row_count); return 0; } === modified file 'sql/sql_insert.cc' --- a/sql/sql_insert.cc 2010-10-07 10:01:51 +0000 +++ b/sql/sql_insert.cc 2010-11-15 15:18:04 +0000 @@ -3506,6 +3506,9 @@ bool select_insert::send_eof() error= (thd->locked_tables_mode <= LTM_LOCK_TABLES ? table->file->ha_end_bulk_insert() : 0); + if (!error && thd->is_error()) + error= thd->stmt_da->sql_errno(); + table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); @@ -4049,7 +4052,7 @@ bool select_create::send_eof() { bool tmp=select_insert::send_eof(); if (tmp) - abort(); + abort_result_set(); else { /* @@ -4081,7 +4084,7 @@ void select_create::abort_result_set() DBUG_ENTER("select_create::abort_result_set"); /* - In select_insert::abort() we roll back the statement, including + In select_insert::abort_result_set() we roll back the statement, including truncating the transaction cache of the binary log. To do this, we pretend that the statement is transactional, even though it might be the case that it was not. === modified file 'sql/sql_prepare.cc' --- a/sql/sql_prepare.cc 2010-11-13 15:05:02 +0000 +++ b/sql/sql_prepare.cc 2010-11-15 15:18:04 +0000 @@ -2898,8 +2898,15 @@ bool Select_fetch_protocol_binary::send_ bool Select_fetch_protocol_binary::send_eof() { + /* + Don't send EOF if we're in error condition (which implies we've already + sent or are sending an error) + */ + if (thd->is_error()) + return true; + ::my_eof(thd); - return FALSE; + return false; } === modified file 'sql/sql_update.cc' --- a/sql/sql_update.cc 2010-10-07 10:01:51 +0000 +++ b/sql/sql_update.cc 2010-11-15 15:18:04 +0000 @@ -2064,7 +2064,9 @@ bool multi_update::send_eof() Does updates for the last n - 1 tables, returns 0 if ok; error takes into account killed status gained in do_updates() */ - int local_error = (table_count) ? do_updates() : 0; + int local_error= thd->is_error(); + if (!local_error) + local_error = (table_count) ? do_updates() : 0; /* if local_error is not set ON until after do_updates() then later carried out killing should not affect binlogging. --===============2304109715650336393== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/jorgen.loland@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: jorgen.loland@stripped\ # p929m6jujxlcftay # target_branch: file:///export/home/jl208045/mysql/mysql-5.5-bugteam-\ # 54812/ # testament_sha1: bd638228baeed14a593c595158272efb7f0f4148 # timestamp: 2010-11-15 16:18:08 +0100 # base_revision_id: vvaintroub@stripped\ # a08f8kyzl4eoo082 # # Begin bundle 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 Mm929LJzuNT0aOx/50f/F3JFOFCQ99hPBQ== --===============2304109715650336393==--