872 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			872 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
set sql_mode=oracle;
 | 
						|
--echo #
 | 
						|
--echo # MDEV-10697  sql_mode=ORACLE: GOTO statement
 | 
						|
--echo #
 | 
						|
 | 
						|
--echo # matrice of tests in procedure
 | 
						|
--echo # |--------------------------------------------------------
 | 
						|
--echo # |               | Same  | Outside   | to sub | No       |
 | 
						|
--echo # |               | block | one block | block  | matching |
 | 
						|
--echo # |               |       |           |        | label    |
 | 
						|
--echo # |--------------------------------------------------------
 | 
						|
--echo # | Forward jump  | F1    | F3        | F5     | F7       |
 | 
						|
--echo # |--------------------------------------------------------
 | 
						|
--echo # | Backward jump | F2    | F4        | F6     | F8       |
 | 
						|
--echo # |--------------------------------------------------------
 | 
						|
--echo # Jump from handler to outside handling code block : F9
 | 
						|
--echo # Jump from handler to handling code block : F10 (forbidden)
 | 
						|
--echo # Jump inside handler : F21
 | 
						|
--echo # Jump between handler : F22 (forbidden)
 | 
						|
--echo # Jump from cascaded block with handler : F11
 | 
						|
--echo # Duplicate label in same block : F12 (forbidden)
 | 
						|
--echo # Duplicate label in different block : F13
 | 
						|
--echo # Jump outside unlabeled block : F14
 | 
						|
--echo # Jump inside/outside labeled block  : F15
 | 
						|
--echo # Jump from if / else  : F16
 | 
						|
--echo # Jump with cursors : F17
 | 
						|
--echo # Jump outside case  : F18
 | 
						|
--echo # Jump inside/outside case block : F19
 | 
						|
--echo # Jump outside labeled loop : F20
 | 
						|
--echo # Jump (continue) labeled loop : F23
 | 
						|
--echo # Two consecutive label : P24
 | 
						|
--echo # Two consecutive label (backward and forward jump) : P25
 | 
						|
--echo # Two consecutive label, continue to wrong label : P26
 | 
						|
--echo # Consecutive goto label and block label : P27
 | 
						|
 | 
						|
--echo # Test in function
 | 
						|
--echo # backward jump : func1
 | 
						|
--echo # forward jump : func2
 | 
						|
 | 
						|
--echo # Test in trigger
 | 
						|
--echo # forward jump : trg1
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # Forward jump in same block
 | 
						|
--echo #
 | 
						|
DELIMITER $$;
 | 
						|
CREATE or replace procedure f1(p2 IN OUT VARCHAR)
 | 
						|
AS
 | 
						|
BEGIN 
 | 
						|
  p2:='a';
 | 
						|
  goto lab1;
 | 
						|
<<lab1>>
 | 
						|
  goto lab2;
 | 
						|
  p2:='b';
 | 
						|
<<lab2>> 
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
 | 
						|
DELIMITER ;$$
 | 
						|
call f1(@wp1);
 | 
						|
select 'f1',@wp1;
 | 
						|
DROP PROCEDURE f1;
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # Backward jump in same block
 | 
						|
--echo #
 | 
						|
DELIMITER $$;
 | 
						|
CREATE or replace procedure f2(p2 IN OUT VARCHAR)
 | 
						|
AS
 | 
						|
BEGIN 
 | 
						|
  p2:='a';
 | 
						|
<<lab1>>
 | 
						|
  if (p2='b') then
 | 
						|
    return ;
 | 
						|
  end if;
 | 
						|
  p2:='b';
 | 
						|
  goto lab1;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
call f2(@wp1);
 | 
						|
select 'f2',@wp1;
 | 
						|
DROP PROCEDURE f2;
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # Forward jump outside one block
 | 
						|
--echo #
 | 
						|
DELIMITER $$;
 | 
						|
CREATE or replace procedure f3(p2 IN OUT VARCHAR)
 | 
						|
AS
 | 
						|
