-- source include/have_debug.inc SET sql_mode=ORACLE; --echo # --echo # Testing exceptions in the top-level blocks --echo # --echo # No HANDLER declarations, no exceptions DELIMITER /; CREATE FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END; / DELIMITER ;/ SHOW FUNCTION CODE f1; SELECT f1(); DROP FUNCTION f1; --echo # No HANDLER declarations, no code, no exceptions DELIMITER /; CREATE PROCEDURE p1 () IS BEGIN END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; CALL p1; DROP PROCEDURE p1; --echo # No HANDLER declarations, no code, some exceptions DELIMITER /; CREATE PROCEDURE p1 (v IN OUT INT) IS BEGIN EXCEPTION WHEN 1002 THEN v:=225; END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; set @v= 10; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; --echo # No HANDLER declarations, some code, some exceptions DELIMITER /; CREATE PROCEDURE p1 (v IN OUT INT) IS BEGIN v:=224; EXCEPTION WHEN 1002 THEN v:=225; END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; set @v= 10; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; --echo # Some HANDLER declarations, no code, no exceptions DELIMITER /; CREATE PROCEDURE p1 (v IN OUT INT) IS EXIT HANDLER FOR 1000 BEGIN v:=123; END; BEGIN END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; set @v= 10; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; --echo # Some HANDLER declarations, no code, some exceptions DELIMITER /; CREATE PROCEDURE p1 (v IN OUT INT) IS EXIT HANDLER FOR 1000 BEGIN v:=123; END; BEGIN EXCEPTION WHEN 1002 THEN v:=225; END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; set @v= 10; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; --echo # Some HANDLER declarations, some code, no exceptions DELIMITER /; CREATE PROCEDURE p1 (v IN OUT INT) IS EXIT HANDLER FOR 1000 BEGIN v:=123; END; BEGIN v:=223; END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; set @v= 10; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; --echo # Some HANDLER declarations, some code, some exceptions DELIMITER /; CREATE PROCEDURE p1 (v IN OUT VARCHAR2(20)) IS EXIT HANDLER FOR 1000 BEGIN v:=123; END; CONTINUE HANDLER FOR 1001 BEGIN SET v=223; END; BEGIN v:= 1; EXCEPTION WHEN 1002 THEN SET v=225; END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; DROP PROCEDURE p1; --echo # --echo # Testing EXCEPTIONS in internal blocks --echo # --echo # No HANDLER declarations, no code, no exceptions DELIMITER /; CREATE PROCEDURE p1 (v IN OUT INT) IS BEGIN v:=123; BEGIN END; END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; SET @v=10; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; --echo # No HANDLER declarations, no code, some exceptions DELIMITER /; CREATE PROCEDURE p1 (v IN OUT INT) IS BEGIN v:=123; BEGIN EXCEPTION WHEN 20002 THEN v:=335; END; END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; SET @v=10; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; --echo # No HANDLER declarations, some code, no exceptions DELIMITER /; CREATE PROCEDURE p1 (v IN OUT INT) IS BEGIN v:=123; BEGIN v:=223; END; END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; SET @v=10; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; --echo # No HANDLER declarations, some code, some exceptions DELIMITER /; CREATE PROCEDURE p1 (v IN OUT INT) IS BEGIN v:=123; BEGIN v:=223; EXCEPTION WHEN 20002 THEN v:=335; END; END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; SET @v=10; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; --echo # Some HANDLER declarations, no code, no exceptions DELIMITER /; CREATE PROCEDURE p1 (v IN OUT INT) IS BEGIN v:=123; DECLARE EXIT HANDLER FOR 1000 BEGIN v:=323; END; BEGIN END; END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; SET @v=10; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; --echo # Some HANDLER declarations, no code, some exceptions DELIMITER /; CREATE PROCEDURE p1 (v IN OUT INT) IS BEGIN v:=123; DECLARE EXIT HANDLER FOR 1000 BEGIN v:=323; END; BEGIN EXCEPTION WHEN 20002 THEN v:=335; END; END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; SET @v=10; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; --echo # Some HANDLER declarations, some code, no exceptions DELIMITER /; CREATE PROCEDURE p1 (v IN OUT INT) IS BEGIN v:=123; DECLARE EXIT HANDLER FOR 1000 BEGIN v:=323; END; BEGIN v:= 324; END; END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; SET @v=10; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; --echo # Some HANDLER declarations, some code, some exceptions DELIMITER /; CREATE PROCEDURE p1 (v IN OUT INT) IS BEGIN v:=123; DECLARE EXIT HANDLER FOR 1000 BEGIN v:=323; END; BEGIN v:= 324; EXCEPTION WHEN 2002 THEN v:= 325; END; END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; SET @v=10; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; --echo # --echo # Testing EXIT statement --echo # DELIMITER /; CREATE FUNCTION f1 RETURN INT IS i INT := 0; BEGIN LOOP i:= i + 1; IF i >= 5 THEN EXIT; END IF; END LOOP; RETURN i; END; / DELIMITER ;/ SHOW FUNCTION CODE f1; 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 ;/ SHOW FUNCTION CODE f1; SELECT f1() FROM DUAL; DROP FUNCTION f1; DELIMITER /; CREATE FUNCTION f1 RETURN INT IS i INT := 0; BEGIN LOOP BEGIN i:= i + 1; IF i >= 5 THEN EXIT; END IF; EXCEPTION WHEN OTHERS THEN i:= 1000; END; END LOOP; RETURN i; END; / DELIMITER ;/ SHOW FUNCTION CODE f1; SELECT f1() FROM DUAL; DROP FUNCTION f1; DELIMITER /; CREATE PROCEDURE p1(a IN OUT INT) IS i INT := 0; BEGIN LOOP LOOP BEGIN i:= i + 1; IF i >=5 THEN EXIT; END IF; EXCEPTION WHEN OTHERS THEN a:=1000; END; END LOOP; i:= i + 100; EXIT; END LOOP; a:= i; EXCEPTION WHEN OTHERS THEN a:=11; END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; set @v= 10; CALL p1(@v); SELECT @v; DROP PROCEDURE p1; --echo # Testing RETURN in procedures DELIMITER /; CREATE PROCEDURE p1 (a IN OUT INT) AS BEGIN IF a < 10 THEN BEGIN a:= a + 1; RETURN; END; END IF; a:= 200; EXCEPTION WHEN OTHERS THEN BEGIN a:= 100; RETURN; END; END; / DELIMITER ;/ SHOW PROCEDURE CODE p1; DROP PROCEDURE p1; --echo # Testing FOR loop statement DELIMITER /; CREATE FUNCTION f1 (a INT, b INT) RETURN INT AS total INT := 0; BEGIN FOR i IN 1 .. a LOOP total:= total + i; IF i = b THEN EXIT; END IF; END LOOP; RETURN total; END / DELIMITER ;/ SHOW FUNCTION CODE f1; SELECT f1(3, 100) FROM DUAL; SELECT f1(3, 2) FROM DUAL; DROP FUNCTION f1; DELIMITER /; CREATE FUNCTION f1 (a INT, b INT) RETURN INT AS total INT := 0; BEGIN FOR i IN REVERSE a..1 LOOP total:= total + i; IF i = b THEN EXIT; END IF; END LOOP; RETURN total; END / DELIMITER ;/ SHOW FUNCTION CODE f1; SELECT f1(3, 100) FROM DUAL; SELECT f1(3, 2) FROM DUAL; DROP FUNCTION f1; --echo # Testing labeled FOR LOOP statement DELIMITER /; CREATE FUNCTION f1 (a INT, limita INT, b INT, limitb INT) RETURN INT AS total INT := 0; BEGIN <> FOR ia IN 1 .. a LOOP total:= total + 1000; <> FOR ib IN 1 .. b LOOP total:= total + 1; EXIT lb WHEN ib = limitb; EXIT la WHEN ia = limita; END LOOP lb; END LOOP la; RETURN total; END; / DELIMITER ;/ SHOW FUNCTION CODE f1; SELECT f1(2, 1, 2, 2) FROM DUAL; SELECT f1(2, 2, 2, 2) FROM DUAL; SELECT f1(2, 3, 2, 3) FROM DUAL; DROP FUNCTION f1; --echo # Testing labeled ITERATE in a labeled FOR LOOP DELIMITER /; CREATE FUNCTION f1(a INT) RETURN INT AS total INT:= 0; BEGIN <
  • > FOR i IN 1 .. a LOOP total:= total + 1000; IF i = 5 THEN ITERATE li; END IF; total:= total + 1; END LOOP; RETURN total; END; / DELIMITER ;/ SHOW FUNCTION CODE f1; SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; DROP FUNCTION f1; DELIMITER /; CREATE FUNCTION f1(a INT) RETURN INT AS total INT:= 0; BEGIN <
  • > FOR i IN 1 .. a LOOP FOR j IN 1 .. 2 LOOP total:= total + 1000; IF i = 5 THEN ITERATE li; END IF; total:= total + 1; END LOOP; END LOOP; RETURN total; END; / DELIMITER ;/ SHOW FUNCTION CODE f1; SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; DROP FUNCTION f1; DELIMITER /; CREATE FUNCTION f1(a INT) RETURN INT AS total INT:= 0; BEGIN <> FOR j IN 1 .. 2 LOOP <
  • > FOR i IN 1 .. a LOOP total:= total + 1000; IF i = 5 THEN ITERATE li; END IF; total:= total + 1; END LOOP; END LOOP; RETURN total; END; / DELIMITER ;/ SHOW FUNCTION CODE f1; SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; DROP FUNCTION f1; --echo # Testing CONTINUE statement DELIMITER /; CREATE FUNCTION f1(a INT) RETURN INT AS total INT:= 0; BEGIN FOR i IN 1 .. a LOOP CONTINUE WHEN i=5; total:= total + 1; END LOOP; RETURN total; END; / DELIMITER ;/ SHOW FUNCTION CODE f1; SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; DROP FUNCTION f1; --echo # --echo # Start of MDEV-10597 Cursors with parameters --echo # DELIMITER $$; CREATE PROCEDURE p1(arg_value_a VARCHAR, arg_value_b VARCHAR, arg_pattern_a VARCHAR, arg_pattern_b VARCHAR) AS v_a VARCHAR(10); v_b VARCHAR(20); CURSOR c (p_value_a VARCHAR, p_value_b VARCHAR, p_pattern_a VARCHAR, p_pattern_b VARCHAR, p_limit_a INT, p_limit_b INT, p_unused TEXT) IS (SELECT p_value_a, p_value_b FROM DUAL WHERE p_value_a LIKE p_pattern_a LIMIT p_limit_a) UNION (SELECT p_value_b, p_value_a FROM DUAL WHERE p_value_b LIKE p_pattern_b LIMIT p_limit_b); BEGIN OPEN c(arg_value_a, (SELECT arg_value_b), arg_pattern_a, arg_pattern_b, 100, 101, 'x'); LOOP FETCH c INTO v_a, v_b; EXIT WHEN c%NOTFOUND; SELECT v_a, v_b; END LOOP; CLOSE c; END; $$ DELIMITER ;$$ CALL p1('aaa','bbb','aaa','bbb'); SHOW PROCEDURE CODE p1; DROP PROCEDURE p1; --echo # --echo # End of MDEV-10597 Cursors with parameters --echo # --echo # --echo # MDEV-10914 ROW data type for stored routine variables --echo # DELIMITER $$; CREATE FUNCTION f1() RETURN INT AS a ROW(a INT, b INT); BEGIN a.b:= 200; RETURN a.b; END; $$ DELIMITER ;$$ SHOW FUNCTION CODE f1; SELECT f1(); DROP FUNCTION f1; DELIMITER $$; CREATE PROCEDURE p1 AS rec ROW(a INT,b DOUBLE,c DECIMAL(10,3),d VARCHAR(10)); BEGIN rec:= ROW(10,20.123456,30.123,'test'); SELECT rec.a, rec.b, rec.c, rec.d; END; $$ DELIMITER ;$$ SHOW PROCEDURE CODE p1; CALL p1; DROP PROCEDURE p1; DELIMITER $$; CREATE PROCEDURE p1 AS rec ROW(a INT,b DOUBLE,c DECIMAL(10,3),d VARCHAR(10)) := ROW(10,20.123456,30.123,'test'); BEGIN SELECT rec.a, rec.b, rec.c, rec.d; END; $$ DELIMITER ;$$ SHOW PROCEDURE CODE p1; CALL p1; DROP PROCEDURE p1; DELIMITER $$; CREATE PROCEDURE p1 AS rec1 ROW(a INT,b DOUBLE,c DECIMAL(10,3),d VARCHAR(10)); rec2 ROW(a INT,b DOUBLE,c DECIMAL(10,3),d VARCHAR(10)); BEGIN rec1:= ROW(10,20.123456,30.123,'test'); rec2:= rec1; SELECT rec2.a, rec2.b, rec2.c, rec2.d; END; $$ DELIMITER ;$$ SHOW PROCEDURE CODE p1; CALL p1; DROP PROCEDURE p1; DELIMITER $$; CREATE PROCEDURE p1 AS rec1 ROW(a INT,b DOUBLE,c DECIMAL(10,3),d VARCHAR(10)) := ROW(10,20.123456,30.123,'test'); rec2 ROW(a INT,b DOUBLE,c DECIMAL(10,3),d VARCHAR(10)) := rec1; BEGIN SELECT rec2.a, rec2.b, rec2.c, rec2.d; END; $$ DELIMITER ;$$ SHOW PROCEDURE CODE p1; CALL p1; DROP PROCEDURE p1; --echo # --echo # End of MDEV-10914 ROW data type for stored routine variables --echo # --echo # --echo # MDEV-12133 sql_mode=ORACLE: table%ROWTYPE in variable declarations --echo # CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10,2)); DELIMITER $$; CREATE PROCEDURE p1() AS rec1 t1%ROWTYPE; BEGIN rec1.a:= 10; rec1.b:= 'bbb'; rec1.c:= 10e2; rec1.d:= 10.12; rec1.c:= rec1.d; END; $$ DELIMITER ;$$ SHOW PROCEDURE CODE p1; DROP PROCEDURE p1; DROP TABLE t1; --echo # --echo # MDEV-12011 sql_mode=ORACLE: cursor%ROWTYPE in variable declarations --echo # CREATE TABLE t1 (a INT, b VARCHAR(10)); DELIMITER $$; CREATE PROCEDURE p1() AS CURSOR cur1 IS SELECT * FROM t1; CURSOR cur2 IS SELECT * FROM t1; BEGIN DECLARE rec1,rec2 cur1%ROWTYPE; rec3 cur2%ROWTYPE; BEGIN rec1.a:= 10; rec1.b:= 'bbb'; END; END; $$ DELIMITER ;$$ SHOW PROCEDURE CODE p1; DROP PROCEDURE p1; DROP TABLE t1;