SET sql_mode=ORACLE; --echo # Testing routines with no parameters DELIMITER /; CREATE FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END; / DELIMITER ;/ --vertical_results SHOW CREATE FUNCTION f1; --horizontal_results SELECT f1(); DROP FUNCTION f1; DELIMITER /; CREATE PROCEDURE p1 AS BEGIN SET @a=10; END; / DELIMITER ;/ --vertical_results SHOW CREATE PROCEDURE p1; --horizontal_results SET @a=0; CALL p1(); SELECT @a; DROP PROCEDURE p1; --echo # Testing ":=" to set the default value of a variable DELIMITER /; CREATE FUNCTION f1 () RETURN NUMBER(10) AS a NUMBER(10) := 10; BEGIN DECLARE b NUMBER(10) DEFAULT 3; BEGIN RETURN a+b; END; END; / DELIMITER ;/ SELECT f1(); DROP FUNCTION f1; --echo # Testing labels DELIMITER /; CREATE FUNCTION f1 (a INT) RETURN CLOB AS BEGIN <> BEGIN IF a = 1 THEN LEAVE label1; END IF; RETURN 'IS NOT 1'; END label1; RETURN 'IS 1'; END; / DELIMITER ;/ SELECT f1(1); SELECT f1(2); DROP FUNCTION f1; DELIMITER /; CREATE FUNCTION f1 (a INT) RETURN INT IS BEGIN <> LOOP IF a = 2 THEN LEAVE label1; END IF; SET a= a-1; END LOOP; RETURN a; END; / DELIMITER ;/ SELECT f1(4); DROP FUNCTION f1; DELIMITER /; CREATE FUNCTION f1 (a INT) RETURN INT AS BEGIN <> WHILE a>0 LOOP IF a = 2 THEN LEAVE label1; END IF; SET a= a-1; END LOOP label1; RETURN a; END; / DELIMITER ;/ SELECT f1(4); DROP FUNCTION f1; DELIMITER /; CREATE FUNCTION f1 (a INT) RETURN INT AS BEGIN <> REPEAT IF a = 2 THEN LEAVE label1; END IF; SET a= a-1; UNTIL a=0 END REPEAT; RETURN a; END; / DELIMITER ;/ SELECT f1(4); DROP FUNCTION f1; --echo # Testing IN/OUT/INOUT DELIMITER /; CREATE PROCEDURE p1 (p1 IN VARCHAR2(10), p2 OUT VARCHAR2(10)) AS BEGIN SET p1='p1new'; SET p2='p2new'; END; / DELIMITER ;/ SET @p1='p1', @p2='p2'; CALL p1(@p1, @p2); SELECT @p1, @p2; DROP PROCEDURE p1; --echo # Testing Oracle-style assigment DELIMITER /; CREATE PROCEDURE p1 (p1 OUT VARCHAR2(10)) AS BEGIN p1:= 'p1new'; END; / DELIMITER ;/ SET @p1='p1'; CALL p1(@p1); SELECT @p1; DROP PROCEDURE p1; --echo # Testing that NULL is a valid statement DELIMITER /; CREATE PROCEDURE p1(a INT) AS BEGIN NULL; END; / DELIMITER ;/ DROP PROCEDURE p1; DELIMITER /; CREATE PROCEDURE p1(a INT) AS a INT:=10; BEGIN IF a=10 THEN NULL; ELSE NULL; END IF; END; / DELIMITER ;/ DROP PROCEDURE p1; --echo # Testing that (some) keyword_sp are allowed in Oracle-style assignments DELIMITER /; CREATE PROCEDURE p1 (action OUT INT) AS BEGIN action:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (clob OUT INT) AS BEGIN clob:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (enum OUT INT) AS BEGIN enum:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (via OUT INT) AS BEGIN via:=10; END;/ DROP PROCEDURE p1/ DELIMITER ;/ --echo # Testing keyword_directly_assignable DELIMITER /; CREATE PROCEDURE p1 (ascii OUT INT) AS BEGIN ascii:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (backup OUT INT) AS BEGIN backup:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (binlog OUT INT) AS BEGIN binlog:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (byte OUT INT) AS BEGIN byte:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (cache OUT INT) AS BEGIN cache:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (checksum OUT INT) AS BEGIN checksum:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (checkpoint OUT INT) AS BEGIN checkpoint:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (column_add OUT INT) AS BEGIN column_add:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (column_check OUT INT) AS BEGIN column_check:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (column_create OUT INT) AS BEGIN column_create:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (column_delete OUT INT) AS BEGIN column_delete:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (column_get OUT INT) AS BEGIN column_get:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (deallocate OUT INT) AS BEGIN deallocate:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (examined OUT INT) AS BEGIN examined:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (execute OUT INT) AS BEGIN execute:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (flush OUT INT) AS BEGIN flush:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (format OUT INT) AS BEGIN format:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (get OUT INT) AS BEGIN get:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (help OUT INT) AS BEGIN help:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (host OUT INT) AS BEGIN host:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (install OUT INT) AS BEGIN install:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (option OUT INT) AS BEGIN option:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (options OUT INT) AS BEGIN options:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (owner OUT INT) AS BEGIN owner:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (parser OUT INT) AS BEGIN parser:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (port OUT INT) AS BEGIN port:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (prepare OUT INT) AS BEGIN prepare:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (remove OUT INT) AS BEGIN remove:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (reset OUT INT) AS BEGIN reset:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (restore OUT INT) AS BEGIN restore:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (security OUT INT) AS BEGIN security:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (server OUT INT) AS BEGIN server:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (signed OUT INT) AS BEGIN signed:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (socket OUT INT) AS BEGIN socket:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (slave OUT INT) AS BEGIN slave:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (slaves OUT INT) AS BEGIN slaves:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (soname OUT INT) AS BEGIN soname:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (start OUT INT) AS BEGIN start:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (stop OUT INT) AS BEGIN stop:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (stored OUT INT) AS BEGIN stored:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (unicode OUT INT) AS BEGIN unicode:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (uninstall OUT INT) AS BEGIN uninstall:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (upgrade OUT INT) AS BEGIN upgrade:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (wrapper OUT INT) AS BEGIN wrapper:=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (xa OUT INT) AS BEGIN xa:=10; END;/ DROP PROCEDURE p1/ DELIMITER ;/ --echo # Testing that keyword_directly_not_assignable does not work in := DELIMITER /; --error ER_PARSE_ERROR CREATE PROCEDURE p1 (commit OUT INT) AS BEGIN commit:=10; END;/ --error ER_PARSE_ERROR CREATE PROCEDURE p1 (rollback OUT INT) AS BEGIN rollback:=10; END;/ --error ER_PARSE_ERROR CREATE PROCEDURE p1 (shutdown OUT INT) AS BEGIN shutdown:=10; END;/ DELIMITER ;/ --echo # Testing that keyword_directly_not_assignable works in SET statements. DELIMITER /; CREATE PROCEDURE p1 (contains OUT INT) AS BEGIN SET contains=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (language OUT INT) AS BEGIN SET language=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (no OUT INT) AS BEGIN SET no=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (charset OUT INT) AS BEGIN SET charset=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (do OUT INT) AS BEGIN SET do=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (repair OUT INT) AS BEGIN SET repair=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (handler OUT INT) AS BEGIN SET handler=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (open OUT INT) AS BEGIN SET open=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (close OUT INT) AS BEGIN SET close=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (savepoint OUT INT) AS BEGIN SET savepoint=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (truncate OUT INT) AS BEGIN SET truncate=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (begin OUT INT) AS BEGIN SET begin=10; END;/ DROP PROCEDURE p1/ CREATE PROCEDURE p1 (end OUT INT) AS BEGIN SET end=10; END;/ DROP PROCEDURE p1/ DELIMITER ;/ --echo # Testing that keyword_directly_not_assignable works in table/column names CREATE TABLE contains (contains INT); DROP TABLE contains; CREATE TABLE language (language INT); DROP TABLE language; CREATE TABLE no (no INT); DROP TABLE no; CREATE TABLE charset (charset INT); DROP TABLE charset; CREATE TABLE do (do INT); DROP TABLE do; CREATE TABLE repair (repair INT); DROP TABLE repair; CREATE TABLE handler (handler INT); DROP TABLE handler; CREATE TABLE open (open INT); DROP TABLE open; CREATE TABLE close (close INT); DROP TABLE close; CREATE TABLE savepoint (savepoint INT); DROP TABLE savepoint; CREATE TABLE truncate (truncate INT); DROP TABLE truncate; CREATE TABLE begin (begin INT); DROP TABLE begin; CREATE TABLE end (end INT); DROP TABLE end; --echo # Testing ELSIF DELIMITER /; CREATE FUNCTION f1(a INT) RETURN CLOB AS BEGIN IF a=1 THEN RETURN 'a is 1'; ELSIF a=2 THEN RETURN 'a is 2'; ELSE RETURN 'a is unknown'; END IF; END; / DELIMITER ;/ SELECT f1(2) FROM DUAL; DROP FUNCTION f1; --echo # Testing top-level declarations DELIMITER /; CREATE PROCEDURE p1 (p1 OUT VARCHAR2(10)) AS p2 VARCHAR(10); BEGIN p2:='p1new'; p1:=p2; END; / DELIMITER ;/ SET @p1='p1'; CALL p1(@p1); SELECT @p1; DROP PROCEDURE p1; DELIMITER /; CREATE FUNCTION f1 (p1 VARCHAR2(10)) RETURN VARCHAR(20) AS p2 VARCHAR(10); BEGIN p2:='new'; RETURN CONCAT(p1, p2); END; / DELIMITER ;/ SET @p1='p1'; SELECT f1(@p1); DROP FUNCTION f1; --echo # Testing non-top declarations DELIMITER /; CREATE PROCEDURE p1 (p1 OUT VARCHAR2(10)) AS BEGIN DECLARE p2 VARCHAR(10); BEGIN p2:='p1new'; p1:=p2; END; DECLARE t1 VARCHAR(10); t2 VARCHAR(10); BEGIN END; END; / DELIMITER ;/ SET @p1='p1'; CALL p1(@p1); SELECT @p1; DROP PROCEDURE p1; DELIMITER /; CREATE FUNCTION f1 (p1 VARCHAR2(10)) RETURN VARCHAR(20) AS BEGIN DECLARE p2 VARCHAR(10); BEGIN p2:='new'; RETURN CONCAT(p1, p2); END; DECLARE t1 VARCHAR(10); t2 VARCHAR(10); BEGIN END; END; / DELIMITER ;/ SET @p1='p1'; SELECT f1(@p1); DROP FUNCTION f1; --echo # Testing exceptions CREATE TABLE t1 (c1 INT); DELIMITER /; CREATE PROCEDURE sp1 (p1 IN VARCHAR2(20), p2 OUT VARCHAR2(30)) IS v1 INT; BEGIN SELECT c1 INTO v1 FROM t1; p2 := p1; EXCEPTION WHEN NOT FOUND THEN BEGIN p2 := 'def'; END; END; / DELIMITER ;/ CALL sp1('abc', @a); SELECT @a; DROP PROCEDURE sp1; DROP TABLE t1; DELIMITER /; CREATE PROCEDURE sp1 (v IN OUT INT, error IN INT) IS BEGIN SIGNAL SQLSTATE '45000' SET MYSQL_ERRNO=error, MESSAGE_TEXT='User defined error!'; v:= 223; EXCEPTION WHEN 30001 THEN BEGIN v:= 113; END; END; / DELIMITER ;/ SET @v=10; CALL sp1(@v, 30001); --error 30002 CALL sp1(@v, 30002); SELECT @v; DROP PROCEDURE sp1; DELIMITER /; CREATE PROCEDURE sp1 (v IN OUT INT, error IN INT) IS BEGIN BEGIN BEGIN SIGNAL SQLSTATE '45000' SET MYSQL_ERRNO=error, MESSAGE_TEXT='User defined error!'; v:= 223; EXCEPTION WHEN 30001 THEN BEGIN v:= 113; END; END; END; END; / DELIMITER ;/ SET @v=10; CALL sp1(@v, 30001); SELECT @v; SET @v=10; --error 30002 CALL sp1(@v, 30002); SELECT @v; DROP PROCEDURE sp1; --echo # --echo # Testing EXIT statement --echo # DELIMITER /; --error ER_SP_LILABEL_MISMATCH CREATE FUNCTION f1 RETURN INT IS i INT := 0; BEGIN EXIT; END; / DELIMITER ;/ DELIMITER /; --error ER_SP_LILABEL_MISMATCH CREATE FUNCTION f1 RETURN INT IS i INT := 0; BEGIN <> BEGIN <> LOOP EXIT label1; END LOOP; END; END; / DELIMITER ;/ DELIMITER /; CREATE FUNCTION f1 RETURN INT IS i INT := 0; BEGIN LOOP LOOP i:= i + 1; IF i >= 5 THEN EXIT; END IF; END LOOP; i:= i + 100; EXIT; END LOOP; RETURN i; END; / DELIMITER ;/ SELECT f1() FROM DUAL; DROP FUNCTION f1; DELIMITER /; CREATE FUNCTION f1 RETURN INT IS i INT := 0; BEGIN <> LOOP <> LOOP i:= i + 1; IF i >= 5 THEN EXIT label2; END IF; END LOOP; i:= i + 100; EXIT; END LOOP; RETURN i; END; / DELIMITER ;/ SELECT f1() FROM DUAL; DROP FUNCTION f1; DELIMITER /; CREATE FUNCTION f1 RETURN INT IS i INT := 0; BEGIN <> LOOP <> LOOP i:= i + 1; IF i >= 5 THEN EXIT label1; END IF; END LOOP; i:= i + 100; EXIT; END LOOP; RETURN i; END; / DELIMITER ;/ SELECT f1() FROM DUAL; DROP FUNCTION f1; DELIMITER /; CREATE FUNCTION f1 RETURN INT IS i INT := 0; BEGIN LOOP i:= i + 1; EXIT WHEN i >=5; END LOOP; RETURN i; END; / DELIMITER ;/ SELECT f1() FROM DUAL; DROP FUNCTION f1; DELIMITER /; CREATE FUNCTION f1 RETURN INT IS i INT := 0; BEGIN <> LOOP <> LOOP i:= i + 1; EXIT label2 WHEN i >= 5; END LOOP; i:= i + 100; EXIT; END LOOP; RETURN i; END; / DELIMITER ;/ SELECT f1() FROM DUAL; DROP FUNCTION f1; DELIMITER /; CREATE FUNCTION f1 RETURN INT IS i INT := 0; BEGIN <> LOOP <> LOOP i:= i + 1; EXIT label1 WHEN i >= 5; END LOOP; i:= i + 100; EXIT; END LOOP; RETURN i; END; / DELIMITER ;/ SELECT f1() FROM DUAL; DROP FUNCTION f1; --echo # Testing CURSOR declaration CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1); DELIMITER /; CREATE FUNCTION f1 RETURN INT AS v_a INT:=10; CURSOR c IS SELECT a FROM t1; BEGIN OPEN c; FETCH c INTO v_a; CLOSE c; RETURN v_a; EXCEPTION WHEN OTHERS THEN RETURN -1; END; / DELIMITER ;/ SELECT f1() FROM DUAL; DROP FUNCTION f1; DROP TABLE t1; --echo # Testing RETURN in procedures DELIMITER /; --error ER_SP_BADRETURN CREATE PROCEDURE p1 (a IN OUT INT) AS BEGIN RETURN 10; END; / DELIMITER ;/ DELIMITER /; --error ER_PARSE_ERROR CREATE FUNCTION f1 (a INT) RETURN INT AS BEGIN RETURN; END; / DELIMITER ;/ DELIMITER /; CREATE PROCEDURE p1 (a IN OUT INT) AS BEGIN IF a < 10 THEN BEGIN a:= a - 1; RETURN; END; END IF; a:= a + 1; EXCEPTION WHEN OTHERS THEN RETURN; END; / DELIMITER ;/ SET @v=10; CALL p1(@v); SELECT @v; SET @v=9; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; DELIMITER /; CREATE PROCEDURE p1 (a IN OUT INT) AS BEGIN DROP TABLE t1_non_existent; EXCEPTION WHEN OTHERS THEN BEGIN a:= 100; RETURN; END; END; / DELIMITER ;/ SET @v=10; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; --echo # Testing WHILE loop DELIMITER /; CREATE PROCEDURE p1 (a IN OUT INT) AS i INT:= 1; j INT:= 3; BEGIN WHILE i<=j LOOP a:= a + i; i:= i + 1; END LOOP; END; / DELIMITER ;/ SET @v=0; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; DELIMITER /; CREATE PROCEDURE p1 (a IN OUT INT) AS i INT:= 1; j INT:= 3; BEGIN <