BEGIN 
 | 
						|
  p2:='a';
 | 
						|
  if (p2='a') then
 | 
						|
    goto lab1;
 | 
						|
  end if;
 | 
						|
  p2:='c';
 | 
						|
<<lab1>>
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
call f3(@wp1);
 | 
						|
select 'f3',@wp1;
 | 
						|
DROP PROCEDURE f3;
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # Backward jump outside one block
 | 
						|
--echo #
 | 
						|
DELIMITER $$;
 | 
						|
CREATE or replace procedure f4(p2 IN OUT VARCHAR)
 | 
						|
AS
 | 
						|
BEGIN 
 | 
						|
  p2:='a';
 | 
						|
<<lab1>>
 | 
						|
  if (p2='a') then
 | 
						|
    p2:=p2||'b';
 | 
						|
    goto lab1;
 | 
						|
  end if; 
 | 
						|
  if (p2='ab') then
 | 
						|
    p2:=p2||'c';
 | 
						|
  end if;
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
call f4(@wp1);
 | 
						|
select 'f4',@wp1;
 | 
						|
DROP PROCEDURE f4;
 | 
						|
 | 
						|
DELIMITER $$;
 | 
						|
--echo #
 | 
						|
--echo # Forward jump inside sub block
 | 
						|
--error ER_SP_LILABEL_MISMATCH
 | 
						|
CREATE or replace procedure f5(p2 IN OUT VARCHAR)
 | 
						|
AS
 | 
						|
BEGIN 
 | 
						|
  p2:='a';
 | 
						|
goto lab5 ;
 | 
						|
  if (p2='a') then
 | 
						|
<<lab5>>
 | 
						|
    p2:=p2||'b';
 | 
						|
  end if; 
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
 | 
						|
DELIMITER $$;
 | 
						|
--echo #
 | 
						|
--echo # Backward jump inside sub block
 | 
						|
--error ER_SP_LILABEL_MISMATCH
 | 
						|
CREATE or replace procedure f6(p2 IN OUT VARCHAR)
 | 
						|
AS
 | 
						|
BEGIN 
 | 
						|
  p2:='a';
 | 
						|
  if (p2='a') then
 | 
						|
<<lab6>>
 | 
						|
    p2:=p2||'b';
 | 
						|
    return ;
 | 
						|
  end if; 
 | 
						|
goto lab6 ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
 | 
						|
DELIMITER $$;
 | 
						|
--echo #
 | 
						|
--echo # Backward jump - missing label
 | 
						|
--error ER_SP_LILABEL_MISMATCH
 | 
						|
CREATE or replace procedure f7(p2 IN OUT VARCHAR)
 | 
						|
AS
 | 
						|
BEGIN 
 | 
						|
<<lab>>
 | 
						|
  goto lab7 ;
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
 | 
						|
DELIMITER $$;
 | 
						|
--echo #
 | 
						|
--echo # Forward jump - missing label
 | 
						|
--error ER_SP_LILABEL_MISMATCH
 | 
						|
CREATE or replace procedure f8(p2 IN OUT VARCHAR)
 | 
						|
AS
 | 
						|
BEGIN 
 | 
						|
  goto lab8 ;
 | 
						|
<<lab>>
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # Jump from handler to procedure code
 | 
						|
--echo #
 | 
						|
DELIMITER $$;
 | 
						|
CREATE or replace procedure f9(lim INT, res OUT VARCHAR)
 | 
						|
AS
 | 
						|
  a INT;
 | 
						|
BEGIN
 | 
						|
