diff options
author | Alexander Barkov <bar@mariadb.org> | 2017-02-01 23:12:16 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-04-05 15:02:55 +0400 |
commit | 81f32145fab9e335fbc0c01aabc9dffd776afa7b (patch) | |
tree | 03663685e6e788b2793d12b9894ffa202b8652e9 | |
parent | 08799831ccf5f052518ce121bf532dda86168ca3 (diff) | |
download | mariadb-git-81f32145fab9e335fbc0c01aabc9dffd776afa7b.tar.gz |
MDEV-10655 Anonymous blocks
-rw-r--r-- | mysql-test/suite/compat/oracle/r/sp-anonymous.result | 220 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/r/sp.result | 26 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/t/sp-anonymous.test | 244 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/t/sp.test | 27 | ||||
-rw-r--r-- | sql/sql_yacc_ora.yy | 46 |
5 files changed, 478 insertions, 85 deletions
diff --git a/mysql-test/suite/compat/oracle/r/sp-anonymous.result b/mysql-test/suite/compat/oracle/r/sp-anonymous.result new file mode 100644 index 00000000000..26bce0f435f --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-anonymous.result @@ -0,0 +1,220 @@ +SET sql_mode=ORACLE; +# +# MDEV-10655 Anonymous blocks +# +# Testing BEGIN NOT ATOMIC with no declarations +BEGIN NOT ATOMIC +SELECT 1 AS a; +END +/ +a +1 +# Testing BEGIN NOT ATOMIC with declarations +# DECLARE starts a new block and thus must be followed by BEGIN .. END +BEGIN NOT ATOMIC +DECLARE +i INT DEFAULT 5; +x INT DEFAULT 10; +BEGIN +<<label>> +WHILE i > 3 LOOP +i:= i - 1; +SELECT i; +END LOOP label; +END; +END +/ +i +4 +i +3 +# Anonymous blocks with no declarations and no exceptions +BEGIN +SELECT 1 AS a; +END +$$ +a +1 +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +BEGIN +INSERT INTO t1 VALUES(20); +INSERT INTO t1 VALUES(30); +ROLLBACK; +END; +$$ +SELECT * FROM t1; +a +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +BEGIN +INSERT INTO t1 VALUES(20); +INSERT INTO t1 VALUES(30); +END; +$$ +ROLLBACK; +SELECT * FROM t1; +a +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +BEGIN +INSERT INTO t1 VALUES(20); +INSERT INTO t1 VALUES(30); +COMMIT; +END; +$$ +SELECT * FROM t1; +a +10 +20 +30 +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +BEGIN +INSERT INTO t1 VALUES(20); +INSERT INTO t1 VALUES(30); +END; +$$ +COMMIT; +SELECT * FROM t1; +a +10 +20 +30 +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +BEGIN +INSERT INTO t1 VALUES(20); +INSERT INTO t1 VALUES(20); +END; +$$ +ERROR 23000: Duplicate entry '20' for key 'PRIMARY' +COMMIT; +SELECT * FROM t1; +a +10 +20 +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +# Anonymous blocks with no declarations, with exceptions +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +BEGIN +INSERT INTO t1 VALUES(20); +INSERT INTO t1 VALUES(20); +EXCEPTION +WHEN DUP_VAL_ON_INDEX THEN NULL; +END; +$$ +COMMIT; +SELECT * FROM t1; +a +10 +20 +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +# Anonymous blocks with declarations, with no exceptions +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DECLARE +a20 INT:=20; +a30 INT:=30; +BEGIN +INSERT INTO t1 VALUES(a20); +INSERT INTO t1 VALUES(a30); +ROLLBACK; +END; +$$ +SELECT * FROM t1; +a +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DECLARE +a20 INT:=20; +a30 INT:=30; +BEGIN +INSERT INTO t1 VALUES(a20); +INSERT INTO t1 VALUES(a30); +END; +$$ +ROLLBACK; +SELECT * FROM t1; +a +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DECLARE +a20 INT:=20; +a30 INT:=30; +BEGIN +INSERT INTO t1 VALUES(a20); +INSERT INTO t1 VALUES(a30); +COMMIT; +END; +$$ +SELECT * FROM t1; +a +10 +20 +30 +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DECLARE +a20 INT:=20; +a30 INT:=30; +BEGIN +INSERT INTO t1 VALUES(a20); +INSERT INTO t1 VALUES(a30); +END; +$$ +COMMIT; +SELECT * FROM t1; +a +10 +20 +30 +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +# Anonymous blocks with declarations, with exceptions +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DECLARE +a20 INT:=20; +BEGIN +INSERT INTO t1 VALUES(a20); +INSERT INTO t1 VALUES(a20); +EXCEPTION +WHEN DUP_VAL_ON_INDEX THEN NULL; +END; +$$ +COMMIT; +SELECT * FROM t1; +a +10 +20 +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; diff --git a/mysql-test/suite/compat/oracle/r/sp.result b/mysql-test/suite/compat/oracle/r/sp.result index 1000080dbdb..5a1c0928831 100644 --- a/mysql-test/suite/compat/oracle/r/sp.result +++ b/mysql-test/suite/compat/oracle/r/sp.result @@ -412,32 +412,6 @@ SELECT f1(@p1); f1(@p1) p1new DROP FUNCTION f1; -# Testing BEGIN NOT ATOMIC with no declarations -BEGIN NOT ATOMIC -SELECT 1 AS a; -END -/ -a -1 -# Testing BEGIN NOT ATOMIC with declarations -# DECLARE starts a new block and thus must be followed by BEGIN .. END -BEGIN NOT ATOMIC -DECLARE -i INT DEFAULT 5; -x INT DEFAULT 10; -BEGIN -<<label>> -WHILE i > 3 LOOP -i:= i - 1; -SELECT i; -END LOOP label; -END; -END -/ -i -4 -i -3 # Testing exceptions CREATE TABLE t1 (c1 INT); CREATE PROCEDURE sp1 (p1 IN VARCHAR2(20), p2 OUT VARCHAR2(30)) diff --git a/mysql-test/suite/compat/oracle/t/sp-anonymous.test b/mysql-test/suite/compat/oracle/t/sp-anonymous.test new file mode 100644 index 00000000000..ac61e8ace2e --- /dev/null +++ b/mysql-test/suite/compat/oracle/t/sp-anonymous.test @@ -0,0 +1,244 @@ +--source include/have_innodb.inc + +SET sql_mode=ORACLE; + +--echo # +--echo # MDEV-10655 Anonymous blocks +--echo # + +--echo # Testing BEGIN NOT ATOMIC with no declarations +DELIMITER /; +BEGIN NOT ATOMIC + SELECT 1 AS a; +END +/ +DELIMITER ;/ + +--echo # Testing BEGIN NOT ATOMIC with declarations +--echo # DECLARE starts a new block and thus must be followed by BEGIN .. END +DELIMITER /; +BEGIN NOT ATOMIC + DECLARE + i INT DEFAULT 5; + x INT DEFAULT 10; + BEGIN + <<label>> + WHILE i > 3 LOOP + i:= i - 1; + SELECT i; + END LOOP label; + END; +END +/ +DELIMITER ;/ + + +--echo # Anonymous blocks with no declarations and no exceptions + +DELIMITER $$; +BEGIN + SELECT 1 AS a; +END +$$ +DELIMITER ;$$ + + +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DELIMITER $$; +BEGIN + INSERT INTO t1 VALUES(20); + INSERT INTO t1 VALUES(30); + ROLLBACK; +END; +$$ +DELIMITER ;$$ +SELECT * FROM t1; +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; + + +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DELIMITER $$; +BEGIN + INSERT INTO t1 VALUES(20); + INSERT INTO t1 VALUES(30); +END; +$$ +DELIMITER ;$$ +ROLLBACK; +SELECT * FROM t1; +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; + + +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DELIMITER $$; +BEGIN + INSERT INTO t1 VALUES(20); + INSERT INTO t1 VALUES(30); + COMMIT; +END; +$$ +DELIMITER ;$$ +SELECT * FROM t1; +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; + + +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DELIMITER $$; +BEGIN + INSERT INTO t1 VALUES(20); + INSERT INTO t1 VALUES(30); +END; +$$ +DELIMITER ;$$ +COMMIT; +SELECT * FROM t1; +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; + + +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DELIMITER $$; +--error ER_DUP_ENTRY +BEGIN + INSERT INTO t1 VALUES(20); + INSERT INTO t1 VALUES(20); +END; +$$ +DELIMITER ;$$ +COMMIT; +SELECT * FROM t1; +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; + + +--echo # Anonymous blocks with no declarations, with exceptions + +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DELIMITER $$; +BEGIN + INSERT INTO t1 VALUES(20); + INSERT INTO t1 VALUES(20); +EXCEPTION + WHEN DUP_VAL_ON_INDEX THEN NULL; +END; +$$ +DELIMITER ;$$ +COMMIT; +SELECT * FROM t1; +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; + + +--echo # Anonymous blocks with declarations, with no exceptions + +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DELIMITER $$; +DECLARE + a20 INT:=20; + a30 INT:=30; +BEGIN + INSERT INTO t1 VALUES(a20); + INSERT INTO t1 VALUES(a30); + ROLLBACK; +END; +$$ +DELIMITER ;$$ +SELECT * FROM t1; +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; + + +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DELIMITER $$; +DECLARE + a20 INT:=20; + a30 INT:=30; +BEGIN + INSERT INTO t1 VALUES(a20); + INSERT INTO t1 VALUES(a30); +END; +$$ +DELIMITER ;$$ +ROLLBACK; +SELECT * FROM t1; +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; + + +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DELIMITER $$; +DECLARE + a20 INT:=20; + a30 INT:=30; +BEGIN + INSERT INTO t1 VALUES(a20); + INSERT INTO t1 VALUES(a30); + COMMIT; +END; +$$ +DELIMITER ;$$ +SELECT * FROM t1; +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; + + +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DELIMITER $$; +DECLARE + a20 INT:=20; + a30 INT:=30; +BEGIN + INSERT INTO t1 VALUES(a20); + INSERT INTO t1 VALUES(a30); +END; +$$ +DELIMITER ;$$ +COMMIT; +SELECT * FROM t1; +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; + + +--echo # Anonymous blocks with declarations, with exceptions + +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DELIMITER $$; +DECLARE + a20 INT:=20; +BEGIN + INSERT INTO t1 VALUES(a20); + INSERT INTO t1 VALUES(a20); +EXCEPTION + WHEN DUP_VAL_ON_INDEX THEN NULL; +END; +$$ +DELIMITER ;$$ +COMMIT; +SELECT * FROM t1; +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; diff --git a/mysql-test/suite/compat/oracle/t/sp.test b/mysql-test/suite/compat/oracle/t/sp.test index 5fc6a63dea4..8caf77485e2 100644 --- a/mysql-test/suite/compat/oracle/t/sp.test +++ b/mysql-test/suite/compat/oracle/t/sp.test @@ -437,33 +437,6 @@ SELECT f1(@p1); DROP FUNCTION f1; ---echo # Testing BEGIN NOT ATOMIC with no declarations -DELIMITER /; -BEGIN NOT ATOMIC - SELECT 1 AS a; -END -/ -DELIMITER ;/ - ---echo # Testing BEGIN NOT ATOMIC with declarations ---echo # DECLARE starts a new block and thus must be followed by BEGIN .. END -DELIMITER /; -BEGIN NOT ATOMIC - DECLARE - i INT DEFAULT 5; - x INT DEFAULT 10; - BEGIN - <<label>> - WHILE i > 3 LOOP - i:= i - 1; - SELECT i; - END LOOP label; - END; -END -/ -DELIMITER ;/ - - --echo # Testing exceptions CREATE TABLE t1 (c1 INT); diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 6f145910b99..de712e33bc3 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -1236,7 +1236,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); query verb_clause create change select do drop insert replace insert2 insert_values update delete truncate rename compound_statement show describe load alter optimize keycache preload flush - reset purge begin commit rollback savepoint release + reset purge commit rollback savepoint release slave master_def master_defs master_file_def slave_until_opts repair analyze opt_with_admin opt_with_admin_option analyze_table_list analyze_table_elem_spec @@ -1305,7 +1305,7 @@ END_OF_INPUT %type <NONE> sp_proc_stmt_compound_ok %type <NONE> sp_proc_stmt_if %type <NONE> sp_labeled_control sp_unlabeled_control -%type <NONE> sp_labeled_block sp_unlabeled_block sp_unlabeled_block_not_atomic +%type <NONE> sp_labeled_block sp_unlabeled_block %type <NONE> sp_proc_stmt_continue %type <NONE> sp_proc_stmt_exit %type <NONE> sp_proc_stmt_leave @@ -1440,7 +1440,6 @@ opt_end_of_input: verb_clause: statement - | begin | compound_statement ; @@ -2977,7 +2976,6 @@ sp_opt_default: sp_proc_stmt_in_returns_clause: sp_proc_stmt_return | sp_labeled_block - | sp_unlabeled_block | sp_labeled_control | sp_proc_stmt_compound_ok ; @@ -2998,7 +2996,7 @@ sp_proc_stmt: sp_proc_stmt_compound_ok: sp_proc_stmt_if | case_stmt_specification - | sp_unlabeled_block_not_atomic + | sp_unlabeled_block | sp_unlabeled_control ; @@ -3561,9 +3559,16 @@ sp_labeled_block: } ; +opt_not_atomic: + /* Empty */ + | not ATOMIC_SYM /* TODO: BEGIN ATOMIC (not -> opt_not) */ + ; + sp_unlabeled_block: - BEGIN_SYM + BEGIN_SYM opt_not_atomic { + if (Lex->maybe_start_compound_statement(thd)) + MYSQL_YYABORT; Lex->sp_block_init(thd); if (Lex->sp_block_with_exceptions_finalize_declarations(thd)) MYSQL_YYABORT; @@ -3571,11 +3576,13 @@ sp_unlabeled_block: sp_block_statements_and_exceptions END { - if (Lex->sp_block_finalize(thd, Lex_spblock($3))) + if (Lex->sp_block_finalize(thd, Lex_spblock($4))) MYSQL_YYABORT; } | DECLARE_SYM { + if (Lex->maybe_start_compound_statement(thd)) + MYSQL_YYABORT; Lex->sp_block_init(thd); } sp_decl_body_list @@ -3632,21 +3639,6 @@ sp_block_statements_and_exceptions: } ; -sp_unlabeled_block_not_atomic: - BEGIN_SYM not ATOMIC_SYM /* TODO: BEGIN ATOMIC (not -> opt_not) */ - { - if (Lex->maybe_start_compound_statement(thd)) - MYSQL_YYABORT; - Lex->sp_block_init(thd); - } - sp_proc_stmts - END - { - if (Lex->sp_block_finalize(thd)) - MYSQL_YYABORT; - } - ; - opt_exception_clause: /* Empty */ { $$= 0; } | EXCEPTION_SYM exception_handlers { $$= $2; } @@ -15798,16 +15790,6 @@ grant_option: | resource_option {} ; -begin: - BEGIN_SYM - { - LEX *lex=Lex; - lex->sql_command = SQLCOM_BEGIN; - lex->start_transaction_opt= 0; - } - opt_work {} - ; - compound_statement: sp_proc_stmt_compound_ok { |