mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +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:
@ -803,11 +803,11 @@ MYSQL_DATA *THD::alloc_new_dataset()
|
||||
*/
|
||||
|
||||
static
|
||||
void
|
||||
bool
|
||||
write_eof_packet(THD *thd, uint server_status, uint total_warn_count)
|
||||
{
|
||||
if (!thd->mysql) // bootstrap file handling
|
||||
return;
|
||||
return FALSE;
|
||||
/*
|
||||
The following test should never be true, but it's better to do it
|
||||
because if 'is_fatal_error' is set the server is not going to execute
|
||||
@ -822,6 +822,7 @@ write_eof_packet(THD *thd, uint server_status, uint total_warn_count)
|
||||
*/
|
||||
thd->cur_data->embedded_info->warning_count=
|
||||
(thd->spcont ? 0 : min(total_warn_count, 65535));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@ -1032,31 +1033,34 @@ bool Protocol_binary::write()
|
||||
@sa Server implementation of net_send_ok in protocol.cc for
|
||||
description of the arguments.
|
||||
|
||||
@return The function does not return errors.
|
||||
@return
|
||||
@retval TRUE An error occurred
|
||||
@retval FALSE Success
|
||||
*/
|
||||
|
||||
void
|
||||
bool
|
||||
net_send_ok(THD *thd,
|
||||
uint server_status, uint total_warn_count,
|
||||
ha_rows affected_rows, ulonglong id, const char *message)
|
||||
{
|
||||
DBUG_ENTER("emb_net_send_ok");
|
||||
MYSQL_DATA *data;
|
||||
bool error;
|
||||
MYSQL *mysql= thd->mysql;
|
||||
|
||||
if (!mysql) // bootstrap file handling
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(FALSE);
|
||||
if (!(data= thd->alloc_new_dataset()))
|
||||
return;
|
||||
return TRUE;
|
||||
data->embedded_info->affected_rows= affected_rows;
|
||||
data->embedded_info->insert_id= id;
|
||||
if (message)
|
||||
strmake(data->embedded_info->info, message,
|
||||
sizeof(data->embedded_info->info)-1);
|
||||
|
||||
write_eof_packet(thd, server_status, total_warn_count);
|
||||
error= write_eof_packet(thd, server_status, total_warn_count);
|
||||
thd->cur_data= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
@ -1065,18 +1069,21 @@ net_send_ok(THD *thd,
|
||||
|
||||
@sa net_send_ok
|
||||
|
||||
@return This function does not return errors.
|
||||
@return
|
||||
@retval TRUE An error occurred
|
||||
@retval FALSE Success
|
||||
*/
|
||||
|
||||
void
|
||||
bool
|
||||
net_send_eof(THD *thd, uint server_status, uint total_warn_count)
|
||||
{
|
||||
write_eof_packet(thd, server_status, total_warn_count);
|
||||
bool error= write_eof_packet(thd, server_status, total_warn_count);
|
||||
thd->cur_data= 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
|
||||
bool net_send_error_packet(THD *thd, uint sql_errno, const char *err)
|
||||
{
|
||||
MYSQL_DATA *data= thd->cur_data;
|
||||
struct embedded_query_result *ei;
|
||||
@ -1084,7 +1091,7 @@ void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
|
||||
if (!thd->mysql) // bootstrap file handling
|
||||
{
|
||||
fprintf(stderr, "ERROR: %d %s\n", sql_errno, err);
|
||||
return;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!data)
|
||||
@ -1096,6 +1103,7 @@ void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
|
||||
strmov(ei->sqlstate, mysql_errno_to_sqlstate(sql_errno));
|
||||
ei->server_status= thd->server_status;
|
||||
thd->cur_data= 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user