Loading mysql-test/r/sp.result +56 −0 Original line number Diff line number Diff line Loading @@ -4801,4 +4801,60 @@ date_format(t3.d, pDateFormat) count(*) 2005-02 2 drop table t3| 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; mysql-test/t/sp.test +55 −0 Original line number Diff line number Diff line Loading @@ -5638,6 +5638,7 @@ drop function bug17615| drop table t3| # # BUG#17476: Stored procedure not returning data when it is called first # time per connection # Loading @@ -5662,6 +5663,60 @@ drop table t3| 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 # Loading sql/sp_pcontext.cc +12 −4 Original line number Diff line number Diff line Loading @@ -122,30 +122,38 @@ sp_pcontext::pop_context() } uint sp_pcontext::diff_handlers(sp_pcontext *ctx) sp_pcontext::diff_handlers(sp_pcontext *ctx, bool exclusive) { uint n= 0; sp_pcontext *pctx= this; sp_pcontext *last_ctx= NULL; while (pctx && pctx != ctx) { n+= pctx->m_handlers; last_ctx= pctx; pctx= pctx->parent_context(); } if (pctx) return n; return (exclusive && last_ctx ? n - last_ctx->m_handlers : n); return 0; // Didn't find ctx } 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 *last_ctx= NULL; while (pctx && pctx != ctx) { n+= pctx->m_cursor.elements; last_ctx= pctx; pctx= pctx->parent_context(); } 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 } Loading sql/sp_pcontext.h +7 −3 Original line number Diff line number Diff line Loading @@ -119,11 +119,15 @@ class sp_pcontext : public Sql_alloc 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 diff_handlers(sp_pcontext *ctx); diff_handlers(sp_pcontext *ctx, bool exclusive); uint diff_cursors(sp_pcontext *ctx); diff_cursors(sp_pcontext *ctx, bool exclusive); // Loading sql/sql_yacc.yy +4 −4 Original line number Diff line number Diff line Loading @@ -2080,10 +2080,10 @@ sp_proc_stmt: uint ip= sp->instructions(); uint n; n= ctx->diff_handlers(lab->ctx); n= ctx->diff_handlers(lab->ctx, TRUE); /* Exclusive the dest. */ if (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) sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); i= new sp_instr_jump(ip, ctx); Loading @@ -2109,10 +2109,10 @@ sp_proc_stmt: uint ip= sp->instructions(); uint n; n= ctx->diff_handlers(lab->ctx); n= ctx->diff_handlers(lab->ctx, FALSE); /* Inclusive the dest. */ if (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) sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */ Loading Loading
mysql-test/r/sp.result +56 −0 Original line number Diff line number Diff line Loading @@ -4801,4 +4801,60 @@ date_format(t3.d, pDateFormat) count(*) 2005-02 2 drop table t3| 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;
mysql-test/t/sp.test +55 −0 Original line number Diff line number Diff line Loading @@ -5638,6 +5638,7 @@ drop function bug17615| drop table t3| # # BUG#17476: Stored procedure not returning data when it is called first # time per connection # Loading @@ -5662,6 +5663,60 @@ drop table t3| 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 # Loading
sql/sp_pcontext.cc +12 −4 Original line number Diff line number Diff line Loading @@ -122,30 +122,38 @@ sp_pcontext::pop_context() } uint sp_pcontext::diff_handlers(sp_pcontext *ctx) sp_pcontext::diff_handlers(sp_pcontext *ctx, bool exclusive) { uint n= 0; sp_pcontext *pctx= this; sp_pcontext *last_ctx= NULL; while (pctx && pctx != ctx) { n+= pctx->m_handlers; last_ctx= pctx; pctx= pctx->parent_context(); } if (pctx) return n; return (exclusive && last_ctx ? n - last_ctx->m_handlers : n); return 0; // Didn't find ctx } 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 *last_ctx= NULL; while (pctx && pctx != ctx) { n+= pctx->m_cursor.elements; last_ctx= pctx; pctx= pctx->parent_context(); } 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 } Loading
sql/sp_pcontext.h +7 −3 Original line number Diff line number Diff line Loading @@ -119,11 +119,15 @@ class sp_pcontext : public Sql_alloc 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 diff_handlers(sp_pcontext *ctx); diff_handlers(sp_pcontext *ctx, bool exclusive); uint diff_cursors(sp_pcontext *ctx); diff_cursors(sp_pcontext *ctx, bool exclusive); // Loading
sql/sql_yacc.yy +4 −4 Original line number Diff line number Diff line Loading @@ -2080,10 +2080,10 @@ sp_proc_stmt: uint ip= sp->instructions(); uint n; n= ctx->diff_handlers(lab->ctx); n= ctx->diff_handlers(lab->ctx, TRUE); /* Exclusive the dest. */ if (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) sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); i= new sp_instr_jump(ip, ctx); Loading @@ -2109,10 +2109,10 @@ sp_proc_stmt: uint ip= sp->instructions(); uint n; n= ctx->diff_handlers(lab->ctx); n= ctx->diff_handlers(lab->ctx, FALSE); /* Inclusive the dest. */ if (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) sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */ Loading