mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Fixed problem of sending ERROR to client after OK or EOF (BUG#6804)
include/mysql_com.h: Flag which prevent sending error after EOF or OK sent mysql-test/r/kill.result: test of blocking of sending ERROR after OK or EOF mysql-test/t/kill.test: test of blocking of sending ERROR after OK or EOF sql/item_func.cc: typo fixed sql/net_serv.cc: initialization of flag sql/protocol.cc: check and set of flag no_send_error sql/sql_parse.cc: droping flag no_send_error before new command/query execution
This commit is contained in:
@ -187,6 +187,11 @@ typedef struct st_net {
|
|||||||
char save_char;
|
char save_char;
|
||||||
my_bool no_send_ok; /* For SPs and other things that do multiple stmts */
|
my_bool no_send_ok; /* For SPs and other things that do multiple stmts */
|
||||||
my_bool no_send_eof; /* For SPs' first version read-only cursors */
|
my_bool no_send_eof; /* For SPs' first version read-only cursors */
|
||||||
|
/*
|
||||||
|
Set if OK packet is already sent, and we do not need to send error
|
||||||
|
messages
|
||||||
|
*/
|
||||||
|
my_bool no_send_error;
|
||||||
/*
|
/*
|
||||||
Pointer to query object in query cache, do not equal NULL (0) for
|
Pointer to query object in query cache, do not equal NULL (0) for
|
||||||
queries in cache that have not stored its results yet
|
queries in cache that have not stored its results yet
|
||||||
|
@ -9,3 +9,15 @@ select 4;
|
|||||||
4
|
4
|
||||||
4
|
4
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
select get_lock("a", 10);
|
||||||
|
get_lock("a", 10)
|
||||||
|
1
|
||||||
|
select get_lock("a", 10);
|
||||||
|
get_lock("a", 10)
|
||||||
|
NULL
|
||||||
|
select 1;
|
||||||
|
1
|
||||||
|
1
|
||||||
|
select RELEASE_LOCK("a");
|
||||||
|
RELEASE_LOCK("a")
|
||||||
|
1
|
||||||
|
@ -35,3 +35,21 @@ select @id != connection_id();
|
|||||||
connection con2;
|
connection con2;
|
||||||
select 4;
|
select 4;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# test of blocking of sending ERROR after OK or EOF
|
||||||
|
#
|
||||||
|
connection con1;
|
||||||
|
select get_lock("a", 10);
|
||||||
|
connection con2;
|
||||||
|
let $ID= `select connection_id()`;
|
||||||
|
send select get_lock("a", 10);
|
||||||
|
connection con1;
|
||||||
|
disable_query_log;
|
||||||
|
eval kill query $ID;
|
||||||
|
enable_query_log;
|
||||||
|
connection con2;
|
||||||
|
reap;
|
||||||
|
select 1;
|
||||||
|
connection con1;
|
||||||
|
select RELEASE_LOCK("a");
|
||||||
|
@ -3578,7 +3578,7 @@ Item_func_sp::execute(Item **itp)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We don't need to surpress senfing of ok packet here (by setting
|
We don't need to surpress sending of ok packet here (by setting
|
||||||
thd->net.no_send_ok to true), because we are not allowing statements
|
thd->net.no_send_ok to true), because we are not allowing statements
|
||||||
in functions now.
|
in functions now.
|
||||||
*/
|
*/
|
||||||
|
@ -121,8 +121,7 @@ my_bool my_net_init(NET *net, Vio* vio)
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
net->buff_end=net->buff+net->max_packet;
|
net->buff_end=net->buff+net->max_packet;
|
||||||
net->vio = vio;
|
net->vio = vio;
|
||||||
net->no_send_ok = 0;
|
net->no_send_ok= net->no_send_eof= net->no_send_error= 0;
|
||||||
net->no_send_eof = 0;
|
|
||||||
net->error=0; net->return_errno=0; net->return_status=0;
|
net->error=0; net->return_errno=0; net->return_status=0;
|
||||||
net->pkt_nr=net->compress_pkt_nr=0;
|
net->pkt_nr=net->compress_pkt_nr=0;
|
||||||
net->write_pos=net->read_pos = net->buff;
|
net->write_pos=net->read_pos = net->buff;
|
||||||
|
@ -65,6 +65,12 @@ void net_send_error(THD *thd, uint sql_errno, const char *err)
|
|||||||
err ? err : net->last_error[0] ?
|
err ? err : net->last_error[0] ?
|
||||||
net->last_error : "NULL"));
|
net->last_error : "NULL"));
|
||||||
|
|
||||||
|
if (net && net->no_send_error)
|
||||||
|
{
|
||||||
|
thd->clear_error();
|
||||||
|
DBUG_PRINT("info", ("sending error messages prohibited"));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
if (thd->spcont && thd->spcont->find_handler(sql_errno,
|
if (thd->spcont && thd->spcont->find_handler(sql_errno,
|
||||||
MYSQL_ERROR::WARN_LEVEL_ERROR))
|
MYSQL_ERROR::WARN_LEVEL_ERROR))
|
||||||
{
|
{
|
||||||
@ -154,6 +160,13 @@ net_printf_error(THD *thd, uint errcode, ...)
|
|||||||
DBUG_ENTER("net_printf_error");
|
DBUG_ENTER("net_printf_error");
|
||||||
DBUG_PRINT("enter",("message: %u",errcode));
|
DBUG_PRINT("enter",("message: %u",errcode));
|
||||||
|
|
||||||
|
if (net && net->no_send_error)
|
||||||
|
{
|
||||||
|
thd->clear_error();
|
||||||
|
DBUG_PRINT("info", ("sending error messages prohibited"));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
if (thd->spcont && thd->spcont->find_handler(errcode,
|
if (thd->spcont && thd->spcont->find_handler(errcode,
|
||||||
MYSQL_ERROR::WARN_LEVEL_ERROR))
|
MYSQL_ERROR::WARN_LEVEL_ERROR))
|
||||||
{
|
{
|
||||||
@ -300,6 +313,9 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
|
|||||||
VOID(net_flush(net));
|
VOID(net_flush(net));
|
||||||
/* We can't anymore send an error to the client */
|
/* We can't anymore send an error to the client */
|
||||||
thd->net.report_error= 0;
|
thd->net.report_error= 0;
|
||||||
|
thd->net.no_send_error= 1;
|
||||||
|
DBUG_PRINT("info", ("OK sent, so no more error sendong allowed"));
|
||||||
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,6 +373,8 @@ send_eof(THD *thd, bool no_flush)
|
|||||||
if (!no_flush)
|
if (!no_flush)
|
||||||
VOID(net_flush(net));
|
VOID(net_flush(net));
|
||||||
}
|
}
|
||||||
|
thd->net.no_send_error= 1;
|
||||||
|
DBUG_PRINT("info", ("EOF sent, so no more error sendong allowed"));
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
@ -960,6 +960,7 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
|
|||||||
*/
|
*/
|
||||||
save_vio= thd->net.vio;
|
save_vio= thd->net.vio;
|
||||||
thd->net.vio= 0;
|
thd->net.vio= 0;
|
||||||
|
thd->net.no_send_error= 0;
|
||||||
dispatch_command(COM_QUERY, thd, thd->query, thd->query_length+1);
|
dispatch_command(COM_QUERY, thd, thd->query, thd->query_length+1);
|
||||||
rw_unlock(var_mutex);
|
rw_unlock(var_mutex);
|
||||||
thd->client_capabilities= save_client_capabilities;
|
thd->client_capabilities= save_client_capabilities;
|
||||||
@ -1019,6 +1020,7 @@ pthread_handler_decl(handle_one_connection,arg)
|
|||||||
int error;
|
int error;
|
||||||
NET *net= &thd->net;
|
NET *net= &thd->net;
|
||||||
thd->thread_stack= (char*) &thd;
|
thd->thread_stack= (char*) &thd;
|
||||||
|
net->no_send_error= 0;
|
||||||
|
|
||||||
if ((error=check_connection(thd)))
|
if ((error=check_connection(thd)))
|
||||||
{ // Wrong permissions
|
{ // Wrong permissions
|
||||||
@ -1057,6 +1059,7 @@ pthread_handler_decl(handle_one_connection,arg)
|
|||||||
thd->init_for_queries();
|
thd->init_for_queries();
|
||||||
while (!net->error && net->vio != 0 && !(thd->killed == THD::KILL_CONNECTION))
|
while (!net->error && net->vio != 0 && !(thd->killed == THD::KILL_CONNECTION))
|
||||||
{
|
{
|
||||||
|
net->no_send_error= 0;
|
||||||
if (do_command(thd))
|
if (do_command(thd))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2087,6 +2090,7 @@ mysql_execute_command(THD *thd)
|
|||||||
/* most outer SELECT_LEX_UNIT of query */
|
/* most outer SELECT_LEX_UNIT of query */
|
||||||
SELECT_LEX_UNIT *unit= &lex->unit;
|
SELECT_LEX_UNIT *unit= &lex->unit;
|
||||||
DBUG_ENTER("mysql_execute_command");
|
DBUG_ENTER("mysql_execute_command");
|
||||||
|
thd->net.no_send_error= 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In many cases first table of main SELECT_LEX have special meaning =>
|
In many cases first table of main SELECT_LEX have special meaning =>
|
||||||
|
Reference in New Issue
Block a user