Commit ce7262b2 authored by unknown's avatar unknown

Merge mysql.com:/extern/mysql/5.0/bug16887/mysql-5.0-runtime

into  mysql.com:/extern/mysql/5.0/bug16887/mysql-5.0


sql/sql_yacc.yy:
  Auto merged
mysql-test/r/sp.result:
  Manual merge.
mysql-test/t/sp.test:
  Manual merge.
parents 42d6bfa8 062de999
...@@ -4801,4 +4801,60 @@ date_format(t3.d, pDateFormat) count(*) ...@@ -4801,4 +4801,60 @@ date_format(t3.d, pDateFormat) count(*)
2005-02 2 2005-02 2
drop table t3| drop table t3|
drop procedure bug17476| drop procedure bug17476|
drop table if exists t3|
drop procedure if exists bug16887|
create table t3 ( c varchar(1) )|
insert into t3 values
(' '),('.'),(';'),(','),('-'),('_'),('('),(')'),('/'),('\\')|
create procedure bug16887()
begin
declare i int default 10;
again:
while i > 0 do
begin
declare breakchar varchar(1);
declare done int default 0;
declare t3_cursor cursor for select c from t3;
declare continue handler for not found set done = 1;
set i = i - 1;
select i;
if i = 3 then
iterate again;
end if;
open t3_cursor;
loop
fetch t3_cursor into breakchar;
if done = 1 then
begin
close t3_cursor;
iterate again;
end;
end if;
end loop;
end;
end while;
end|
call bug16887()|
i
9
i
8
i
7
i
6
i
5
i
4
i
3
i
2
i
1
i
0
drop table t3|
drop procedure bug16887|
drop table t1,t2; drop table t1,t2;
...@@ -5638,6 +5638,7 @@ drop function bug17615| ...@@ -5638,6 +5638,7 @@ drop function bug17615|
drop table t3| drop table t3|
#
# BUG#17476: Stored procedure not returning data when it is called first # BUG#17476: Stored procedure not returning data when it is called first
# time per connection # time per connection
# #
...@@ -5662,6 +5663,60 @@ drop table t3| ...@@ -5662,6 +5663,60 @@ drop table t3|
drop procedure bug17476| drop procedure bug17476|
#
# BUG#16887: Cursor causes server segfault
#
--disable_warnings
drop table if exists t3|
drop procedure if exists bug16887|
--enable_warnings
create table t3 ( c varchar(1) )|
insert into t3 values
(' '),('.'),(';'),(','),('-'),('_'),('('),(')'),('/'),('\\')|
create procedure bug16887()
begin
declare i int default 10;
again:
while i > 0 do
begin
declare breakchar varchar(1);
declare done int default 0;
declare t3_cursor cursor for select c from t3;
declare continue handler for not found set done = 1;
set i = i - 1;
select i;
if i = 3 then
iterate again;
end if;
open t3_cursor;
loop
fetch t3_cursor into breakchar;
if done = 1 then
begin
close t3_cursor;
iterate again;
end;
end if;
end loop;
end;
end while;
end|
call bug16887()|
drop table t3|
drop procedure bug16887|
# #
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
# #
......
...@@ -122,30 +122,38 @@ sp_pcontext::pop_context() ...@@ -122,30 +122,38 @@ sp_pcontext::pop_context()
} }
uint uint
sp_pcontext::diff_handlers(sp_pcontext *ctx) sp_pcontext::diff_handlers(sp_pcontext *ctx, bool exclusive)
{ {
uint n= 0; uint n= 0;
sp_pcontext *pctx= this; sp_pcontext *pctx= this;
sp_pcontext *last_ctx= NULL;
while (pctx && pctx != ctx) while (pctx && pctx != ctx)
{ {
n+= pctx->m_handlers; n+= pctx->m_handlers;
last_ctx= pctx;
pctx= pctx->parent_context(); pctx= pctx->parent_context();
} }
if (pctx) if (pctx)
return n; return (exclusive && last_ctx ? n - last_ctx->m_handlers : n);
return 0; // Didn't find ctx return 0; // Didn't find ctx
} }
uint uint
sp_pcontext::diff_cursors(sp_pcontext *ctx) sp_pcontext::diff_cursors(sp_pcontext *ctx, bool exclusive)
{ {
uint n= 0;
sp_pcontext *pctx= this; sp_pcontext *pctx= this;
sp_pcontext *last_ctx= NULL;
while (pctx && pctx != ctx) while (pctx && pctx != ctx)
{
n+= pctx->m_cursor.elements;
last_ctx= pctx;
pctx= pctx->parent_context(); pctx= pctx->parent_context();
}
if (pctx) if (pctx)
return ctx->current_cursors() - pctx->current_cursors(); return (exclusive && last_ctx ? n - last_ctx->m_cursor.elements : n);
return 0; // Didn't find ctx return 0; // Didn't find ctx
} }
......
...@@ -119,11 +119,15 @@ class sp_pcontext : public Sql_alloc ...@@ -119,11 +119,15 @@ class sp_pcontext : public Sql_alloc
return m_parent; return m_parent;
} }
/*
Number of handlers/cursors to pop between this context and 'ctx'.
If 'exclusive' is true, don't count the last block we are leaving;
this is used for LEAVE where we will jump to the cpop/hpop instructions.
*/
uint uint
diff_handlers(sp_pcontext *ctx); diff_handlers(sp_pcontext *ctx, bool exclusive);
uint uint
diff_cursors(sp_pcontext *ctx); diff_cursors(sp_pcontext *ctx, bool exclusive);
// //
......
...@@ -2080,10 +2080,10 @@ sp_proc_stmt: ...@@ -2080,10 +2080,10 @@ sp_proc_stmt:
uint ip= sp->instructions(); uint ip= sp->instructions();
uint n; uint n;
n= ctx->diff_handlers(lab->ctx); n= ctx->diff_handlers(lab->ctx, TRUE); /* Exclusive the dest. */
if (n) if (n)
sp->add_instr(new sp_instr_hpop(ip++, ctx, n)); sp->add_instr(new sp_instr_hpop(ip++, ctx, n));
n= ctx->diff_cursors(lab->ctx); n= ctx->diff_cursors(lab->ctx, TRUE); /* Exclusive the dest. */
if (n) if (n)
sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); sp->add_instr(new sp_instr_cpop(ip++, ctx, n));
i= new sp_instr_jump(ip, ctx); i= new sp_instr_jump(ip, ctx);
...@@ -2109,10 +2109,10 @@ sp_proc_stmt: ...@@ -2109,10 +2109,10 @@ sp_proc_stmt:
uint ip= sp->instructions(); uint ip= sp->instructions();
uint n; uint n;
n= ctx->diff_handlers(lab->ctx); n= ctx->diff_handlers(lab->ctx, FALSE); /* Inclusive the dest. */
if (n) if (n)
sp->add_instr(new sp_instr_hpop(ip++, ctx, n)); sp->add_instr(new sp_instr_hpop(ip++, ctx, n));
n= ctx->diff_cursors(lab->ctx); n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */
if (n) if (n)
sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); sp->add_instr(new sp_instr_cpop(ip++, ctx, n));
i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */ i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
......
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