<<lab9>>
 | 
						|
  if lim=-1 then
 | 
						|
    res:=res||' -- goto end limit -1 --';
 | 
						|
    goto lab9_end;
 | 
						|
  end if;
 | 
						|
 | 
						|
  begin
 | 
						|
    SELECT a INTO a FROM information_schema.tables LIMIT lim;
 | 
						|
  EXCEPTION
 | 
						|
    WHEN TOO_MANY_ROWS THEN
 | 
						|
         begin
 | 
						|
           res:=res||'--- too_many_rows cought ---';
 | 
						|
           lim:=0;
 | 
						|
           goto lab9;
 | 
						|
         end;
 | 
						|
    WHEN NO_DATA_FOUND THEN
 | 
						|
         begin
 | 
						|
           res:=res||'--- no_data_found cought ---';
 | 
						|
           lim:=-1;
 | 
						|
           goto lab9;
 | 
						|
         end;
 | 
						|
  end;
 | 
						|
  res:=res||'error';
 | 
						|
<<lab9_end>>
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
SET @res='';
 | 
						|
CALL f9(2, @res);
 | 
						|
SELECT 'f9',@res;
 | 
						|
CALL f9(0, @res);
 | 
						|
SELECT 'f9',@res;
 | 
						|
DROP PROCEDURE f9;
 | 
						|
 | 
						|
DELIMITER $$;
 | 
						|
--echo #
 | 
						|
--echo # Jump from handler to handling bloc
 | 
						|
--error ER_SP_LILABEL_MISMATCH
 | 
						|
CREATE or replace procedure f10(lim INT, res OUT VARCHAR)
 | 
						|
AS
 | 
						|
  a INT;
 | 
						|
BEGIN
 | 
						|
  begin
 | 
						|
<<lab10>>
 | 
						|
    SELECT a INTO a FROM information_schema.tables LIMIT lim;
 | 
						|
  EXCEPTION
 | 
						|
    WHEN TOO_MANY_ROWS THEN
 | 
						|
         begin
 | 
						|
           res:='--- too_many_rows cought ---';
 | 
						|
           goto lab10;
 | 
						|
         end;
 | 
						|
    WHEN NO_DATA_FOUND THEN res:='--- no_data_found cought ---';
 | 
						|
  end;
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # Jump from cascaded block with handler
 | 
						|
--echo #
 | 
						|
CREATE or replace procedure f11(lim INT, res OUT VARCHAR)
 | 
						|
AS
 | 
						|
  a INT;
 | 
						|
BEGIN
 | 
						|
<<lab11a>>
 | 
						|
  begin
 | 
						|
    SELECT a INTO a FROM information_schema.tables LIMIT lim;
 | 
						|
  EXCEPTION
 | 
						|
    WHEN TOO_MANY_ROWS THEN
 | 
						|
         begin
 | 
						|
           res:=res||'--- too_many_rows cought 1 ---';
 | 
						|
           goto lab11b;
 | 
						|
         end;
 | 
						|
    WHEN NO_DATA_FOUND THEN
 | 
						|
         begin
 | 
						|
           res:=res||'--- no_data_found cought 1 ---';
 | 
						|
           lim:=2;
 | 
						|
           SELECT a INTO a FROM information_schema.tables LIMIT lim;
 | 
						|
         EXCEPTION
 | 
						|
           WHEN TOO_MANY_ROWS THEN
 | 
						|
             begin
 | 
						|
               res:=res||'--- too_many_rows cought 2 ---';              
 | 
						|
               goto lab11a;
 | 
						|
             end;
 | 
						|
           WHEN NO_DATA_FOUND THEN res:='--- no_data_found cought 2 ---';
 | 
						|
         end;
 | 
						|
  end;
 | 
						|
  set res:=res||' error ';
 | 
						|
<<lab11b>> 
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
SET @res='';
 | 
						|
CALL f11(0, @res);
 | 
						|
SELECT 'f11',@res;
 | 
						|
DROP PROCEDURE f11;
 | 
						|
 | 
						|
DELIMITER $$;
 | 
						|
--echo #
 | 
						|
--echo # Jump inside handler
 | 
						|
--echo #
 | 
						|
CREATE or replace procedure f21(lim INT, res OUT VARCHAR)
 | 
						|
AS
 | 
						|
  a INT;
 | 
						|
