1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Fixed BUG#1965: Opening a cursor hangs client when malformed select fails

and BUG#1966: "select 1 into a" on top-level hangs client


include/mysql_com.h:
  Added no_send_eof flag to NET for SP cursors (the simple read-only version).
mysql-test/r/sp-error.result:
  Added tests for BUG#1965 and BUG#1966.
mysql-test/t/sp-error.test:
  Added tests for BUG#1965 and BUG#1966.
sql/net_serv.cc:
  Added no_send_eof flag to NET for SP cursors (the simple read-only version).
sql/protocol.cc:
  Added no_send_eof flag to NET for SP cursors (the simple read-only version).
sql/sp_rcontext.cc:
  Use net->no_send_eof flag to prevent eofs during cursor open (instead of
  the dirty vio=0 which didn't work).
sql/sp_rcontext.h:
  Use net->no_send_eof flag to prevent eofs during cursor open (instead of
  the dirty vio=0 which didn't work).
sql/sql_yacc.yy:
  Give error message if doing SELECT ... INTO localvar even if it's outside an SP.
This commit is contained in:
unknown
2003-11-27 16:48:21 +01:00
parent 35eca8e13d
commit 919b5ba6b5
8 changed files with 43 additions and 10 deletions

View File

@ -157,7 +157,8 @@ typedef struct st_net {
unsigned int *return_status; unsigned int *return_status;
unsigned char reading_or_writing; unsigned char reading_or_writing;
char save_char; char save_char;
my_bool no_send_ok; 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 */
/* /*
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

View File

@ -259,4 +259,15 @@ declare c cursor for select * from t1;
declare c cursor for select field from t1; declare c cursor for select field from t1;
end; end;
ERROR 42000: Duplicate cursor: c ERROR 42000: Duplicate cursor: c
create procedure bug1965()
begin
declare c cursor for select val from t1 order by valname;
open c;
close c;
end;
call bug1965();
ERROR 42S22: Unknown column 'valname' in 'order clause'
drop procedure bug1965;
select 1 into a;
ERROR 42000: Undeclared variable: a
drop table t1; drop table t1;

View File

@ -341,6 +341,27 @@ begin
declare c cursor for select field from t1; declare c cursor for select field from t1;
end| end|
#
# BUG#1965
#
create procedure bug1965()
begin
declare c cursor for select val from t1 order by valname;
open c;
close c;
end|
--error 1054
call bug1965()|
drop procedure bug1965|
#
# BUG#1966
#
--error 1308
select 1 into a|
drop table t1| drop table t1|
delimiter ;| delimiter ;|

View File

@ -123,6 +123,7 @@ my_bool my_net_init(NET *net, Vio* vio)
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 = 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;

View File

@ -347,7 +347,7 @@ send_eof(THD *thd, bool no_flush)
static char eof_buff[1]= { (char) 254 }; /* Marker for end of fields */ static char eof_buff[1]= { (char) 254 }; /* Marker for end of fields */
NET *net= &thd->net; NET *net= &thd->net;
DBUG_ENTER("send_eof"); DBUG_ENTER("send_eof");
if (net->vio != 0) if (net->vio != 0 && !net->no_send_eof)
{ {
if (!no_flush && (thd->client_capabilities & CLIENT_PROTOCOL_41)) if (!no_flush && (thd->client_capabilities & CLIENT_PROTOCOL_41))
{ {

View File

@ -149,15 +149,15 @@ sp_cursor::pre_open(THD *thd)
m_oprot= thd->protocol; // Save the original protocol m_oprot= thd->protocol; // Save the original protocol
thd->protocol= m_prot; thd->protocol= m_prot;
m_ovio= thd->net.vio; // Prevent send_eof() m_nseof= thd->net.no_send_eof;
thd->net.vio= 0; thd->net.no_send_eof= TRUE;
return m_lex; return m_lex;
} }
void void
sp_cursor::post_open(THD *thd, my_bool isopen) sp_cursor::post_open(THD *thd, my_bool isopen)
{ {
thd->net.vio= m_ovio; // Restore the originals thd->net.no_send_eof= m_nseof; // Restore the originals
thd->protocol= m_oprot; thd->protocol= m_oprot;
m_isopen= isopen; m_isopen= isopen;
m_current_row= m_prot->data; m_current_row= m_prot->data;

View File

@ -240,7 +240,7 @@ private:
LEX *m_lex; LEX *m_lex;
Protocol_cursor *m_prot; Protocol_cursor *m_prot;
my_bool m_isopen; my_bool m_isopen;
Vio *m_ovio; // Original vio my_bool m_nseof; // Original no_send_eof
Protocol *m_oprot; // Original protcol Protocol *m_oprot; // Original protcol
MYSQL_ROWS *m_current_row; MYSQL_ROWS *m_current_row;

View File

@ -4555,12 +4555,11 @@ select_var_ident:
| ident_or_text | ident_or_text
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (!lex->spcont)
YYABORT;
sp_pvar_t *t; sp_pvar_t *t;
if (!(t=lex->spcont->find_pvar(&$1)))
if (!lex->spcont || !(t=lex->spcont->find_pvar(&$1)))
{ {
send_error(lex->thd, ER_SP_UNDECLARED_VAR); net_printf(YYTHD, ER_SP_UNDECLARED_VAR, $1.str);
YYABORT; YYABORT;
} }
if (! lex->result) if (! lex->result)