diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2012-08-25 20:57:17 +0500 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2012-08-25 20:57:17 +0500 |
commit | d99b8004e6b46e2a1b321bf50825254bf841cddb (patch) | |
tree | 0d890d92947dc3c08d0ca9d173c26a3eb27768ce | |
parent | f277f27ae2fb4ab45a014027f08093a28acc1c14 (diff) | |
download | mariadb-git-d99b8004e6b46e2a1b321bf50825254bf841cddb.tar.gz |
SQL syntax extended with START TRANSACTION READ ONLY|READ WRITE
and SET TRANSACTION READ ONLT|READ WRITE
statements.
per-file comments:
mysql-test/include/check-warnings.test
READ ONLY transaction flag cleaned.
mysql-test/r/commit.result
result updated
mysql-test/r/read_only.result
result updated
mysql-test/t/commit.test
tests added.
mysql-test/t/read_only.test
tests added
sql/lex.h
ONLY symbol added.
sql/sql_base.cc
DBUG_RETURN added.
sql/sql_parse.cc
implementations added.
sql/sql_yacc.yy
SQL syntax extended.
storage/perfschema/gen_pfs_lex_token
changes forced by lex.h
storage/perfschema/pfs_lex_token.h
changes forced by lex.h
-rw-r--r-- | mysql-test/include/check-warnings.test | 6 | ||||
-rw-r--r-- | mysql-test/r/commit.result | 306 | ||||
-rw-r--r-- | mysql-test/r/read_only.result | 37 | ||||
-rw-r--r-- | mysql-test/r/trans_read_only.result | 40 | ||||
-rw-r--r-- | mysql-test/t/commit.test | 359 | ||||
-rw-r--r-- | mysql-test/t/read_only.test | 59 | ||||
-rw-r--r-- | mysql-test/t/trans_read_only-master.opt | 1 | ||||
-rw-r--r-- | mysql-test/t/trans_read_only.test | 50 | ||||
-rw-r--r-- | sql/lex.h | 1 | ||||
-rw-r--r-- | sql/sql_base.cc | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 1 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 472 | ||||
-rwxr-xr-x | storage/perfschema/gen_pfs_lex_token | bin | 160124 -> 132216 bytes | |||
-rw-r--r-- | storage/perfschema/pfs_lex_token.h | 535 |
14 files changed, 1451 insertions, 418 deletions
diff --git a/mysql-test/include/check-warnings.test b/mysql-test/include/check-warnings.test index 3a26f7eecb1..720f90d7b02 100644 --- a/mysql-test/include/check-warnings.test +++ b/mysql-test/include/check-warnings.test @@ -14,10 +14,12 @@ set SQL_LOG_BIN=0; # Turn off any debug crashes, allow the variable to be # non existent in release builds --error 0,1193 -set debug_dbug=""; - +set debug=""; use mtr; +# Allow this session to read-write even if server is started +# with --transaction-read-only +set session transaction read write; create temporary table error_log ( row int auto_increment primary key, diff --git a/mysql-test/r/commit.result b/mysql-test/r/commit.result index 00e39c29768..a62d2940d85 100644 --- a/mysql-test/r/commit.result +++ b/mysql-test/r/commit.result @@ -264,9 +264,313 @@ Should only read the '1000' as this transaction is now in REP READ COMMIT AND NO CHAIN; SET @@completion_type=0; COMMIT AND NO CHAIN; -SET @autocommit=1; +SET @@autocommit=1; COMMIT; DROP TABLE t1; # # End of test cases for Bug#20837 # +# +# WL#5968 Implement START TRANSACTION READ (WRITE|ONLY); +# +# +# Test 1: Check supported syntax +START TRANSACTION; +COMMIT; +START TRANSACTION READ ONLY; +COMMIT; +START TRANSACTION READ WRITE; +COMMIT; +START TRANSACTION READ ONLY, READ WRITE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 +START TRANSACTION READ ONLY, WITH CONSISTENT SNAPSHOT; +COMMIT; +START TRANSACTION READ WRITE, WITH CONSISTENT SNAPSHOT; +COMMIT; +START TRANSACTION WITH CONSISTENT SNAPSHOT, READ ONLY; +COMMIT; +START TRANSACTION WITH CONSISTENT SNAPSHOT, READ WRITE; +COMMIT; +START TRANSACTION READ ONLY, WITH CONSISTENT SNAPSHOT, READ WRITE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 +SET TRANSACTION READ ONLY; +SET TRANSACTION READ WRITE; +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ ONLY; +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ WRITE; +SET TRANSACTION READ ONLY, ISOLATION LEVEL READ COMMITTED; +SET TRANSACTION READ WRITE, ISOLATION LEVEL READ COMMITTED; +SET TRANSACTION READ ONLY, READ WRITE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'READ WRITE' at line 1 +COMMIT; +# +# Test 2: Check setting of variable. +SET SESSION TRANSACTION READ WRITE; +SELECT @@tx_read_only; +@@tx_read_only +0 +SET SESSION TRANSACTION READ ONLY; +SELECT @@tx_read_only; +@@tx_read_only +1 +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE; +SELECT @@tx_read_only; +@@tx_read_only +0 +SET SESSION TRANSACTION READ ONLY, ISOLATION LEVEL REPEATABLE READ; +SELECT @@tx_read_only; +@@tx_read_only +1 +START TRANSACTION; +# Not allowed inside a transaction +SET TRANSACTION READ ONLY; +ERROR 25001: Transaction characteristics can't be changed while a transaction is in progress +# But these are allowed. +SET SESSION TRANSACTION READ ONLY; +SET GLOBAL TRANSACTION READ ONLY; +COMMIT; +SET SESSION TRANSACTION READ WRITE; +SET GLOBAL TRANSACTION READ WRITE; +# +# Test 3: Test that write operations are properly blocked. +CREATE TABLE t1(a INT); +CREATE TEMPORARY TABLE temp_t2(a INT); +SET SESSION TRANSACTION READ ONLY; +# 1: DDL should be blocked, also on temporary tables. +CREATE TABLE t3(a INT); +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +ALTER TABLE t1 COMMENT "Test"; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +DROP TABLE t1; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +CREATE TEMPORARY TABLE temp_t3(a INT); +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +ALTER TABLE temp_t2 COMMENT "Test"; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +DROP TEMPORARY TABLE temp_t2; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +CREATE FUNCTION f1() RETURNS INT RETURN 1; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +DROP FUNCTION f1; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +CREATE PROCEDURE p1() BEGIN END; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +DROP PROCEDURE p1; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +CREATE VIEW v1 AS SELECT 1; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +SET SESSION TRANSACTION READ WRITE; +CREATE VIEW v1 AS SELECT 1; +SET SESSION TRANSACTION READ ONLY; +DROP VIEW v1; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +SET SESSION TRANSACTION READ WRITE; +DROP VIEW v1; +SET SESSION TRANSACTION READ ONLY; +RENAME TABLE t1 TO t2; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +RENAME TABLE temp_t2 TO temp_t3; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +TRUNCATE TABLE t1; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +CREATE DATABASE db1; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +DROP DATABASE db1; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +SET SESSION TRANSACTION READ WRITE; +# 2: DML should be blocked on non-temporary tables. +START TRANSACTION READ ONLY; +INSERT INTO t1 VALUES (1), (2); +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +UPDATE t1 SET a= 3; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +DELETE FROM t1; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +# 3: DML should be allowed on temporary tables. +INSERT INTO temp_t2 VALUES (1), (2); +UPDATE temp_t2 SET a= 3; +DELETE FROM temp_t2; +# 4: Queries should not be blocked. +SELECT * FROM t1; +a +SELECT * FROM temp_t2; +a +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +a +HANDLER t1 CLOSE; +HANDLER temp_t2 OPEN; +HANDLER temp_t2 READ FIRST; +a +HANDLER temp_t2 CLOSE; +# 5: Prepared statements +PREPARE stmt FROM "DELETE FROM t1"; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +PREPARE stmt FROM "DELETE FROM temp_t2"; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +COMMIT; +# 6: Stored routines +CREATE FUNCTION f1() RETURNS INT +BEGIN +DELETE FROM t1; +RETURN 1; +END| +CREATE FUNCTION f2() RETURNS INT +BEGIN +DELETE FROM temp_t2; +RETURN 1; +END| +CREATE PROCEDURE p1() DELETE FROM t1; +CREATE PROCEDURE p2() DELETE FROM temp_t2; +START TRANSACTION READ ONLY; +SELECT f1(); +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +SELECT f2(); +f2() +1 +CALL p1(); +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +CALL p2(); +COMMIT; +DROP FUNCTION f1; +DROP FUNCTION f2; +DROP PROCEDURE p1; +DROP PROCEDURE p2; +# 7: Views +CREATE VIEW v1 AS SELECT a FROM t1; +START TRANSACTION READ ONLY; +INSERT INTO v1 VALUES (1), (2); +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +SELECT * FROM v1; +a +COMMIT; +DROP VIEW v1; +# 8: LOCK TABLE +SET SESSION TRANSACTION READ ONLY; +LOCK TABLE t1 WRITE; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +LOCK TABLE t1 READ; +UNLOCK TABLES; +SET SESSION TRANSACTION READ WRITE; +DROP TABLE temp_t2, t1; +# +# Test 4: SET TRANSACTION, CHAINing transactions +CREATE TABLE t1(a INT); +SET SESSION TRANSACTION READ ONLY; +START TRANSACTION; +DELETE FROM t1; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +COMMIT; +START TRANSACTION READ WRITE; +DELETE FROM t1; +COMMIT; +SET SESSION TRANSACTION READ WRITE; +SET TRANSACTION READ ONLY; +START TRANSACTION; +DELETE FROM t1; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +COMMIT; +START TRANSACTION READ WRITE; +DELETE FROM t1; +COMMIT; +START TRANSACTION READ ONLY; +SELECT * FROM t1; +a +COMMIT AND CHAIN; +DELETE FROM t1; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +COMMIT; +START TRANSACTION READ ONLY; +SELECT * FROM t1; +a +ROLLBACK AND CHAIN; +DELETE FROM t1; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +COMMIT; +DROP TABLE t1; +# +# Test 5: Test that reserved keyword ONLY is still allowed as +# identifier - both directly and in SPs. +SET @only= 1; +CREATE TABLE t1 (only INT); +INSERT INTO t1 (only) values (1); +SELECT only FROM t1 WHERE only = 1; +only +1 +DROP TABLE t1; +CREATE PROCEDURE p1() +BEGIN +DECLARE only INT DEFAULT 1; +END| +CALL p1(); +DROP PROCEDURE p1; +# +# Test 6: Check that XA transactions obey default access mode. +CREATE TABLE t1(a INT); +SET TRANSACTION READ ONLY; +XA START 'test1'; +INSERT INTO t1 VALUES (1); +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +UPDATE t1 SET a=2; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +DELETE FROM t1; +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +XA END 'test1'; +XA PREPARE 'test1'; +XA COMMIT 'test1'; +DROP TABLE t1; +# +# Test 7: SET TRANSACTION inside stored routines +CREATE PROCEDURE p1() SET SESSION TRANSACTION READ ONLY; +CALL p1(); +SELECT @@tx_read_only; +@@tx_read_only +1 +SET SESSION TRANSACTION READ WRITE; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() SET SESSION TRANSACTION READ ONLY, +ISOLATION LEVEL SERIALIZABLE; +CALL p1(); +SELECT @@tx_read_only; +@@tx_read_only +1 +SET SESSION TRANSACTION READ WRITE, ISOLATION LEVEL REPEATABLE READ; +DROP PROCEDURE p1; +CREATE FUNCTION f1() RETURNS INT +BEGIN +SET SESSION TRANSACTION READ ONLY; +RETURN 1; +END| +SELECT f1(); +f1() +1 +SELECT @@tx_read_only; +@@tx_read_only +1 +SET SESSION TRANSACTION READ WRITE; +DROP FUNCTION f1; +CREATE FUNCTION f1() RETURNS INT +BEGIN +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ ONLY; +RETURN 1; +END| +SELECT f1(); +f1() +1 +SELECT @@tx_read_only; +@@tx_read_only +1 +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE; +DROP FUNCTION f1; +# +# Test 8: SET TRANSACTION and auto-commit +SELECT @@autocommit; +@@autocommit +1 +CREATE TABLE t1(a INT) engine=InnoDB; +SET TRANSACTION READ ONLY; +SELECT * FROM t1; +a +# This statement should work, since last statement committed. +INSERT INTO t1 VALUES (1); +DROP TABLE t1; diff --git a/mysql-test/r/read_only.result b/mysql-test/r/read_only.result index 1ffe2b86f70..3811c6c5487 100644 --- a/mysql-test/r/read_only.result +++ b/mysql-test/r/read_only.result @@ -157,3 +157,40 @@ delete from mysql.columns_priv where User like 'mysqltest_%'; flush privileges; drop database mysqltest_db1; set global read_only= @start_read_only; +# +# WL#5968 Implement START TRANSACTION READ (WRITE|ONLY); +# +# +# Test interaction with read_only system variable. +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1), (2); +CREATE USER user1; +SET GLOBAL read_only= 1; +# All allowed with super privilege +START TRANSACTION; +COMMIT; +START TRANSACTION READ ONLY; +COMMIT; +START TRANSACTION READ WRITE; +COMMIT; +# We allow implicit RW transaction without super privilege +# for compatibility reasons +START TRANSACTION; +# Check that table updates are still disallowed. +INSERT INTO t1 VALUES (3); +ERROR HY000: The MariaDB server is running with the --read-only option so it cannot execute this statement +UPDATE t1 SET a= 1; +ERROR HY000: The MariaDB server is running with the --read-only option so it cannot execute this statement +DELETE FROM t1; +ERROR HY000: The MariaDB server is running with the --read-only option so it cannot execute this statement +COMMIT; +START TRANSACTION READ ONLY; +COMMIT; +# Explicit RW trans is not allowed without super privilege +START TRANSACTION READ WRITE; +ERROR HY000: The MariaDB server is running with the --read-only option so it cannot execute this statement +COMMIT; +DROP USER user1; +SET GLOBAL read_only= 0; +DROP TABLE t1; diff --git a/mysql-test/r/trans_read_only.result b/mysql-test/r/trans_read_only.result new file mode 100644 index 00000000000..2b1055d4a7b --- /dev/null +++ b/mysql-test/r/trans_read_only.result @@ -0,0 +1,40 @@ +# +# WL#5968: Implement START TRANSACTION READ (WRITE|ONLY); +# +# +# Test9: The --transaction-read-only startup option. +# Check that the option was set by the .opt file. +SELECT @@tx_read_only; +@@tx_read_only +1 +# Also for new connections. Switching to con1 +SELECT @@tx_read_only; +@@tx_read_only +1 +SET SESSION TRANSACTION READ WRITE; +SELECT @@tx_read_only; +@@tx_read_only +0 +# Connection default +SELECT @@tx_read_only; +@@tx_read_only +1 +# +# Test 10: SET TRANSACTION / START TRANSACTION + implicit commit. +SET SESSION TRANSACTION READ WRITE; +SET TRANSACTION READ ONLY; +# Since DDL does implicit commit before starting, SET TRANSACTION +# will have no effect because the "next" transaction will already +# be over before the DDL statement starts. +CREATE TABLE t1 (a INT); +START TRANSACTION READ ONLY; +# The same happens with START TRANSACTION +DROP TABLE t1; +# +# Test 11: INSERT DELAYED +CREATE TABLE t1(a INT); +START TRANSACTION READ ONLY; +INSERT DELAYED INTO t1 VALUES (1); +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +COMMIT; +DROP TABLE t1; diff --git a/mysql-test/t/commit.test b/mysql-test/t/commit.test index 6ed784df3c2..c2051358073 100644 --- a/mysql-test/t/commit.test +++ b/mysql-test/t/commit.test @@ -338,7 +338,7 @@ COMMIT AND NO CHAIN; # # Cleanup # -SET @autocommit=1; +SET @@autocommit=1; COMMIT; disconnect con1; @@ -348,3 +348,360 @@ DROP TABLE t1; --echo # --echo # End of test cases for Bug#20837 --echo # + + +--echo # +--echo # WL#5968 Implement START TRANSACTION READ (WRITE|ONLY); +--echo # + +--echo # +--echo # Test 1: Check supported syntax + +START TRANSACTION; +COMMIT; + +START TRANSACTION READ ONLY; +COMMIT; + +START TRANSACTION READ WRITE; +COMMIT; + +--error ER_PARSE_ERROR +START TRANSACTION READ ONLY, READ WRITE; + +START TRANSACTION READ ONLY, WITH CONSISTENT SNAPSHOT; +COMMIT; + +START TRANSACTION READ WRITE, WITH CONSISTENT SNAPSHOT; +COMMIT; + +START TRANSACTION WITH CONSISTENT SNAPSHOT, READ ONLY; +COMMIT; + +START TRANSACTION WITH CONSISTENT SNAPSHOT, READ WRITE; +COMMIT; + +--error ER_PARSE_ERROR +START TRANSACTION READ ONLY, WITH CONSISTENT SNAPSHOT, READ WRITE; + +SET TRANSACTION READ ONLY; +SET TRANSACTION READ WRITE; +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ ONLY; +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ WRITE; +SET TRANSACTION READ ONLY, ISOLATION LEVEL READ COMMITTED; +SET TRANSACTION READ WRITE, ISOLATION LEVEL READ COMMITTED; +--error ER_PARSE_ERROR +SET TRANSACTION READ ONLY, READ WRITE; +COMMIT; + +--echo # +--echo # Test 2: Check setting of variable. + +SET SESSION TRANSACTION READ WRITE; +SELECT @@tx_read_only; + +SET SESSION TRANSACTION READ ONLY; +SELECT @@tx_read_only; + +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE; +SELECT @@tx_read_only; + +SET SESSION TRANSACTION READ ONLY, ISOLATION LEVEL REPEATABLE READ; +SELECT @@tx_read_only; + +START TRANSACTION; +--echo # Not allowed inside a transaction +--error ER_CANT_CHANGE_TX_CHARACTERISTICS +SET TRANSACTION READ ONLY; +--echo # But these are allowed. +SET SESSION TRANSACTION READ ONLY; +SET GLOBAL TRANSACTION READ ONLY; +COMMIT; + +# Reset to defaults +SET SESSION TRANSACTION READ WRITE; +SET GLOBAL TRANSACTION READ WRITE; + +--echo # +--echo # Test 3: Test that write operations are properly blocked. + +CREATE TABLE t1(a INT); +CREATE TEMPORARY TABLE temp_t2(a INT); + +SET SESSION TRANSACTION READ ONLY; + +--echo # 1: DDL should be blocked, also on temporary tables. +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +CREATE TABLE t3(a INT); +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +ALTER TABLE t1 COMMENT "Test"; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +DROP TABLE t1; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +CREATE TEMPORARY TABLE temp_t3(a INT); +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +ALTER TABLE temp_t2 COMMENT "Test"; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +DROP TEMPORARY TABLE temp_t2; + +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +CREATE FUNCTION f1() RETURNS INT RETURN 1; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +DROP FUNCTION f1; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +CREATE PROCEDURE p1() BEGIN END; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +DROP PROCEDURE p1; + +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +CREATE VIEW v1 AS SELECT 1; +SET SESSION TRANSACTION READ WRITE; +CREATE VIEW v1 AS SELECT 1; +SET SESSION TRANSACTION READ ONLY; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +DROP VIEW v1; +SET SESSION TRANSACTION READ WRITE; +DROP VIEW v1; +SET SESSION TRANSACTION READ ONLY; + +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +RENAME TABLE t1 TO t2; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +RENAME TABLE temp_t2 TO temp_t3; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +TRUNCATE TABLE t1; + +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +CREATE DATABASE db1; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +DROP DATABASE db1; +SET SESSION TRANSACTION READ WRITE; + +--echo # 2: DML should be blocked on non-temporary tables. +START TRANSACTION READ ONLY; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +INSERT INTO t1 VALUES (1), (2); +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +UPDATE t1 SET a= 3; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +DELETE FROM t1; + +--echo # 3: DML should be allowed on temporary tables. +INSERT INTO temp_t2 VALUES (1), (2); +UPDATE temp_t2 SET a= 3; +DELETE FROM temp_t2; + +--echo # 4: Queries should not be blocked. +SELECT * FROM t1; +SELECT * FROM temp_t2; + +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +HANDLER t1 CLOSE; + +HANDLER temp_t2 OPEN; +HANDLER temp_t2 READ FIRST; +HANDLER temp_t2 CLOSE; + +--echo # 5: Prepared statements +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +PREPARE stmt FROM "DELETE FROM t1"; + +PREPARE stmt FROM "DELETE FROM temp_t2"; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +COMMIT; + +--echo # 6: Stored routines + +delimiter |; +CREATE FUNCTION f1() RETURNS INT +BEGIN + DELETE FROM t1; + RETURN 1; +END| + +CREATE FUNCTION f2() RETURNS INT +BEGIN + DELETE FROM temp_t2; + RETURN 1; +END| +delimiter ;| + +CREATE PROCEDURE p1() DELETE FROM t1; +CREATE PROCEDURE p2() DELETE FROM temp_t2; + +START TRANSACTION READ ONLY; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +SELECT f1(); +SELECT f2(); +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +CALL p1(); +CALL p2(); +COMMIT; + +DROP FUNCTION f1; +DROP FUNCTION f2; +DROP PROCEDURE p1; +DROP PROCEDURE p2; + +--echo # 7: Views +CREATE VIEW v1 AS SELECT a FROM t1; +# Not supported for temporary tables. + +START TRANSACTION READ ONLY; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +INSERT INTO v1 VALUES (1), (2); +SELECT * FROM v1; +COMMIT; + +DROP VIEW v1; + +--echo # 8: LOCK TABLE +SET SESSION TRANSACTION READ ONLY; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +LOCK TABLE t1 WRITE; + +LOCK TABLE t1 READ; +UNLOCK TABLES; + +# Not supported for temporary tables. + +SET SESSION TRANSACTION READ WRITE; +DROP TABLE temp_t2, t1; + +--echo # +--echo # Test 4: SET TRANSACTION, CHAINing transactions + +CREATE TABLE t1(a INT); + +SET SESSION TRANSACTION READ ONLY; +START TRANSACTION; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +DELETE FROM t1; +COMMIT; +START TRANSACTION READ WRITE; +DELETE FROM t1; +COMMIT; + +SET SESSION TRANSACTION READ WRITE; +SET TRANSACTION READ ONLY; +START TRANSACTION; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +DELETE FROM t1; +COMMIT; +START TRANSACTION READ WRITE; +DELETE FROM t1; +COMMIT; + +START TRANSACTION READ ONLY; +SELECT * FROM t1; +COMMIT AND CHAIN; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +DELETE FROM t1; +COMMIT; + +START TRANSACTION READ ONLY; +SELECT * FROM t1; +ROLLBACK AND CHAIN; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +DELETE FROM t1; +COMMIT; + +DROP TABLE t1; + +--echo # +--echo # Test 5: Test that reserved keyword ONLY is still allowed as +--echo # identifier - both directly and in SPs. + +SET @only= 1; + +CREATE TABLE t1 (only INT); +INSERT INTO t1 (only) values (1); +SELECT only FROM t1 WHERE only = 1; +DROP TABLE t1; + +DELIMITER |; +CREATE PROCEDURE p1() +BEGIN + DECLARE only INT DEFAULT 1; +END| +DELIMITER ;| + +CALL p1(); + +DROP PROCEDURE p1; + +--echo # +--echo # Test 6: Check that XA transactions obey default access mode. + +CREATE TABLE t1(a INT); + +SET TRANSACTION READ ONLY; +XA START 'test1'; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +INSERT INTO t1 VALUES (1); +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +UPDATE t1 SET a=2; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +DELETE FROM t1; +XA END 'test1'; +XA PREPARE 'test1'; +XA COMMIT 'test1'; + +DROP TABLE t1; + +--echo # +--echo # Test 7: SET TRANSACTION inside stored routines + +CREATE PROCEDURE p1() SET SESSION TRANSACTION READ ONLY; +CALL p1(); +SELECT @@tx_read_only; +SET SESSION TRANSACTION READ WRITE; +DROP PROCEDURE p1; + +CREATE PROCEDURE p1() SET SESSION TRANSACTION READ ONLY, + ISOLATION LEVEL SERIALIZABLE; +CALL p1(); +SELECT @@tx_read_only; +SET SESSION TRANSACTION READ WRITE, ISOLATION LEVEL REPEATABLE READ; +DROP PROCEDURE p1; + +delimiter |; +CREATE FUNCTION f1() RETURNS INT +BEGIN + SET SESSION TRANSACTION READ ONLY; + RETURN 1; +END| +delimiter ;| + +SELECT f1(); +SELECT @@tx_read_only; +SET SESSION TRANSACTION READ WRITE; +DROP FUNCTION f1; + +delimiter |; +CREATE FUNCTION f1() RETURNS INT +BEGIN + SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ ONLY; + RETURN 1; +END| +delimiter ;| + +SELECT f1(); +SELECT @@tx_read_only; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE; +DROP FUNCTION f1; + +--echo # +--echo # Test 8: SET TRANSACTION and auto-commit + +SELECT @@autocommit; +CREATE TABLE t1(a INT) engine=InnoDB; + +SET TRANSACTION READ ONLY; +SELECT * FROM t1; +--echo # This statement should work, since last statement committed. +INSERT INTO t1 VALUES (1); + +DROP TABLE t1; diff --git a/mysql-test/t/read_only.test b/mysql-test/t/read_only.test index 52349747883..8ea0f2db9b7 100644 --- a/mysql-test/t/read_only.test +++ b/mysql-test/t/read_only.test @@ -299,6 +299,65 @@ flush privileges; drop database mysqltest_db1; set global read_only= @start_read_only; + +--echo # +--echo # WL#5968 Implement START TRANSACTION READ (WRITE|ONLY); +--echo # + +--echo # +--echo # Test interaction with read_only system variable. + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1), (2); + +CREATE USER user1; +connect (con1, localhost, user1); +connection default; + +SET GLOBAL read_only= 1; + +--echo # All allowed with super privilege +START TRANSACTION; +COMMIT; + +START TRANSACTION READ ONLY; +COMMIT; + +START TRANSACTION READ WRITE; +COMMIT; + +--echo # We allow implicit RW transaction without super privilege +--echo # for compatibility reasons +connection con1; +START TRANSACTION; +--echo # Check that table updates are still disallowed. +--error ER_OPTION_PREVENTS_STATEMENT +INSERT INTO t1 VALUES (3); +--error ER_OPTION_PREVENTS_STATEMENT +UPDATE t1 SET a= 1; +--error ER_OPTION_PREVENTS_STATEMENT +DELETE FROM t1; +COMMIT; + +START TRANSACTION READ ONLY; +COMMIT; + +--echo # Explicit RW trans is not allowed without super privilege +--error ER_OPTION_PREVENTS_STATEMENT +START TRANSACTION READ WRITE; +COMMIT; +disconnect con1; +--source include/wait_until_disconnected.inc +connection default; +DROP USER user1; + +SET GLOBAL read_only= 0; +DROP TABLE t1; + # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc diff --git a/mysql-test/t/trans_read_only-master.opt b/mysql-test/t/trans_read_only-master.opt new file mode 100644 index 00000000000..cf84816ec90 --- /dev/null +++ b/mysql-test/t/trans_read_only-master.opt @@ -0,0 +1 @@ +--transaction-read-only=true diff --git a/mysql-test/t/trans_read_only.test b/mysql-test/t/trans_read_only.test new file mode 100644 index 00000000000..f50fb7db376 --- /dev/null +++ b/mysql-test/t/trans_read_only.test @@ -0,0 +1,50 @@ +--source include/not_embedded.inc + +--echo # +--echo # WL#5968: Implement START TRANSACTION READ (WRITE|ONLY); +--echo # + +--echo # +--echo # Test9: The --transaction-read-only startup option. + +--echo # Check that the option was set by the .opt file. +SELECT @@tx_read_only; + +--echo # Also for new connections. Switching to con1 +connect (con1, localhost, root); +SELECT @@tx_read_only; +SET SESSION TRANSACTION READ WRITE; +SELECT @@tx_read_only; +disconnect con1; +--source include/wait_until_disconnected.inc + +--echo # Connection default +connection default; +SELECT @@tx_read_only; + + +--echo # +--echo # Test 10: SET TRANSACTION / START TRANSACTION + implicit commit. + +SET SESSION TRANSACTION READ WRITE; +--disable_ps_protocol +SET TRANSACTION READ ONLY; +--echo # Since DDL does implicit commit before starting, SET TRANSACTION +--echo # will have no effect because the "next" transaction will already +--echo # be over before the DDL statement starts. +CREATE TABLE t1 (a INT); + +START TRANSACTION READ ONLY; +--echo # The same happens with START TRANSACTION +DROP TABLE t1; +--enable_ps_protocol + +--echo # +--echo # Test 11: INSERT DELAYED + +CREATE TABLE t1(a INT); +START TRANSACTION READ ONLY; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +INSERT DELAYED INTO t1 VALUES (1); +COMMIT; +DROP TABLE t1; diff --git a/sql/lex.h b/sql/lex.h index 9bd1a9b93aa..6587f5b8a9c 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -402,6 +402,7 @@ static SYMBOL symbols[] = { { "ONE", SYM(ONE_SYM)}, { "ONE_SHOT", SYM(ONE_SHOT_SYM)}, { "ONLINE", SYM(ONLINE_SYM)}, + { "ONLY", SYM(ONLY_SYM)}, { "OPEN", SYM(OPEN_SYM)}, { "OPTIMIZE", SYM(OPTIMIZE)}, { "OPTIONS", SYM(OPTIONS_SYM)}, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index fadcd64b98e..07de4b0d761 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4722,7 +4722,7 @@ lock_table_names(THD *thd, if (thd->tx_read_only) { my_error(ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION, MYF(0)); - return true; + DBUG_RETURN(true); } if (! (flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK) && diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 48ae2f066db..887bace6c42 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4005,6 +4005,7 @@ end_with_restore_list: { /* Reset the isolation level if no chaining transaction. */ thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation; + thd->tx_read_only= thd->variables.tx_read_only; } /* Disconnect the current client connection. */ if (tx_release) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e2263e21e8f..7b7f766bbd1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -730,6 +730,116 @@ static bool add_create_index (LEX *lex, Key::Keytype type, return FALSE; } + +/** + Create a separate LEX for each assignment if in SP. + + If we are in SP we want have own LEX for each assignment. + This is mostly because it is hard for several sp_instr_set + and sp_instr_set_trigger instructions share one LEX. + (Well, it is theoretically possible but adds some extra + overhead on preparation for execution stage and IMO less + robust). + + QQ: May be we should simply prohibit group assignments in SP? + + @see sp_create_assignment_instr + + @param thd Thread context + @param no_lookahead True if the parser has no lookahead +*/ + +static void sp_create_assignment_lex(THD *thd, bool no_lookahead) +{ + LEX *lex= thd->lex; + + if (lex->sphead) + { + Lex_input_stream *lip= &thd->m_parser_state->m_lip; + LEX *old_lex= lex; + lex->sphead->reset_lex(thd); + lex= thd->lex; + + /* Set new LEX as if we at start of set rule. */ + lex->sql_command= SQLCOM_SET_OPTION; + mysql_init_select(lex); + lex->var_list.empty(); + lex->one_shot_set= 0; + lex->autocommit= 0; + /* get_ptr() is only correct with no lookahead. */ + DBUG_ASSERT(no_lookahead); + lex->sphead->m_tmp_query= lip->get_ptr(); + /* Inherit from outer lex. */ + lex->option_type= old_lex->option_type; + } +} + + +/** + Create a SP instruction for a SET assignment. + + @see sp_create_assignment_lex + + @param thd Thread context + @param no_lookahead True if the parser has no lookahead + + @return false if success, true otherwise. +*/ + +static bool sp_create_assignment_instr(THD *thd, bool no_lookahead) +{ + LEX *lex= thd->lex; + + if (lex->sphead) + { + sp_head *sp= lex->sphead; + + if (!lex->var_list.is_empty()) + { + /* + We have assignment to user or system variable or + option setting, so we should construct sp_instr_stmt + for it. + */ + LEX_STRING qbuff; + sp_instr_stmt *i; + Lex_input_stream *lip= &thd->m_parser_state->m_lip; + + if (!(i= new sp_instr_stmt(sp->instructions(), lex->spcont, + lex))) + return true; + + /* + Extract the query statement from the tokenizer. The + end is either lip->ptr, if there was no lookahead, + lip->tok_end otherwise. + */ + if (no_lookahead) + qbuff.length= lip->get_ptr() - sp->m_tmp_query; + else + qbuff.length= lip->get_tok_end() - sp->m_tmp_query; + + if (!(qbuff.str= (char*) alloc_root(thd->mem_root, + qbuff.length + 5))) + return true; + + strmake(strmake(qbuff.str, "SET ", 4), sp->m_tmp_query, + qbuff.length); + qbuff.length+= 4; + i->m_query= qbuff; + if (sp->add_instr(i)) + return true; + } + enum_var_type inner_option_type= lex->option_type; + if (lex->sphead->restore_lex(thd)) + return true; + /* Copy option_type to outer lex in case it has changed. */ + thd->lex->option_type= inner_option_type; + } + return false; +} + + %} %union { int num; @@ -788,10 +898,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %pure_parser /* We have threads */ /* - Currently there are 174 shift/reduce conflicts. + Currently there are 171 shift/reduce conflicts. We should not introduce new conflicts any more. */ -%expect 174 +%expect 171 /* Comments for TOKENS. @@ -1172,6 +1282,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token ON /* SQL-2003-R */ %token ONE_SHOT_SYM %token ONE_SYM +%token ONLY_SYM /* SQL-2003-R */ %token ONLINE_SYM %token OPEN_SYM /* SQL-2003-R */ %token OPTIMIZE @@ -1475,14 +1586,21 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); table_option opt_if_not_exists opt_no_write_to_binlog opt_temporary all_or_any opt_distinct opt_ignore_leaves fulltext_options spatial_type union_option - start_transaction_opts field_def - union_opt select_derived_init option_type2 + field_def + union_opt select_derived_init transaction_access_mode_types opt_natural_language_mode opt_query_expansion opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt optional_flush_tables_arguments opt_dyncol_type dyncol_type opt_time_precision kill_type kill_option int_num +/* + Bit field of MYSQL_START_TRANS_OPT_* flags. +*/ +%type <num> opt_start_transaction_option_list +%type <num> start_transaction_option_list +%type <num> start_transaction_option + %type <m_yes_no_unk> opt_chain opt_release @@ -1610,7 +1728,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ref_list opt_match_clause opt_on_update_delete use opt_delete_options opt_delete_option varchar nchar nvarchar opt_outer table_list table_name table_alias_ref_list table_alias_ref - opt_option opt_place + opt_place opt_attribute opt_attribute_list attribute column_list column_list_id opt_column_list grant_privileges grant_ident grant_list grant_option object_privilege object_privilege_list user_list rename_list @@ -7100,20 +7218,56 @@ slave: ; start: - START_SYM TRANSACTION_SYM start_transaction_opts + START_SYM TRANSACTION_SYM opt_start_transaction_option_list { LEX *lex= Lex; lex->sql_command= SQLCOM_BEGIN; + /* READ ONLY and READ WRITE are mutually exclusive. */ + if (($3 & MYSQL_START_TRANS_OPT_READ_WRITE) && + ($3 & MYSQL_START_TRANS_OPT_READ_ONLY)) + { + my_parse_error(ER(ER_SYNTAX_ERROR)); + MYSQL_YYABORT; + } lex->start_transaction_opt= $3; } ; -start_transaction_opts: - /*empty*/ { $$ = 0; } - | WITH CONSISTENT_SYM SNAPSHOT_SYM +opt_start_transaction_option_list: + /* empty */ + { + $$= 0; + } + | start_transaction_option_list + { + $$= $1; + } + ; + +start_transaction_option_list: + start_transaction_option + { + $$= $1; + } + | start_transaction_option_list ',' start_transaction_option + { + $$= $1 | $3; + } + ; + +start_transaction_option: + WITH CONSISTENT_SYM SNAPSHOT_SYM { $$= MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT; } + | READ_SYM ONLY_SYM + { + $$= MYSQL_START_TRANS_OPT_READ_ONLY; + } + | READ_SYM WRITE_SYM + { + $$= MYSQL_START_TRANS_OPT_READ_WRITE; + } ; slave_thread_opts: @@ -13148,6 +13302,7 @@ keyword_sp: | ONE_SHOT_SYM {} | ONE_SYM {} | ONLINE_SYM {} + | ONLY_SYM {} | PACK_KEYS_SYM {} | PAGE_SYM {} | PARTIAL {} @@ -13271,8 +13426,15 @@ keyword_sp: /* Option functions */ +/* + SQLCOM_SET_OPTION statement. + + Note that to avoid shift/reduce conflicts, we have separate rules for the + first option listed in the statement. +*/ + set: - SET opt_option + SET { LEX *lex=Lex; lex->sql_command= SQLCOM_SET_OPTION; @@ -13281,115 +13443,96 @@ set: lex->var_list.empty(); lex->one_shot_set= 0; lex->autocommit= 0; + sp_create_assignment_lex(YYTHD, yychar == YYEMPTY); } - option_value_list + start_option_value_list {} ; -opt_option: - /* empty */ {} - | OPTION {} - ; -option_value_list: - option_type_value - | option_value_list ',' option_type_value - ; - -option_type_value: +// Start of option value list +start_option_value_list: + option_value_no_option_type { - THD *thd= YYTHD; - LEX *lex= thd->lex; - Lex_input_stream *lip= YYLIP; - - if (lex->sphead) - { - /* - If we are in SP we want have own LEX for each assignment. - This is mostly because it is hard for several sp_instr_set - and sp_instr_set_trigger instructions share one LEX. - (Well, it is theoretically possible but adds some extra - overhead on preparation for execution stage and IMO less - robust). - - QQ: May be we should simply prohibit group assignments in SP? - */ - lex->sphead->reset_lex(thd); - lex= thd->lex; - - /* Set new LEX as if we at start of set rule. */ - lex->sql_command= SQLCOM_SET_OPTION; - mysql_init_select(lex); - lex->option_type=OPT_SESSION; - lex->var_list.empty(); - lex->one_shot_set= 0; - lex->autocommit= 0; - lex->sphead->m_tmp_query= lip->get_tok_start(); - } + if (sp_create_assignment_instr(YYTHD, yychar == YYEMPTY)) + MYSQL_YYABORT; } - ext_option_value + option_value_list_continued + | TRANSACTION_SYM { - THD *thd= YYTHD; - LEX *lex= thd->lex; - Lex_input_stream *lip= YYLIP; - - if (lex->sphead) - { - sp_head *sp= lex->sphead; + Lex->option_type= OPT_DEFAULT; + } + transaction_characteristics + { + if (sp_create_assignment_instr(YYTHD, yychar == YYEMPTY)) + MYSQL_YYABORT; + } + | option_type + { + Lex->option_type= $1; + } + start_option_value_list_following_option_type + ; - if (!lex->var_list.is_empty()) - { - /* - We have assignment to user or system variable or - option setting, so we should construct sp_instr_stmt - for it. - */ - LEX_STRING qbuff; - sp_instr_stmt *i; - if (!(i= new sp_instr_stmt(sp->instructions(), lex->spcont, - lex))) - MYSQL_YYABORT; +// Start of option value list, option_type was given +start_option_value_list_following_option_type: + option_value_following_option_type + { + if (sp_create_assignment_instr(YYTHD, yychar == YYEMPTY)) + MYSQL_YYABORT; + } + option_value_list_continued + | TRANSACTION_SYM transaction_characteristics + { + if (sp_create_assignment_instr(YYTHD, yychar == YYEMPTY)) + MYSQL_YYABORT; + } + ; - /* - Extract the query statement from the tokenizer. The - end is either lip->ptr, if there was no lookahead, - lip->tok_end otherwise. - */ - if (yychar == YYEMPTY) - qbuff.length= lip->get_ptr() - sp->m_tmp_query; - else - qbuff.length= lip->get_tok_end() - sp->m_tmp_query; +// Remainder of the option value list after first option value. +option_value_list_continued: + /* empty */ + | ',' option_value_list + ; - if (!(qbuff.str= (char*) alloc_root(thd->mem_root, - qbuff.length + 5))) - MYSQL_YYABORT; +// Repeating list of option values after first option value. +option_value_list: + { + sp_create_assignment_lex(YYTHD, yychar == YYEMPTY); + } + option_value + { + if (sp_create_assignment_instr(YYTHD, yychar == YYEMPTY)) + MYSQL_YYABORT; + } + | option_value_list ',' + { + sp_create_assignment_lex(YYTHD, yychar == YYEMPTY); + } + option_value + { + if (sp_create_assignment_instr(YYTHD, yychar == YYEMPTY)) + MYSQL_YYABORT; + } + ; - strmake(strmake(qbuff.str, "SET ", 4), sp->m_tmp_query, - qbuff.length); - qbuff.length+= 4; - i->m_query= qbuff; - if (sp->add_instr(i)) - MYSQL_YYABORT; - } - if (lex->sphead->restore_lex(thd)) - MYSQL_YYABORT; - } +// Wrapper around option values following the first option value in the stmt. +option_value: + option_type + { + Lex->option_type= $1; } + option_value_following_option_type + | option_value_no_option_type ; option_type: - option_type2 {} - | GLOBAL_SYM { $$=OPT_GLOBAL; } + GLOBAL_SYM { $$=OPT_GLOBAL; } | LOCAL_SYM { $$=OPT_SESSION; } | SESSION_SYM { $$=OPT_SESSION; } ; -option_type2: - /* empty */ { $$= OPT_DEFAULT; } - | ONE_SHOT_SYM { Lex->one_shot_set= 1; $$= OPT_SESSION; } - ; - opt_var_type: /* empty */ { $$=OPT_SESSION; } | GLOBAL_SYM { $$=OPT_GLOBAL; } @@ -13404,74 +13547,62 @@ opt_var_ident_type: | SESSION_SYM '.' { $$=OPT_SESSION; } ; -ext_option_value: - sys_option_value - | option_type2 option_value +// Option values with preceeding option_type. +option_value_following_option_type: + internal_variable_name equal set_expr_or_default + { + THD *thd= YYTHD; + LEX *lex= Lex; + + if ($1.var && $1.var != trg_new_row_fake_var) + { + /* It is a system variable. */ + if (set_system_variable(thd, &$1, lex->option_type, $3)) + MYSQL_YYABORT; + } + else + { + /* + Not in trigger assigning value to new row, + and option_type preceeding local variable is illegal. + */ + my_parse_error(ER(ER_SYNTAX_ERROR)); + MYSQL_YYABORT; + } + } ; -sys_option_value: - option_type internal_variable_name equal set_expr_or_default +// Option values without preceeding option_type. +option_value_no_option_type: + internal_variable_name equal set_expr_or_default { THD *thd= YYTHD; LEX *lex= Lex; - LEX_STRING *name= &$2.base_name; + LEX_STRING *name= &$1.base_name; - if ($2.var == trg_new_row_fake_var) + if ($1.var == trg_new_row_fake_var) { /* We are in trigger and assigning value to field of new row */ - if ($1) - { - my_parse_error(ER(ER_SYNTAX_ERROR)); - MYSQL_YYABORT; - } - if (set_trigger_new_row(YYTHD, name, $4)) + if (set_trigger_new_row(YYTHD, name, $3)) MYSQL_YYABORT; } - else if ($2.var) + else if ($1.var) { - if ($1) - lex->option_type= $1; - /* It is a system variable. */ - if (set_system_variable(thd, &$2, lex->option_type, $4)) + if (set_system_variable(thd, &$1, lex->option_type, $3)) MYSQL_YYABORT; } else { sp_pcontext *spc= lex->spcont; - sp_variable_t *spv= spc->find_variable(name); - - if ($1) - { - my_parse_error(ER(ER_SYNTAX_ERROR)); - MYSQL_YYABORT; - } + sp_variable *spv= spc->find_variable(name, false); /* It is a local variable. */ - if (set_local_variable(thd, spv, $4)) + if (set_local_variable(thd, spv, $3)) MYSQL_YYABORT; } } - | option_type TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types - { - THD *thd= YYTHD; - LEX *lex=Lex; - lex->option_type= $1; - Item *item= new (thd->mem_root) Item_int((int32) $5); - if (item == NULL) - MYSQL_YYABORT; - set_var *var= new set_var(lex->option_type, - find_sys_var(thd, "tx_isolation"), - &null_lex_str, - item); - if (var == NULL) - MYSQL_YYABORT; - lex->var_list.push_back(var); - } - ; - -option_value: - '@' ident_or_text equal expr + | '@' ident_or_text equal expr { Item_func_set_user_var *item; item= new (YYTHD->mem_root) Item_func_set_user_var($2, $4); @@ -13517,7 +13648,7 @@ option_value: names.str= (char *)"names"; names.length= 5; - if (spc && spc->find_variable(&names)) + if (spc && spc->find_variable(&names, false)) my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), names.str); else my_parse_error(ER(ER_SYNTAX_ERROR)); @@ -13553,7 +13684,7 @@ option_value: pw.str= (char *)"password"; pw.length= 8; - if (spc && spc->find_variable(&pw)) + if (spc && spc->find_variable(&pw, false)) { my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), pw.str); MYSQL_YYABORT; @@ -13562,6 +13693,7 @@ option_value: MYSQL_YYABORT; user->host=null_lex_str; user->user.str=thd->security_ctx->user; + user->user.length= strlen(thd->security_ctx->user); set_var_password *var= new set_var_password(user, $3); if (var == NULL) MYSQL_YYABORT; @@ -13666,6 +13798,54 @@ internal_variable_name: } ; +transaction_characteristics: + transaction_access_mode + | isolation_level + | transaction_access_mode ',' isolation_level + | isolation_level ',' transaction_access_mode + ; + +transaction_access_mode: + transaction_access_mode_types + { + THD *thd= YYTHD; + LEX *lex=Lex; + Item *item= new (thd->mem_root) Item_int((int32) $1); + if (item == NULL) + MYSQL_YYABORT; + set_var *var= new set_var(lex->option_type, + find_sys_var(thd, "tx_read_only"), + &null_lex_str, + item); + if (var == NULL) + MYSQL_YYABORT; + lex->var_list.push_back(var); + } + ; + +isolation_level: + ISOLATION LEVEL_SYM isolation_types + { + THD *thd= YYTHD; + LEX *lex=Lex; + Item *item= new (thd->mem_root) Item_int((int32) $3); + if (item == NULL) + MYSQL_YYABORT; + set_var *var= new set_var(lex->option_type, + find_sys_var(thd, "tx_isolation"), + &null_lex_str, + item); + if (var == NULL) + MYSQL_YYABORT; + lex->var_list.push_back(var); + } + ; + +transaction_access_mode_types: + READ_SYM ONLY_SYM { $$= true; } + | READ_SYM WRITE_SYM { $$= false; } + ; + isolation_types: READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; } | READ_SYM COMMITTED_SYM { $$= ISO_READ_COMMITTED; } diff --git a/storage/perfschema/gen_pfs_lex_token b/storage/perfschema/gen_pfs_lex_token Binary files differindex 504a29a75f2..d86469d846c 100755 --- a/storage/perfschema/gen_pfs_lex_token +++ b/storage/perfschema/gen_pfs_lex_token diff --git a/storage/perfschema/pfs_lex_token.h b/storage/perfschema/pfs_lex_token.h index 43e8f647f9a..c6981a7df6c 100644 --- a/storage/perfschema/pfs_lex_token.h +++ b/storage/perfschema/pfs_lex_token.h @@ -636,273 +636,274 @@ lex_token_string lex_token_array[]= /* 617 */ { "ON", 2}, /* 618 */ { "ONE_SHOT", 8}, /* 619 */ { "ONE", 3}, -/* 620 */ { "ONLINE", 6}, -/* 621 */ { "OPEN", 4}, -/* 622 */ { "OPTIMIZE", 8}, -/* 623 */ { "OPTIONS", 7}, -/* 624 */ { "OPTION", 6}, -/* 625 */ { "OPTIONALLY", 10}, -/* 626 */ { "|", 1}, -/* 627 */ { "ORDER", 5}, -/* 628 */ { "||", 2}, -/* 629 */ { "OR", 2}, -/* 630 */ { "OUTER", 5}, -/* 631 */ { "OUTFILE", 7}, -/* 632 */ { "OUT", 3}, -/* 633 */ { "OWNER", 5}, -/* 634 */ { "PACK_KEYS", 9}, -/* 635 */ { "PAGE", 4}, -/* 636 */ { "PAGE_CHECKSUM", 13}, -/* 637 */ { "?", 1}, -/* 638 */ { "PARSER", 6}, -/* 639 */ { "PARSE_VCOL_EXPR", 15}, -/* 640 */ { "PARTIAL", 7}, -/* 641 */ { "PARTITIONING", 12}, -/* 642 */ { "PARTITIONS", 10}, -/* 643 */ { "PARTITION", 9}, -/* 644 */ { "PASSWORD", 8}, -/* 645 */ { "PERSISTENT", 10}, -/* 646 */ { "PHASE", 5}, -/* 647 */ { "PLUGINS", 7}, -/* 648 */ { "PLUGIN", 6}, -/* 649 */ { "POINT", 5}, -/* 650 */ { "POLYGON", 7}, -/* 651 */ { "PORT", 4}, -/* 652 */ { "POSITION", 8}, -/* 653 */ { "PRECISION", 9}, -/* 654 */ { "PREPARE", 7}, -/* 655 */ { "PRESERVE", 8}, -/* 656 */ { "PREV", 4}, -/* 657 */ { "PRIMARY", 7}, -/* 658 */ { "PRIVILEGES", 10}, -/* 659 */ { "PROCEDURE", 9}, -/* 660 */ { "PROCESS", 7}, -/* 661 */ { "PROCESSLIST", 11}, -/* 662 */ { "PROFILE", 7}, -/* 663 */ { "PROFILES", 8}, -/* 664 */ { "PROXY", 5}, -/* 665 */ { "PURGE", 5}, -/* 666 */ { "SQL_TSI_QUARTER", 15}, -/* 667 */ { "QUERY", 5}, -/* 668 */ { "QUICK", 5}, -/* 669 */ { "RANGE", 5}, -/* 670 */ { "READS", 5}, -/* 671 */ { "READ_ONLY", 9}, -/* 672 */ { "READ", 4}, -/* 673 */ { "READ_WRITE", 10}, -/* 674 */ { "REAL", 4}, -/* 675 */ { "REBUILD", 7}, -/* 676 */ { "RECOVER", 7}, -/* 677 */ { "REDOFILE", 8}, -/* 678 */ { "REDO_BUFFER_SIZE", 16}, -/* 679 */ { "REDUNDANT", 9}, -/* 680 */ { "REFERENCES", 10}, -/* 681 */ { "RLIKE", 5}, -/* 682 */ { "RELAY", 5}, -/* 683 */ { "RELAYLOG", 8}, -/* 684 */ { "RELAY_LOG_FILE", 14}, -/* 685 */ { "RELAY_LOG_POS", 13}, -/* 686 */ { "RELAY_THREAD", 12}, -/* 687 */ { "RELEASE", 7}, -/* 688 */ { "RELOAD", 6}, -/* 689 */ { "REMOVE", 6}, -/* 690 */ { "RENAME", 6}, -/* 691 */ { "REORGANIZE", 10}, -/* 692 */ { "REPAIR", 6}, -/* 693 */ { "REPEATABLE", 10}, -/* 694 */ { "REPEAT", 6}, -/* 695 */ { "REPLACE", 7}, -/* 696 */ { "REPLICATION", 11}, -/* 697 */ { "REQUIRE", 7}, -/* 698 */ { "RESET", 5}, -/* 699 */ { "RESIGNAL", 8}, -/* 700 */ { "USER_RESOURCES", 14}, -/* 701 */ { "RESTORE", 7}, -/* 702 */ { "RESTRICT", 8}, -/* 703 */ { "RESUME", 6}, -/* 704 */ { "RETURNS", 7}, -/* 705 */ { "RETURN", 6}, -/* 706 */ { "REVOKE", 6}, -/* 707 */ { "RIGHT", 5}, -/* 708 */ { "ROLLBACK", 8}, -/* 709 */ { "ROLLUP", 6}, -/* 710 */ { "ROUTINE", 7}, -/* 711 */ { "ROWS", 4}, -/* 712 */ { "ROW_FORMAT", 10}, -/* 713 */ { "ROW", 3}, -/* 714 */ { "RTREE", 5}, -/* 715 */ { "SAVEPOINT", 9}, -/* 716 */ { "SCHEDULE", 8}, -/* 717 */ { "SCHEMA_NAME", 11}, -/* 718 */ { "SECOND_MICROSECOND", 18}, -/* 719 */ { "SQL_TSI_SECOND", 14}, -/* 720 */ { "SECURITY", 8}, -/* 721 */ { "SELECT", 6}, -/* 722 */ { "SENSITIVE", 9}, -/* 723 */ { "SEPARATOR", 9}, -/* 724 */ { "SERIALIZABLE", 12}, -/* 725 */ { "SERIAL", 6}, -/* 726 */ { "SESSION", 7}, -/* 727 */ { "SERVER", 6}, -/* 728 */ { "SERVER_OPTIONS", 14}, -/* 729 */ { "SET", 3}, -/* 730 */ { ":=", 2}, -/* 731 */ { "SHARE", 5}, -/* 732 */ { "<<", 2}, -/* 733 */ { ">>", 2}, -/* 734 */ { "SHOW", 4}, -/* 735 */ { "SHUTDOWN", 8}, -/* 736 */ { "SIGNAL", 6}, -/* 737 */ { "SIGNED", 6}, -/* 738 */ { "SIMPLE", 6}, -/* 739 */ { "SLAVE", 5}, -/* 740 */ { "SLOW", 4}, -/* 741 */ { "SMALLINT", 8}, -/* 742 */ { "SNAPSHOT", 8}, -/* 743 */ { "SOCKET", 6}, -/* 744 */ { "SOFT", 4}, -/* 745 */ { "SONAME", 6}, -/* 746 */ { "SOUNDS", 6}, -/* 747 */ { "SOURCE", 6}, -/* 748 */ { "SPATIAL", 7}, -/* 749 */ { "SPECIFIC", 8}, -/* 750 */ { "SQLEXCEPTION", 12}, -/* 751 */ { "SQLSTATE", 8}, -/* 752 */ { "SQLWARNING", 10}, -/* 753 */ { "SQL_BIG_RESULT", 14}, -/* 754 */ { "SQL_BUFFER_RESULT", 17}, -/* 755 */ { "SQL_CACHE", 9}, -/* 756 */ { "SQL_CALC_FOUND_ROWS", 19}, -/* 757 */ { "SQL_NO_CACHE", 12}, -/* 758 */ { "SQL_SMALL_RESULT", 16}, -/* 759 */ { "SQL", 3}, -/* 760 */ { "SQL_THREAD", 10}, -/* 761 */ { "SSL", 3}, -/* 762 */ { "STARTING", 8}, -/* 763 */ { "STARTS", 6}, -/* 764 */ { "START", 5}, -/* 765 */ { "STATUS", 6}, -/* 766 */ { "STDDEV_SAMP", 11}, -/* 767 */ { "STDDEV_POP", 10}, -/* 768 */ { "STOP", 4}, -/* 769 */ { "STORAGE", 7}, -/* 770 */ { "STRAIGHT_JOIN", 13}, -/* 771 */ { "STRING", 6}, -/* 772 */ { "SUBCLASS_ORIGIN", 15}, -/* 773 */ { "SUBDATE", 7}, -/* 774 */ { "SUBJECT", 7}, -/* 775 */ { "SUBPARTITIONS", 13}, -/* 776 */ { "SUBPARTITION", 12}, -/* 777 */ { "SUBSTRING", 9}, -/* 778 */ { "SUM", 3}, -/* 779 */ { "SUPER", 5}, -/* 780 */ { "SUSPEND", 7}, -/* 781 */ { "SWAPS", 5}, -/* 782 */ { "SWITCHES", 8}, -/* 783 */ { "SYSDATE", 7}, -/* 784 */ { "TABLES", 6}, -/* 785 */ { "TABLESPACE", 10}, -/* 786 */ { "TABLE_REF_PRIORITY", 18}, -/* 787 */ { "TABLE_STATISTICS", 16}, -/* 788 */ { "TABLE", 5}, -/* 789 */ { "TABLE_CHECKSUM", 14}, -/* 790 */ { "TABLE_NAME", 10}, -/* 791 */ { "TEMPORARY", 9}, -/* 792 */ { "TEMPTABLE", 9}, -/* 793 */ { "TERMINATED", 10}, -/* 794 */ { "(text)", 6}, -/* 795 */ { "TEXT", 4}, -/* 796 */ { "THAN", 4}, -/* 797 */ { "THEN", 4}, -/* 798 */ { "TIMESTAMP", 9}, -/* 799 */ { "TIMESTAMPADD", 12}, -/* 800 */ { "TIMESTAMPDIFF", 13}, -/* 801 */ { "TIME", 4}, -/* 802 */ { "TINYBLOB", 8}, -/* 803 */ { "TINYINT", 7}, -/* 804 */ { "TINYTEXT", 8}, -/* 805 */ { "TO", 2}, -/* 806 */ { "TRAILING", 8}, -/* 807 */ { "TRANSACTION", 11}, -/* 808 */ { "TRANSACTIONAL", 13}, -/* 809 */ { "TRIGGERS", 8}, -/* 810 */ { "TRIGGER", 7}, -/* 811 */ { "TRIM", 4}, -/* 812 */ { "TRUE", 4}, -/* 813 */ { "TRUNCATE", 8}, -/* 814 */ { "TYPES", 5}, -/* 815 */ { "TYPE", 4}, -/* 816 */ { "UDF_RETURNS", 11}, -/* 817 */ { "(ulonglong)", 11}, -/* 818 */ { "UNCOMMITTED", 11}, -/* 819 */ { "UNDEFINED", 9}, -/* 820 */ { "(_charset)", 10}, -/* 821 */ { "UNDOFILE", 8}, -/* 822 */ { "UNDO_BUFFER_SIZE", 16}, -/* 823 */ { "UNDO", 4}, -/* 824 */ { "UNICODE", 7}, -/* 825 */ { "UNINSTALL", 9}, -/* 826 */ { "UNION", 5}, -/* 827 */ { "UNIQUE", 6}, -/* 828 */ { "UNKNOWN", 7}, -/* 829 */ { "UNLOCK", 6}, -/* 830 */ { "UNSIGNED", 8}, -/* 831 */ { "UNTIL", 5}, -/* 832 */ { "UPDATE", 6}, -/* 833 */ { "UPGRADE", 7}, -/* 834 */ { "USAGE", 5}, -/* 835 */ { "SYSTEM_USER", 11}, -/* 836 */ { "USER_STATISTICS", 15}, -/* 837 */ { "USE_FRM", 7}, -/* 838 */ { "USE", 3}, -/* 839 */ { "USING", 5}, -/* 840 */ { "UTC_DATE", 8}, -/* 841 */ { "UTC_TIMESTAMP", 13}, -/* 842 */ { "UTC_TIME", 8}, -/* 843 */ { "VALUES", 6}, -/* 844 */ { "VALUE", 5}, -/* 845 */ { "VARBINARY", 9}, -/* 846 */ { "VARCHARACTER", 12}, -/* 847 */ { "VARIABLES", 9}, -/* 848 */ { "VAR_POP", 7}, -/* 849 */ { "VARYING", 7}, -/* 850 */ { "VAR_SAMP", 8}, -/* 851 */ { "VIA", 3}, -/* 852 */ { "VIEW", 4}, -/* 853 */ { "VIRTUAL", 7}, -/* 854 */ { "WAIT", 4}, -/* 855 */ { "WARNINGS", 8}, -/* 856 */ { "WEEK", 4}, -/* 857 */ { "WHEN", 4}, -/* 858 */ { "WHERE", 5}, -/* 859 */ { "WHILE", 5}, -/* 860 */ { "WITH", 4}, -/* 861 */ { "WITH CUBE", 9}, -/* 862 */ { "WITH ROLLUP", 11}, -/* 863 */ { "WORK", 4}, -/* 864 */ { "WRAPPER", 7}, -/* 865 */ { "WRITE", 5}, -/* 866 */ { "X509", 4}, -/* 867 */ { "XA", 2}, -/* 868 */ { "XML", 3}, -/* 869 */ { "XOR", 3}, -/* 870 */ { "YEAR_MONTH", 10}, -/* 871 */ { "YEAR", 4}, -/* 872 */ { "ZEROFILL", 8}, -/* 873 */ { "?", 1}, -/* 874 */ { "?, ...", 6}, -/* 875 */ { "(?)", 3}, -/* 876 */ { "(?) /* , ... */", 15}, -/* 877 */ { "(...)", 5}, -/* 878 */ { "(...) /* , ... */", 17}, -/* 879 */ { "UNUSED", 6}, +/* 620 */ { "ONLY", 4}, +/* 621 */ { "ONLINE", 6}, +/* 622 */ { "OPEN", 4}, +/* 623 */ { "OPTIMIZE", 8}, +/* 624 */ { "OPTIONS", 7}, +/* 625 */ { "OPTION", 6}, +/* 626 */ { "OPTIONALLY", 10}, +/* 627 */ { "|", 1}, +/* 628 */ { "ORDER", 5}, +/* 629 */ { "||", 2}, +/* 630 */ { "OR", 2}, +/* 631 */ { "OUTER", 5}, +/* 632 */ { "OUTFILE", 7}, +/* 633 */ { "OUT", 3}, +/* 634 */ { "OWNER", 5}, +/* 635 */ { "PACK_KEYS", 9}, +/* 636 */ { "PAGE", 4}, +/* 637 */ { "PAGE_CHECKSUM", 13}, +/* 638 */ { "?", 1}, +/* 639 */ { "PARSER", 6}, +/* 640 */ { "PARSE_VCOL_EXPR", 15}, +/* 641 */ { "PARTIAL", 7}, +/* 642 */ { "PARTITIONING", 12}, +/* 643 */ { "PARTITIONS", 10}, +/* 644 */ { "PARTITION", 9}, +/* 645 */ { "PASSWORD", 8}, +/* 646 */ { "PERSISTENT", 10}, +/* 647 */ { "PHASE", 5}, +/* 648 */ { "PLUGINS", 7}, +/* 649 */ { "PLUGIN", 6}, +/* 650 */ { "POINT", 5}, +/* 651 */ { "POLYGON", 7}, +/* 652 */ { "PORT", 4}, +/* 653 */ { "POSITION", 8}, +/* 654 */ { "PRECISION", 9}, +/* 655 */ { "PREPARE", 7}, +/* 656 */ { "PRESERVE", 8}, +/* 657 */ { "PREV", 4}, +/* 658 */ { "PRIMARY", 7}, +/* 659 */ { "PRIVILEGES", 10}, +/* 660 */ { "PROCEDURE", 9}, +/* 661 */ { "PROCESS", 7}, +/* 662 */ { "PROCESSLIST", 11}, +/* 663 */ { "PROFILE", 7}, +/* 664 */ { "PROFILES", 8}, +/* 665 */ { "PROXY", 5}, +/* 666 */ { "PURGE", 5}, +/* 667 */ { "SQL_TSI_QUARTER", 15}, +/* 668 */ { "QUERY", 5}, +/* 669 */ { "QUICK", 5}, +/* 670 */ { "RANGE", 5}, +/* 671 */ { "READS", 5}, +/* 672 */ { "READ_ONLY", 9}, +/* 673 */ { "READ", 4}, +/* 674 */ { "READ_WRITE", 10}, +/* 675 */ { "REAL", 4}, +/* 676 */ { "REBUILD", 7}, +/* 677 */ { "RECOVER", 7}, +/* 678 */ { "REDOFILE", 8}, +/* 679 */ { "REDO_BUFFER_SIZE", 16}, +/* 680 */ { "REDUNDANT", 9}, +/* 681 */ { "REFERENCES", 10}, +/* 682 */ { "RLIKE", 5}, +/* 683 */ { "RELAY", 5}, +/* 684 */ { "RELAYLOG", 8}, +/* 685 */ { "RELAY_LOG_FILE", 14}, +/* 686 */ { "RELAY_LOG_POS", 13}, +/* 687 */ { "RELAY_THREAD", 12}, +/* 688 */ { "RELEASE", 7}, +/* 689 */ { "RELOAD", 6}, +/* 690 */ { "REMOVE", 6}, +/* 691 */ { "RENAME", 6}, +/* 692 */ { "REORGANIZE", 10}, +/* 693 */ { "REPAIR", 6}, +/* 694 */ { "REPEATABLE", 10}, +/* 695 */ { "REPEAT", 6}, +/* 696 */ { "REPLACE", 7}, +/* 697 */ { "REPLICATION", 11}, +/* 698 */ { "REQUIRE", 7}, +/* 699 */ { "RESET", 5}, +/* 700 */ { "RESIGNAL", 8}, +/* 701 */ { "USER_RESOURCES", 14}, +/* 702 */ { "RESTORE", 7}, +/* 703 */ { "RESTRICT", 8}, +/* 704 */ { "RESUME", 6}, +/* 705 */ { "RETURNS", 7}, +/* 706 */ { "RETURN", 6}, +/* 707 */ { "REVOKE", 6}, +/* 708 */ { "RIGHT", 5}, +/* 709 */ { "ROLLBACK", 8}, +/* 710 */ { "ROLLUP", 6}, +/* 711 */ { "ROUTINE", 7}, +/* 712 */ { "ROWS", 4}, +/* 713 */ { "ROW_FORMAT", 10}, +/* 714 */ { "ROW", 3}, +/* 715 */ { "RTREE", 5}, +/* 716 */ { "SAVEPOINT", 9}, +/* 717 */ { "SCHEDULE", 8}, +/* 718 */ { "SCHEMA_NAME", 11}, +/* 719 */ { "SECOND_MICROSECOND", 18}, +/* 720 */ { "SQL_TSI_SECOND", 14}, +/* 721 */ { "SECURITY", 8}, +/* 722 */ { "SELECT", 6}, +/* 723 */ { "SENSITIVE", 9}, +/* 724 */ { "SEPARATOR", 9}, +/* 725 */ { "SERIALIZABLE", 12}, +/* 726 */ { "SERIAL", 6}, +/* 727 */ { "SESSION", 7}, +/* 728 */ { "SERVER", 6}, +/* 729 */ { "SERVER_OPTIONS", 14}, +/* 730 */ { "SET", 3}, +/* 731 */ { ":=", 2}, +/* 732 */ { "SHARE", 5}, +/* 733 */ { "<<", 2}, +/* 734 */ { ">>", 2}, +/* 735 */ { "SHOW", 4}, +/* 736 */ { "SHUTDOWN", 8}, +/* 737 */ { "SIGNAL", 6}, +/* 738 */ { "SIGNED", 6}, +/* 739 */ { "SIMPLE", 6}, +/* 740 */ { "SLAVE", 5}, +/* 741 */ { "SLOW", 4}, +/* 742 */ { "SMALLINT", 8}, +/* 743 */ { "SNAPSHOT", 8}, +/* 744 */ { "SOCKET", 6}, +/* 745 */ { "SOFT", 4}, +/* 746 */ { "SONAME", 6}, +/* 747 */ { "SOUNDS", 6}, +/* 748 */ { "SOURCE", 6}, +/* 749 */ { "SPATIAL", 7}, +/* 750 */ { "SPECIFIC", 8}, +/* 751 */ { "SQLEXCEPTION", 12}, +/* 752 */ { "SQLSTATE", 8}, +/* 753 */ { "SQLWARNING", 10}, +/* 754 */ { "SQL_BIG_RESULT", 14}, +/* 755 */ { "SQL_BUFFER_RESULT", 17}, +/* 756 */ { "SQL_CACHE", 9}, +/* 757 */ { "SQL_CALC_FOUND_ROWS", 19}, +/* 758 */ { "SQL_NO_CACHE", 12}, +/* 759 */ { "SQL_SMALL_RESULT", 16}, +/* 760 */ { "SQL", 3}, +/* 761 */ { "SQL_THREAD", 10}, +/* 762 */ { "SSL", 3}, +/* 763 */ { "STARTING", 8}, +/* 764 */ { "STARTS", 6}, +/* 765 */ { "START", 5}, +/* 766 */ { "STATUS", 6}, +/* 767 */ { "STDDEV_SAMP", 11}, +/* 768 */ { "STDDEV_POP", 10}, +/* 769 */ { "STOP", 4}, +/* 770 */ { "STORAGE", 7}, +/* 771 */ { "STRAIGHT_JOIN", 13}, +/* 772 */ { "STRING", 6}, +/* 773 */ { "SUBCLASS_ORIGIN", 15}, +/* 774 */ { "SUBDATE", 7}, +/* 775 */ { "SUBJECT", 7}, +/* 776 */ { "SUBPARTITIONS", 13}, +/* 777 */ { "SUBPARTITION", 12}, +/* 778 */ { "SUBSTRING", 9}, +/* 779 */ { "SUM", 3}, +/* 780 */ { "SUPER", 5}, +/* 781 */ { "SUSPEND", 7}, +/* 782 */ { "SWAPS", 5}, +/* 783 */ { "SWITCHES", 8}, +/* 784 */ { "SYSDATE", 7}, +/* 785 */ { "TABLES", 6}, +/* 786 */ { "TABLESPACE", 10}, +/* 787 */ { "TABLE_REF_PRIORITY", 18}, +/* 788 */ { "TABLE_STATISTICS", 16}, +/* 789 */ { "TABLE", 5}, +/* 790 */ { "TABLE_CHECKSUM", 14}, +/* 791 */ { "TABLE_NAME", 10}, +/* 792 */ { "TEMPORARY", 9}, +/* 793 */ { "TEMPTABLE", 9}, +/* 794 */ { "TERMINATED", 10}, +/* 795 */ { "(text)", 6}, +/* 796 */ { "TEXT", 4}, +/* 797 */ { "THAN", 4}, +/* 798 */ { "THEN", 4}, +/* 799 */ { "TIMESTAMP", 9}, +/* 800 */ { "TIMESTAMPADD", 12}, +/* 801 */ { "TIMESTAMPDIFF", 13}, +/* 802 */ { "TIME", 4}, +/* 803 */ { "TINYBLOB", 8}, +/* 804 */ { "TINYINT", 7}, +/* 805 */ { "TINYTEXT", 8}, +/* 806 */ { "TO", 2}, +/* 807 */ { "TRAILING", 8}, +/* 808 */ { "TRANSACTION", 11}, +/* 809 */ { "TRANSACTIONAL", 13}, +/* 810 */ { "TRIGGERS", 8}, +/* 811 */ { "TRIGGER", 7}, +/* 812 */ { "TRIM", 4}, +/* 813 */ { "TRUE", 4}, +/* 814 */ { "TRUNCATE", 8}, +/* 815 */ { "TYPES", 5}, +/* 816 */ { "TYPE", 4}, +/* 817 */ { "UDF_RETURNS", 11}, +/* 818 */ { "(ulonglong)", 11}, +/* 819 */ { "UNCOMMITTED", 11}, +/* 820 */ { "UNDEFINED", 9}, +/* 821 */ { "(_charset)", 10}, +/* 822 */ { "UNDOFILE", 8}, +/* 823 */ { "UNDO_BUFFER_SIZE", 16}, +/* 824 */ { "UNDO", 4}, +/* 825 */ { "UNICODE", 7}, +/* 826 */ { "UNINSTALL", 9}, +/* 827 */ { "UNION", 5}, +/* 828 */ { "UNIQUE", 6}, +/* 829 */ { "UNKNOWN", 7}, +/* 830 */ { "UNLOCK", 6}, +/* 831 */ { "UNSIGNED", 8}, +/* 832 */ { "UNTIL", 5}, +/* 833 */ { "UPDATE", 6}, +/* 834 */ { "UPGRADE", 7}, +/* 835 */ { "USAGE", 5}, +/* 836 */ { "SYSTEM_USER", 11}, +/* 837 */ { "USER_STATISTICS", 15}, +/* 838 */ { "USE_FRM", 7}, +/* 839 */ { "USE", 3}, +/* 840 */ { "USING", 5}, +/* 841 */ { "UTC_DATE", 8}, +/* 842 */ { "UTC_TIMESTAMP", 13}, +/* 843 */ { "UTC_TIME", 8}, +/* 844 */ { "VALUES", 6}, +/* 845 */ { "VALUE", 5}, +/* 846 */ { "VARBINARY", 9}, +/* 847 */ { "VARCHARACTER", 12}, +/* 848 */ { "VARIABLES", 9}, +/* 849 */ { "VAR_POP", 7}, +/* 850 */ { "VARYING", 7}, +/* 851 */ { "VAR_SAMP", 8}, +/* 852 */ { "VIA", 3}, +/* 853 */ { "VIEW", 4}, +/* 854 */ { "VIRTUAL", 7}, +/* 855 */ { "WAIT", 4}, +/* 856 */ { "WARNINGS", 8}, +/* 857 */ { "WEEK", 4}, +/* 858 */ { "WHEN", 4}, +/* 859 */ { "WHERE", 5}, +/* 860 */ { "WHILE", 5}, +/* 861 */ { "WITH", 4}, +/* 862 */ { "WITH CUBE", 9}, +/* 863 */ { "WITH ROLLUP", 11}, +/* 864 */ { "WORK", 4}, +/* 865 */ { "WRAPPER", 7}, +/* 866 */ { "WRITE", 5}, +/* 867 */ { "X509", 4}, +/* 868 */ { "XA", 2}, +/* 869 */ { "XML", 3}, +/* 870 */ { "XOR", 3}, +/* 871 */ { "YEAR_MONTH", 10}, +/* 872 */ { "YEAR", 4}, +/* 873 */ { "ZEROFILL", 8}, +/* 874 */ { "?", 1}, +/* 875 */ { "?, ...", 6}, +/* 876 */ { "(?)", 3}, +/* 877 */ { "(?) /* , ... */", 15}, +/* 878 */ { "(...)", 5}, +/* 879 */ { "(...) /* , ... */", 17}, +/* 880 */ { "UNUSED", 6}, /* DUMMY */ { "", 0} }; /* PFS specific tokens. */ -#define TOK_PFS_GENERIC_VALUE 873 -#define TOK_PFS_GENERIC_VALUE_LIST 874 -#define TOK_PFS_ROW_SINGLE_VALUE 875 -#define TOK_PFS_ROW_SINGLE_VALUE_LIST 876 -#define TOK_PFS_ROW_MULTIPLE_VALUE 877 -#define TOK_PFS_ROW_MULTIPLE_VALUE_LIST 878 -#define TOK_PFS_UNUSED 879 +#define TOK_PFS_GENERIC_VALUE 874 +#define TOK_PFS_GENERIC_VALUE_LIST 875 +#define TOK_PFS_ROW_SINGLE_VALUE 876 +#define TOK_PFS_ROW_SINGLE_VALUE_LIST 877 +#define TOK_PFS_ROW_MULTIPLE_VALUE 878 +#define TOK_PFS_ROW_MULTIPLE_VALUE_LIST 879 +#define TOK_PFS_UNUSED 880 |