mirror of
https://github.com/MariaDB/server.git
synced 2025-02-04 21:02:17 +01:00
e0f9540bcc
When backpatching a forward GOTO label, the old code erroneously used CURSOR/HANDLER difference between context frames "c" and "a" to tune a cpop/hpop command. So the cpop/hpop command later tried to pop all cursors/handlers declared between "a" and "c", but those between "b" and "c" were not cpushed/hpoped yet during the execution of "GOTO x". Fixing the code to use the difference between frames "b" and "a" only. BEGIN -- a ... GOTO x; -- b ... <<x>> -- c ... END -- d
913 lines
14 KiB
Text
913 lines
14 KiB
Text
set sql_mode=oracle;
|
|
#
|
|
# MDEV-10697 sql_mode=ORACLE: GOTO statement
|
|
#
|
|
# matrice of tests in procedure
|
|
# |--------------------------------------------------------
|
|
# | | Same | Outside | to sub | No |
|
|
# | | block | one block | block | matching |
|
|
# | | | | | label |
|
|
# |--------------------------------------------------------
|
|
# | Forward jump | F1 | F3 | F5 | F7 |
|
|
# |--------------------------------------------------------
|
|
# | Backward jump | F2 | F4 | F6 | F8 |
|
|
# |--------------------------------------------------------
|
|
# Jump from handler to outside handling code block : F9
|
|
# Jump from handler to handling code block : F10 (forbidden)
|
|
# Jump inside handler : F21
|
|
# Jump between handler : F22 (forbidden)
|
|
# Jump from cascaded block with handler : F11
|
|
# Duplicate label in same block : F12 (forbidden)
|
|
# Duplicate label in different block : F13
|
|
# Jump outside unlabeled block : F14
|
|
# Jump inside/outside labeled block : F15
|
|
# Jump from if / else : F16
|
|
# Jump with cursors : F17
|
|
# Jump outside case : F18
|
|
# Jump inside/outside case block : F19
|
|
# Jump outside labeled loop : F20
|
|
# Jump (continue) labeled loop : F23
|
|
# Two consecutive label : P24
|
|
# Two consecutive label (backward and forward jump) : P25
|
|
# Two consecutive label, continue to wrong label : P26
|
|
# Consecutive goto label and block label : P27
|
|
# Test in function
|
|
# backward jump : func1
|
|
# forward jump : func2
|
|
# Test in trigger
|
|
# forward jump : trg1
|
|
#
|
|
# Forward jump in same block
|
|
#
|
|
CREATE or replace procedure f1(p2 IN OUT VARCHAR)
|
|
AS
|
|
BEGIN
|
|
p2:='a';
|
|
goto lab1;
|
|
<<lab1>>
|
|
goto lab2;
|
|
p2:='b';
|
|
<<lab2>>
|
|
return ;
|
|
END;
|
|
$$
|
|
call f1(@wp1);
|
|
select 'f1',@wp1;
|
|
f1 @wp1
|
|
f1 a
|
|
DROP PROCEDURE f1;
|
|
#
|
|
# Backward jump in same block
|
|
#
|
|
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;
|
|
$$
|
|
call f2(@wp1);
|
|
select 'f2',@wp1;
|
|
f2 @wp1
|
|
f2 b
|
|
DROP PROCEDURE f2;
|
|
#
|
|
# Forward jump outside one block
|
|
#
|
|
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;
|
|
$$
|
|
call f3(@wp1);
|
|
select 'f3',@wp1;
|
|
f3 @wp1
|
|
f3 a
|
|
DROP PROCEDURE f3;
|
|
#
|
|
# Backward jump outside one block
|
|
#
|
|
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;
|
|
$$
|
|
call f4(@wp1);
|
|
select 'f4',@wp1;
|
|
f4 @wp1
|
|
f4 abc
|
|
DROP PROCEDURE f4;
|
|
#
|
|
# Forward jump inside sub block
|
|
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;
|
|
$$
|
|
ERROR 42000: GOTO with no matching label: lab5
|
|
#
|
|
# Backward jump inside sub block
|
|
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;
|
|
$$
|
|
ERROR 42000: GOTO with no matching label: lab6
|
|
#
|
|
# Backward jump - missing label
|
|
CREATE or replace procedure f7(p2 IN OUT VARCHAR)
|
|
AS
|
|
BEGIN
|
|
<<lab>>
|
|
goto lab7 ;
|
|
return ;
|
|
END;
|
|
$$
|
|
ERROR 42000: GOTO with no matching label: lab7
|
|
#
|
|
# Forward jump - missing label
|
|
CREATE or replace procedure f8(p2 IN OUT VARCHAR)
|
|
AS
|
|
BEGIN
|
|
goto lab8 ;
|
|
<<lab>>
|
|
return ;
|
|
END;
|
|
$$
|
|
ERROR 42000: GOTO with no matching label: lab8
|
|
#
|
|
# Jump from handler to procedure code
|
|
#
|
|
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;
|
|
$$
|
|
SET @res='';
|
|
CALL f9(2, @res);
|
|
SELECT 'f9',@res;
|
|
f9 @res
|
|
f9 --- too_many_rows cought ------ no_data_found cought --- -- goto end limit -1 --
|
|
CALL f9(0, @res);
|
|
SELECT 'f9',@res;
|
|
f9 @res
|
|
f9 --- no_data_found cought --- -- goto end limit -1 --
|
|
DROP PROCEDURE f9;
|
|
#
|
|
# Jump from handler to handling bloc
|
|
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;
|
|
$$
|
|
ERROR 42000: GOTO with no matching label: lab10
|
|
#
|
|
# Jump from cascaded block with handler
|
|
#
|
|
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;
|
|
$$
|
|
SET @res='';
|
|
CALL f11(0, @res);
|
|
SELECT 'f11',@res;
|
|
f11 @res
|
|
f11 --- no_data_found cought 1 ------ too_many_rows cought 2 ------ too_many_rows cought 1 ---
|
|
DROP PROCEDURE f11;
|
|
#
|
|
# Jump inside handler
|
|
#
|
|
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;
|
|
$$
|
|
SET @res='';
|
|
CALL f21(10, @res);
|
|
SELECT 'f21',@res;
|
|
f21 @res
|
|
f21 1
|
|
drop procedure f21;
|
|
#
|
|
# Jump beetween handler
|
|
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;
|
|
$$
|
|
ERROR 42000: GOTO with no matching label: nodata
|
|
#
|
|
# Duplicate label in same bloc
|
|
CREATE or replace procedure f12(lim INT, res OUT VARCHAR)
|
|
AS
|
|
a INT;
|
|
BEGIN
|
|
<<lab12>>
|
|
res:='error';
|
|
<<lab12>>
|
|
return ;
|
|
END;
|
|
$$
|
|
ERROR 42000: Redefining label lab12
|
|
#
|
|
# Duplicate label in different block
|
|
#
|
|
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;
|
|
$$
|
|
SET @res='';
|
|
CALL f13(0, @res);
|
|
SELECT 'f13',@res;
|
|
f13 @res
|
|
f13 12
|
|
DROP PROCEDURE f13;
|
|
#
|
|
# Jump outside unlabeled block
|
|
#
|
|
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;
|
|
$$
|
|
SET @res='';
|
|
CALL f14(15, @res);
|
|
SELECT 'f14',@res;
|
|
f14 @res
|
|
f14 15
|
|
CALL f14(8, @res);
|
|
SELECT 'f14',@res;
|
|
f14 @res
|
|
f14 10
|
|
CALL f14(25, @res);
|
|
SELECT 'f14',@res;
|
|
f14 @res
|
|
f14 20
|
|
DROP PROCEDURE f14;
|
|
#
|
|
# Jump inside/outside labeled block
|
|
#
|
|
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;
|
|
$$
|
|
SET @res='';
|
|
CALL f15(15, @res);
|
|
SELECT 'f15',@res;
|
|
f15 @res
|
|
f15 15
|
|
CALL f15(8, @res);
|
|
SELECT 'f15',@res;
|
|
f15 @res
|
|
f15 10
|
|
CALL f15(25, @res);
|
|
SELECT 'f15',@res;
|
|
f15 @res
|
|
f15 20
|
|
DROP PROCEDURE f15;
|
|
#
|
|
# Jump from if / else
|
|
#
|
|
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;
|
|
$$
|
|
SET @res='';
|
|
CALL f16(15, @res);
|
|
SELECT 'f16',@res;
|
|
f16 @res
|
|
f16 else lab16_2
|
|
CALL f16(8, @res);
|
|
SELECT 'f16',@res;
|
|
f16 @res
|
|
f16 if lab16_1
|
|
DROP PROCEDURE f16;
|
|
#
|
|
# Jump with cursors
|
|
#
|
|
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;
|
|
$$
|
|
SET @res='';
|
|
CALL f17(5, @res);
|
|
SELECT 'f17',@res;
|
|
f17 @res
|
|
f17 -4-3-2-1-0
|
|
DROP PROCEDURE f17;
|
|
#
|
|
# Jump outside case
|
|
#
|
|
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;
|
|
$$
|
|
SET @res='';
|
|
CALL f18(0, @res);
|
|
SELECT 'f18',@res;
|
|
f18 @res
|
|
f18 default branch 18
|
|
CALL f18(1, @res);
|
|
SELECT 'f18',@res;
|
|
f18 @res
|
|
f18 case branch 18_1
|
|
CALL f18(2, @res);
|
|
SELECT 'f18',@res;
|
|
f18 @res
|
|
f18 case branch 18_2
|
|
DROP PROCEDURE f18;
|
|
#
|
|
# Jump inside/outside case block
|
|
#
|
|
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;
|
|
$$
|
|
SET @res='';
|
|
CALL f19(1, @res);
|
|
SELECT 'f19',@res;
|
|
f19 @res
|
|
f19 10
|
|
DROP PROCEDURE f19;
|
|
#
|
|
# Jump outside labeled loop
|
|
#
|
|
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;
|
|
$$
|
|
CALL f20(@res);
|
|
SELECT 'f20',@res;
|
|
f20 @res
|
|
f20 6
|
|
DROP PROCEDURE f20;
|
|
#
|
|
# Jump (continue) labeled loop
|
|
#
|
|
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;
|
|
$$
|
|
CALL f23(@res);
|
|
SELECT 'f23',@res;
|
|
f23 @res
|
|
f23 2
|
|
DROP PROCEDURE f23;
|
|
#
|
|
# Two consecutive label (backward jump)
|
|
#
|
|
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;
|
|
$$
|
|
call p24(1,@res);
|
|
select 'p24',@res;
|
|
p24 @res
|
|
p24 1 2
|
|
DROP PROCEDURE p24;
|
|
#
|
|
# Two consecutive label (backward and forward jump)
|
|
#
|
|
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;
|
|
$$
|
|
call p25(1,@res);
|
|
select 'p25',@res;
|
|
p25 @res
|
|
p25 1 2 2 3
|
|
DROP PROCEDURE p25;
|
|
#
|
|
# Two consecutive label, continue to wrong label
|
|
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;
|
|
$$
|
|
ERROR 42000: CONTINUE with no matching label: lab1
|
|
#
|
|
# Consecutive goto label and block label
|
|
#
|
|
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;
|
|
$$
|
|
call p27(1,@res);
|
|
select 'p27',@res;
|
|
p27 @res
|
|
p27 1-1 2-2 3-1 4-1
|
|
DROP PROCEDURE p27;
|
|
# ----------------------
|
|
# -- TEST IN FUNCTION --
|
|
# ----------------------
|
|
#
|
|
# FUNCTION : Backward jump
|
|
#
|
|
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;
|
|
$$
|
|
select 'func1',func1();
|
|
func1 func1()
|
|
func1 abc
|
|
DROP function func1;
|
|
#
|
|
# FUNCTION : forward jump
|
|
#
|
|
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;
|
|
$$
|
|
select 'func2',func2();
|
|
func2 func2()
|
|
func2 a
|
|
DROP function func2;
|
|
# ---------------------
|
|
# -- TEST IN TRIGGER --
|
|
# ---------------------
|
|
#
|
|
# TRIGGER : forward jump
|
|
#
|
|
CREATE TABLE t1 (a INT);
|
|
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;
|
|
$$
|
|
insert into t1 values (1);
|
|
insert into t1 values (null);
|
|
SELECT * FROM t1;
|
|
a
|
|
10
|
|
15
|
|
DROP TRIGGER trg1;
|
|
DROP TABLE t1;
|
|
#
|
|
# MDEV-20667 Server crash on pop_cursor
|
|
#
|
|
CREATE TABLE t1 (a VARCHAR(6));
|
|
CREATE PROCEDURE p1() IS
|
|
BEGIN
|
|
IF 1=2 THEN
|
|
BEGIN
|
|
DECLARE
|
|
CURSOR cur1 IS SELECT a FROM t1 ;
|
|
BEGIN
|
|
GOTO iac_err;
|
|
END;
|
|
END;
|
|
END IF;
|
|
IF 1=1 THEN
|
|
GOTO iac_err;
|
|
END IF;
|
|
<< iac_err >>
|
|
RETURN;
|
|
END//
|
|
CALL p1();
|
|
DROP PROCEDURE p1;
|
|
DROP TABLE t1;
|
|
CREATE PROCEDURE p1() IS
|
|
BEGIN
|
|
IF 1=2 THEN
|
|
BEGIN
|
|
DECLARE
|
|
CURSOR cur1 IS SELECT a FROM t1 ;
|
|
BEGIN
|
|
GOTO iac_err;
|
|
END;
|
|
END;
|
|
END IF;
|
|
IF 1=1 THEN
|
|
GOTO iac_err;
|
|
END IF;
|
|
<< iac_err >>
|
|
RETURN ;
|
|
END//
|
|
CALL p1;
|
|
DROP PROCEDURE p1;
|
|
CREATE PROCEDURE p1() IS
|
|
BEGIN
|
|
IF 1=2 THEN
|
|
BEGIN
|
|
DECLARE
|
|
CURSOR cur1 IS SELECT a FROM t1 ;
|
|
BEGIN
|
|
GOTO iac_err;
|
|
END;
|
|
END;
|
|
END IF;
|
|
GOTO iac_err;
|
|
<< iac_err >>
|
|
RETURN ;
|
|
END//
|
|
CALL p1;
|
|
DROP PROCEDURE p1;
|
|
CREATE PROCEDURE p1() IS
|
|
BEGIN
|
|
IF 1=2 THEN
|
|
BEGIN
|
|
DECLARE
|
|
CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;
|
|
BEGIN
|
|
GOTO iac_err;
|
|
END;
|
|
END;
|
|
END IF;
|
|
IF 1=1 THEN
|
|
GOTO iac_err;
|
|
END IF;
|
|
<<iac_err >>
|
|
RETURN;
|
|
END//
|
|
CALL p1;
|
|
DROP PROCEDURE p1;
|