Skip to content

Commit

Permalink
MDEV-10580 sql_mode=ORACLE: FOR loop statement
Browse files Browse the repository at this point in the history
Adding labeled FOR LOOP
  • Loading branch information
Alexander Barkov committed Apr 5, 2017
1 parent c570636 commit 2ea6349
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 0 deletions.
50 changes: 50 additions & 0 deletions mysql-test/suite/compat/oracle/r/sp-code.result
Expand Up @@ -627,3 +627,53 @@ SELECT f1(3, 2) FROM DUAL;
f1(3, 2)
5
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;
39 changes: 39 additions & 0 deletions mysql-test/suite/compat/oracle/r/sp.result
Expand Up @@ -860,3 +860,42 @@ SELECT f1(3, 2) FROM DUAL;
f1(3, 2)
5
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;
29 changes: 29 additions & 0 deletions mysql-test/suite/compat/oracle/t/sp-code.test
Expand Up @@ -485,3 +485,32 @@ SHOW FUNCTION CODE f1;
SELECT f1(3, 100) FROM DUAL;
SELECT f1(3, 2) FROM DUAL;
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;
32 changes: 32 additions & 0 deletions mysql-test/suite/compat/oracle/t/sp.test
Expand Up @@ -931,3 +931,35 @@ DELIMITER ;/
SELECT f1(3, 100) FROM DUAL;
SELECT f1(3, 2) FROM DUAL;
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;
24 changes: 24 additions & 0 deletions sql/sql_yacc_ora.yy
Expand Up @@ -3575,6 +3575,30 @@ sp_labeled_control:
}
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
{
if (Lex->sp_push_loop_label(thd, $1))
Expand Down

0 comments on commit 2ea6349

Please sign in to comment.