BEGIN
 | 
						|
  begin
 | 
						|
    SELECT a INTO a FROM information_schema.tables LIMIT lim;
 | 
						|
  EXCEPTION
 | 
						|
    WHEN TOO_MANY_ROWS THEN
 | 
						|
      begin
 | 
						|
      <<retry>>
 | 
						|
        lim:=lim-1;
 | 
						|
        loop
 | 
						|
          begin
 | 
						|
            SELECT a INTO a FROM information_schema.tables LIMIT lim;
 | 
						|
          EXCEPTION
 | 
						|
            WHEN TOO_MANY_ROWS THEN
 | 
						|
              begin
 | 
						|
                lim:=lim-1;
 | 
						|
                goto retry;
 | 
						|
              end;
 | 
						|
          end;
 | 
						|
          exit ;
 | 
						|
        end loop;
 | 
						|
      end;
 | 
						|
  end;
 | 
						|
  res:=lim;
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
SET @res='';
 | 
						|
CALL f21(10, @res);
 | 
						|
SELECT 'f21',@res;
 | 
						|
drop procedure f21;
 | 
						|
 | 
						|
DELIMITER $$;
 | 
						|
--echo #
 | 
						|
--echo # Jump beetween handler
 | 
						|
--error ER_SP_LILABEL_MISMATCH
 | 
						|
CREATE or replace procedure f22(lim INT, res OUT VARCHAR)
 | 
						|
AS
 | 
						|
  a INT;
 | 
						|
BEGIN
 | 
						|
  res:='ok';
 | 
						|
  begin
 | 
						|
    SELECT a INTO a FROM information_schema.tables LIMIT lim;
 | 
						|
  EXCEPTION
 | 
						|
    WHEN TOO_MANY_ROWS THEN
 | 
						|
       goto nodata ;
 | 
						|
    WHEN NO_DATA_FOUND THEN
 | 
						|
       begin
 | 
						|
<<nodata>>      
 | 
						|
         res:='error';
 | 
						|
       end;
 | 
						|
  end;
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
 | 
						|
 | 
						|
DELIMITER $$;
 | 
						|
--echo #
 | 
						|
--echo # Duplicate label in same bloc
 | 
						|
--error 1309
 | 
						|
CREATE or replace procedure f12(lim INT, res OUT VARCHAR)
 | 
						|
AS
 | 
						|
  a INT;
 | 
						|
BEGIN
 | 
						|
<<lab12>>
 | 
						|
  res:='error';
 | 
						|
<<lab12>> 
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # Duplicate label in different block
 | 
						|
--echo #
 | 
						|
DELIMITER $$;
 | 
						|
CREATE or replace procedure f13(lim INT, res OUT VARCHAR)
 | 
						|
AS
 | 
						|
  a INT;
 | 
						|
BEGIN
 | 
						|
  a:=0;
 | 
						|
<<lab13>>
 | 
						|
  a:=a+1;
 | 
						|
  begin      
 | 
						|
    <<lab13>> 
 | 
						|
    a:=a+1;
 | 
						|
    if (a<10) then
 | 
						|
      goto lab13;
 | 
						|
    end if;   
 | 
						|
  end;
 | 
						|
  res:=a;
 | 
						|
  if (a=10) then
 | 
						|
    goto lab13;
 | 
						|
  end if;
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
SET @res='';
 | 
						|
CALL f13(0, @res);
 | 
						|
SELECT 'f13',@res;
 | 
						|
DROP PROCEDURE f13;
 | 
						|
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # Jump outside unlabeled block
 | 
						|
--echo #
 | 
						|
DELIMITER $$;
 | 
						|
CREATE or replace procedure f14(lim INT, res OUT VARCHAR)
 | 
						|
AS
 | 
						|
  a INT;
 | 
						|
BEGIN
 | 
						|
  a:=0;
 | 
						|
  loop
 | 
						|
    a:=a+1;
 | 
						|
    if (a<10) then
 | 
						|
      continue;
 | 
						|
    end if;
 | 
						|
    if (a>=lim) then
 | 
						|
      goto lab14;
 | 
						|
    end if;
 | 
						|
    if (a>=20) then
 | 
						|
      exit;
 | 
						|
    end if;  
 | 
						|
  end loop;
 | 
						|
<<lab14>>
 | 
						|
  res:=a;
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
SET @res='';
 | 
						|
CALL f14(15, @res);
 | 
						|
SELECT 'f14',@res;
 | 
						|
CALL f14(8, @res);
 | 
						|
SELECT 'f14',@res;
 | 
						|
CALL f14(25, @res);
 | 
						|
SELECT 'f14',@res;
 | 
						|
DROP PROCEDURE f14;
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # Jump inside/outside labeled block 
 | 
						|
--echo #
 | 
						|
DELIMITER $$;
 | 
						|
CREATE or replace procedure f15(lim INT, res OUT VARCHAR)
 | 
						|
AS
 | 
						|
  a INT;
 | 
						|
BEGIN
 | 
						|
  a:=0;
 | 
						|
  <<looplabel>> loop
 | 
						|
  <<beginlooplabel>>
 | 
						|
    a:=a+1;
 | 
						|
    if (a<10) then
 | 
						|
      continue looplabel;
 | 
						|
    end if;
 | 
						|
    if (a>=lim) then
 | 
						|
      goto lab15;
 | 
						|
    end if;
 | 
						|
    if (a>=20) then
 | 
						|
      exit looplabel;
 | 
						|
    end if;
 | 
						|
    goto beginlooplabel;
 | 
						|
  end loop;
 | 
						|
<<lab15>>
 | 
						|
  res:=a;
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
SET @res='';
 | 
						|
CALL f15(15, @res);
 | 
						|
SELECT 'f15',@res;
 | 
						|
CALL f15(8, @res);
 | 
						|
SELECT 'f15',@res;
 | 
						|
CALL f15(25, @res);
 | 
						|
SELECT 'f15',@res;
 | 
						|
DROP PROCEDURE f15;
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # Jump from if / else 
 | 
						|
--echo #
 | 
						|
DELIMITER $$;
 | 
						|
CREATE or replace procedure f16(lim INT, res OUT VARCHAR)
 | 
						|
AS
 | 
						|
  a INT;
 | 
						|
BEGIN
 | 
						|
    if (lim<10) then
 | 
						|
      goto lab16_1;
 | 
						|
    else
 | 
						|
      goto lab16_2;
 | 
						|
    end if;
 | 
						|
<<lab16_1>>
 | 
						|
  res:='if lab16_1';
 | 
						|
  goto lab16_3;
 | 
						|
<<lab16_2>>
 | 
						|
  res:='else lab16_2';
 | 
						|
  goto lab16_3; 
 | 
						|
  res:='error lab16_3'; 
 | 
						|
<<lab16_3>>
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
SET @res='';
 | 
						|
CALL f16(15, @res);
 | 
						|
SELECT 'f16',@res;
 | 
						|
CALL f16(8, @res);
 | 
						|
SELECT 'f16',@res;
 | 
						|
DROP PROCEDURE f16;
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # Jump with cursors
 | 
						|
--echo #
 | 
						|
DELIMITER $$;
 | 
						|
CREATE or replace procedure f17(lim INT, res OUT VARCHAR)
 | 
						|
AS
 | 
						|
  v_a INT;
 | 
						|
  v_b VARCHAR(10);
 | 
						|
  CURSOR cur1 IS SELECT 1 FROM dual where 1=2;
 | 
						|
BEGIN
 | 
						|
  OPEN cur1;
 | 
						|
  LOOP
 | 
						|
    FETCH cur1 INTO v_a;
 | 
						|
    EXIT WHEN cur1%NOTFOUND; 
 | 
						|
  END LOOP;
 | 
						|
  CLOSE cur1;
 | 
						|
  <<lab17>>
 | 
						|
  lim:=lim-1;
 | 
						|
  begin
 | 
						|
    declare
 | 
						|
       CURSOR cur1 IS SELECT 1 FROM dual;
 | 
						|
       CURSOR cur2 IS SELECT 1 FROM dual where 1=2;
 | 
						|
    begin
 | 
						|
      LOOP
 | 
						|
        OPEN cur1;
 | 
						|
        FETCH cur1 INTO v_a;
 | 
						|
        EXIT WHEN cur1%NOTFOUND; 
 | 
						|
        res:=res||'-'||lim ;
 | 
						|
        close cur1;
 | 
						|
        if (lim>0) then
 | 
						|
          goto lab17;
 | 
						|
        else
 | 
						|
          goto lab17_end;
 | 
						|
        end if;
 | 
						|
      END LOOP;
 | 
						|
    end;
 | 
						|
    <<lab17_end>>
 | 
						|
    null;
 | 
						|
  end;   
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
SET @res='';
 | 
						|
CALL f17(5, @res);
 | 
						|
SELECT 'f17',@res;
 | 
						|
DROP PROCEDURE f17;
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # Jump outside case 
 | 
						|
--echo #
 | 
						|
DELIMITER $$;
 | 
						|
CREATE or replace procedure f18(lim INT, res OUT VARCHAR)
 | 
						|
AS
 | 
						|
  a INT;
 | 
						|
BEGIN
 | 
						|
  case lim
 | 
						|
    when 1 then
 | 
						|
      res:='case branch 18_1';
 | 
						|
      goto lab18_1;
 | 
						|
      res:='error';
 | 
						|
    when 2 then
 | 
						|
      res:='case branch 18_2';
 | 
						|
      goto lab18_2;
 | 
						|
      res:='error';
 | 
						|
    else
 | 
						|
      res:='default branch 18';
 | 
						|
  end case;
 | 
						|
<<lab18_1>>
 | 
						|
  null;
 | 
						|
<<lab18_2>>
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
SET @res='';
 | 
						|
CALL f18(0, @res);
 | 
						|
SELECT 'f18',@res;
 | 
						|
CALL f18(1, @res);
 | 
						|
SELECT 'f18',@res;
 | 
						|
CALL f18(2, @res);
 | 
						|
SELECT 'f18',@res;
 | 
						|
DROP PROCEDURE f18;
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # Jump inside/outside case block
 | 
						|
--echo #
 | 
						|
DELIMITER $$;
 | 
						|
CREATE or replace procedure f19(lim INT, res OUT VARCHAR)
 | 
						|
AS
 | 
						|
  a INT;
 | 
						|
BEGIN
 | 
						|
  a:=1;
 | 
						|
  case lim
 | 
						|
    when 1 then
 | 
						|
<<lab19_0>>   
 | 
						|
      a:=a+1;
 | 
						|
      if (a<10) then
 | 
						|
        goto lab19_0;
 | 
						|
      else
 | 
						|
        goto lab19_1;
 | 
						|
      end if;
 | 
						|
      res:='case branch 19_1';
 | 
						|
    else
 | 
						|
      res:='default branch 18';
 | 
						|
  end case;
 | 
						|
  goto lab19_end;
 | 
						|
<<lab19_1>>
 | 
						|
  res:=a;
 | 
						|
<<lab19_end>>
 | 
						|
  return ;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
SET @res='';
 | 
						|
CALL f19(1, @res);
 | 
						|
SELECT 'f19',@res;
 | 
						|
DROP PROCEDURE f19;
 | 
						|
 | 
						|
DELIMITER $$;
 | 
						|
--echo #
 | 
						|
--echo # Jump outside labeled loop
 | 
						|
--echo #
 | 
						|
CREATE OR REPLACE PROCEDURE f20(res OUT VARCHAR)
 | 
						|
AS
 | 
						|
  a INT := 1;
 | 
						|
BEGIN
 | 
						|
  <<lab>>
 | 
						|
  FOR i IN a..10 LOOP
 | 
						|
    IF i = 5 THEN
 | 
						|
      a:= a+1;
 | 
						|
      goto lab;
 | 
						|
    END IF;
 | 
						|
  END LOOP;
 | 
						|
  res:=a;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
