mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-10580 sql_mode=ORACLE: FOR loop statement
Adding labeled FOR LOOP
This commit is contained in:
@ -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;
|
|||||||
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;
|
|||||||
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 ;/
|
|||||||
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:
|
|||||||
}
|
}
|
||||||
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))
|
||||||
|
Reference in New Issue
Block a user