From: Jorgen Loland Date: November 12 2010 1:40pm Subject: bzr commit into mysql-5.5-bugteam branch (jorgen.loland:3121) Bug#54812 List-Archive: http://lists.mysql.com/commits/123727 X-Bug: 54812 Message-Id: <20101112134047.BE63A18DF@atum21.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============8279709967082593368==" --===============8279709967082593368== 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 3121 Jorgen Loland 2010-11-12 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. @ 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-12 13:40:43 +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-12 13:40:43 +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-12 13:40:43 +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-12 13:40:43 +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-03 14:15:18 +0000 +++ b/sql/sql_prepare.cc 2010-11-12 13:40:43 +0000 @@ -2898,6 +2898,13 @@ 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; } === 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-12 13:40:43 +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. --===============8279709967082593368== 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\ # 8vzppl4ksyq0jkt5 # target_branch: file:///export/home/jl208045/mysql/mysql-5.5-bugteam-\ # 54812/ # testament_sha1: 61d134c27ba13f7bc5e52c96b54487a9e6e12c46 # timestamp: 2010-11-12 14:40:47 +0100 # base_revision_id: vvaintroub@stripped\ # hy6dp03mkujaucde # # Begin bundle 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 --===============8279709967082593368==--