Commit 2ea63492 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-10580 sql_mode=ORACLE: FOR loop statement

Adding labeled FOR LOOP
parent c570636b
...@@ -627,3 +627,53 @@ SELECT f1(3, 2) FROM DUAL; ...@@ -627,3 +627,53 @@ SELECT f1(3, 2) FROM DUAL;
f1(3, 2) f1(3, 2)
5 5
DROP FUNCTION f1; DROP FUNCTION f1;
# Testing labeled FOR LOOP statement
CREATE FUNCTION f1 (a INT, limita INT, b INT, limitb INT) RETURN INT
AS
total INT := 0;
BEGIN
<<la>>
FOR ia IN 1 .. a
LOOP
total:= total + 1000;
<<lb>>
FOR ib IN 1 .. b
LOOP
total:= total + 1;
EXIT lb WHEN ib = limitb;
EXIT la WHEN ia = limita;
END LOOP lb;
END LOOP la;
RETURN total;
END;
/
SHOW FUNCTION CODE f1;
Pos Instruction
0 set total@4 0
1 set ia@5 1
2 set [upper_bound]@6 a@0
3 jump_if_not 17(17) (ia@5 <= [upper_bound]@6)
4 set total@4 (total@4 + 1000)
5 set ib@7 1
6 set [upper_bound]@8 b@2
7 jump_if_not 15(15) (ib@7 <= [upper_bound]@8)
8 set total@4 (total@4 + 1)
9 jump_if_not 11(0) (ib@7 = limitb@3)
10 jump 15
11 jump_if_not 13(0) (ia@5 = limita@1)
12 jump 17
13 set ib@7 (ib@7 + 1)
14 jump 7
15 set ia@5 (ia@5 + 1)
16 jump 3
17 freturn 3 total@4
SELECT f1(2, 1, 2, 2) FROM DUAL;
f1(2, 1, 2, 2)
1001
SELECT f1(2, 2, 2, 2) FROM DUAL;
f1(2, 2, 2, 2)
2003
SELECT f1(2, 3, 2, 3) FROM DUAL;
f1(2, 3, 2, 3)
2004
DROP FUNCTION f1;
...@@ -860,3 +860,42 @@ SELECT f1(3, 2) FROM DUAL; ...@@ -860,3 +860,42 @@ SELECT f1(3, 2) FROM DUAL;
f1(3, 2) f1(3, 2)
5 5
DROP FUNCTION f1; DROP FUNCTION f1;
# Testing labeled FOR LOOP statement
CREATE FUNCTION f1 (a INT, limita INT, b INT, limitb INT) RETURN INT
AS
total INT := 0;
BEGIN
<<la>>
FOR ia IN 1 .. a
LOOP
total:= total + 1000;
<<lb>>
FOR ib IN 1 .. b
LOOP
total:= total + 1;
EXIT lb WHEN ib = limitb;
EXIT la WHEN ia = limita;
END LOOP lb;
END LOOP la;
RETURN total;
END;
/
SELECT f1(1, 1, 1, 1) FROM DUAL;
f1(1, 1, 1, 1)
1001
SELECT f1(1, 2, 1, 2) FROM DUAL;
f1(1, 2, 1, 2)
1001
SELECT f1(2, 1, 2, 1) FROM DUAL;
f1(2, 1, 2, 1)
2002
SELECT f1(2, 1, 2, 2) FROM DUAL;
f1(2, 1, 2, 2)
1001
SELECT f1(2, 2, 2, 2) FROM DUAL;
f1(2, 2, 2, 2)
2003
SELECT f1(2, 3, 2, 3) FROM DUAL;
f1(2, 3, 2, 3)
2004
DROP FUNCTION f1;
...@@ -485,3 +485,32 @@ SHOW FUNCTION CODE f1; ...@@ -485,3 +485,32 @@ SHOW FUNCTION CODE f1;
SELECT f1(3, 100) FROM DUAL; SELECT f1(3, 100) FROM DUAL;
SELECT f1(3, 2) FROM DUAL; SELECT f1(3, 2) FROM DUAL;
DROP FUNCTION f1; DROP FUNCTION f1;
--echo # Testing labeled FOR LOOP statement
DELIMITER /;
CREATE FUNCTION f1 (a INT, limita INT, b INT, limitb INT) RETURN INT
AS
total INT := 0;
BEGIN
<<la>>
FOR ia IN 1 .. a
LOOP
total:= total + 1000;
<<lb>>
FOR ib IN 1 .. b
LOOP
total:= total + 1;
EXIT lb WHEN ib = limitb;
EXIT la WHEN ia = limita;
END LOOP lb;
END LOOP la;
RETURN total;
END;
/
DELIMITER ;/
SHOW FUNCTION CODE f1;
SELECT f1(2, 1, 2, 2) FROM DUAL;
SELECT f1(2, 2, 2, 2) FROM DUAL;
SELECT f1(2, 3, 2, 3) FROM DUAL;
DROP FUNCTION f1;
...@@ -931,3 +931,35 @@ DELIMITER ;/ ...@@ -931,3 +931,35 @@ DELIMITER ;/
SELECT f1(3, 100) FROM DUAL; SELECT f1(3, 100) FROM DUAL;
SELECT f1(3, 2) FROM DUAL; SELECT f1(3, 2) FROM DUAL;
DROP FUNCTION f1; DROP FUNCTION f1;
--echo # Testing labeled FOR LOOP statement
DELIMITER /;
CREATE FUNCTION f1 (a INT, limita INT, b INT, limitb INT) RETURN INT
AS
total INT := 0;
BEGIN
<<la>>
FOR ia IN 1 .. a
LOOP
total:= total + 1000;
<<lb>>
FOR ib IN 1 .. b
LOOP
total:= total + 1;
EXIT lb WHEN ib = limitb;
EXIT la WHEN ia = limita;
END LOOP lb;
END LOOP la;
RETURN total;
END;
/
DELIMITER ;/
SELECT f1(1, 1, 1, 1) FROM DUAL;
SELECT f1(1, 2, 1, 2) FROM DUAL;
SELECT f1(2, 1, 2, 1) FROM DUAL;
SELECT f1(2, 1, 2, 2) FROM DUAL;
SELECT f1(2, 2, 2, 2) FROM DUAL;
SELECT f1(2, 3, 2, 3) FROM DUAL;
DROP FUNCTION f1;
...@@ -3575,6 +3575,30 @@ sp_labeled_control: ...@@ -3575,6 +3575,30 @@ sp_labeled_control:
} }
while_body pop_sp_loop_label while_body pop_sp_loop_label
{ } { }
| label_declaration_oracle FOR_SYM
{
// See "The FOR LOOP statement" comments in sql_lex.cc
Lex->sp_block_init(thd); // The outer DECLARE..BEGIN..END block
}
sp_for_loop_index_and_bounds
{
if (Lex->sp_push_loop_label(thd, $1)) // The inner WHILE block
MYSQL_YYABORT;
if (Lex->sp_for_loop_index_and_bounds(thd, $4))
MYSQL_YYABORT;
}
LOOP_SYM
sp_proc_stmts1
END LOOP_SYM
{
if (Lex->sp_for_loop_finalize(thd, $4))
MYSQL_YYABORT;
}
pop_sp_loop_label // The inner WHILE block
{
if (Lex->sp_block_finalize(thd)) // The outer DECLARE..BEGIN..END
MYSQL_YYABORT;
}
| label_declaration_oracle REPEAT_SYM | label_declaration_oracle REPEAT_SYM
{ {
if (Lex->sp_push_loop_label(thd, $1)) if (Lex->sp_push_loop_label(thd, $1))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment