#At file:///export/home/jl208045/mysql/mysql-5.5-bugteam-54812/ based on revid:svoj@stripped
3120 Jorgen Loland 2010-11-11
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.
In the bug, an ASSERT triggered because
select_dumpvar::send_eof() was not well behaved after an
error had occured, 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/errors.result
Add test for BUG#54812
@ mysql-test/t/errors.test
Add test for BUG#54812
@ sql/sql_class.cc
Make send_eof() of all subclasses of select_result handle being
called after an error has occured.
@ sql/sql_insert.cc
Make send_eof() of all subclasses of select_result handle being
called after an error has occured.
@ sql/sql_update.cc
Make send_eof() of all subclasses of select_result handle being
called after an error has occured.
modified:
mysql-test/r/errors.result
mysql-test/t/errors.test
sql/sql_class.cc
sql/sql_insert.cc
sql/sql_update.cc
=== modified file 'mysql-test/r/errors.result'
--- a/mysql-test/r/errors.result 2010-11-04 12:36:36 +0000
+++ b/mysql-test/r/errors.result 2010-11-11 12:06:45 +0000
@@ -146,3 +146,29 @@ ERROR 22003: BIGINT value is out of rang
#
# End Bug#57882
#
+# Bug#54812: assert in Diagnostics_area::set_ok_status during EXPLAIN
+#
+CREATE USER nopriv_user@localhost;
+connection: default
+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#57882
+#
=== modified file 'mysql-test/t/errors.test'
--- a/mysql-test/t/errors.test 2010-11-04 12:36:36 +0000
+++ b/mysql-test/t/errors.test 2010-11-11 12:06:45 +0000
@@ -171,3 +171,47 @@ SELECT UPDATEXML(-73 * -2465717823867977
--echo #
--echo # End Bug#57882
--echo #
+--echo # Bug#54812: assert in Diagnostics_area::set_ok_status during EXPLAIN
+--echo #
+
+CREATE USER nopriv_user@localhost;
+
+connection default;
+--echo connection: default
+
+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 1370
+SELECT MAX(key1) FROM t1 WHERE f() < 1 INTO OUTFILE 'mytest';
+
+--error 1370
+INSERT INTO t2 SELECT MAX(key1) FROM t1 WHERE f() < 1;
+
+--error 1370
+SELECT MAX(key1) INTO @dummy FROM t1 WHERE f() < 1;
+
+--error 1370
+CREATE TABLE t3 (i INT) AS SELECT MAX(key1) FROM t1 WHERE f() < 1;
+
+connection default;
+--echo connection: default
+
+DROP TABLE t1,t2;
+DROP FUNCTION f;
+DROP USER nopriv_user@localhost;
+
+--echo #
+--echo # End Bug#57882
+--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-11 12:06:45 +0000
@@ -1841,6 +1841,13 @@ void select_to_file::send_error(uint err
bool select_to_file::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;
+
int error= test(end_io_cache(&cache));
if (mysql_file_close(file, MYF(MY_WME)))
error= 1;
@@ -2881,6 +2888,13 @@ bool select_dumpvar::send_data(List<Item
bool select_dumpvar::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;
+
if (! row_count)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
=== 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-11 12:06:45 +0000
@@ -3504,6 +3504,13 @@ bool select_insert::send_eof()
DBUG_PRINT("enter", ("trans_table=%d, table_type='%s'",
trans_table, table->file->table_type()));
+ /*
+ 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())
+ DBUG_RETURN(TRUE);
+
error= (thd->locked_tables_mode <= LTM_LOCK_TABLES ?
table->file->ha_end_bulk_insert() : 0);
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
@@ -4047,6 +4054,13 @@ void select_create::send_error(uint errc
bool select_create::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;
+
bool tmp=select_insert::send_eof();
if (tmp)
abort();
=== 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-11 12:06:45 +0000
@@ -2061,6 +2061,13 @@ bool multi_update::send_eof()
thd_proc_info(thd, "updating reference tables");
/*
+ 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;
+
+ /*
Does updates for the last n - 1 tables, returns 0 if ok;
error takes into account killed status gained in do_updates()
*/
Attachment: [text/bzr-bundle] bzr/jorgen.loland@oracle.com-20101111120645-v1r3u5wue91bxci6.bundle