summaryrefslogtreecommitdiff
path: root/libmysqld
diff options
context:
space:
mode:
authorKristofer Pettersson <kristofer.pettersson@sun.com>2009-07-29 22:07:08 +0200
committerKristofer Pettersson <kristofer.pettersson@sun.com>2009-07-29 22:07:08 +0200
commitfc1acef6b2b08b13388afd255aa259f6cd5e20e8 (patch)
tree5b1e05b2c4937be9524d4cae2be1ae9517d5be95 /libmysqld
parent1df8ad6c1471602abb9e11865ad2ba302a8fca08 (diff)
downloadmariadb-git-fc1acef6b2b08b13388afd255aa259f6cd5e20e8.tar.gz
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().
Diffstat (limited to 'libmysqld')
-rw-r--r--libmysqld/lib_sql.cc34
1 files changed, 21 insertions, 13 deletions
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index ec108bf372e..d4a200c07b2 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -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;
}