Commit 4212039d authored by Alexander Barkov's avatar Alexander Barkov

MDEV-10411 Providing compatibility for basic PL/SQL constructs

Part 17: RETURN in stored procedures
parent ed19ed6a
...@@ -415,8 +415,8 @@ END; ...@@ -415,8 +415,8 @@ END;
SHOW FUNCTION CODE f1; SHOW FUNCTION CODE f1;
Pos Instruction Pos Instruction
0 set i@0 0 0 set i@0 0
1 set i@0 (i@0 + 1) 1 set i@0 i@0 + 1
2 jump_if_not 1(1) (i@0 >= 5) 2 jump_if_not 1(1) i@0 >= 5
3 jump 4 3 jump 4
4 freturn 3 i@0 4 freturn 3 i@0
SELECT f1() FROM DUAL; SELECT f1() FROM DUAL;
...@@ -437,8 +437,8 @@ END; ...@@ -437,8 +437,8 @@ END;
SHOW FUNCTION CODE f1; SHOW FUNCTION CODE f1;
Pos Instruction Pos Instruction
0 set i@0 0 0 set i@0 0
1 set i@0 (i@0 + 1) 1 set i@0 i@0 + 1
2 jump_if_not 1(0) (i@0 >= 5) 2 jump_if_not 1(0) i@0 >= 5
3 jump 4 3 jump 4
4 freturn 3 i@0 4 freturn 3 i@0
SELECT f1() FROM DUAL; SELECT f1() FROM DUAL;
...@@ -466,8 +466,8 @@ SHOW FUNCTION CODE f1; ...@@ -466,8 +466,8 @@ SHOW FUNCTION CODE f1;
Pos Instruction Pos Instruction
0 set i@0 0 0 set i@0 0
1 jump 5 1 jump 5
2 set i@0 (i@0 + 1) 2 set i@0 i@0 + 1
3 jump_if_not 8(8) (i@0 >= 5) 3 jump_if_not 8(8) i@0 >= 5
4 jump 10 4 jump 10
5 hpush_jump 2 1 EXIT 5 hpush_jump 2 1 EXIT
6 set i@0 1000 6 set i@0 1000
...@@ -506,15 +506,15 @@ SHOW PROCEDURE CODE p1; ...@@ -506,15 +506,15 @@ SHOW PROCEDURE CODE p1;
Pos Instruction Pos Instruction
0 set i@1 0 0 set i@1 0
1 jump 14 1 jump 14
2 set i@1 (i@1 + 1) 2 set i@1 i@1 + 1
3 jump_if_not 8(8) (i@1 >= 5) 3 jump_if_not 8(8) i@1 >= 5
4 jump 10 4 jump 10
5 hpush_jump 2 2 EXIT 5 hpush_jump 2 2 EXIT
6 set a@0 1000 6 set a@0 1000
7 hreturn 0 8 7 hreturn 0 8
8 hpop 1 8 hpop 1
9 jump 5 9 jump 5
10 set i@1 (i@1 + 100) 10 set i@1 i@1 + 100
11 jump 12 11 jump 12
12 set a@0 i@1 12 set a@0 i@1
13 jump 17 13 jump 17
...@@ -528,3 +528,35 @@ SELECT @v; ...@@ -528,3 +528,35 @@ SELECT @v;
@v @v
105 105
DROP PROCEDURE p1; DROP PROCEDURE p1;
# Testing RETURN in procedures
CREATE PROCEDURE p1 (a IN OUT INT)
AS
BEGIN
IF a < 10 THEN
BEGIN
a:= a + 1;
RETURN;
END;
END IF;
a:= 200;
EXCEPTION
WHEN OTHERS THEN
BEGIN
a:= 100;
RETURN;
END;
END;
/
SHOW PROCEDURE CODE p1;
Pos Instruction
0 jump 6
1 jump_if_not 4(4) a@0 < 10
2 set a@0 a@0 + 1
3 preturn
4 set a@0 200
5 jump 9
6 hpush_jump 1 1 EXIT
7 set a@0 100
8 preturn
9 hpop 1
DROP PROCEDURE p1;
...@@ -677,3 +677,62 @@ f1() ...@@ -677,3 +677,62 @@ f1()
1 1
DROP FUNCTION f1; DROP FUNCTION f1;
DROP TABLE t1; DROP TABLE t1;
# Testing RETURN in procedures
CREATE PROCEDURE p1 (a IN OUT INT)
AS
BEGIN
RETURN 10;
END;
/
ERROR 42000: RETURN is only allowed in a FUNCTION
CREATE FUNCTION f1 (a INT) RETURN INT
AS
BEGIN
RETURN;
END;
/
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ';
END' at line 4
CREATE PROCEDURE p1 (a IN OUT INT)
AS
BEGIN
IF a < 10 THEN
BEGIN
a:= a - 1;
RETURN;
END;
END IF;
a:= a + 1;
EXCEPTION
WHEN OTHERS THEN RETURN;
END;
/
SET @v=10;
CALL p1(@v);
SELECT @v;
@v
11
SET @v=9;
CALL p1(@v);
SELECT @v;
@v
8
DROP PROCEDURE p1;
CREATE PROCEDURE p1 (a IN OUT INT)
AS
BEGIN
DROP TABLE t1_non_existent;
EXCEPTION
WHEN OTHERS THEN
BEGIN
a:= 100;
RETURN;
END;
END;
/
SET @v=10;
CALL p1(@v);
SELECT @v;
@v
100
DROP PROCEDURE p1;
...@@ -416,3 +416,28 @@ set @v= 10; ...@@ -416,3 +416,28 @@ set @v= 10;
CALL p1(@v); CALL p1(@v);
SELECT @v; SELECT @v;
DROP PROCEDURE p1; DROP PROCEDURE p1;
--echo # Testing RETURN in procedures
DELIMITER /;
CREATE PROCEDURE p1 (a IN OUT INT)
AS
BEGIN
IF a < 10 THEN
BEGIN
a:= a + 1;
RETURN;
END;
END IF;
a:= 200;
EXCEPTION
WHEN OTHERS THEN
BEGIN
a:= 100;
RETURN;
END;
END;
/
DELIMITER ;/
SHOW PROCEDURE CODE p1;
DROP PROCEDURE p1;
...@@ -735,3 +735,69 @@ DELIMITER ;/ ...@@ -735,3 +735,69 @@ DELIMITER ;/
SELECT f1() FROM DUAL; SELECT f1() FROM DUAL;
DROP FUNCTION f1; DROP FUNCTION f1;
DROP TABLE t1; DROP TABLE t1;
--echo # Testing RETURN in procedures
DELIMITER /;
--error ER_SP_BADRETURN
CREATE PROCEDURE p1 (a IN OUT INT)
AS
BEGIN
RETURN 10;
END;
/
DELIMITER ;/
DELIMITER /;
--error ER_PARSE_ERROR
CREATE FUNCTION f1 (a INT) RETURN INT
AS
BEGIN
RETURN;
END;
/
DELIMITER ;/
DELIMITER /;
CREATE PROCEDURE p1 (a IN OUT INT)
AS
BEGIN
IF a < 10 THEN
BEGIN
a:= a - 1;
RETURN;
END;
END IF;
a:= a + 1;
EXCEPTION
WHEN OTHERS THEN RETURN;
END;
/
DELIMITER ;/
SET @v=10;
CALL p1(@v);
SELECT @v;
SET @v=9;
CALL p1(@v);
SELECT @v;
DROP PROCEDURE p1;
DELIMITER /;
CREATE PROCEDURE p1 (a IN OUT INT)
AS
BEGIN
DROP TABLE t1_non_existent;
EXCEPTION
WHEN OTHERS THEN
BEGIN
a:= 100;
RETURN;
END;
END;
/
DELIMITER ;/
SET @v=10;
CALL p1(@v);
SELECT @v;
DROP PROCEDURE p1;
...@@ -1030,6 +1030,41 @@ class sp_instr_jump_if_not : public sp_instr_jump ...@@ -1030,6 +1030,41 @@ class sp_instr_jump_if_not : public sp_instr_jump
}; // class sp_instr_jump_if_not : public sp_instr_jump }; // class sp_instr_jump_if_not : public sp_instr_jump
class sp_instr_preturn : public sp_instr
{
sp_instr_preturn(const sp_instr_preturn &); /**< Prevent use of these */
void operator=(sp_instr_preturn &);
public:
sp_instr_preturn(uint ip, sp_pcontext *ctx)
: sp_instr(ip, ctx)
{}
virtual ~sp_instr_preturn()
{}
virtual int execute(THD *thd, uint *nextp)
{
DBUG_ENTER("sp_instr_preturn::execute");
*nextp= UINT_MAX;
DBUG_RETURN(0);
}
virtual void print(String *str)
{
str->append(STRING_WITH_LEN("preturn"));
}
virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads)
{
marked= 1;
return UINT_MAX;
}
}; // class sp_instr_preturn : public sp_instr
class sp_instr_freturn : public sp_instr class sp_instr_freturn : public sp_instr
{ {
sp_instr_freturn(const sp_instr_freturn &); /**< Prevent use of these */ sp_instr_freturn(const sp_instr_freturn &); /**< Prevent use of these */
......
...@@ -2963,6 +2963,22 @@ sp_proc_stmt_return: ...@@ -2963,6 +2963,22 @@ sp_proc_stmt_return:
if (sp->restore_lex(thd)) if (sp->restore_lex(thd))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| RETURN_SYM
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
if (sp->m_type != TYPE_ENUM_PROCEDURE)
{
thd->parse_error();
MYSQL_YYABORT;
}
sp_instr_preturn *i;
i= new (thd->mem_root)
sp_instr_preturn(sp->instructions(), lex->spcont);
if (i == NULL || sp->add_instr(i))
MYSQL_YYABORT;
}
; ;
opt_sp_proc_stmt_exit_when_clause: opt_sp_proc_stmt_exit_when_clause:
......
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