Commit e685e7e3 authored by malff@lambda.hsd1.co.comcast.net.'s avatar malff@lambda.hsd1.co.comcast.net.
Browse files

Manual merge

parent ec6c4fad
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -1579,3 +1579,51 @@ drop function f2;
drop table t2;
ERROR 42S02: Unknown table 't2'
End of 5.1 tests
drop procedure if exists proc_33983_a;
drop procedure if exists proc_33983_b;
drop procedure if exists proc_33983_c;
drop procedure if exists proc_33983_d;
create procedure proc_33983_a()
begin
label1:
begin
label2:
begin
select 1;
end label1;
end;
end|
ERROR 42000: End-label label1 without match
create procedure proc_33983_b()
begin
label1:
repeat
label2:
repeat
select 1;
until FALSE end repeat label1;
until FALSE end repeat;
end|
ERROR 42000: End-label label1 without match
create procedure proc_33983_c()
begin
label1:
while TRUE do
label2:
while TRUE do
select 1;
end while label1;
end while;
end|
ERROR 42000: End-label label1 without match
create procedure proc_33983_d()
begin
label1:
loop
label2:
loop
select 1;
end loop label1;
end loop;
end|
ERROR 42000: End-label label1 without match
+35 −0
Original line number Diff line number Diff line
@@ -6827,6 +6827,41 @@ SELECT @state, @exception;
run	NULL
DROP TABLE t1;
DROP PROCEDURE bug29770;
use test;
drop table if exists t_33618;
drop procedure if exists proc_33618;
create table t_33618 (`a` int, unique(`a`), `b` varchar(30)) engine=myisam;
insert into t_33618 (`a`,`b`) values (1,'1'),(2,'2');
create procedure proc_33618(num int)
begin
declare count1 int default '0';
declare vb varchar(30);
declare last_row int;
while(num>=1) do
set num=num-1;
begin
declare cur1 cursor for select `a` from t_33618;
declare continue handler for not found set last_row = 1;
set last_row:=0;
open cur1;
rep1:
repeat
begin
declare exit handler for 1062 begin end;
fetch cur1 into vb;
if (last_row = 1) then
leave rep1;
end if;
end;
until last_row=1
end repeat;
close cur1;
end;
end while;
end//
call proc_33618(20);
drop table t_33618;
drop procedure proc_33618;
# ------------------------------------------------------------------
# -- End of 5.0 tests
# ------------------------------------------------------------------
+63 −0
Original line number Diff line number Diff line
@@ -2305,6 +2305,69 @@ drop table t2;

--echo End of 5.1 tests

#
# Bug#33983 (Stored Procedures: wrong end <label> syntax is accepted)
#

--disable_warnings
drop procedure if exists proc_33983_a;
drop procedure if exists proc_33983_b;
drop procedure if exists proc_33983_c;
drop procedure if exists proc_33983_d;
--enable_warnings

delimiter |;

--error ER_SP_LABEL_MISMATCH
create procedure proc_33983_a()
begin
  label1:
    begin
      label2:
      begin
        select 1;
      end label1;
    end;
end|

--error ER_SP_LABEL_MISMATCH
create procedure proc_33983_b()
begin
  label1:
    repeat
      label2:
      repeat
        select 1;
      until FALSE end repeat label1;
    until FALSE end repeat;
end|

--error ER_SP_LABEL_MISMATCH
create procedure proc_33983_c()
begin
  label1:
    while TRUE do
      label2:
      while TRUE do
        select 1;
      end while label1;
    end while;
end|

--error ER_SP_LABEL_MISMATCH
create procedure proc_33983_d()
begin
  label1:
    loop
      label2:
      loop
        select 1;
      end loop label1;
    end loop;
end|

delimiter ;|

#
# BUG#NNNN: New bug synopsis
#
+52 −0
Original line number Diff line number Diff line
@@ -7925,6 +7925,58 @@ SELECT @state, @exception;
DROP TABLE t1;
DROP PROCEDURE bug29770;

#
# Bug#33618 Crash in sp_rcontext
#

use test;

--disable_warnings
drop table if exists t_33618;
drop procedure if exists proc_33618;
--enable_warnings

create table t_33618 (`a` int, unique(`a`), `b` varchar(30)) engine=myisam;
insert into t_33618 (`a`,`b`) values (1,'1'),(2,'2');

delimiter //;

create procedure proc_33618(num int)
begin
  declare count1 int default '0';
  declare vb varchar(30);
  declare last_row int;

  while(num>=1) do
    set num=num-1;
    begin
      declare cur1 cursor for select `a` from t_33618;
      declare continue handler for not found set last_row = 1;
      set last_row:=0;
      open cur1;
      rep1:
      repeat
        begin
          declare exit handler for 1062 begin end;
          fetch cur1 into vb;
          if (last_row = 1) then
            leave rep1;
          end if;
        end;
        until last_row=1
      end repeat;
      close cur1;
    end;
  end while;
end//

delimiter ;//

call proc_33618(20);

drop table t_33618;
drop procedure proc_33618;

###########################################################################

--echo # ------------------------------------------------------------------
+99 −17
Original line number Diff line number Diff line
@@ -1284,7 +1284,9 @@ END_OF_INPUT
%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
%type <NONE> sp_proc_stmt_statement sp_proc_stmt_return
%type <NONE> sp_proc_stmt_if
%type <NONE> sp_labeled_control sp_proc_stmt_unlabeled sp_proc_stmt_leave
%type <NONE> sp_labeled_control sp_proc_stmt_unlabeled
%type <NONE> sp_labeled_block sp_unlabeled_block
%type <NONE> sp_proc_stmt_leave
%type <NONE> sp_proc_stmt_iterate
%type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close
%type <NONE> case_stmt_specification simple_case_stmt searched_case_stmt
@@ -1945,6 +1947,8 @@ ev_sql_stmt_inner:
        | sp_proc_stmt_return
        | sp_proc_stmt_if
        | case_stmt_specification
        | sp_labeled_block
        | sp_unlabeled_block
        | sp_labeled_control
        | sp_proc_stmt_unlabeled
        | sp_proc_stmt_leave