CALL f20(@res);
 | 
						|
SELECT 'f20',@res;
 | 
						|
DROP PROCEDURE f20;
 | 
						|
 | 
						|
DELIMITER $$;
 | 
						|
--echo #
 | 
						|
--echo # Jump (continue) labeled loop
 | 
						|
--echo #
 | 
						|
CREATE OR REPLACE PROCEDURE f23(res OUT VARCHAR)
 | 
						|
AS
 | 
						|
  a INT := 1;
 | 
						|
BEGIN
 | 
						|
  <<lab>>
 | 
						|
  FOR i IN a..10 LOOP
 | 
						|
    IF i = 5 THEN
 | 
						|
      a:= a+1;
 | 
						|
      continue lab;
 | 
						|
    END IF;
 | 
						|
  END LOOP;
 | 
						|
  res:=a;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
CALL f23(@res);
 | 
						|
SELECT 'f23',@res;
 | 
						|
DROP PROCEDURE f23;
 | 
						|
 | 
						|
DELIMITER $$;
 | 
						|
--echo #
 | 
						|
--echo # Two consecutive label (backward jump)
 | 
						|
--echo #
 | 
						|
CREATE OR REPLACE PROCEDURE p24(action IN INT, res OUT varchar) AS
 | 
						|
 a integer;
 | 
						|
BEGIN
 | 
						|
  <<lab1>>
 | 
						|
  <<lab2>>
 | 
						|
  if (action = 1) then
 | 
						|
     res:=res||' '||action;
 | 
						|
     action:=2;
 | 
						|
     goto lab1;
 | 
						|
  end if;
 | 
						|
  if (action = 2) then
 | 
						|
     res:=res||' '||action;
 | 
						|
     action:=3;
 | 
						|
     goto lab2;
 | 
						|
  end if;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
call p24(1,@res);
 | 
						|
select 'p24',@res;
 | 
						|
DROP PROCEDURE p24;
 | 
						|
 | 
						|
DELIMITER $$;
 | 
						|
--echo #
 | 
						|
--echo # Two consecutive label (backward and forward jump)
 | 
						|
--echo #
 | 
						|
CREATE OR REPLACE PROCEDURE p25(action IN INT, res OUT varchar) AS
 | 
						|
 a integer;
 | 
						|
BEGIN
 | 
						|
  if (action = 1) then
 | 
						|
     res:=res||' '||action;
 | 
						|
     action:=2;
 | 
						|
     goto lab2;
 | 
						|
  end if;
 | 
						|
  goto lab_end;
 | 
						|
  <<lab1>>
 | 
						|
  <<lab2>>
 | 
						|
  res:=res||' '||action;
 | 
						|
  if (action = 2) then
 | 
						|
     res:=res||' '||action;
 | 
						|
     action:=3;
 | 
						|
     goto lab1;
 | 
						|
  end if;
 | 
						|
<<lab_end>>
 | 
						|
  null;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
call p25(1,@res);
 | 
						|
select 'p25',@res;
 | 
						|
DROP PROCEDURE p25;
 | 
						|
 | 
						|
 | 
						|
DELIMITER $$;
 | 
						|
--echo #
 | 
						|
--echo # Two consecutive label, continue to wrong label
 | 
						|
--error ER_SP_LILABEL_MISMATCH
 | 
						|
CREATE OR REPLACE PROCEDURE p26(action IN INT, res OUT varchar) AS
 | 
						|
BEGIN
 | 
						|
  <<lab1>>
 | 
						|
  <<lab2>>
 | 
						|
  FOR i IN 1..10 LOOP
 | 
						|
    continue lab1;
 | 
						|
  END LOOP;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
 | 
						|
DELIMITER $$;
 | 
						|
--echo #
 | 
						|
--echo # Consecutive goto label and block label
 | 
						|
--echo #
 | 
						|
