Commit 942ba22e authored by unknown's avatar unknown
Browse files

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 9f2d21f6 7f02b0a0
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
@@ -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;
+55 −0
Original line number Diff line number Diff line
@@ -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
#
@@ -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
#
+12 −4
Original line number Diff line number Diff line
@@ -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
}

+7 −3
Original line number Diff line number Diff line
@@ -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);


  //
+4 −4
Original line number Diff line number Diff line
@@ -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);
@@ -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 */