mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Bug#44521 Executing a stored procedure as a prepared statement can sometimes cause
an assertion in a debug build. The reason is that the C API doesn't support multiple result sets for prepared statements and attempting to execute a stored routine which returns multiple result sets sometimes lead to a network error. The network error sets the diagnostic area prematurely which later leads to the assert when an attempt is made to set a second server state. This patch fixes the issue by changing the scope of the error code returned by sp_instr_stmt::execute() to include any error which happened during the execution. To assure that Diagnostic_area::is_sent really mean that the message was sent all network related functions are checked for return status. libmysqld/lib_sql.cc: * Changed prototype to return success/failure status on net_send_error_packet(), net_send_ok(), net_send_eof(), write_eof_packet(). mysql-test/r/sp_notembedded.result: * Added test case for bug 44521 mysql-test/t/sp_notembedded.test: * Added test case for bug 44521 sql/protocol.cc: * Changed prototype to return success/failure status on net_send_error_packet(), net_send_ok(), net_send_eof(), write_eof_packet(). sql/protocol.h: * Changed prototype to return success/failure status on net_send_error_packet(), net_send_ok(), net_send_eof(), write_eof_packet(). sql/sp_head.cc: * Changed prototype to return success/failure status on net_send_error_packet(), net_send_ok(), net_send_eof(), write_eof_packet().
This commit is contained in:
@ -249,3 +249,25 @@ DROP PROCEDURE p1;
|
||||
DELETE FROM mysql.user WHERE User='mysqltest_1';
|
||||
FLUSH PRIVILEGES;
|
||||
set @@global.concurrent_insert= @old_concurrent_insert;
|
||||
#
|
||||
# Bug#44521 Prepared Statement: CALL p() - crashes: `! thd->main_da.is_sent' failed et.al.
|
||||
#
|
||||
SELECT GET_LOCK('Bug44521', 0);
|
||||
GET_LOCK('Bug44521', 0)
|
||||
1
|
||||
** Connection con1
|
||||
CREATE PROCEDURE p()
|
||||
BEGIN
|
||||
SELECT 1;
|
||||
SELECT GET_LOCK('Bug44521', 100);
|
||||
SELECT 2;
|
||||
END$
|
||||
CALL p();;
|
||||
** Default connection
|
||||
SELECT RELEASE_LOCK('Bug44521');
|
||||
RELEASE_LOCK('Bug44521')
|
||||
1
|
||||
DROP PROCEDURE p;
|
||||
# ------------------------------------------------------------------
|
||||
# -- End of 5.1 tests
|
||||
# ------------------------------------------------------------------
|
||||
|
@ -380,3 +380,39 @@ set @@global.concurrent_insert= @old_concurrent_insert;
|
||||
# Wait till all disconnects are completed
|
||||
--source include/wait_until_count_sessions.inc
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Bug#44521 Prepared Statement: CALL p() - crashes: `! thd->main_da.is_sent' failed et.al.
|
||||
--echo #
|
||||
SELECT GET_LOCK('Bug44521', 0);
|
||||
--connect (con1,localhost,root,,)
|
||||
--echo ** Connection con1
|
||||
delimiter $;
|
||||
CREATE PROCEDURE p()
|
||||
BEGIN
|
||||
SELECT 1;
|
||||
SELECT GET_LOCK('Bug44521', 100);
|
||||
SELECT 2;
|
||||
END$
|
||||
delimiter ;$
|
||||
--send CALL p();
|
||||
--connection default
|
||||
--echo ** Default connection
|
||||
let $wait_condition=
|
||||
SELECT count(*) = 1 FROM information_schema.processlist
|
||||
WHERE state = "User lock" AND info = "SELECT GET_LOCK('Bug44521', 100)";
|
||||
--source include/wait_condition.inc
|
||||
let $conid =
|
||||
`SELECT id FROM information_schema.processlist
|
||||
WHERE state = "User lock" AND info = "SELECT GET_LOCK('Bug44521', 100)"`;
|
||||
dirty_close con1;
|
||||
SELECT RELEASE_LOCK('Bug44521');
|
||||
let $wait_condition=
|
||||
SELECT count(*) = 0 FROM information_schema.processlist
|
||||
WHERE id = $conid;
|
||||
--source include/wait_condition.inc
|
||||
DROP PROCEDURE p;
|
||||
|
||||
--echo # ------------------------------------------------------------------
|
||||
--echo # -- End of 5.1 tests
|
||||
--echo # ------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user