Commit 016c5b89 authored by unknown's avatar unknown

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.
parent d019fc46
...@@ -157,7 +157,8 @@ typedef struct st_net { ...@@ -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
......
...@@ -259,4 +259,15 @@ declare c cursor for select * from t1; ...@@ -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;
...@@ -341,6 +341,27 @@ begin ...@@ -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 ;|
...@@ -123,6 +123,7 @@ my_bool my_net_init(NET *net, Vio* vio) ...@@ -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;
......
...@@ -347,7 +347,7 @@ send_eof(THD *thd, bool no_flush) ...@@ -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))
{ {
......
...@@ -149,15 +149,15 @@ sp_cursor::pre_open(THD *thd) ...@@ -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;
......
...@@ -240,7 +240,7 @@ class sp_cursor : public Sql_alloc ...@@ -240,7 +240,7 @@ class sp_cursor : public Sql_alloc
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;
......
...@@ -4555,12 +4555,11 @@ select_var_ident: ...@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment