From 1945734c2de6853a2921e3560fe7c956ca286e0e Mon Sep 17 00:00:00 2001 From: Jorgen Loland Date: Mon, 15 Nov 2010 16:18:04 +0100 Subject: 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. --- sql/sql_class.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'sql/sql_class.cc') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index daf9217a5a1..fc4ab1bd27b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1842,8 +1842,9 @@ void select_to_file::send_error(uint errcode,const char *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; } -- cgit v1.2.1