mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
A fix and a test case for Bug#10794 "mysql_stmt_attr_set no
open cursor after mysql_stmt_execute" + post-review fixes. The bug was caused by wrong flags in stmt->server_status on the client side: if there was no cursor, the server didn't send server_status flags to the client, and the old flags were used to set up the fetch function of a statement. Consequently, stmt_read_row_from_cursor was used when there was no cursor. The fix fixes the server to always send server flags to the client.
This commit is contained in:
@ -28,6 +28,7 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
|
||||
static void write_eof_packet(THD *thd, NET *net);
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
bool Protocol::net_store_data(const char *from, uint length)
|
||||
@ -362,43 +363,52 @@ static char eof_buff[1]= { (char) 254 }; /* Marker for end of fields */
|
||||
*/
|
||||
|
||||
void
|
||||
send_eof(THD *thd, bool no_flush)
|
||||
send_eof(THD *thd)
|
||||
{
|
||||
NET *net= &thd->net;
|
||||
DBUG_ENTER("send_eof");
|
||||
if (net->vio != 0 && !net->no_send_eof)
|
||||
{
|
||||
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
|
||||
{
|
||||
uchar buff[5];
|
||||
/* Don't send warn count during SP execution, as the warn_list
|
||||
is cleared between substatements, and mysqltest gets confused */
|
||||
uint tmp= (thd->spcont ? 0 : min(thd->total_warn_count, 65535));
|
||||
buff[0]=254;
|
||||
int2store(buff+1, tmp);
|
||||
/*
|
||||
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
|
||||
other queries (see the if test in dispatch_command / COM_QUERY)
|
||||
*/
|
||||
if (thd->is_fatal_error)
|
||||
thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
|
||||
int2store(buff+3, thd->server_status);
|
||||
VOID(my_net_write(net,(char*) buff,5));
|
||||
VOID(net_flush(net));
|
||||
}
|
||||
else
|
||||
{
|
||||
VOID(my_net_write(net,eof_buff,1));
|
||||
if (!no_flush)
|
||||
VOID(net_flush(net));
|
||||
}
|
||||
write_eof_packet(thd, net);
|
||||
VOID(net_flush(net));
|
||||
thd->net.no_send_error= 1;
|
||||
DBUG_PRINT("info", ("EOF sent, so no more error sending allowed"));
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Format EOF packet according to the current protocol and
|
||||
write it to the network output buffer.
|
||||
*/
|
||||
|
||||
static void write_eof_packet(THD *thd, NET *net)
|
||||
{
|
||||
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
|
||||
{
|
||||
uchar buff[5];
|
||||
/*
|
||||
Don't send warn count during SP execution, as the warn_list
|
||||
is cleared between substatements, and mysqltest gets confused
|
||||
*/
|
||||
uint tmp= (thd->spcont ? 0 : min(thd->total_warn_count, 65535));
|
||||
buff[0]= 254;
|
||||
int2store(buff+1, tmp);
|
||||
/*
|
||||
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
|
||||
other queries (see the if test in dispatch_command / COM_QUERY)
|
||||
*/
|
||||
if (thd->is_fatal_error)
|
||||
thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
|
||||
int2store(buff+3, thd->server_status);
|
||||
VOID(my_net_write(net, (char*) buff, 5));
|
||||
}
|
||||
else
|
||||
VOID(my_net_write(net, eof_buff, 1));
|
||||
}
|
||||
|
||||
/*
|
||||
Please client to send scrambled_password in old format.
|
||||
SYNOPSYS
|
||||
@ -640,7 +650,7 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
|
||||
}
|
||||
|
||||
if (flags & SEND_EOF)
|
||||
my_net_write(&thd->net, eof_buff, 1);
|
||||
write_eof_packet(thd, &thd->net);
|
||||
DBUG_RETURN(prepare_for_send(list));
|
||||
|
||||
err:
|
||||
|
Reference in New Issue
Block a user