diff options
author | Alexander Barkov <bar@mariadb.com> | 2021-11-26 06:56:04 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2021-12-16 04:06:54 +0400 |
commit | aff084d139a9fca9d569fedd9ec80bd9576614b1 (patch) | |
tree | 41ca142e1c5692c5684b38ffcd9d91970acd1337 | |
parent | 5d23c67d37e822a994b32990ec1ac57af5896120 (diff) | |
download | mariadb-git-preview-10.8-MDEV-10654-inout-params.tar.gz |
A clean-up for MDEV-10654 add support IN, OUT, INOUT parameter qualifiers for stored functionspreview-10.8-MDEV-10654-inout-params
Changes:
1. Enabling IN/OUT/INOUT mode for sql_mode=DEFAULT,
adding tests for sql_mode=DEFAULT based by mostly
translating compat/oracle.sp-inout.test to SQL/PSM
with minor changes (e.g. testing trigger OLD.column and
NEW.column as IN/OUT parameters).
2. Removing duplicate grammar:
sp_pdparam and sp_fdparam implemented exactly the same syntax after
- the first patch for MDEV-10654 (for sql_mode=ORACLE)
- the change #1 from this patch (for sql_mode=DEFAULT)
Removing separate rules and adding a single "sp_param" rule instead,
which now covers both PRDEDURE and FUNCTION parameters
(and CURSOR parameters as well!).
3. Adding a helper rule sp_param_name_and_mode, which is a combination
of the parameter name and the IN/OUT/INOUT mode. It allows to simplify
the grammer a bit.
4. The first patch unintentionally allowed IN/OUT/INOUT mode
to be specified in CURSOR parameters.
This is good for the IN keyword - it is allowed in PL/SQL CURSORs.
This is not good the the OUT/INOUT keywords - they should not be allowed.
Adding a additional symantic post-check.
-rw-r--r-- | mysql-test/main/sp-cursor.result | 40 | ||||
-rw-r--r-- | mysql-test/main/sp-cursor.test | 51 | ||||
-rw-r--r-- | mysql-test/main/sp-inout.result | 2033 | ||||
-rw-r--r-- | mysql-test/main/sp-inout.test | 1964 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/r/sp-cursor.result | 43 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/t/sp-cursor.test | 55 | ||||
-rw-r--r-- | sql/sql_lex.cc | 21 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 128 |
8 files changed, 4254 insertions, 81 deletions
diff --git a/mysql-test/main/sp-cursor.result b/mysql-test/main/sp-cursor.result index 110ae7be03a..dc38ad64069 100644 --- a/mysql-test/main/sp-cursor.result +++ b/mysql-test/main/sp-cursor.result @@ -737,3 +737,43 @@ rec.en1 c DROP PROCEDURE p1; DROP TABLE t1; +# +# Start of 10.8 tests +# +# +# MDEV-10654 IN, OUT, INOUT parameters in CREATE FUNCTION +# +BEGIN NOT ATOMIC +DECLARE va INT; +DECLARE cur CURSOR (IN a INT) FOR SELECT a FROM dual; +OPEN cur(1); +FETCH cur INTO va; +CLOSE cur; +SELECT va; +END; +$$ +va +1 +BEGIN NOT ATOMIC +DECLARE va INT; +DECLARE cur CURSOR (OUT a INT) FOR SELECT a FROM dual; +OPEN cur(1); +FETCH cur INTO va; +CLOSE cur; +SELECT va; +END; +$$ +ERROR 42000: This version of MariaDB doesn't yet support 'OUT/INOUT cursor parameter' +BEGIN NOT ATOMIC +DECLARE va INT; +DECLARE cur CURSOR (INOUT a INT) FOR SELECT a FROM dual; +OPEN cur(1); +FETCH cur INTO va; +CLOSE cur; +SELECT va; +END; +$$ +ERROR 42000: This version of MariaDB doesn't yet support 'OUT/INOUT cursor parameter' +# +# End of 10.8 tests +# diff --git a/mysql-test/main/sp-cursor.test b/mysql-test/main/sp-cursor.test index 97483ef9caf..f86721f41e8 100644 --- a/mysql-test/main/sp-cursor.test +++ b/mysql-test/main/sp-cursor.test @@ -744,3 +744,54 @@ DELIMITER ;$$ CALL p1(); DROP PROCEDURE p1; DROP TABLE t1; + + +--echo # +--echo # Start of 10.8 tests +--echo # + +--echo # +--echo # MDEV-10654 IN, OUT, INOUT parameters in CREATE FUNCTION +--echo # + +DELIMITER $$; +BEGIN NOT ATOMIC + DECLARE va INT; + DECLARE cur CURSOR (IN a INT) FOR SELECT a FROM dual; + OPEN cur(1); + FETCH cur INTO va; + CLOSE cur; + SELECT va; +END; +$$ +DELIMITER ;$$ + +DELIMITER $$; +--error ER_NOT_SUPPORTED_YET +BEGIN NOT ATOMIC + DECLARE va INT; + DECLARE cur CURSOR (OUT a INT) FOR SELECT a FROM dual; + OPEN cur(1); + FETCH cur INTO va; + CLOSE cur; + SELECT va; +END; +$$ +DELIMITER ;$$ + +DELIMITER $$; +--error ER_NOT_SUPPORTED_YET +BEGIN NOT ATOMIC + DECLARE va INT; + DECLARE cur CURSOR (INOUT a INT) FOR SELECT a FROM dual; + OPEN cur(1); + FETCH cur INTO va; + CLOSE cur; + SELECT va; +END; +$$ +DELIMITER ;$$ + +--echo # +--echo # End of 10.8 tests +--echo # diff --git a/mysql-test/main/sp-inout.result b/mysql-test/main/sp-inout.result new file mode 100644 index 00000000000..a1e7ffa9799 --- /dev/null +++ b/mysql-test/main/sp-inout.result @@ -0,0 +1,2033 @@ +# +# MDEV-10654 IN, OUT, INOUT parameters in CREATE FUNCTION +# +# +# CREATE FUNCTION with IN, OUT, INOUT qualifiers +# SHOW CREATE FUNCTION +# +CREATE FUNCTION add_func(IN a INT, IN b INT, OUT c INT, INOUT d INT) RETURNS INT +BEGIN +SET c= 100; +SET d= d + 1; +RETURN a + b; +END; +$$ +SHOW CREATE FUNCTION add_func; +Function sql_mode Create Function character_set_client collation_connection Database Collation +add_func STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `add_func`(IN a INT, IN b INT, OUT c INT, INOUT d INT) RETURNS int(11) +BEGIN +SET c= 100; +SET d= d + 1; +RETURN a + b; +END latin1 latin1_swedish_ci latin1_swedish_ci +DROP FUNCTION add_func; +# +# CREATE PROCEDURE with IN, OUT, INOUT qualifiers +# SHOW CREATE PROCEDURE +# +CREATE PROCEDURE add_proc(IN a INT, IN b INT, INOUT c INT, OUT d INT) +BEGIN +SET d= a + b + c + d; +END; +$$ +SHOW CREATE PROCEDURE add_proc; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +add_proc STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `add_proc`(IN a INT, IN b INT, INOUT c INT, OUT d INT) +BEGIN +SET d= a + b + c + d; +END latin1 latin1_swedish_ci latin1_swedish_ci +DROP PROCEDURE add_proc; +# +# Call function from SELECT query +# SELECT > FUNCTION(IN) +# +CREATE FUNCTION add_func2(IN a INT, IN b INT) RETURNS INT +BEGIN +RETURN a + b; +END; +$$ +SET @a = 2; +SET @b = 3; +SELECT add_func2(@a, @b); +add_func2(@a, @b) +5 +DROP FUNCTION add_func2; +# +# Call function from SELECT query +# SELECT > FUNCTION(OUT) +# +CREATE FUNCTION add_func3(IN a INT, IN b INT, OUT c INT) RETURNS INT +BEGIN +SET c = 100; +RETURN a + b; +END; +$$ +SET @a = 2; +SET @b = 3; +SET @c = 0; +SET @res= add_func3(@a, @b, @c); +SELECT @res, @a, @b, @c; +@res @a @b @c +5 2 3 100 +SELECT add_func3(@a, @b, @c); +ERROR HY000: OUT or INOUT argument 3 for function add_func3 is not allowed here +DROP FUNCTION add_func3; +# +# Call function from SELECT query +# SELECT > FUNCTION(INOUT) +# +CREATE FUNCTION add_func4(IN a INT, IN b INT, OUT c INT, INOUT d INT) RETURNS INT +BEGIN +SET c = 100; +SET d = d + 1; +RETURN a + b; +END; +$$ +SET @a = 2; +SET @b = 3; +SET @c = 0; +SET @d = 9; +SET @res= add_func4(@a, @b, @c, @d); +SELECT @res, @a, @b, @c, @d; +@res @a @b @c @d +5 2 3 100 10 +SELECT add_func4(@a, @b, @c, @d); +ERROR HY000: OUT or INOUT argument 3 for function add_func4 is not allowed here +DROP FUNCTION add_func4; +# +# Call from procedure +# PROCEDURE(OUT) > FUNCTION(IN) +# +CREATE FUNCTION add_func2(IN a INT, IN b INT) RETURNS INT +BEGIN +RETURN a + b; +END; +$$ +CREATE PROCEDURE add_proc2(IN a INT, IN b INT, OUT c INT) +BEGIN +SET c = add_func2(a, b); +END; +$$ +SET @a = 2; +SET @b = 3; +SET @c = 0; +CALL add_proc2(@a, @b, @c); +SELECT @a, @b, @c; +@a @b @c +2 3 5 +DROP FUNCTION add_func2; +DROP PROCEDURE add_proc2; +# +# Call from procedure +# PROCEDURE(OUT) > FUNCTION(OUT) +# +CREATE FUNCTION add_func3(IN a INT, IN b INT, OUT c INT) RETURNS INT +BEGIN +SET c = 100; +RETURN a + b; +END; +$$ +CREATE PROCEDURE add_proc3(IN a INT, IN b INT, OUT c INT) +BEGIN +DECLARE res INT; +SET res = add_func3(a, b, c); +END; +$$ +SET @a = 2; +SET @b = 3; +SET @c = 0; +CALL add_proc3(@a, @b, @c); +SELECT @a, @b, @c; +@a @b @c +2 3 100 +DROP FUNCTION add_func3; +DROP PROCEDURE add_proc3; +# +# Call from procedure +# PROCEDURE(OUT) > FUNCTION(INOUT) +# +CREATE FUNCTION add_func4(IN a INT, IN b INT, OUT c INT, INOUT d INT) RETURNS INT +BEGIN +SET c = 100; +SET d = d + 1; +RETURN a + b; +END; +$$ +CREATE PROCEDURE add_proc4(IN a INT, IN b INT, OUT res INT) +BEGIN +DECLARE c INT; +DECLARE d INT; +SET d = 30; +SET res = add_func4(a, b, c, d); +SET res = c + d; +END; +$$ +SET @a = 2; +SET @b = 3; +SET @res = 0; +CALL add_proc4(@a, @b, @res); +SELECT @a, @b, @res; +@a @b @res +2 3 131 +DROP FUNCTION add_func4; +DROP PROCEDURE add_proc4; +# +# Call from procedure +# PROCEDURE(OUT) > PROCEDURE(OUT) +# +CREATE PROCEDURE add_proc(IN a INT, IN b INT, OUT c INT) +BEGIN +SET c = a + b; +END; +$$ +CREATE PROCEDURE test_proc1(IN a INT, IN b INT, OUT c INT) +BEGIN +CALL add_proc(a, b, c); +END; +$$ +SET @a = 2; +SET @b = 3; +SET @c = 0; +CALL test_proc1(@a, @b, @c); +SELECT @a, @b, @c; +@a @b @c +2 3 5 +DROP PROCEDURE add_proc; +DROP PROCEDURE test_proc1; +# +# Argument's order change +# PROCEDURE(a IN, b IN, c OUT) > FUNCTION(b IN, a IN, c OUT) +# +CREATE FUNCTION func_sub(IN b INT, IN a INT, OUT c INT) RETURNS INT +BEGIN +DECLARE res INT; +SET c = a - b; +SET res = a; +RETURN res; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, IN b INT, OUT c INT) +BEGIN +DECLARE res INT; +SET res = func_sub(b, a, c); +END; +$$ +SET @a = 2; +SET @b = 3; +SET @c = 0; +CALL proc_main(@a, @b, @c); +SELECT @a, @b, @c; +@a @b @c +2 3 -1 +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; +# +# Argument's order change +# PROCEDURE(a IN, b IN, c OUT) > FUNCTION(c OUT, b IN, a IN) +# +CREATE FUNCTION func_sub(OUT c INT, IN b INT, IN a INT) RETURNS INT +BEGIN +DECLARE res INT; +SET c = a - b; +SET res = a; +RETURN res; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, IN b INT, OUT c INT) +BEGIN +DECLARE res INT; +SET res = func_sub(c, b, a); +END; +$$ +SET @a = 2; +SET @b = 3; +SET @c = 0; +CALL proc_main(@a, @b, @c); +SELECT @a, @b, @c; +@a @b @c +2 3 -1 +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; +# +# Argument's order change +# PROCEDURE(a IN, b IN, c INOUT, d OUT) > FUNCTION(d OUT, a IN, b IN, c INOUT) +# +CREATE FUNCTION func_sub(OUT d INT, IN a INT, IN b INT, INOUT c INT) RETURNS INT +BEGIN +SET c = c + 6; +SET d = 10; +RETURN a - b; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, IN b INT, INOUT c INT, OUT d INT) +BEGIN +DECLARE res INT; +SET res = func_sub(d, a, b, c); +SET d = d + c + res; +END; +$$ +SET @a = 15; +SET @b = 5; +SET @c = 4; +SET @d= 0; +CALL proc_main(@a, @b, @c, @d); +SELECT @a, @b, @c, @d; +@a @b @c @d +15 5 10 30 +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; +# +# Argument's order change +# PROCEDURE(IN a INT, IN b INT, INOUT c INT, OUT d INT) > FUNCTION1(c INOUT INT, IN b INT) > FUNCTION2(d OUT INT, IN a INT) +# +CREATE FUNCTION func_sub1(INOUT c INT, IN b INT) RETURNS INT +BEGIN +SET c = c + b; +RETURN 0; +END; +$$ +CREATE FUNCTION func_sub2(OUT d INT, IN a INT) RETURNS INT +BEGIN +SET d = 5 + a; +RETURN 0; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, IN b INT, INOUT c INT, OUT d INT) +BEGIN +DECLARE res1 INT; +DECLARE res2 INT; +SET res1 = func_sub1(c, b); +SET res2 = func_sub2(d, a); +SET d = d + c; +END; +$$ +SET @a = 15; +SET @b = 6; +SET @c = 4; +SET @d= 0; +CALL proc_main(@a, @b, @c, @d); +SELECT @a, @b, @c, @d; +@a @b @c @d +15 6 10 30 +DROP FUNCTION func_sub1; +DROP FUNCTION func_sub2; +DROP PROCEDURE proc_main; +# +# Argument's order change +# FUNCTION1(a IN, b IN) > FUNCTION2(b IN, c OUT, a IN) +# +CREATE FUNCTION func_sub(IN b INT, OUT c INT, IN a INT) RETURNS INT +BEGIN +SET c = 100; +RETURN a + b; +END; +$$ +CREATE FUNCTION func_main(IN a INT, IN b INT) RETURNS INT +BEGIN +DECLARE c INT; +DECLARE res INT; +SET res = func_sub(b, c, a); +RETURN res + c; +END; +$$ +SET @a = 2; +SET @b = 3; +SELECT func_main(@a, @b); +func_main(@a, @b) +105 +DROP FUNCTION func_sub; +DROP FUNCTION func_main; +# +# Call procedure inside function +# FUNCTION1(a IN, b IN) > PROCEDURE(a IN, b IN, c OUT) +# +CREATE PROCEDURE proc_sub(IN a INT, IN b INT, OUT c INT) +BEGIN +SET c = a + b; +END; +$$ +CREATE FUNCTION func_main(IN b INT, IN a INT) RETURNS INT +BEGIN +DECLARE c INT; +CALL proc_sub(a, b, c); +RETURN c; +END; +$$ +SET @a = 2; +SET @b = 3; +SELECT func_main(@a, @b); +func_main(@a, @b) +5 +DROP PROCEDURE proc_sub; +DROP FUNCTION func_main; +# +# Call procedure inside function +# FUNCTION1(a IN, b IN) > PROCEDURE(a IN, b INOUT) +# +CREATE PROCEDURE proc_sub(IN a INT, INOUT b INT) +BEGIN +SET b = a + b; +END; +$$ +CREATE FUNCTION func_main(IN b INT, IN a INT) RETURNS INT +BEGIN +CALL proc_sub(a, b); +RETURN b; +END; +$$ +SET @a = 2; +SET @b = 3; +SELECT func_main(@a, @b); +func_main(@a, @b) +5 +DROP PROCEDURE proc_sub; +DROP FUNCTION func_main; +# +# Call procedure inside function +# FUNCTION1(a IN, b IN, c OUT) > PROCEDURE(a IN, b IN, c OUT) +# +CREATE PROCEDURE proc_sub(IN a INT, IN b INT, OUT c INT) +BEGIN +SET c = a + b; +END; +$$ +CREATE FUNCTION func_main(IN b INT, IN a INT, OUT c INT) RETURNS INT +BEGIN +DECLARE res INT; +CALL proc_sub(a, b, c); +RETURN 0; +END; +$$ +SET @a = 2; +SET @b = 3; +SET @c = 0; +DO func_main(@a, @b, @c); +SELECT @a, @b, @c; +@a @b @c +2 3 5 +SELECT func_main(@a, @b, @c); +ERROR HY000: OUT or INOUT argument 3 for function func_main is not allowed here +DROP PROCEDURE proc_sub; +DROP FUNCTION func_main; +# +# Call function from UPDATE query +# UPDATE <table> SET <column> = FUNCTION(a IN) +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE FUNCTION func(IN a INT) RETURNS INT +BEGIN +RETURN a * 10; +END; +$$ +SET @a = 5; +UPDATE Persons SET Age = func(@a) WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +DROP TABLE Persons; +DROP FUNCTION func; +# +# Call function from UPDATE query +# UPDATE <table> SET <column> = FUNCTION(a OUT) +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE FUNCTION func(OUT a INT) RETURNS INT +BEGIN +SET a = 5; +RETURN 80; +END; +$$ +SET @a = 0; +UPDATE Persons SET Age = func(@a) WHERE ID = 1; +ERROR HY000: OUT or INOUT argument 1 for function func is not allowed here +DROP TABLE Persons; +DROP FUNCTION func; +# +# Call function from INSERT query +# INSERT INTO <table> SELECT <val1>, <val2>, FUNCTION(a IN) +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE FUNCTION func(IN a INT) RETURNS INT +BEGIN +RETURN a * 10; +END; +$$ +SET @a = 4; +INSERT INTO Persons SELECT 4, 'DDD', func(@a); +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +DROP TABLE Persons; +DROP FUNCTION func; +# +# Call function from INSERT query +# INSERT INTO <table> SELECT <val1>, <val2>, FUNCTION(a OUT) +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE FUNCTION func(OUT a INT) RETURNS INT +BEGIN +SET a = 45; +RETURN 40; +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SET @a = 0; +INSERT INTO Persons SELECT 5, 'EEE', func(@a); +ERROR HY000: OUT or INOUT argument 1 for function func is not allowed here +DROP TABLE Persons; +DROP FUNCTION func; +# +# Call function from DELETE query +# DELETE FROM <table> WHERE <column> = FUNCTION(a IN) +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE FUNCTION func(IN a INT) RETURNS INT +BEGIN +RETURN a; +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +SET @a = 4; +DELETE FROM Persons WHERE ID = func(@a); +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +DROP TABLE Persons; +DROP FUNCTION func; +# +# Call function from DELETE query +# DELETE FROM <table> WHERE <column> = FUNCTION(a OUT) +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE FUNCTION func(OUT a INT) RETURNS INT +BEGIN +SET a = 40; +RETURN 4; +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +SET @a = 0; +DELETE FROM Persons WHERE ID = func(@a); +ERROR HY000: OUT or INOUT argument 1 for function func is not allowed here +DROP TABLE Persons; +DROP FUNCTION func; +# +# SELECT query inside function +# FUNCTION(a IN) > SELECT … FROM <table> +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE FUNCTION func_main(IN a INT) RETURNS INT +BEGIN +DECLARE c INT; +SELECT AGE INTO c FROM Persons WHERE ID = a; +RETURN c; +END; +$$ +SET @a = 3; +SELECT func_main(@a); +func_main(@a) +30 +SELECT * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +DROP TABLE Persons; +DROP FUNCTION func_main; +# +# SELECT query inside function +# FUNCTION(a OUT) > SELECT … FROM <table> +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE FUNCTION func_main(OUT a INT) RETURNS INT +BEGIN +SELECT AGE INTO a FROM Persons WHERE ID = 3; +RETURN 0; +END; +$$ +SET @a = 0; +SELECT func_main(@a); +ERROR HY000: OUT or INOUT argument 1 for function func_main is not allowed here +DROP TABLE Persons; +DROP FUNCTION func_main; +# +# SELECT query inside function +# FUNCTION(a INOUT) > SELECT … FROM <table> +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE FUNCTION func_main(INOUT a INT) RETURNS INT +BEGIN +SELECT AGE INTO a FROM Persons WHERE ID = a; +RETURN 0; +END; +$$ +SET @a = 1; +SELECT func_main(@a); +ERROR HY000: OUT or INOUT argument 1 for function func_main is not allowed here +DROP TABLE Persons; +DROP FUNCTION func_main; +# +# SELECT query inside function +# FUNCTION(a IN) > FUNCTION(a IN, b OUT) > SELECT … FROM <table> +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE FUNCTION func_sub(IN a INT, OUT b INT) RETURNS INT +BEGIN +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +$$ +CREATE FUNCTION func_main(IN a INT) RETURNS INT +BEGIN +DECLARE b INT; +DECLARE res INT; +SET res = func_sub(a, b); +RETURN b; +END; +$$ +SET @a = 2; +SELECT func_main(@a); +func_main(@a) +20 +SELECT * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP FUNCTION func_main; +# +# UPDATE query inside function +# FUNCTION(a IN) > UPDATE <table> SET … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); +CREATE FUNCTION func_main(IN a INT) RETURNS INT +BEGIN +DECLARE c INT; +UPDATE Persons SET AGE = 50 WHERE ID = a; +SELECT AGE INTO c FROM Persons WHERE ID = a; +RETURN c; +END; +$$ +SELECT * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 40 +SET @a = 5; +SELECT func_main(@a); +func_main(@a) +50 +SELECT * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 50 +DROP TABLE Persons; +DROP FUNCTION func_main; +# +# UPDATE query inside function +# FUNCTION(a IN, b OUT) > UPDATE <table> SET … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); +CREATE FUNCTION func_main(IN a INT, OUT b INT) RETURNS INT +BEGIN +UPDATE Persons SET AGE = 60 WHERE ID = a; +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +$$ +SET @a = 5; +SET @b = 0; +SELECT func_main(@a, @b); +ERROR HY000: OUT or INOUT argument 2 for function func_main is not allowed here +DROP TABLE Persons; +DROP FUNCTION func_main; +# +# UPDATE query inside function +# FUNCTION(a IN, b INOUT) > UPDATE <table> SET … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); +CREATE FUNCTION func_main(IN a INT, INOUT b INT) RETURNS INT +BEGIN +UPDATE Persons SET AGE = 60 WHERE ID = a; +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +$$ +SET @a = 5; +SET @b = 0; +SELECT func_main(@a, @b); +ERROR HY000: OUT or INOUT argument 2 for function func_main is not allowed here +DROP TABLE Persons; +DROP FUNCTION func_main; +# +# UPDATE query inside function +# FUNCTION(a IN) > FUNCTION(a IN, b OUT) > UPDATE <table> SET … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 80); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); +CREATE FUNCTION func_sub(IN a INT, OUT b INT) RETURNS INT +BEGIN +UPDATE Persons SET AGE = 10 WHERE ID = a; +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +$$ +CREATE FUNCTION func_main(IN a INT) RETURNS INT +BEGIN +DECLARE b INT; +DECLARE res INT; +SET res = func_sub(a, b); +RETURN b; +END; +$$ +SELECT * from Persons; +ID Name Age +1 AAA 80 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 40 +SET @a = 1; +SELECT func_main(@a); +func_main(@a) +10 +SELECT * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 40 +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP FUNCTION func_main; +# +# INSERT query inside function +# FUNCTION(a IN) > INSERT INTO <table> VALUES … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 50); +CREATE FUNCTION func_main(IN a INT) RETURNS INT +BEGIN +DECLARE b INT; +INSERT INTO Persons VALUE (a, 'FFF', 60); +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN b; +END; +$$ +SELECT * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 50 +SET @a = 6; +SELECT func_main(@a); +func_main(@a) +60 +SELECT * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 50 +6 FFF 60 +DROP TABLE Persons; +DROP FUNCTION func_main; +# +# INSERT query inside function +# FUNCTION(a IN, b OUT) > INSERT INTO <table> VALUES … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 50); +CREATE FUNCTION func_main(IN a INT, OUT b INT) RETURNS INT +BEGIN +INSERT INTO Persons VALUE (a, 'FFF', 60); +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +$$ +SELECT * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 50 +SET @a = 6; +SET @b = 0; +SELECT func_main(@a, @b); +ERROR HY000: OUT or INOUT argument 2 for function func_main is not allowed here +DROP TABLE Persons; +DROP FUNCTION func_main; +# +# INSERT query inside function +# FUNCTION(a IN, b INOUT) > INSERT INTO <table> VALUES … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); +CREATE FUNCTION func_main(IN a INT, INOUT b INT) RETURNS INT +BEGIN +INSERT INTO Persons VALUE (a, 'FFF', 60); +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +$$ +SELECT * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 40 +SET @a = 6; +SET @b = 0; +SELECT func_main(@a, @b); +ERROR HY000: OUT or INOUT argument 2 for function func_main is not allowed here +DROP TABLE Persons; +DROP FUNCTION func_main; +# +# INSERT query inside function +# FUNCTION(a IN) > FUNCTION(a IN, b OUT) > INSERT INTO <table> VALUES … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); +CREATE FUNCTION func_sub(IN a INT, OUT b INT) RETURNS INT +BEGIN +INSERT INTO Persons VALUE (a, 'FFF', 60); +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +$$ +CREATE FUNCTION func_main(IN a INT) RETURNS INT +BEGIN +DECLARE b INT; +DECLARE res INT; +SET res = func_sub(a, b); +RETURN b; +END; +$$ +SELECT * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 40 +SET @a = 6; +SELECT func_main(@a); +func_main(@a) +60 +SELECT * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 40 +6 FFF 60 +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP FUNCTION func_main; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(IN) > SELECT FROM <table> … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE FUNCTION func_sub(IN a INT) RETURNS INT +BEGIN +DECLARE b INT; +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN b; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN +SET b = func_sub(a); +END; +$$ +SELECT * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +SET @a = 2; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT @b; +@b +20 +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(OUT) > SELECT FROM <table> … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE FUNCTION func_sub(IN a INT, OUT b INT) RETURNS INT +BEGIN +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN +DECLARE res INT; +SET res = func_sub(a, b); +END; +$$ +SELECT * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +SET @a = 1; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT @b; +@b +50 +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(INOUT) > SELECT FROM <table> … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE FUNCTION func_sub(IN a INT, INOUT c INT) RETURNS INT +BEGIN +DECLARE res INT; +SELECT AGE INTO res FROM Persons WHERE ID = a; +SET c = c * 100; +RETURN res; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN +DECLARE c INT; +DECLARE res INT; +SET c = 5; +SET res = func_sub(a, c); +SET b = c; +END; +$$ +SELECT * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +SET @a = 2; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT @b; +@b +500 +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(IN) > INSESRT INTO <table> … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE FUNCTION func_sub(IN a INT) RETURNS INT +BEGIN +INSERT INTO Persons VALUE (a, 'FFF', 50); +RETURN 0; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN +SET b = func_sub(a); +END; +$$ +SELECT * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +SET @a = 5; +SET @b = 1; +CALL proc_main(@a, @b); +SELECT @b; +@b +0 +SELECT * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 50 +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(OUT) > INSESRT INTO <table> … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'FFF', 50); +CREATE FUNCTION func_sub(IN a INT, OUT b INT) RETURNS INT +BEGIN +INSERT INTO Persons VALUE (a, 'GGG', 60); +RETURN 0; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN +DECLARE res INT; +SET res = func_sub(a, b); +END; +$$ +SELECT * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 50 +SET @a = 6; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 50 +6 GGG 60 +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(INOUT) > INSESRT INTO <table> … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'FFF', 50); +INSERT INTO Persons VALUES (6, 'GGG', 60); +CREATE FUNCTION func_sub(IN a INT, INOUT c INT) RETURNS INT +BEGIN +DECLARE res INT; +INSERT INTO Persons VALUE (a, 'HHH', 70); +SET c = c * 100; +RETURN res; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN +DECLARE c INT; +DECLARE res INT; +SET c = 5; +SET res = func_sub(a, c); +SET b = c; +END; +$$ +SELECT * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 50 +6 GGG 60 +SET @a = 7; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT @b; +@b +500 +SELECT * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 50 +6 GGG 60 +7 HHH 70 +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(IN) > UPDATE <table> SET … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'FFF', 50); +INSERT INTO Persons VALUES (6, 'GGG', 60); +INSERT INTO Persons VALUES (7, 'HHH', 70); +CREATE FUNCTION func_sub(IN a INT) RETURNS INT +BEGIN +UPDATE Persons SET AGE = 100 WHERE ID = a; +RETURN 0; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN +SET b = func_sub(a); +END; +$$ +SELECT * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 50 +6 GGG 60 +7 HHH 70 +SET @a = 5; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 100 +6 GGG 60 +7 HHH 70 +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(OUT) > UPDATE <table> SET … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'FFF', 100); +INSERT INTO Persons VALUES (6, 'GGG', 60); +INSERT INTO Persons VALUES (7, 'HHH', 70); +CREATE FUNCTION func_sub(IN a INT, OUT b INT) RETURNS INT +BEGIN +UPDATE Persons SET AGE = 100 WHERE ID = a; +SET b = 1; +RETURN 0; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN +DECLARE res INT; +SET res = func_sub(a, b); +END; +$$ +SELECT * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 100 +6 GGG 60 +7 HHH 70 +SET @a = 6; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT @b; +@b +1 +SELECT * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 100 +6 GGG 100 +7 HHH 70 +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(INOUT) > UPDATE <table> SET … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'FFF', 100); +INSERT INTO Persons VALUES (6, 'GGG', 100); +INSERT INTO Persons VALUES (7, 'HHH', 70); +CREATE FUNCTION func_sub(IN a INT, INOUT c INT) RETURNS INT +BEGIN +DECLARE res INT; +UPDATE Persons SET AGE = 100 WHERE ID = a; +SET c = c * 100; +RETURN res; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN +DECLARE c INT; +DECLARE res INT; +SET c = 5; +SET res = func_sub(a, c); +SET b = c; +END; +$$ +SELECT * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 100 +6 GGG 100 +7 HHH 70 +SET @a = 7; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT @b; +@b +500 +SELECT * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 100 +6 GGG 100 +7 HHH 100 +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 20 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 20 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > FUNCTION(IN) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE FUNCTION func(IN a INT) RETURNS INT +BEGIN +UPDATE PersonsLog SET UpdateCount = UpdateCount+a; +RETURN 0; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN +DECLARE a INT; +DECLARE res INT; +SET a = 1; +SET res = 0; +SET res = func(a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 30 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 30 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP FUNCTION func; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > FUNCTION(OUT) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 40); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE FUNCTION func(IN age_in INT, OUT age_out INT) RETURNS INT +BEGIN +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +SET age_out = age_in + 1; +RETURN 0; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +BEFORE UPDATE ON Persons +FOR EACH ROW +BEGIN +DECLARE res INT DEFAULT (func(OLD.age, NEW.age)); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 40 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 50 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 41 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP FUNCTION func; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > FUNCTION(INOUT) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE FUNCTION func(INOUT a INT) RETURNS INT +BEGIN +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +SET a = 100; +RETURN 0; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN +DECLARE a INT; +DECLARE res INT; +SET a = 10; +SET res = 0; +SET res = func(a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 60 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 60 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP FUNCTION func; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(IN) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE PROCEDURE proc(IN a INT) +BEGIN +UPDATE PersonsLog SET UpdateCount = UpdateCount+a; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN +CALL proc(1); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 30 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 30 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP PROCEDURE proc; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(OUT) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE PROCEDURE proc(IN old_age INT, OUT new_age INT) +BEGIN +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +SET new_age=old_age+41; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +BEFORE UPDATE ON Persons +FOR EACH ROW +BEGIN +CALL proc(OLD.age, NEW.age); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 50 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 51 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP PROCEDURE proc; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(INOUT) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE PROCEDURE proc(INOUT a INT) +BEGIN +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +SET a = 51; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +BEFORE UPDATE ON Persons +FOR EACH ROW +BEGIN +CALL proc(NEW.age); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 50 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 51 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP PROCEDURE proc; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(OUT) > FUNCTION(IN) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE FUNCTION func(IN a INT) RETURNS INT +BEGIN +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +RETURN 0; +END; +$$ +CREATE PROCEDURE proc(OUT a INT) +BEGIN +DECLARE res INT; +SET a = 100; +SET res = func(a); +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN +CALL proc(@a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 60 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 60 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP FUNCTION func; +DROP PROCEDURE proc; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(OUT) > FUNCTION(OUT) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE FUNCTION func(OUT a INT) RETURNS INT +BEGIN +SET a = 200; +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +RETURN 0; +END; +$$ +CREATE PROCEDURE proc(OUT a INT) +BEGIN +DECLARE res INT; +SET a = 100; +SET res = func(a); +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN +CALL proc(@a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 80 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 80 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP FUNCTION func; +DROP PROCEDURE proc; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(OUT) > FUNCTION(INOUT) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE FUNCTION func(INOUT a INT) RETURNS INT +BEGIN +SET a = 200; +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +RETURN 0; +END; +$$ +CREATE PROCEDURE proc(OUT a INT) +BEGIN +DECLARE res INT; +SET a = 100; +SET res = func(a); +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN +CALL proc(@a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 90 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 90 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP FUNCTION func; +DROP PROCEDURE proc; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(OUT) > FUNCTION(OUT) > UPDATE TABLE2 with OUT argument (to check if OUT is returning by reference) +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE FUNCTION func(OUT a INT) RETURNS INT +BEGIN +SET a = 111; +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +RETURN 0; +END; +$$ +CREATE PROCEDURE proc(OUT a INT) +BEGIN +DECLARE res INT; +SET res = func(a); +UPDATE PersonsLog SET UpdateCount = a; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN +CALL proc(@a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 80 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 80 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +111 +DROP TRIGGER my_trigger; +DROP FUNCTION func; +DROP PROCEDURE proc; +DROP TABLE Persons; +DROP TABLE PersonsLog; diff --git a/mysql-test/main/sp-inout.test b/mysql-test/main/sp-inout.test new file mode 100644 index 00000000000..8f3f134b675 --- /dev/null +++ b/mysql-test/main/sp-inout.test @@ -0,0 +1,1964 @@ +--echo # +--echo # MDEV-10654 IN, OUT, INOUT parameters in CREATE FUNCTION +--echo # + + +--echo # +--echo # CREATE FUNCTION with IN, OUT, INOUT qualifiers +--echo # SHOW CREATE FUNCTION +--echo # + +DELIMITER $$; +CREATE FUNCTION add_func(IN a INT, IN b INT, OUT c INT, INOUT d INT) RETURNS INT +BEGIN + SET c= 100; + SET d= d + 1; + RETURN a + b; +END; +$$ +DELIMITER ;$$ + +SHOW CREATE FUNCTION add_func; +DROP FUNCTION add_func; + +--echo # +--echo # CREATE PROCEDURE with IN, OUT, INOUT qualifiers +--echo # SHOW CREATE PROCEDURE +--echo # + +DELIMITER $$; +CREATE PROCEDURE add_proc(IN a INT, IN b INT, INOUT c INT, OUT d INT) +BEGIN + SET d= a + b + c + d; +END; +$$ +DELIMITER ;$$ + +SHOW CREATE PROCEDURE add_proc; +DROP PROCEDURE add_proc; + +--echo # +--echo # Call function from SELECT query +--echo # SELECT > FUNCTION(IN) +--echo # + +DELIMITER $$; +CREATE FUNCTION add_func2(IN a INT, IN b INT) RETURNS INT +BEGIN + RETURN a + b; +END; +$$ +DELIMITER ;$$ + +SET @a = 2; +SET @b = 3; +SELECT add_func2(@a, @b); +DROP FUNCTION add_func2; + +--echo # +--echo # Call function from SELECT query +--echo # SELECT > FUNCTION(OUT) +--echo # + +DELIMITER $$; +CREATE FUNCTION add_func3(IN a INT, IN b INT, OUT c INT) RETURNS INT +BEGIN + SET c = 100; + RETURN a + b; +END; +$$ +DELIMITER ;$$ + +SET @a = 2; +SET @b = 3; +SET @c = 0; +SET @res= add_func3(@a, @b, @c); +SELECT @res, @a, @b, @c; +--error ER_SF_OUT_INOUT_ARG_NOT_ALLOWED +SELECT add_func3(@a, @b, @c); +DROP FUNCTION add_func3; + +--echo # +--echo # Call function from SELECT query +--echo # SELECT > FUNCTION(INOUT) +--echo # + +DELIMITER $$; +CREATE FUNCTION add_func4(IN a INT, IN b INT, OUT c INT, INOUT d INT) RETURNS INT +BEGIN + SET c = 100; + SET d = d + 1; + RETURN a + b; +END; +$$ +DELIMITER ;$$ + +SET @a = 2; +SET @b = 3; +SET @c = 0; +SET @d = 9; +SET @res= add_func4(@a, @b, @c, @d); +SELECT @res, @a, @b, @c, @d; +--error ER_SF_OUT_INOUT_ARG_NOT_ALLOWED +SELECT add_func4(@a, @b, @c, @d); +DROP FUNCTION add_func4; + +--echo # +--echo # Call from procedure +--echo # PROCEDURE(OUT) > FUNCTION(IN) +--echo # + +DELIMITER $$; +CREATE FUNCTION add_func2(IN a INT, IN b INT) RETURNS INT +BEGIN + RETURN a + b; +END; +$$ +CREATE PROCEDURE add_proc2(IN a INT, IN b INT, OUT c INT) +BEGIN + SET c = add_func2(a, b); +END; +$$ +DELIMITER ;$$ + +SET @a = 2; +SET @b = 3; +SET @c = 0; +CALL add_proc2(@a, @b, @c); +SELECT @a, @b, @c; +DROP FUNCTION add_func2; +DROP PROCEDURE add_proc2; + +--echo # +--echo # Call from procedure +--echo # PROCEDURE(OUT) > FUNCTION(OUT) +--echo # + +DELIMITER $$; +CREATE FUNCTION add_func3(IN a INT, IN b INT, OUT c INT) RETURNS INT +BEGIN + SET c = 100; + RETURN a + b; +END; +$$ +CREATE PROCEDURE add_proc3(IN a INT, IN b INT, OUT c INT) +BEGIN + DECLARE res INT; + SET res = add_func3(a, b, c); +END; +$$ +DELIMITER ;$$ + +SET @a = 2; +SET @b = 3; +SET @c = 0; +CALL add_proc3(@a, @b, @c); +SELECT @a, @b, @c; +DROP FUNCTION add_func3; +DROP PROCEDURE add_proc3; + +--echo # +--echo # Call from procedure +--echo # PROCEDURE(OUT) > FUNCTION(INOUT) +--echo # + +DELIMITER $$; +CREATE FUNCTION add_func4(IN a INT, IN b INT, OUT c INT, INOUT d INT) RETURNS INT +BEGIN + SET c = 100; + SET d = d + 1; + RETURN a + b; +END; +$$ +CREATE PROCEDURE add_proc4(IN a INT, IN b INT, OUT res INT) +BEGIN + DECLARE c INT; + DECLARE d INT; + SET d = 30; + SET res = add_func4(a, b, c, d); + SET res = c + d; +END; +$$ +DELIMITER ;$$ + +SET @a = 2; +SET @b = 3; +SET @res = 0; +CALL add_proc4(@a, @b, @res); +SELECT @a, @b, @res; +DROP FUNCTION add_func4; +DROP PROCEDURE add_proc4; + +--echo # +--echo # Call from procedure +--echo # PROCEDURE(OUT) > PROCEDURE(OUT) +--echo # + +DELIMITER $$; +CREATE PROCEDURE add_proc(IN a INT, IN b INT, OUT c INT) +BEGIN + SET c = a + b; +END; +$$ +CREATE PROCEDURE test_proc1(IN a INT, IN b INT, OUT c INT) +BEGIN + CALL add_proc(a, b, c); +END; +$$ +DELIMITER ;$$ + +SET @a = 2; +SET @b = 3; +SET @c = 0; +CALL test_proc1(@a, @b, @c); +SELECT @a, @b, @c; +DROP PROCEDURE add_proc; +DROP PROCEDURE test_proc1; + +--echo # +--echo # Argument's order change +--echo # PROCEDURE(a IN, b IN, c OUT) > FUNCTION(b IN, a IN, c OUT) +--echo # + +DELIMITER $$; +CREATE FUNCTION func_sub(IN b INT, IN a INT, OUT c INT) RETURNS INT +BEGIN + DECLARE res INT; + SET c = a - b; + SET res = a; + RETURN res; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, IN b INT, OUT c INT) +BEGIN + DECLARE res INT; + SET res = func_sub(b, a, c); +END; +$$ +DELIMITER ;$$ + +SET @a = 2; +SET @b = 3; +SET @c = 0; +CALL proc_main(@a, @b, @c); +SELECT @a, @b, @c; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; + +--echo # +--echo # Argument's order change +--echo # PROCEDURE(a IN, b IN, c OUT) > FUNCTION(c OUT, b IN, a IN) +--echo # + +DELIMITER $$; +CREATE FUNCTION func_sub(OUT c INT, IN b INT, IN a INT) RETURNS INT +BEGIN + DECLARE res INT; + SET c = a - b; + SET res = a; + RETURN res; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, IN b INT, OUT c INT) +BEGIN + DECLARE res INT; + SET res = func_sub(c, b, a); +END; +$$ +DELIMITER ;$$ + +SET @a = 2; +SET @b = 3; +SET @c = 0; +CALL proc_main(@a, @b, @c); +SELECT @a, @b, @c; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; + +--echo # +--echo # Argument's order change +--echo # PROCEDURE(a IN, b IN, c INOUT, d OUT) > FUNCTION(d OUT, a IN, b IN, c INOUT) +--echo # + +DELIMITER $$; +CREATE FUNCTION func_sub(OUT d INT, IN a INT, IN b INT, INOUT c INT) RETURNS INT +BEGIN + SET c = c + 6; + SET d = 10; + RETURN a - b; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, IN b INT, INOUT c INT, OUT d INT) +BEGIN + DECLARE res INT; + SET res = func_sub(d, a, b, c); + SET d = d + c + res; +END; +$$ +DELIMITER ;$$ + +SET @a = 15; +SET @b = 5; +SET @c = 4; +SET @d= 0; +CALL proc_main(@a, @b, @c, @d); +SELECT @a, @b, @c, @d; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; + +--echo # +--echo # Argument's order change +--echo # PROCEDURE(IN a INT, IN b INT, INOUT c INT, OUT d INT) > FUNCTION1(c INOUT INT, IN b INT) > FUNCTION2(d OUT INT, IN a INT) +--echo # + +DELIMITER $$; +CREATE FUNCTION func_sub1(INOUT c INT, IN b INT) RETURNS INT +BEGIN + SET c = c + b; + RETURN 0; +END; +$$ +CREATE FUNCTION func_sub2(OUT d INT, IN a INT) RETURNS INT +BEGIN + SET d = 5 + a; + RETURN 0; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, IN b INT, INOUT c INT, OUT d INT) +BEGIN + DECLARE res1 INT; + DECLARE res2 INT; + SET res1 = func_sub1(c, b); + SET res2 = func_sub2(d, a); + SET d = d + c; +END; +$$ +DELIMITER ;$$ + +SET @a = 15; +SET @b = 6; +SET @c = 4; +SET @d= 0; +CALL proc_main(@a, @b, @c, @d); +SELECT @a, @b, @c, @d; +DROP FUNCTION func_sub1; +DROP FUNCTION func_sub2; +DROP PROCEDURE proc_main; + +--echo # +--echo # Argument's order change +--echo # FUNCTION1(a IN, b IN) > FUNCTION2(b IN, c OUT, a IN) +--echo # + +DELIMITER $$; +CREATE FUNCTION func_sub(IN b INT, OUT c INT, IN a INT) RETURNS INT +BEGIN + SET c = 100; + RETURN a + b; +END; +$$ +CREATE FUNCTION func_main(IN a INT, IN b INT) RETURNS INT +BEGIN + DECLARE c INT; + DECLARE res INT; + SET res = func_sub(b, c, a); + RETURN res + c; +END; +$$ +DELIMITER ;$$ + +SET @a = 2; +SET @b = 3; +SELECT func_main(@a, @b); +DROP FUNCTION func_sub; +DROP FUNCTION func_main; + +--echo # +--echo # Call procedure inside function +--echo # FUNCTION1(a IN, b IN) > PROCEDURE(a IN, b IN, c OUT) +--echo # + +DELIMITER $$; +CREATE PROCEDURE proc_sub(IN a INT, IN b INT, OUT c INT) +BEGIN + SET c = a + b; +END; +$$ +CREATE FUNCTION func_main(IN b INT, IN a INT) RETURNS INT +BEGIN + DECLARE c INT; + CALL proc_sub(a, b, c); + RETURN c; +END; +$$ +DELIMITER ;$$ + +SET @a = 2; +SET @b = 3; +SELECT func_main(@a, @b); +DROP PROCEDURE proc_sub; +DROP FUNCTION func_main; + +--echo # +--echo # Call procedure inside function +--echo # FUNCTION1(a IN, b IN) > PROCEDURE(a IN, b INOUT) +--echo # + +DELIMITER $$; +CREATE PROCEDURE proc_sub(IN a INT, INOUT b INT) +BEGIN + SET b = a + b; +END; +$$ +CREATE FUNCTION func_main(IN b INT, IN a INT) RETURNS INT +BEGIN + CALL proc_sub(a, b); + RETURN b; +END; +$$ +DELIMITER ;$$ + +SET @a = 2; +SET @b = 3; +SELECT func_main(@a, @b); +DROP PROCEDURE proc_sub; +DROP FUNCTION func_main; + +--echo # +--echo # Call procedure inside function +--echo # FUNCTION1(a IN, b IN, c OUT) > PROCEDURE(a IN, b IN, c OUT) +--echo # + +DELIMITER $$; +CREATE PROCEDURE proc_sub(IN a INT, IN b INT, OUT c INT) +BEGIN + SET c = a + b; +END; +$$ +CREATE FUNCTION func_main(IN b INT, IN a INT, OUT c INT) RETURNS INT +BEGIN + DECLARE res INT; + CALL proc_sub(a, b, c); + RETURN 0; +END; +$$ +DELIMITER ;$$ + +SET @a = 2; +SET @b = 3; +SET @c = 0; +DO func_main(@a, @b, @c); +SELECT @a, @b, @c; +--error ER_SF_OUT_INOUT_ARG_NOT_ALLOWED +SELECT func_main(@a, @b, @c); +DROP PROCEDURE proc_sub; +DROP FUNCTION func_main; + +--echo # +--echo # Call function from UPDATE query +--echo # UPDATE <table> SET <column> = FUNCTION(a IN) +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); + +DELIMITER $$; +CREATE FUNCTION func(IN a INT) RETURNS INT +BEGIN + RETURN a * 10; +END; +$$ +DELIMITER ;$$ + +SET @a = 5; +UPDATE Persons SET Age = func(@a) WHERE ID = 1; +SELECT * FROM Persons; +DROP TABLE Persons; +DROP FUNCTION func; + +--echo # +--echo # Call function from UPDATE query +--echo # UPDATE <table> SET <column> = FUNCTION(a OUT) +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); + +DELIMITER $$; +CREATE FUNCTION func(OUT a INT) RETURNS INT +BEGIN + SET a = 5; + RETURN 80; +END; +$$ +DELIMITER ;$$ + +SET @a = 0; +--error ER_SF_OUT_INOUT_ARG_NOT_ALLOWED +UPDATE Persons SET Age = func(@a) WHERE ID = 1; +DROP TABLE Persons; +DROP FUNCTION func; + +--echo # +--echo # Call function from INSERT query +--echo # INSERT INTO <table> SELECT <val1>, <val2>, FUNCTION(a IN) +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); + +DELIMITER $$; +CREATE FUNCTION func(IN a INT) RETURNS INT +BEGIN + RETURN a * 10; +END; +$$ +DELIMITER ;$$ + +SET @a = 4; +INSERT INTO Persons SELECT 4, 'DDD', func(@a); +SELECT * FROM Persons; +DROP TABLE Persons; +DROP FUNCTION func; + +--echo # +--echo # Call function from INSERT query +--echo # INSERT INTO <table> SELECT <val1>, <val2>, FUNCTION(a OUT) +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); + +DELIMITER $$; +CREATE FUNCTION func(OUT a INT) RETURNS INT +BEGIN + SET a = 45; + RETURN 40; +END; +$$ +DELIMITER ;$$ + +SELECT * FROM Persons; +SET @a = 0; +--error ER_SF_OUT_INOUT_ARG_NOT_ALLOWED +INSERT INTO Persons SELECT 5, 'EEE', func(@a); +DROP TABLE Persons; +DROP FUNCTION func; + +--echo # +--echo # Call function from DELETE query +--echo # DELETE FROM <table> WHERE <column> = FUNCTION(a IN) +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); + +DELIMITER $$; +CREATE FUNCTION func(IN a INT) RETURNS INT +BEGIN + RETURN a; +END; +$$ +DELIMITER ;$$ + +SELECT * FROM Persons; +SET @a = 4; +DELETE FROM Persons WHERE ID = func(@a); +SELECT * FROM Persons; +DROP TABLE Persons; +DROP FUNCTION func; + +--echo # +--echo # Call function from DELETE query +--echo # DELETE FROM <table> WHERE <column> = FUNCTION(a OUT) +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); + +DELIMITER $$; +CREATE FUNCTION func(OUT a INT) RETURNS INT +BEGIN + SET a = 40; + RETURN 4; +END; +$$ +DELIMITER ;$$ + +SELECT * FROM Persons; +SET @a = 0; +--error ER_SF_OUT_INOUT_ARG_NOT_ALLOWED +DELETE FROM Persons WHERE ID = func(@a); +DROP TABLE Persons; +DROP FUNCTION func; + +--echo # +--echo # SELECT query inside function +--echo # FUNCTION(a IN) > SELECT … FROM <table> +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); + +DELIMITER $$; +CREATE FUNCTION func_main(IN a INT) RETURNS INT +BEGIN + DECLARE c INT; + SELECT AGE INTO c FROM Persons WHERE ID = a; + RETURN c; +END; +$$ +DELIMITER ;$$ + +SET @a = 3; +SELECT func_main(@a); +SELECT * from Persons; +DROP TABLE Persons; +DROP FUNCTION func_main; + +--echo # +--echo # SELECT query inside function +--echo # FUNCTION(a OUT) > SELECT … FROM <table> +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); + +DELIMITER $$; +CREATE FUNCTION func_main(OUT a INT) RETURNS INT +BEGIN + SELECT AGE INTO a FROM Persons WHERE ID = 3; + RETURN 0; +END; +$$ +DELIMITER ;$$ + +SET @a = 0; +--error ER_SF_OUT_INOUT_ARG_NOT_ALLOWED +SELECT func_main(@a); +DROP TABLE Persons; +DROP FUNCTION func_main; + +--echo # +--echo # SELECT query inside function +--echo # FUNCTION(a INOUT) > SELECT … FROM <table> +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); + +DELIMITER $$; +CREATE FUNCTION func_main(INOUT a INT) RETURNS INT +BEGIN + SELECT AGE INTO a FROM Persons WHERE ID = a; + RETURN 0; +END; +$$ +DELIMITER ;$$ + +SET @a = 1; +--error ER_SF_OUT_INOUT_ARG_NOT_ALLOWED +SELECT func_main(@a); +DROP TABLE Persons; +DROP FUNCTION func_main; + +--echo # +--echo # SELECT query inside function +--echo # FUNCTION(a IN) > FUNCTION(a IN, b OUT) > SELECT … FROM <table> +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); + +DELIMITER $$; +CREATE FUNCTION func_sub(IN a INT, OUT b INT) RETURNS INT +BEGIN + SELECT AGE INTO b FROM Persons WHERE ID = a; + RETURN 0; +END; +$$ +CREATE FUNCTION func_main(IN a INT) RETURNS INT +BEGIN + DECLARE b INT; + DECLARE res INT; + SET res = func_sub(a, b); + RETURN b; +END; +$$ +DELIMITER ;$$ + +SET @a = 2; +SELECT func_main(@a); +SELECT * from Persons; +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP FUNCTION func_main; + +--echo # +--echo # UPDATE query inside function +--echo # FUNCTION(a IN) > UPDATE <table> SET … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); + +DELIMITER $$; +CREATE FUNCTION func_main(IN a INT) RETURNS INT +BEGIN + DECLARE c INT; + UPDATE Persons SET AGE = 50 WHERE ID = a; + SELECT AGE INTO c FROM Persons WHERE ID = a; + RETURN c; +END; +$$ +DELIMITER ;$$ + +SELECT * from Persons; +SET @a = 5; +SELECT func_main(@a); +SELECT * from Persons; +DROP TABLE Persons; +DROP FUNCTION func_main; + +--echo # +--echo # UPDATE query inside function +--echo # FUNCTION(a IN, b OUT) > UPDATE <table> SET … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); + +DELIMITER $$; +CREATE FUNCTION func_main(IN a INT, OUT b INT) RETURNS INT +BEGIN + UPDATE Persons SET AGE = 60 WHERE ID = a; + SELECT AGE INTO b FROM Persons WHERE ID = a; + RETURN 0; +END; +$$ +DELIMITER ;$$ + +SET @a = 5; +SET @b = 0; +--error ER_SF_OUT_INOUT_ARG_NOT_ALLOWED +SELECT func_main(@a, @b); +DROP TABLE Persons; +DROP FUNCTION func_main; + +--echo # +--echo # UPDATE query inside function +--echo # FUNCTION(a IN, b INOUT) > UPDATE <table> SET … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); + +DELIMITER $$; +CREATE FUNCTION func_main(IN a INT, INOUT b INT) RETURNS INT +BEGIN + UPDATE Persons SET AGE = 60 WHERE ID = a; + SELECT AGE INTO b FROM Persons WHERE ID = a; + RETURN 0; +END; +$$ +DELIMITER ;$$ + +SET @a = 5; +SET @b = 0; +--error ER_SF_OUT_INOUT_ARG_NOT_ALLOWED +SELECT func_main(@a, @b); +DROP TABLE Persons; +DROP FUNCTION func_main; + +--echo # +--echo # UPDATE query inside function +--echo # FUNCTION(a IN) > FUNCTION(a IN, b OUT) > UPDATE <table> SET … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 80); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); + +DELIMITER $$; +CREATE FUNCTION func_sub(IN a INT, OUT b INT) RETURNS INT +BEGIN + UPDATE Persons SET AGE = 10 WHERE ID = a; + SELECT AGE INTO b FROM Persons WHERE ID = a; + RETURN 0; +END; +$$ +CREATE FUNCTION func_main(IN a INT) RETURNS INT +BEGIN + DECLARE b INT; + DECLARE res INT; + SET res = func_sub(a, b); + RETURN b; +END; +$$ +DELIMITER ;$$ + +SELECT * from Persons; +SET @a = 1; +SELECT func_main(@a); +SELECT * from Persons; +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP FUNCTION func_main; + + +--echo # +--echo # INSERT query inside function +--echo # FUNCTION(a IN) > INSERT INTO <table> VALUES … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 50); + +DELIMITER $$; +CREATE FUNCTION func_main(IN a INT) RETURNS INT +BEGIN + DECLARE b INT; + INSERT INTO Persons VALUE (a, 'FFF', 60); + SELECT AGE INTO b FROM Persons WHERE ID = a; + RETURN b; +END; +$$ +DELIMITER ;$$ + +SELECT * from Persons; +SET @a = 6; +SELECT func_main(@a); +SELECT * from Persons; +DROP TABLE Persons; +DROP FUNCTION func_main; + +--echo # +--echo # INSERT query inside function +--echo # FUNCTION(a IN, b OUT) > INSERT INTO <table> VALUES … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 50); + +DELIMITER $$; +CREATE FUNCTION func_main(IN a INT, OUT b INT) RETURNS INT +BEGIN + INSERT INTO Persons VALUE (a, 'FFF', 60); + SELECT AGE INTO b FROM Persons WHERE ID = a; + RETURN 0; +END; +$$ +DELIMITER ;$$ + +SELECT * from Persons; +SET @a = 6; +SET @b = 0; +--error ER_SF_OUT_INOUT_ARG_NOT_ALLOWED +SELECT func_main(@a, @b); +DROP TABLE Persons; +DROP FUNCTION func_main; + +--echo # +--echo # INSERT query inside function +--echo # FUNCTION(a IN, b INOUT) > INSERT INTO <table> VALUES … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); + +DELIMITER $$; +CREATE FUNCTION func_main(IN a INT, INOUT b INT) RETURNS INT +BEGIN + INSERT INTO Persons VALUE (a, 'FFF', 60); + SELECT AGE INTO b FROM Persons WHERE ID = a; + RETURN 0; +END; +$$ +DELIMITER ;$$ + +SELECT * from Persons; +SET @a = 6; +SET @b = 0; +--error ER_SF_OUT_INOUT_ARG_NOT_ALLOWED +SELECT func_main(@a, @b); +DROP TABLE Persons; +DROP FUNCTION func_main; + +--echo # +--echo # INSERT query inside function +--echo # FUNCTION(a IN) > FUNCTION(a IN, b OUT) > INSERT INTO <table> VALUES … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); + +DELIMITER $$; +CREATE FUNCTION func_sub(IN a INT, OUT b INT) RETURNS INT +BEGIN + INSERT INTO Persons VALUE (a, 'FFF', 60); + SELECT AGE INTO b FROM Persons WHERE ID = a; + RETURN 0; +END; +$$ +CREATE FUNCTION func_main(IN a INT) RETURNS INT +BEGIN + DECLARE b INT; + DECLARE res INT; + SET res = func_sub(a, b); + RETURN b; +END; +$$ +DELIMITER ;$$ + +SELECT * from Persons; +SET @a = 6; +SELECT func_main(@a); +SELECT * from Persons; +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP FUNCTION func_main; + +--echo # +--echo # PROCEDURE > FUNCTION > SQL query +--echo # PROCEDURE(OUT) > FUNCTION(IN) > SELECT FROM <table> … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); + +DELIMITER $$; +CREATE FUNCTION func_sub(IN a INT) RETURNS INT +BEGIN + DECLARE b INT; + SELECT AGE INTO b FROM Persons WHERE ID = a; + RETURN b; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN + SET b = func_sub(a); +END; +$$ +DELIMITER ;$$ + +SELECT * from Persons; +SET @a = 2; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT @b; +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; + +--echo # +--echo # PROCEDURE > FUNCTION > SQL query +--echo # PROCEDURE(OUT) > FUNCTION(OUT) > SELECT FROM <table> … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); + +DELIMITER $$; +CREATE FUNCTION func_sub(IN a INT, OUT b INT) RETURNS INT +BEGIN + SELECT AGE INTO b FROM Persons WHERE ID = a; + RETURN 0; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN + DECLARE res INT; + SET res = func_sub(a, b); +END; +$$ +DELIMITER ;$$ + +SELECT * from Persons; +SET @a = 1; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT @b; +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; + +--echo # +--echo # PROCEDURE > FUNCTION > SQL query +--echo # PROCEDURE(OUT) > FUNCTION(INOUT) > SELECT FROM <table> … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); + +DELIMITER $$; +CREATE FUNCTION func_sub(IN a INT, INOUT c INT) RETURNS INT +BEGIN + DECLARE res INT; + SELECT AGE INTO res FROM Persons WHERE ID = a; + SET c = c * 100; + RETURN res; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN + DECLARE c INT; + DECLARE res INT; + SET c = 5; + SET res = func_sub(a, c); + SET b = c; +END; +$$ +DELIMITER ;$$ + +SELECT * from Persons; +SET @a = 2; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT @b; +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; + + +--echo # +--echo # PROCEDURE > FUNCTION > SQL query +--echo # PROCEDURE(OUT) > FUNCTION(IN) > INSESRT INTO <table> … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); + +DELIMITER $$; +CREATE FUNCTION func_sub(IN a INT) RETURNS INT +BEGIN + INSERT INTO Persons VALUE (a, 'FFF', 50); + RETURN 0; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN + SET b = func_sub(a); +END; +$$ +DELIMITER ;$$ + +SELECT * from Persons; +SET @a = 5; +SET @b = 1; +CALL proc_main(@a, @b); +SELECT @b; +SELECT * from Persons; +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; + + +--echo # +--echo # PROCEDURE > FUNCTION > SQL query +--echo # PROCEDURE(OUT) > FUNCTION(OUT) > INSESRT INTO <table> … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'FFF', 50); + +DELIMITER $$; +CREATE FUNCTION func_sub(IN a INT, OUT b INT) RETURNS INT +BEGIN + INSERT INTO Persons VALUE (a, 'GGG', 60); + RETURN 0; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN + DECLARE res INT; + SET res = func_sub(a, b); +END; +$$ +DELIMITER ;$$ + +SELECT * from Persons; +SET @a = 6; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT * from Persons; +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; + + +--echo # +--echo # PROCEDURE > FUNCTION > SQL query +--echo # PROCEDURE(OUT) > FUNCTION(INOUT) > INSESRT INTO <table> … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'FFF', 50); +INSERT INTO Persons VALUES (6, 'GGG', 60); + +DELIMITER $$; +CREATE FUNCTION func_sub(IN a INT, INOUT c INT) RETURNS INT +BEGIN + DECLARE res INT; + INSERT INTO Persons VALUE (a, 'HHH', 70); + SET c = c * 100; + RETURN res; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN + DECLARE c INT; + DECLARE res INT; + SET c = 5; + SET res = func_sub(a, c); + SET b = c; +END; +$$ +DELIMITER ;$$ + +SELECT * from Persons; +SET @a = 7; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT @b; +SELECT * from Persons; +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; + + +--echo # +--echo # PROCEDURE > FUNCTION > SQL query +--echo # PROCEDURE(OUT) > FUNCTION(IN) > UPDATE <table> SET … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'FFF', 50); +INSERT INTO Persons VALUES (6, 'GGG', 60); +INSERT INTO Persons VALUES (7, 'HHH', 70); + +DELIMITER $$; +CREATE FUNCTION func_sub(IN a INT) RETURNS INT +BEGIN + UPDATE Persons SET AGE = 100 WHERE ID = a; + RETURN 0; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN + SET b = func_sub(a); +END; +$$ +DELIMITER ;$$ + +SELECT * from Persons; +SET @a = 5; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT * from Persons; +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; + +--echo # +--echo # PROCEDURE > FUNCTION > SQL query +--echo # PROCEDURE(OUT) > FUNCTION(OUT) > UPDATE <table> SET … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'FFF', 100); +INSERT INTO Persons VALUES (6, 'GGG', 60); +INSERT INTO Persons VALUES (7, 'HHH', 70); + +DELIMITER $$; +CREATE FUNCTION func_sub(IN a INT, OUT b INT) RETURNS INT +BEGIN + UPDATE Persons SET AGE = 100 WHERE ID = a; + SET b = 1; + RETURN 0; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN + DECLARE res INT; + SET res = func_sub(a, b); +END; +$$ +DELIMITER ;$$ + +SELECT * from Persons; +SET @a = 6; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT @b; +SELECT * from Persons; +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; + + +--echo # +--echo # PROCEDURE > FUNCTION > SQL query +--echo # PROCEDURE(OUT) > FUNCTION(INOUT) > UPDATE <table> SET … +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'FFF', 100); +INSERT INTO Persons VALUES (6, 'GGG', 100); +INSERT INTO Persons VALUES (7, 'HHH', 70); + +DELIMITER $$; +CREATE FUNCTION func_sub(IN a INT, INOUT c INT) RETURNS INT +BEGIN + DECLARE res INT; + UPDATE Persons SET AGE = 100 WHERE ID = a; + SET c = c * 100; + RETURN res; +END; +$$ +CREATE PROCEDURE proc_main(IN a INT, OUT b INT) +BEGIN + DECLARE c INT; + DECLARE res INT; + SET c = 5; + SET res = func_sub(a, c); + SET b = c; +END; +$$ +DELIMITER ;$$ + +SELECT * from Persons; +SET @a = 7; +SET @b = 0; +CALL proc_main(@a, @b); +SELECT @b; +SELECT * from Persons; +DROP TABLE Persons; +DROP FUNCTION func_sub; +DROP PROCEDURE proc_main; + + +--echo # +--echo # Trigger +--echo # TRIGGER AFTER UPDATE ON TABLE1 > UPDATE TABLE2 +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); + +CREATE TABLE PersonsLog ( + UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); + +DELIMITER $$; +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW + UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +$$ +DELIMITER ;$$ + +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +UPDATE Persons SET Age = 20 WHERE ID = 1; +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +DROP TRIGGER my_trigger; +DROP TABLE Persons; +DROP TABLE PersonsLog; + +--echo # +--echo # Trigger +--echo # TRIGGER AFTER UPDATE ON TABLE1 > FUNCTION(IN) > UPDATE TABLE2 +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); + +CREATE TABLE PersonsLog ( + UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); + +DELIMITER $$; +CREATE FUNCTION func(IN a INT) RETURNS INT +BEGIN + UPDATE PersonsLog SET UpdateCount = UpdateCount+a; + RETURN 0; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN + DECLARE a INT; + DECLARE res INT; + SET a = 1; + SET res = 0; + SET res = func(a); +END; +$$ +DELIMITER ;$$ + +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +UPDATE Persons SET Age = 30 WHERE ID = 1; +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +DROP TRIGGER my_trigger; +DROP FUNCTION func; +DROP TABLE Persons; +DROP TABLE PersonsLog; + +--echo # +--echo # Trigger +--echo # TRIGGER AFTER UPDATE ON TABLE1 > FUNCTION(OUT) > UPDATE TABLE2 +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 40); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); + +CREATE TABLE PersonsLog ( + UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); + +DELIMITER $$; +CREATE FUNCTION func(IN age_in INT, OUT age_out INT) RETURNS INT +BEGIN + UPDATE PersonsLog SET UpdateCount = UpdateCount+1; + SET age_out = age_in + 1; + RETURN 0; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +BEFORE UPDATE ON Persons +FOR EACH ROW +BEGIN + DECLARE res INT DEFAULT (func(OLD.age, NEW.age)); +END; +$$ +DELIMITER ;$$ + +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +UPDATE Persons SET Age = 50 WHERE ID = 1; +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +DROP TRIGGER my_trigger; +DROP FUNCTION func; +DROP TABLE Persons; +DROP TABLE PersonsLog; + +--echo # +--echo # Trigger +--echo # TRIGGER AFTER UPDATE ON TABLE1 > FUNCTION(INOUT) > UPDATE TABLE2 +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); + +CREATE TABLE PersonsLog ( + UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); + +DELIMITER $$; +CREATE FUNCTION func(INOUT a INT) RETURNS INT +BEGIN + UPDATE PersonsLog SET UpdateCount = UpdateCount+1; + SET a = 100; + RETURN 0; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN + DECLARE a INT; + DECLARE res INT; + SET a = 10; + SET res = 0; + SET res = func(a); +END; +$$ +DELIMITER ;$$ + +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +UPDATE Persons SET Age = 60 WHERE ID = 1; +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +DROP TRIGGER my_trigger; +DROP FUNCTION func; +DROP TABLE Persons; +DROP TABLE PersonsLog; + +--echo # +--echo # Trigger +--echo # TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(IN) > UPDATE TABLE2 +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); + +CREATE TABLE PersonsLog ( + UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); + +DELIMITER $$; +CREATE PROCEDURE proc(IN a INT) +BEGIN + UPDATE PersonsLog SET UpdateCount = UpdateCount+a; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN + CALL proc(1); +END; +$$ +DELIMITER ;$$ + +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +UPDATE Persons SET Age = 30 WHERE ID = 1; +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +DROP TRIGGER my_trigger; +DROP PROCEDURE proc; +DROP TABLE Persons; +DROP TABLE PersonsLog; + +--echo # +--echo # Trigger +--echo # TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(OUT) > UPDATE TABLE2 +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); + +CREATE TABLE PersonsLog ( + UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); + +DELIMITER $$; +CREATE PROCEDURE proc(IN old_age INT, OUT new_age INT) +BEGIN + UPDATE PersonsLog SET UpdateCount = UpdateCount+1; + SET new_age=old_age+41; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +BEFORE UPDATE ON Persons +FOR EACH ROW +BEGIN + CALL proc(OLD.age, NEW.age); +END; +$$ +DELIMITER ;$$ + +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +UPDATE Persons SET Age = 50 WHERE ID = 1; +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +DROP TRIGGER my_trigger; +DROP PROCEDURE proc; +DROP TABLE Persons; +DROP TABLE PersonsLog; + +--echo # +--echo # Trigger +--echo # TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(INOUT) > UPDATE TABLE2 +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); + +CREATE TABLE PersonsLog ( + UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); + +DELIMITER $$; +CREATE PROCEDURE proc(INOUT a INT) +BEGIN + UPDATE PersonsLog SET UpdateCount = UpdateCount+1; + SET a = 51; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +BEFORE UPDATE ON Persons +FOR EACH ROW +BEGIN + CALL proc(NEW.age); +END; +$$ +DELIMITER ;$$ + +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +UPDATE Persons SET Age = 50 WHERE ID = 1; +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +DROP TRIGGER my_trigger; +DROP PROCEDURE proc; +DROP TABLE Persons; +DROP TABLE PersonsLog; + +--echo # +--echo # Trigger +--echo # TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(OUT) > FUNCTION(IN) > UPDATE TABLE2 +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); + +CREATE TABLE PersonsLog ( + UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); + +DELIMITER $$; +CREATE FUNCTION func(IN a INT) RETURNS INT +BEGIN + UPDATE PersonsLog SET UpdateCount = UpdateCount+1; + RETURN 0; +END; +$$ +CREATE PROCEDURE proc(OUT a INT) +BEGIN + DECLARE res INT; + SET a = 100; + SET res = func(a); +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN + CALL proc(@a); +END; +$$ +DELIMITER ;$$ + +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +UPDATE Persons SET Age = 60 WHERE ID = 1; +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +DROP TRIGGER my_trigger; +DROP FUNCTION func; +DROP PROCEDURE proc; +DROP TABLE Persons; +DROP TABLE PersonsLog; + +--echo # +--echo # Trigger +--echo # TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(OUT) > FUNCTION(OUT) > UPDATE TABLE2 +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); + +CREATE TABLE PersonsLog ( + UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); + +DELIMITER $$; +CREATE FUNCTION func(OUT a INT) RETURNS INT +BEGIN + SET a = 200; + UPDATE PersonsLog SET UpdateCount = UpdateCount+1; + RETURN 0; +END; +$$ +CREATE PROCEDURE proc(OUT a INT) +BEGIN + DECLARE res INT; + SET a = 100; + SET res = func(a); +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN + CALL proc(@a); +END; +$$ +DELIMITER ;$$ + +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +UPDATE Persons SET Age = 80 WHERE ID = 1; +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +DROP FUNCTION func; +DROP PROCEDURE proc; +DROP TABLE Persons; +DROP TABLE PersonsLog; + +--echo # +--echo # Trigger +--echo # TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(OUT) > FUNCTION(INOUT) > UPDATE TABLE2 +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); + +CREATE TABLE PersonsLog ( + UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); + +DELIMITER $$; +CREATE FUNCTION func(INOUT a INT) RETURNS INT +BEGIN + SET a = 200; + UPDATE PersonsLog SET UpdateCount = UpdateCount+1; + RETURN 0; +END; +$$ +CREATE PROCEDURE proc(OUT a INT) +BEGIN + DECLARE res INT; + SET a = 100; + SET res = func(a); +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN + CALL proc(@a); +END; +$$ +DELIMITER ;$$ + +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +UPDATE Persons SET Age = 90 WHERE ID = 1; +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +DROP TRIGGER my_trigger; +DROP FUNCTION func; +DROP PROCEDURE proc; +DROP TABLE Persons; +DROP TABLE PersonsLog; + +--echo # +--echo # Trigger +--echo # TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(OUT) > FUNCTION(OUT) > UPDATE TABLE2 with OUT argument (to check if OUT is returning by reference) +--echo # + +CREATE TABLE Persons ( + ID int, + Name varchar(255), + Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); + +CREATE TABLE PersonsLog ( + UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); + +DELIMITER $$; +CREATE FUNCTION func(OUT a INT) RETURNS INT +BEGIN + SET a = 111; + UPDATE PersonsLog SET UpdateCount = UpdateCount+1; + RETURN 0; +END; +$$ +CREATE PROCEDURE proc(OUT a INT) +BEGIN + DECLARE res INT; + SET res = func(a); + UPDATE PersonsLog SET UpdateCount = a; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN + CALL proc(@a); +END; +$$ +DELIMITER ;$$ + +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +UPDATE Persons SET Age = 80 WHERE ID = 1; +SELECT * FROM Persons; +SELECT * FROM PersonsLog; +DROP TRIGGER my_trigger; +DROP FUNCTION func; +DROP PROCEDURE proc; +DROP TABLE Persons; +DROP TABLE PersonsLog; diff --git a/mysql-test/suite/compat/oracle/r/sp-cursor.result b/mysql-test/suite/compat/oracle/r/sp-cursor.result index d7e88430bc7..aa9c5de8bc9 100644 --- a/mysql-test/suite/compat/oracle/r/sp-cursor.result +++ b/mysql-test/suite/compat/oracle/r/sp-cursor.result @@ -977,3 +977,46 @@ $$ CALL p1(); DROP PROCEDURE p1; DROP TABLE t1; +# +# Start of 10.8 tests +# +# +# MDEV-10654 IN, OUT, INOUT parameters in CREATE FUNCTION +# +DECLARE +va INT; +CURSOR cur (a IN INT) IS SELECT a FROM dual; +BEGIN +OPEN cur(1); +FETCH cur INTO va; +CLOSE cur; +SELECT va; +END; +$$ +va +1 +DECLARE +va INT; +CURSOR cur (a OUT INT) IS SELECT a FROM dual; +BEGIN +OPEN cur(1); +FETCH cur INTO va; +CLOSE cur; +SELECT va; +END; +$$ +ERROR 42000: This version of MariaDB doesn't yet support 'OUT/INOUT cursor parameter' +DECLARE +va INT; +CURSOR cur (a INOUT INT) IS SELECT a FROM dual; +BEGIN +OPEN cur(1); +FETCH cur INTO va; +CLOSE cur; +SELECT va; +END; +$$ +ERROR 42000: This version of MariaDB doesn't yet support 'OUT/INOUT cursor parameter' +# +# End of 10.8 tests +# diff --git a/mysql-test/suite/compat/oracle/t/sp-cursor.test b/mysql-test/suite/compat/oracle/t/sp-cursor.test index 03b8b016ee0..d7e2a5dee68 100644 --- a/mysql-test/suite/compat/oracle/t/sp-cursor.test +++ b/mysql-test/suite/compat/oracle/t/sp-cursor.test @@ -987,3 +987,58 @@ DELIMITER ;$$ CALL p1(); DROP PROCEDURE p1; DROP TABLE t1; + + +--echo # +--echo # Start of 10.8 tests +--echo # + +--echo # +--echo # MDEV-10654 IN, OUT, INOUT parameters in CREATE FUNCTION +--echo # + +DELIMITER $$; +DECLARE + va INT; + CURSOR cur (a IN INT) IS SELECT a FROM dual; +BEGIN + OPEN cur(1); + FETCH cur INTO va; + CLOSE cur; + SELECT va; +END; +$$ +DELIMITER ;$$ + +DELIMITER $$; +--error ER_NOT_SUPPORTED_YET +DECLARE + va INT; + CURSOR cur (a OUT INT) IS SELECT a FROM dual; +BEGIN + OPEN cur(1); + FETCH cur INTO va; + CLOSE cur; + SELECT va; +END; +$$ +DELIMITER ;$$ + +DELIMITER $$; +--error ER_NOT_SUPPORTED_YET +DECLARE + va INT; + CURSOR cur (a INOUT INT) IS SELECT a FROM dual; +BEGIN + OPEN cur(1); + FETCH cur INTO va; + CLOSE cur; + SELECT va; +END; +$$ +DELIMITER ;$$ + + +--echo # +--echo # End of 10.8 tests +--echo # diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index b5f8cf4a886..2ca44721df7 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -7130,6 +7130,27 @@ bool LEX::sp_declare_cursor(THD *thd, const LEX_CSTRING *name, uint offp; sp_instr_cpush *i; + /* In some cases param_ctx can be NULL. e.g.: FOR rec IN (SELECT...) */ + if (param_ctx) + { + for (uint prm= 0; prm < param_ctx->context_var_count(); prm++) + { + const sp_variable *param= param_ctx->get_context_variable(prm); + if (param->mode != sp_variable::MODE_IN) + { + /* + PL/SQL supports the IN keyword in cursor parameters. + We also support this for compatibility. Note, OUT/INOUT parameters + will unlikely be ever supported. So "YET" may sound confusing here. + But it should be better than using a generic error. Adding a dedicated + error message for this small issue is not desirable. + */ + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "OUT/INOUT cursor parameter"); + return true; + } + } + } + if (spcont->find_cursor(name, &offp, true)) { my_error(ER_SP_DUP_CURS, MYF(0), name->str); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d80a33bb8b2..d147dd28ba8 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1748,8 +1748,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type <num> sp_handler_type sp_hcond_list %type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value %type <spname> sp_name -%type <spvar> sp_param_name sp_param_name_and_type -%type <spvar> sp_param_name_and_type_anchored +%type <spvar> sp_param_name sp_param_name_and_mode sp_param +%type <spvar> sp_param_anchored %type <for_loop> sp_for_loop_index_and_bounds %type <for_loop_bounds> sp_for_loop_bounds %type <trim> trim_operands @@ -3049,8 +3049,8 @@ sp_fdparam_list: ; sp_fdparams: - sp_fdparams ',' sp_param_name_and_type - | sp_param_name_and_type + sp_fdparams ',' sp_param + | sp_param ; sp_param_name: @@ -3068,8 +3068,8 @@ sp_pdparam_list: ; sp_pdparams: - sp_pdparams ',' sp_pdparam - | sp_pdparam + sp_pdparams ',' sp_param + | sp_param ; sp_parameter_type: @@ -18028,11 +18028,6 @@ sp_opt_default: | DEFAULT expr { $$ = $2; } ; -sp_pdparam: - sp_parameter_type sp_param_name_and_type { $2->mode=$1; } - | sp_param_name_and_type { $1->mode= sp_variable::MODE_IN; } - ; - sp_decl_variable_list_anchored: sp_decl_idents_init_vars TYPE_SYM OF_SYM optionally_qualified_column_ident @@ -18052,40 +18047,49 @@ sp_decl_variable_list_anchored: } ; -sp_param_name_and_type: - sp_param_name field_type +sp_param_name_and_mode: + sp_parameter_type sp_param_name + { + $2->mode= $1; + $$= $2; + } + | sp_param_name + ; + +sp_param: + sp_param_name_and_mode field_type { if (unlikely(Lex->sp_param_fill_definition($$= $1, $2))) MYSQL_YYABORT; } - | sp_param_name ROW_SYM row_type_body + | sp_param_name_and_mode ROW_SYM row_type_body { if (unlikely(Lex->sphead->spvar_fill_row(thd, $$= $1, $3))) MYSQL_YYABORT; } - | sp_param_name_and_type_anchored + | sp_param_anchored ; -sp_param_name_and_type_anchored: - sp_param_name TYPE_SYM OF_SYM ident '.' ident +sp_param_anchored: + sp_param_name_and_mode TYPE_SYM OF_SYM ident '.' ident { if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $4, $6))) MYSQL_YYABORT; } - | sp_param_name TYPE_SYM OF_SYM ident '.' ident '.' ident + | sp_param_name_and_mode TYPE_SYM OF_SYM ident '.' ident '.' ident { if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $4, $6, $8))) MYSQL_YYABORT; } - | sp_param_name ROW_SYM TYPE_SYM OF_SYM ident + | sp_param_name_and_mode ROW_SYM TYPE_SYM OF_SYM ident { if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $5))) MYSQL_YYABORT; } - | sp_param_name ROW_SYM TYPE_SYM OF_SYM ident '.' ident + | sp_param_name_and_mode ROW_SYM TYPE_SYM OF_SYM ident '.' ident { if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $5, $7))) MYSQL_YYABORT; @@ -18469,46 +18473,6 @@ sp_opt_inout: | IN_SYM OUT_SYM { $$= sp_variable::MODE_INOUT; } ; -sp_pdparam: - sp_param_name sp_opt_inout field_type - { - $1->mode= $2; - if (unlikely(Lex->sp_param_fill_definition($1, $3))) - MYSQL_YYABORT; - } - | sp_param_name sp_opt_inout sp_decl_ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM - { - $1->mode= $2; - if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $1, $3, $5))) - MYSQL_YYABORT; - } - | sp_param_name sp_opt_inout sp_decl_ident '.' ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM - { - $1->mode= $2; - if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $1, $3, $5, $7))) - MYSQL_YYABORT; - } - | sp_param_name sp_opt_inout sp_decl_ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM - { - $1->mode= $2; - if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $1, $3))) - MYSQL_YYABORT; - } - | sp_param_name sp_opt_inout sp_decl_ident '.' ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM - { - $1->mode= $2; - if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $1, $3, $5))) - MYSQL_YYABORT; - } - | sp_param_name sp_opt_inout ROW_SYM row_type_body - { - $1->mode= $2; - if (unlikely(Lex->sphead->spvar_fill_row(thd, $1, $4))) - MYSQL_YYABORT; - } - ; - - sp_proc_stmts1_implicit_block: { Lex->sp_block_init(thd); @@ -18940,45 +18904,47 @@ sp_decl_variable_list_anchored: } ; -sp_param_name_and_type: - sp_param_name sp_opt_inout field_type +sp_param_name_and_mode: + sp_param_name sp_opt_inout + { + $1->mode= $2; + $$= $1; + } + ; + +sp_param: + sp_param_name_and_mode field_type { - $1->mode= $2; - if (unlikely(Lex->sp_param_fill_definition($$= $1, $3))) + if (unlikely(Lex->sp_param_fill_definition($$= $1, $2))) MYSQL_YYABORT; } - | sp_param_name sp_opt_inout ROW_SYM row_type_body + | sp_param_name_and_mode ROW_SYM row_type_body { - $1->mode= $2; - if (unlikely(Lex->sphead->spvar_fill_row(thd, $$= $1, $4))) + if (unlikely(Lex->sphead->spvar_fill_row(thd, $$= $1, $3))) MYSQL_YYABORT; } - | sp_param_name_and_type_anchored + | sp_param_anchored ; -sp_param_name_and_type_anchored: - sp_param_name sp_opt_inout sp_decl_ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM +sp_param_anchored: + sp_param_name_and_mode sp_decl_ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM { - $1->mode= $2; - if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $3, $5))) + if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $2, $4))) MYSQL_YYABORT; } - | sp_param_name sp_opt_inout sp_decl_ident '.' ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM + | sp_param_name_and_mode sp_decl_ident '.' ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM { - $1->mode= $2; - if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $3, $5, $7))) + if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $2, $4, $6))) MYSQL_YYABORT; } - | sp_param_name sp_opt_inout sp_decl_ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM + | sp_param_name_and_mode sp_decl_ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM { - $1->mode= $2; - if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $3))) + if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $2))) MYSQL_YYABORT; } - | sp_param_name sp_opt_inout sp_decl_ident '.' ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM + | sp_param_name_and_mode sp_decl_ident '.' ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM { - $1->mode= $2; - if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $3, $5))) + if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $2, $4))) MYSQL_YYABORT; } ; |