CREATE OR REPLACE PROCEDURE p27(action IN INT, res OUT varchar) AS
 | 
						|
BEGIN
 | 
						|
  res:='';
 | 
						|
  <<lab1>>
 | 
						|
  <<lab2>>
 | 
						|
  FOR i IN 1..10 LOOP
 | 
						|
    if (action = 1) then
 | 
						|
      res:=res||' '||action||'-'||i;
 | 
						|
      action:=2;
 | 
						|
      continue lab2;
 | 
						|
    end if;
 | 
						|
    if (action = 2) then
 | 
						|
      res:=res||' '||action||'-'||i;
 | 
						|
      action:='3';
 | 
						|
      goto lab2;
 | 
						|
    end if;
 | 
						|
    if (action = 3) then
 | 
						|
      res:=res||' '||action||'-'||i;
 | 
						|
      action:='4';
 | 
						|
      goto lab1;
 | 
						|
    end if;
 | 
						|
    if (action = 4) then
 | 
						|
      res:=res||' '||action||'-'||i;
 | 
						|
      exit lab2;
 | 
						|
    end if;
 | 
						|
  END LOOP;
 | 
						|
END;
 | 
						|
$$
 | 
						|
 | 
						|
DELIMITER ;$$
 | 
						|
call p27(1,@res);
 | 
						|
select 'p27',@res;
 | 
						|
DROP PROCEDURE p27;
 | 
						|
 | 
						|
--echo # ----------------------
 | 
						|
--echo # -- TEST IN FUNCTION --
 | 
						|
--echo # ----------------------
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # FUNCTION : Backward jump
 | 
						|
--echo #
 | 
						|
DELIMITER $$;
 | 
						|
CREATE or replace function func1()
 | 
						|
return varchar
 | 
						|
AS
 | 
						|
  p2 varchar(10);
 | 
						|
BEGIN 
 | 
						|
  p2:='a';
 | 
						|
<<lab1>>
 | 
						|
  if (p2='a') then
 | 
						|
    p2:=p2||'b';
 | 
						|
    goto lab1;
 | 
						|
  end if; 
 | 
						|
  if (p2='ab') then
 | 
						|
    p2:=p2||'c';
 | 
						|
  end if;
 | 
						|
  return p2;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
select 'func1',func1();
 | 
						|
DROP function func1;
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # FUNCTION : forward jump
 | 
						|
--echo #
 | 
						|
DELIMITER $$;
 | 
						|
CREATE or replace function func2()
 | 
						|
return varchar
 | 
						|
AS
 | 
						|
  p2 varchar(10);
 | 
						|
BEGIN 
 | 
						|
  p2:='a';
 | 
						|
  if (p2='a') then
 | 
						|
    goto lab1;
 | 
						|
  end if;
 | 
						|
  p2:='b';
 | 
						|
<<lab1>>
 | 
						|
  return p2;
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
select 'func2',func2();
 | 
						|
DROP function func2;
 | 
						|
 | 
						|
--echo # ---------------------
 | 
						|
--echo # -- TEST IN TRIGGER --
 | 
						|
--echo # ---------------------
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # TRIGGER : forward jump
 | 
						|
--echo #
 | 
						|
CREATE TABLE t1 (a INT);
 | 
						|
DELIMITER $$;
 | 
						|
CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
 | 
						|
BEGIN
 | 
						|
  IF :NEW.a IS NULL
 | 
						|
  THEN
 | 
						|
    :NEW.a:= 15;
 | 
						|
    goto end_trg;
 | 
						|
  END IF;
 | 
						|
  :NEW.a:= 10;
 | 
						|
<<end_trg>>
 | 
						|
  null; 
 | 
						|
END;
 | 
						|
$$
 | 
						|
DELIMITER ;$$
 | 
						|
insert into t1 values (1);
 | 
						|
insert into t1 values (null);
 | 
						|
SELECT * FROM t1;
 | 
						|
DROP TRIGGER trg1;
 | 
						|
DROP TABLE t1; |