@@ -2519,6 +2523,8 @@ sp_proc_stmt:
        | sp_proc_stmt_return
        | sp_proc_stmt_if
        | case_stmt_specification
        | sp_labeled_block
        | sp_unlabeled_block
        | sp_labeled_control
        | sp_proc_stmt_unlabeled
        | sp_proc_stmt_leave
@@ -2645,14 +2651,35 @@ sp_proc_stmt_leave:
              sp_instr_jump *i;
              uint ip= sp->instructions();
              uint n;
              /*
                When jumping to a BEGIN-END block end, the target jump
                points to the block hpop/cpop cleanup instructions,
                so we should exclude the block context here.
                When jumping to something else (i.e., SP_LAB_ITER),
                there are no hpop/cpop at the jump destination,
                so we should include the block context here for cleanup.
              */
              bool exclusive= (lab->type == SP_LAB_BEGIN);

              n= ctx->diff_handlers(lab->ctx, TRUE);  /* Exclusive the dest. */
              n= ctx->diff_handlers(lab->ctx, exclusive);
              if (n)
                sp->add_instr(new sp_instr_hpop(ip++, ctx, n));
              n= ctx->diff_cursors(lab->ctx, TRUE);  /* Exclusive the dest. */
              {
                sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n);
                if (hpop == NULL)
                  MYSQL_YYABORT;
                sp->add_instr(hpop);
              }
              n= ctx->diff_cursors(lab->ctx, exclusive);
              if (n)
                sp->add_instr(new sp_instr_cpop(ip++, ctx, n));
              {
                sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n);
                if (cpop == NULL)
                  MYSQL_YYABORT;
                sp->add_instr(cpop);
              }
              i= new sp_instr_jump(ip, ctx);
              if (i == NULL)
                MYSQL_YYABORT;
              sp->push_backpatch(i, lab);  /* Jumping forward */
              sp->add_instr(i);
            }
@@ -2680,10 +2707,20 @@ sp_proc_stmt_iterate:

              n= ctx->diff_handlers(lab->ctx, FALSE);  /* Inclusive the dest. */
              if (n)
                sp->add_instr(new sp_instr_hpop(ip++, ctx, n));
              {
                sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n);
                if (hpop == NULL)
                  MYSQL_YYABORT;
                sp->add_instr(hpop);
              }
              n= ctx->diff_cursors(lab->ctx, FALSE);  /* Inclusive the dest. */
              if (n)
                sp->add_instr(new sp_instr_cpop(ip++, ctx, n));
              {
                sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n);
                if (cpop == NULL)
                  MYSQL_YYABORT;
                sp->add_instr(cpop);
              }
              i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
              sp->add_instr(i);
            }
@@ -2967,19 +3004,17 @@ sp_labeled_control:
          sp_unlabeled_control sp_opt_label
          {
            LEX *lex= Lex;
            sp_label_t *lab= lex->spcont->pop_label();

            if ($5.str)
            {
              sp_label_t *lab= lex->spcont->find_label($5.str);

              if (!lab ||
                  my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
              if (my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
              {
                my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
                MYSQL_YYABORT;
              }
            }
            lex->sphead->backpatch(lex->spcont->pop_label());
            lex->sphead->backpatch(lab);
          }
        ;

@@ -2988,15 +3023,59 @@ sp_opt_label:
        | label_ident   { $$= $1; }
        ;

sp_unlabeled_control:
sp_labeled_block:
          label_ident ':'
          {
            LEX *lex= Lex;
            sp_pcontext *ctx= lex->spcont;
            sp_label_t *lab= ctx->find_label($1.str);

            if (lab)
            {
              my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str);
              MYSQL_YYABORT;
            }

            lab= lex->spcont->push_label($1.str,
                                         lex->sphead->instructions());
            lab->type= SP_LAB_BEGIN;
          }
          sp_block_content sp_opt_label
          {
            LEX *lex= Lex;
            sp_label_t *lab= lex->spcont->pop_label();

            if ($5.str)
            {
              if (my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
              {
                my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
                MYSQL_YYABORT;
              }
            }
          }
        ;

sp_unlabeled_block:
          { /* Unlabeled blocks get a secret label. */
            LEX *lex= Lex;
            uint ip= lex->sphead->instructions();
            sp_label_t *lab= lex->spcont->push_label((char *)"", ip);
            lab->type= SP_LAB_BEGIN;
          }
          sp_block_content
          {
            LEX *lex= Lex;
            lex->spcont->pop_label();
          }
        ;

sp_block_content:
          BEGIN_SYM
          { /* QQ This is just a dummy for grouping declarations and statements
              together. No [[NOT] ATOMIC] yet, and we need to figure out how
              make it coexist with the existing BEGIN COMMIT/ROLLBACK. */
            LEX *lex= Lex;
            sp_label_t *lab= lex->spcont->last_label();

            lab->type= SP_LAB_BEGIN;
            lex->spcont= lex->spcont->push_context(LABEL_DEFAULT_SCOPE);
          }
          sp_decls
@@ -3016,7 +3095,10 @@ sp_unlabeled_control:
                                              $3.curs));
            lex->spcont= ctx->pop_context();
          }
        | LOOP_SYM
        ;

sp_unlabeled_control:
          LOOP_SYM
          sp_proc_stmts1 END LOOP_SYM
          {
            LEX *lex= Lex;