summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2017-02-01 23:12:16 +0400
committerAlexander Barkov <bar@mariadb.org>2017-04-05 15:02:55 +0400
commit81f32145fab9e335fbc0c01aabc9dffd776afa7b (patch)
tree03663685e6e788b2793d12b9894ffa202b8652e9
parent08799831ccf5f052518ce121bf532dda86168ca3 (diff)
downloadmariadb-git-81f32145fab9e335fbc0c01aabc9dffd776afa7b.tar.gz
MDEV-10655 Anonymous blocks
-rw-r--r--mysql-test/suite/compat/oracle/r/sp-anonymous.result220
-rw-r--r--mysql-test/suite/compat/oracle/r/sp.result26
-rw-r--r--mysql-test/suite/compat/oracle/t/sp-anonymous.test244
-rw-r--r--mysql-test/suite/compat/oracle/t/sp.test27
-rw-r--r--sql/sql_yacc_ora.yy46
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
{