mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
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
This commit is contained in:
@ -14,10 +14,12 @@ set SQL_LOG_BIN=0;
|
|||||||
# Turn off any debug crashes, allow the variable to be
|
# Turn off any debug crashes, allow the variable to be
|
||||||
# non existent in release builds
|
# non existent in release builds
|
||||||
--error 0,1193
|
--error 0,1193
|
||||||
set debug_dbug="";
|
set debug="";
|
||||||
|
|
||||||
|
|
||||||
use mtr;
|
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 (
|
create temporary table error_log (
|
||||||
row int auto_increment primary key,
|
row int auto_increment primary key,
|
||||||
|
@ -264,9 +264,313 @@ Should only read the '1000' as this transaction is now in REP READ
|
|||||||
COMMIT AND NO CHAIN;
|
COMMIT AND NO CHAIN;
|
||||||
SET @@completion_type=0;
|
SET @@completion_type=0;
|
||||||
COMMIT AND NO CHAIN;
|
COMMIT AND NO CHAIN;
|
||||||
SET @autocommit=1;
|
SET @@autocommit=1;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
# End of test cases for Bug#20837
|
# 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;
|
||||||
|
@ -157,3 +157,40 @@ delete from mysql.columns_priv where User like 'mysqltest_%';
|
|||||||
flush privileges;
|
flush privileges;
|
||||||
drop database mysqltest_db1;
|
drop database mysqltest_db1;
|
||||||
set global read_only= @start_read_only;
|
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;
|
||||||
|
40
mysql-test/r/trans_read_only.result
Normal file
40
mysql-test/r/trans_read_only.result
Normal file
@ -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;
|
@ -338,7 +338,7 @@ COMMIT AND NO CHAIN;
|
|||||||
#
|
#
|
||||||
# Cleanup
|
# Cleanup
|
||||||
#
|
#
|
||||||
SET @autocommit=1;
|
SET @@autocommit=1;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
disconnect con1;
|
disconnect con1;
|
||||||
@ -348,3 +348,360 @@ DROP TABLE t1;
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of test cases for Bug#20837
|
--echo # End of test cases for Bug#20837
|
||||||
--echo #
|
--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;
|
||||||
|
@ -299,6 +299,65 @@ flush privileges;
|
|||||||
drop database mysqltest_db1;
|
drop database mysqltest_db1;
|
||||||
set global read_only= @start_read_only;
|
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
|
# Wait till all disconnects are completed
|
||||||
--source include/wait_until_count_sessions.inc
|
--source include/wait_until_count_sessions.inc
|
||||||
|
|
||||||
|
1
mysql-test/t/trans_read_only-master.opt
Normal file
1
mysql-test/t/trans_read_only-master.opt
Normal file
@ -0,0 +1 @@
|
|||||||
|
--transaction-read-only=true
|
50
mysql-test/t/trans_read_only.test
Normal file
50
mysql-test/t/trans_read_only.test
Normal file
@ -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;
|
@ -402,6 +402,7 @@ static SYMBOL symbols[] = {
|
|||||||
{ "ONE", SYM(ONE_SYM)},
|
{ "ONE", SYM(ONE_SYM)},
|
||||||
{ "ONE_SHOT", SYM(ONE_SHOT_SYM)},
|
{ "ONE_SHOT", SYM(ONE_SHOT_SYM)},
|
||||||
{ "ONLINE", SYM(ONLINE_SYM)},
|
{ "ONLINE", SYM(ONLINE_SYM)},
|
||||||
|
{ "ONLY", SYM(ONLY_SYM)},
|
||||||
{ "OPEN", SYM(OPEN_SYM)},
|
{ "OPEN", SYM(OPEN_SYM)},
|
||||||
{ "OPTIMIZE", SYM(OPTIMIZE)},
|
{ "OPTIMIZE", SYM(OPTIMIZE)},
|
||||||
{ "OPTIONS", SYM(OPTIONS_SYM)},
|
{ "OPTIONS", SYM(OPTIONS_SYM)},
|
||||||
|
@ -4722,7 +4722,7 @@ lock_table_names(THD *thd,
|
|||||||
if (thd->tx_read_only)
|
if (thd->tx_read_only)
|
||||||
{
|
{
|
||||||
my_error(ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION, MYF(0));
|
my_error(ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION, MYF(0));
|
||||||
return true;
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! (flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK) &&
|
if (! (flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK) &&
|
||||||
|
@ -4005,6 +4005,7 @@ end_with_restore_list:
|
|||||||
{
|
{
|
||||||
/* Reset the isolation level if no chaining transaction. */
|
/* Reset the isolation level if no chaining transaction. */
|
||||||
thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
|
thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
|
||||||
|
thd->tx_read_only= thd->variables.tx_read_only;
|
||||||
}
|
}
|
||||||
/* Disconnect the current client connection. */
|
/* Disconnect the current client connection. */
|
||||||
if (tx_release)
|
if (tx_release)
|
||||||
|
482
sql/sql_yacc.yy
482
sql/sql_yacc.yy
@ -730,6 +730,116 @@ static bool add_create_index (LEX *lex, Key::Keytype type,
|
|||||||
return FALSE;
|
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 {
|
%union {
|
||||||
int num;
|
int num;
|
||||||
@ -788,10 +898,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
|
|
||||||
%pure_parser /* We have threads */
|
%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.
|
We should not introduce new conflicts any more.
|
||||||
*/
|
*/
|
||||||
%expect 174
|
%expect 171
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Comments for TOKENS.
|
Comments for TOKENS.
|
||||||
@ -1172,6 +1282,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
%token ON /* SQL-2003-R */
|
%token ON /* SQL-2003-R */
|
||||||
%token ONE_SHOT_SYM
|
%token ONE_SHOT_SYM
|
||||||
%token ONE_SYM
|
%token ONE_SYM
|
||||||
|
%token ONLY_SYM /* SQL-2003-R */
|
||||||
%token ONLINE_SYM
|
%token ONLINE_SYM
|
||||||
%token OPEN_SYM /* SQL-2003-R */
|
%token OPEN_SYM /* SQL-2003-R */
|
||||||
%token OPTIMIZE
|
%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
|
table_option opt_if_not_exists opt_no_write_to_binlog
|
||||||
opt_temporary all_or_any opt_distinct
|
opt_temporary all_or_any opt_distinct
|
||||||
opt_ignore_leaves fulltext_options spatial_type union_option
|
opt_ignore_leaves fulltext_options spatial_type union_option
|
||||||
start_transaction_opts field_def
|
field_def
|
||||||
union_opt select_derived_init option_type2
|
union_opt select_derived_init transaction_access_mode_types
|
||||||
opt_natural_language_mode opt_query_expansion
|
opt_natural_language_mode opt_query_expansion
|
||||||
opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment
|
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
|
ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt
|
||||||
optional_flush_tables_arguments opt_dyncol_type dyncol_type
|
optional_flush_tables_arguments opt_dyncol_type dyncol_type
|
||||||
opt_time_precision kill_type kill_option int_num
|
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>
|
%type <m_yes_no_unk>
|
||||||
opt_chain opt_release
|
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
|
ref_list opt_match_clause opt_on_update_delete use
|
||||||
opt_delete_options opt_delete_option varchar nchar nvarchar
|
opt_delete_options opt_delete_option varchar nchar nvarchar
|
||||||
opt_outer table_list table_name table_alias_ref_list table_alias_ref
|
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_attribute opt_attribute_list attribute column_list column_list_id
|
||||||
opt_column_list grant_privileges grant_ident grant_list grant_option
|
opt_column_list grant_privileges grant_ident grant_list grant_option
|
||||||
object_privilege object_privilege_list user_list rename_list
|
object_privilege object_privilege_list user_list rename_list
|
||||||
@ -7100,20 +7218,56 @@ slave:
|
|||||||
;
|
;
|
||||||
|
|
||||||
start:
|
start:
|
||||||
START_SYM TRANSACTION_SYM start_transaction_opts
|
START_SYM TRANSACTION_SYM opt_start_transaction_option_list
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
lex->sql_command= SQLCOM_BEGIN;
|
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;
|
lex->start_transaction_opt= $3;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
start_transaction_opts:
|
opt_start_transaction_option_list:
|
||||||
/*empty*/ { $$ = 0; }
|
/* empty */
|
||||||
| WITH CONSISTENT_SYM SNAPSHOT_SYM
|
{
|
||||||
|
$$= 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;
|
$$= 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:
|
slave_thread_opts:
|
||||||
@ -13148,6 +13302,7 @@ keyword_sp:
|
|||||||
| ONE_SHOT_SYM {}
|
| ONE_SHOT_SYM {}
|
||||||
| ONE_SYM {}
|
| ONE_SYM {}
|
||||||
| ONLINE_SYM {}
|
| ONLINE_SYM {}
|
||||||
|
| ONLY_SYM {}
|
||||||
| PACK_KEYS_SYM {}
|
| PACK_KEYS_SYM {}
|
||||||
| PAGE_SYM {}
|
| PAGE_SYM {}
|
||||||
| PARTIAL {}
|
| PARTIAL {}
|
||||||
@ -13271,8 +13426,15 @@ keyword_sp:
|
|||||||
|
|
||||||
/* Option functions */
|
/* 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:
|
||||||
SET opt_option
|
SET
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->sql_command= SQLCOM_SET_OPTION;
|
lex->sql_command= SQLCOM_SET_OPTION;
|
||||||
@ -13281,115 +13443,96 @@ set:
|
|||||||
lex->var_list.empty();
|
lex->var_list.empty();
|
||||||
lex->one_shot_set= 0;
|
lex->one_shot_set= 0;
|
||||||
lex->autocommit= 0;
|
lex->autocommit= 0;
|
||||||
|
sp_create_assignment_lex(YYTHD, yychar == YYEMPTY);
|
||||||
}
|
}
|
||||||
option_value_list
|
start_option_value_list
|
||||||
{}
|
{}
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_option:
|
|
||||||
/* empty */ {}
|
// Start of option value list
|
||||||
| OPTION {}
|
start_option_value_list:
|
||||||
|
option_value_no_option_type
|
||||||
|
{
|
||||||
|
if (sp_create_assignment_instr(YYTHD, yychar == YYEMPTY))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
option_value_list_continued
|
||||||
|
| TRANSACTION_SYM
|
||||||
|
{
|
||||||
|
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
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
// Remainder of the option value list after first option value.
|
||||||
|
option_value_list_continued:
|
||||||
|
/* empty */
|
||||||
|
| ',' option_value_list
|
||||||
|
;
|
||||||
|
|
||||||
|
// Repeating list of option values after first option value.
|
||||||
option_value_list:
|
option_value_list:
|
||||||
option_type_value
|
{
|
||||||
| option_value_list ',' option_type_value
|
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;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
option_type_value:
|
// Wrapper around option values following the first option value in the stmt.
|
||||||
|
option_value:
|
||||||
|
option_type
|
||||||
{
|
{
|
||||||
THD *thd= YYTHD;
|
Lex->option_type= $1;
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ext_option_value
|
|
||||||
{
|
|
||||||
THD *thd= YYTHD;
|
|
||||||
LEX *lex= thd->lex;
|
|
||||||
Lex_input_stream *lip= YYLIP;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (!(i= new sp_instr_stmt(sp->instructions(), lex->spcont,
|
|
||||||
lex)))
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (!(qbuff.str= (char*) alloc_root(thd->mem_root,
|
|
||||||
qbuff.length + 5)))
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
option_value_following_option_type
|
||||||
|
| option_value_no_option_type
|
||||||
;
|
;
|
||||||
|
|
||||||
option_type:
|
option_type:
|
||||||
option_type2 {}
|
GLOBAL_SYM { $$=OPT_GLOBAL; }
|
||||||
| GLOBAL_SYM { $$=OPT_GLOBAL; }
|
|
||||||
| LOCAL_SYM { $$=OPT_SESSION; }
|
| LOCAL_SYM { $$=OPT_SESSION; }
|
||||||
| SESSION_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:
|
opt_var_type:
|
||||||
/* empty */ { $$=OPT_SESSION; }
|
/* empty */ { $$=OPT_SESSION; }
|
||||||
| GLOBAL_SYM { $$=OPT_GLOBAL; }
|
| GLOBAL_SYM { $$=OPT_GLOBAL; }
|
||||||
@ -13404,74 +13547,62 @@ opt_var_ident_type:
|
|||||||
| SESSION_SYM '.' { $$=OPT_SESSION; }
|
| SESSION_SYM '.' { $$=OPT_SESSION; }
|
||||||
;
|
;
|
||||||
|
|
||||||
ext_option_value:
|
// Option values with preceeding option_type.
|
||||||
sys_option_value
|
option_value_following_option_type:
|
||||||
| option_type2 option_value
|
internal_variable_name equal set_expr_or_default
|
||||||
;
|
|
||||||
|
|
||||||
sys_option_value:
|
|
||||||
option_type internal_variable_name equal set_expr_or_default
|
|
||||||
{
|
{
|
||||||
THD *thd= YYTHD;
|
THD *thd= YYTHD;
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
LEX_STRING *name= &$2.base_name;
|
|
||||||
|
|
||||||
if ($2.var == trg_new_row_fake_var)
|
if ($1.var && $1.var != trg_new_row_fake_var)
|
||||||
{
|
{
|
||||||
/* We are in trigger and assigning value to field of new row */
|
/* It is a system variable. */
|
||||||
if ($1)
|
if (set_system_variable(thd, &$1, lex->option_type, $3))
|
||||||
{
|
|
||||||
my_parse_error(ER(ER_SYNTAX_ERROR));
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
if (set_trigger_new_row(YYTHD, name, $4))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
else if ($2.var)
|
else
|
||||||
{
|
{
|
||||||
if ($1)
|
/*
|
||||||
lex->option_type= $1;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
// 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= &$1.base_name;
|
||||||
|
|
||||||
|
if ($1.var == trg_new_row_fake_var)
|
||||||
|
{
|
||||||
|
/* We are in trigger and assigning value to field of new row */
|
||||||
|
if (set_trigger_new_row(YYTHD, name, $3))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
else if ($1.var)
|
||||||
|
{
|
||||||
/* It is a system variable. */
|
/* 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;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sp_pcontext *spc= lex->spcont;
|
sp_pcontext *spc= lex->spcont;
|
||||||
sp_variable_t *spv= spc->find_variable(name);
|
sp_variable *spv= spc->find_variable(name, false);
|
||||||
|
|
||||||
if ($1)
|
|
||||||
{
|
|
||||||
my_parse_error(ER(ER_SYNTAX_ERROR));
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* It is a local variable. */
|
/* It is a local variable. */
|
||||||
if (set_local_variable(thd, spv, $4))
|
if (set_local_variable(thd, spv, $3))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| option_type TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types
|
| '@' ident_or_text equal expr
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
Item_func_set_user_var *item;
|
Item_func_set_user_var *item;
|
||||||
item= new (YYTHD->mem_root) Item_func_set_user_var($2, $4);
|
item= new (YYTHD->mem_root) Item_func_set_user_var($2, $4);
|
||||||
@ -13517,7 +13648,7 @@ option_value:
|
|||||||
|
|
||||||
names.str= (char *)"names";
|
names.str= (char *)"names";
|
||||||
names.length= 5;
|
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);
|
my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), names.str);
|
||||||
else
|
else
|
||||||
my_parse_error(ER(ER_SYNTAX_ERROR));
|
my_parse_error(ER(ER_SYNTAX_ERROR));
|
||||||
@ -13553,7 +13684,7 @@ option_value:
|
|||||||
|
|
||||||
pw.str= (char *)"password";
|
pw.str= (char *)"password";
|
||||||
pw.length= 8;
|
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);
|
my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), pw.str);
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
@ -13562,6 +13693,7 @@ option_value:
|
|||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
user->host=null_lex_str;
|
user->host=null_lex_str;
|
||||||
user->user.str=thd->security_ctx->user;
|
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);
|
set_var_password *var= new set_var_password(user, $3);
|
||||||
if (var == NULL)
|
if (var == NULL)
|
||||||
MYSQL_YYABORT;
|
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:
|
isolation_types:
|
||||||
READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; }
|
READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; }
|
||||||
| READ_SYM COMMITTED_SYM { $$= ISO_READ_COMMITTED; }
|
| READ_SYM COMMITTED_SYM { $$= ISO_READ_COMMITTED; }
|
||||||
|
Binary file not shown.
@ -636,273 +636,274 @@ lex_token_string lex_token_array[]=
|
|||||||
/* 617 */ { "ON", 2},
|
/* 617 */ { "ON", 2},
|
||||||
/* 618 */ { "ONE_SHOT", 8},
|
/* 618 */ { "ONE_SHOT", 8},
|
||||||
/* 619 */ { "ONE", 3},
|
/* 619 */ { "ONE", 3},
|
||||||
/* 620 */ { "ONLINE", 6},
|
/* 620 */ { "ONLY", 4},
|
||||||
/* 621 */ { "OPEN", 4},
|
/* 621 */ { "ONLINE", 6},
|
||||||
/* 622 */ { "OPTIMIZE", 8},
|
/* 622 */ { "OPEN", 4},
|
||||||
/* 623 */ { "OPTIONS", 7},
|
/* 623 */ { "OPTIMIZE", 8},
|
||||||
/* 624 */ { "OPTION", 6},
|
/* 624 */ { "OPTIONS", 7},
|
||||||
/* 625 */ { "OPTIONALLY", 10},
|
/* 625 */ { "OPTION", 6},
|
||||||
/* 626 */ { "|", 1},
|
/* 626 */ { "OPTIONALLY", 10},
|
||||||
/* 627 */ { "ORDER", 5},
|
/* 627 */ { "|", 1},
|
||||||
/* 628 */ { "||", 2},
|
/* 628 */ { "ORDER", 5},
|
||||||
/* 629 */ { "OR", 2},
|
/* 629 */ { "||", 2},
|
||||||
/* 630 */ { "OUTER", 5},
|
/* 630 */ { "OR", 2},
|
||||||
/* 631 */ { "OUTFILE", 7},
|
/* 631 */ { "OUTER", 5},
|
||||||
/* 632 */ { "OUT", 3},
|
/* 632 */ { "OUTFILE", 7},
|
||||||
/* 633 */ { "OWNER", 5},
|
/* 633 */ { "OUT", 3},
|
||||||
/* 634 */ { "PACK_KEYS", 9},
|
/* 634 */ { "OWNER", 5},
|
||||||
/* 635 */ { "PAGE", 4},
|
/* 635 */ { "PACK_KEYS", 9},
|
||||||
/* 636 */ { "PAGE_CHECKSUM", 13},
|
/* 636 */ { "PAGE", 4},
|
||||||
/* 637 */ { "?", 1},
|
/* 637 */ { "PAGE_CHECKSUM", 13},
|
||||||
/* 638 */ { "PARSER", 6},
|
/* 638 */ { "?", 1},
|
||||||
/* 639 */ { "PARSE_VCOL_EXPR", 15},
|
/* 639 */ { "PARSER", 6},
|
||||||
/* 640 */ { "PARTIAL", 7},
|
/* 640 */ { "PARSE_VCOL_EXPR", 15},
|
||||||
/* 641 */ { "PARTITIONING", 12},
|
/* 641 */ { "PARTIAL", 7},
|
||||||
/* 642 */ { "PARTITIONS", 10},
|
/* 642 */ { "PARTITIONING", 12},
|
||||||
/* 643 */ { "PARTITION", 9},
|
/* 643 */ { "PARTITIONS", 10},
|
||||||
/* 644 */ { "PASSWORD", 8},
|
/* 644 */ { "PARTITION", 9},
|
||||||
/* 645 */ { "PERSISTENT", 10},
|
/* 645 */ { "PASSWORD", 8},
|
||||||
/* 646 */ { "PHASE", 5},
|
/* 646 */ { "PERSISTENT", 10},
|
||||||
/* 647 */ { "PLUGINS", 7},
|
/* 647 */ { "PHASE", 5},
|
||||||
/* 648 */ { "PLUGIN", 6},
|
/* 648 */ { "PLUGINS", 7},
|
||||||
/* 649 */ { "POINT", 5},
|
/* 649 */ { "PLUGIN", 6},
|
||||||
/* 650 */ { "POLYGON", 7},
|
/* 650 */ { "POINT", 5},
|
||||||
/* 651 */ { "PORT", 4},
|
/* 651 */ { "POLYGON", 7},
|
||||||
/* 652 */ { "POSITION", 8},
|
/* 652 */ { "PORT", 4},
|
||||||
/* 653 */ { "PRECISION", 9},
|
/* 653 */ { "POSITION", 8},
|
||||||
/* 654 */ { "PREPARE", 7},
|
/* 654 */ { "PRECISION", 9},
|
||||||
/* 655 */ { "PRESERVE", 8},
|
/* 655 */ { "PREPARE", 7},
|
||||||
/* 656 */ { "PREV", 4},
|
/* 656 */ { "PRESERVE", 8},
|
||||||
/* 657 */ { "PRIMARY", 7},
|
/* 657 */ { "PREV", 4},
|
||||||
/* 658 */ { "PRIVILEGES", 10},
|
/* 658 */ { "PRIMARY", 7},
|
||||||
/* 659 */ { "PROCEDURE", 9},
|
/* 659 */ { "PRIVILEGES", 10},
|
||||||
/* 660 */ { "PROCESS", 7},
|
/* 660 */ { "PROCEDURE", 9},
|
||||||
/* 661 */ { "PROCESSLIST", 11},
|
/* 661 */ { "PROCESS", 7},
|
||||||
/* 662 */ { "PROFILE", 7},
|
/* 662 */ { "PROCESSLIST", 11},
|
||||||
/* 663 */ { "PROFILES", 8},
|
/* 663 */ { "PROFILE", 7},
|
||||||
/* 664 */ { "PROXY", 5},
|
/* 664 */ { "PROFILES", 8},
|
||||||
/* 665 */ { "PURGE", 5},
|
/* 665 */ { "PROXY", 5},
|
||||||
/* 666 */ { "SQL_TSI_QUARTER", 15},
|
/* 666 */ { "PURGE", 5},
|
||||||
/* 667 */ { "QUERY", 5},
|
/* 667 */ { "SQL_TSI_QUARTER", 15},
|
||||||
/* 668 */ { "QUICK", 5},
|
/* 668 */ { "QUERY", 5},
|
||||||
/* 669 */ { "RANGE", 5},
|
/* 669 */ { "QUICK", 5},
|
||||||
/* 670 */ { "READS", 5},
|
/* 670 */ { "RANGE", 5},
|
||||||
/* 671 */ { "READ_ONLY", 9},
|
/* 671 */ { "READS", 5},
|
||||||
/* 672 */ { "READ", 4},
|
/* 672 */ { "READ_ONLY", 9},
|
||||||
/* 673 */ { "READ_WRITE", 10},
|
/* 673 */ { "READ", 4},
|
||||||
/* 674 */ { "REAL", 4},
|
/* 674 */ { "READ_WRITE", 10},
|
||||||
/* 675 */ { "REBUILD", 7},
|
/* 675 */ { "REAL", 4},
|
||||||
/* 676 */ { "RECOVER", 7},
|
/* 676 */ { "REBUILD", 7},
|
||||||
/* 677 */ { "REDOFILE", 8},
|
/* 677 */ { "RECOVER", 7},
|
||||||
/* 678 */ { "REDO_BUFFER_SIZE", 16},
|
/* 678 */ { "REDOFILE", 8},
|
||||||
/* 679 */ { "REDUNDANT", 9},
|
/* 679 */ { "REDO_BUFFER_SIZE", 16},
|
||||||
/* 680 */ { "REFERENCES", 10},
|
/* 680 */ { "REDUNDANT", 9},
|
||||||
/* 681 */ { "RLIKE", 5},
|
/* 681 */ { "REFERENCES", 10},
|
||||||
/* 682 */ { "RELAY", 5},
|
/* 682 */ { "RLIKE", 5},
|
||||||
/* 683 */ { "RELAYLOG", 8},
|
/* 683 */ { "RELAY", 5},
|
||||||
/* 684 */ { "RELAY_LOG_FILE", 14},
|
/* 684 */ { "RELAYLOG", 8},
|
||||||
/* 685 */ { "RELAY_LOG_POS", 13},
|
/* 685 */ { "RELAY_LOG_FILE", 14},
|
||||||
/* 686 */ { "RELAY_THREAD", 12},
|
/* 686 */ { "RELAY_LOG_POS", 13},
|
||||||
/* 687 */ { "RELEASE", 7},
|
/* 687 */ { "RELAY_THREAD", 12},
|
||||||
/* 688 */ { "RELOAD", 6},
|
/* 688 */ { "RELEASE", 7},
|
||||||
/* 689 */ { "REMOVE", 6},
|
/* 689 */ { "RELOAD", 6},
|
||||||
/* 690 */ { "RENAME", 6},
|
/* 690 */ { "REMOVE", 6},
|
||||||
/* 691 */ { "REORGANIZE", 10},
|
/* 691 */ { "RENAME", 6},
|
||||||
/* 692 */ { "REPAIR", 6},
|
/* 692 */ { "REORGANIZE", 10},
|
||||||
/* 693 */ { "REPEATABLE", 10},
|
/* 693 */ { "REPAIR", 6},
|
||||||
/* 694 */ { "REPEAT", 6},
|
/* 694 */ { "REPEATABLE", 10},
|
||||||
/* 695 */ { "REPLACE", 7},
|
/* 695 */ { "REPEAT", 6},
|
||||||
/* 696 */ { "REPLICATION", 11},
|
/* 696 */ { "REPLACE", 7},
|
||||||
/* 697 */ { "REQUIRE", 7},
|
/* 697 */ { "REPLICATION", 11},
|
||||||
/* 698 */ { "RESET", 5},
|
/* 698 */ { "REQUIRE", 7},
|
||||||
/* 699 */ { "RESIGNAL", 8},
|
/* 699 */ { "RESET", 5},
|
||||||
/* 700 */ { "USER_RESOURCES", 14},
|
/* 700 */ { "RESIGNAL", 8},
|
||||||
/* 701 */ { "RESTORE", 7},
|
/* 701 */ { "USER_RESOURCES", 14},
|
||||||
/* 702 */ { "RESTRICT", 8},
|
/* 702 */ { "RESTORE", 7},
|
||||||
/* 703 */ { "RESUME", 6},
|
/* 703 */ { "RESTRICT", 8},
|
||||||
/* 704 */ { "RETURNS", 7},
|
/* 704 */ { "RESUME", 6},
|
||||||
/* 705 */ { "RETURN", 6},
|
/* 705 */ { "RETURNS", 7},
|
||||||
/* 706 */ { "REVOKE", 6},
|
/* 706 */ { "RETURN", 6},
|
||||||
/* 707 */ { "RIGHT", 5},
|
/* 707 */ { "REVOKE", 6},
|
||||||
/* 708 */ { "ROLLBACK", 8},
|
/* 708 */ { "RIGHT", 5},
|
||||||
/* 709 */ { "ROLLUP", 6},
|
/* 709 */ { "ROLLBACK", 8},
|
||||||
/* 710 */ { "ROUTINE", 7},
|
/* 710 */ { "ROLLUP", 6},
|
||||||
/* 711 */ { "ROWS", 4},
|
/* 711 */ { "ROUTINE", 7},
|
||||||
/* 712 */ { "ROW_FORMAT", 10},
|
/* 712 */ { "ROWS", 4},
|
||||||
/* 713 */ { "ROW", 3},
|
/* 713 */ { "ROW_FORMAT", 10},
|
||||||
/* 714 */ { "RTREE", 5},
|
/* 714 */ { "ROW", 3},
|
||||||
/* 715 */ { "SAVEPOINT", 9},
|
/* 715 */ { "RTREE", 5},
|
||||||
/* 716 */ { "SCHEDULE", 8},
|
/* 716 */ { "SAVEPOINT", 9},
|
||||||
/* 717 */ { "SCHEMA_NAME", 11},
|
/* 717 */ { "SCHEDULE", 8},
|
||||||
/* 718 */ { "SECOND_MICROSECOND", 18},
|
/* 718 */ { "SCHEMA_NAME", 11},
|
||||||
/* 719 */ { "SQL_TSI_SECOND", 14},
|
/* 719 */ { "SECOND_MICROSECOND", 18},
|
||||||
/* 720 */ { "SECURITY", 8},
|
/* 720 */ { "SQL_TSI_SECOND", 14},
|
||||||
/* 721 */ { "SELECT", 6},
|
/* 721 */ { "SECURITY", 8},
|
||||||
/* 722 */ { "SENSITIVE", 9},
|
/* 722 */ { "SELECT", 6},
|
||||||
/* 723 */ { "SEPARATOR", 9},
|
/* 723 */ { "SENSITIVE", 9},
|
||||||
/* 724 */ { "SERIALIZABLE", 12},
|
/* 724 */ { "SEPARATOR", 9},
|
||||||
/* 725 */ { "SERIAL", 6},
|
/* 725 */ { "SERIALIZABLE", 12},
|
||||||
/* 726 */ { "SESSION", 7},
|
/* 726 */ { "SERIAL", 6},
|
||||||
/* 727 */ { "SERVER", 6},
|
/* 727 */ { "SESSION", 7},
|
||||||
/* 728 */ { "SERVER_OPTIONS", 14},
|
/* 728 */ { "SERVER", 6},
|
||||||
/* 729 */ { "SET", 3},
|
/* 729 */ { "SERVER_OPTIONS", 14},
|
||||||
/* 730 */ { ":=", 2},
|
/* 730 */ { "SET", 3},
|
||||||
/* 731 */ { "SHARE", 5},
|
/* 731 */ { ":=", 2},
|
||||||
/* 732 */ { "<<", 2},
|
/* 732 */ { "SHARE", 5},
|
||||||
/* 733 */ { ">>", 2},
|
/* 733 */ { "<<", 2},
|
||||||
/* 734 */ { "SHOW", 4},
|
/* 734 */ { ">>", 2},
|
||||||
/* 735 */ { "SHUTDOWN", 8},
|
/* 735 */ { "SHOW", 4},
|
||||||
/* 736 */ { "SIGNAL", 6},
|
/* 736 */ { "SHUTDOWN", 8},
|
||||||
/* 737 */ { "SIGNED", 6},
|
/* 737 */ { "SIGNAL", 6},
|
||||||
/* 738 */ { "SIMPLE", 6},
|
/* 738 */ { "SIGNED", 6},
|
||||||
/* 739 */ { "SLAVE", 5},
|
/* 739 */ { "SIMPLE", 6},
|
||||||
/* 740 */ { "SLOW", 4},
|
/* 740 */ { "SLAVE", 5},
|
||||||
/* 741 */ { "SMALLINT", 8},
|
/* 741 */ { "SLOW", 4},
|
||||||
/* 742 */ { "SNAPSHOT", 8},
|
/* 742 */ { "SMALLINT", 8},
|
||||||
/* 743 */ { "SOCKET", 6},
|
/* 743 */ { "SNAPSHOT", 8},
|
||||||
/* 744 */ { "SOFT", 4},
|
/* 744 */ { "SOCKET", 6},
|
||||||
/* 745 */ { "SONAME", 6},
|
/* 745 */ { "SOFT", 4},
|
||||||
/* 746 */ { "SOUNDS", 6},
|
/* 746 */ { "SONAME", 6},
|
||||||
/* 747 */ { "SOURCE", 6},
|
/* 747 */ { "SOUNDS", 6},
|
||||||
/* 748 */ { "SPATIAL", 7},
|
/* 748 */ { "SOURCE", 6},
|
||||||
/* 749 */ { "SPECIFIC", 8},
|
/* 749 */ { "SPATIAL", 7},
|
||||||
/* 750 */ { "SQLEXCEPTION", 12},
|
/* 750 */ { "SPECIFIC", 8},
|
||||||
/* 751 */ { "SQLSTATE", 8},
|
/* 751 */ { "SQLEXCEPTION", 12},
|
||||||
/* 752 */ { "SQLWARNING", 10},
|
/* 752 */ { "SQLSTATE", 8},
|
||||||
/* 753 */ { "SQL_BIG_RESULT", 14},
|
/* 753 */ { "SQLWARNING", 10},
|
||||||
/* 754 */ { "SQL_BUFFER_RESULT", 17},
|
/* 754 */ { "SQL_BIG_RESULT", 14},
|
||||||
/* 755 */ { "SQL_CACHE", 9},
|
/* 755 */ { "SQL_BUFFER_RESULT", 17},
|
||||||
/* 756 */ { "SQL_CALC_FOUND_ROWS", 19},
|
/* 756 */ { "SQL_CACHE", 9},
|
||||||
/* 757 */ { "SQL_NO_CACHE", 12},
|
/* 757 */ { "SQL_CALC_FOUND_ROWS", 19},
|
||||||
/* 758 */ { "SQL_SMALL_RESULT", 16},
|
/* 758 */ { "SQL_NO_CACHE", 12},
|
||||||
/* 759 */ { "SQL", 3},
|
/* 759 */ { "SQL_SMALL_RESULT", 16},
|
||||||
/* 760 */ { "SQL_THREAD", 10},
|
/* 760 */ { "SQL", 3},
|
||||||
/* 761 */ { "SSL", 3},
|
/* 761 */ { "SQL_THREAD", 10},
|
||||||
/* 762 */ { "STARTING", 8},
|
/* 762 */ { "SSL", 3},
|
||||||
/* 763 */ { "STARTS", 6},
|
/* 763 */ { "STARTING", 8},
|
||||||
/* 764 */ { "START", 5},
|
/* 764 */ { "STARTS", 6},
|
||||||
/* 765 */ { "STATUS", 6},
|
/* 765 */ { "START", 5},
|
||||||
/* 766 */ { "STDDEV_SAMP", 11},
|
/* 766 */ { "STATUS", 6},
|
||||||
/* 767 */ { "STDDEV_POP", 10},
|
/* 767 */ { "STDDEV_SAMP", 11},
|
||||||
/* 768 */ { "STOP", 4},
|
/* 768 */ { "STDDEV_POP", 10},
|
||||||
/* 769 */ { "STORAGE", 7},
|
/* 769 */ { "STOP", 4},
|
||||||
/* 770 */ { "STRAIGHT_JOIN", 13},
|
/* 770 */ { "STORAGE", 7},
|
||||||
/* 771 */ { "STRING", 6},
|
/* 771 */ { "STRAIGHT_JOIN", 13},
|
||||||
/* 772 */ { "SUBCLASS_ORIGIN", 15},
|
/* 772 */ { "STRING", 6},
|
||||||
/* 773 */ { "SUBDATE", 7},
|
/* 773 */ { "SUBCLASS_ORIGIN", 15},
|
||||||
/* 774 */ { "SUBJECT", 7},
|
/* 774 */ { "SUBDATE", 7},
|
||||||
/* 775 */ { "SUBPARTITIONS", 13},
|
/* 775 */ { "SUBJECT", 7},
|
||||||
/* 776 */ { "SUBPARTITION", 12},
|
/* 776 */ { "SUBPARTITIONS", 13},
|
||||||
/* 777 */ { "SUBSTRING", 9},
|
/* 777 */ { "SUBPARTITION", 12},
|
||||||
/* 778 */ { "SUM", 3},
|
/* 778 */ { "SUBSTRING", 9},
|
||||||
/* 779 */ { "SUPER", 5},
|
/* 779 */ { "SUM", 3},
|
||||||
/* 780 */ { "SUSPEND", 7},
|
/* 780 */ { "SUPER", 5},
|
||||||
/* 781 */ { "SWAPS", 5},
|
/* 781 */ { "SUSPEND", 7},
|
||||||
/* 782 */ { "SWITCHES", 8},
|
/* 782 */ { "SWAPS", 5},
|
||||||
/* 783 */ { "SYSDATE", 7},
|
/* 783 */ { "SWITCHES", 8},
|
||||||
/* 784 */ { "TABLES", 6},
|
/* 784 */ { "SYSDATE", 7},
|
||||||
/* 785 */ { "TABLESPACE", 10},
|
/* 785 */ { "TABLES", 6},
|
||||||
/* 786 */ { "TABLE_REF_PRIORITY", 18},
|
/* 786 */ { "TABLESPACE", 10},
|
||||||
/* 787 */ { "TABLE_STATISTICS", 16},
|
/* 787 */ { "TABLE_REF_PRIORITY", 18},
|
||||||
/* 788 */ { "TABLE", 5},
|
/* 788 */ { "TABLE_STATISTICS", 16},
|
||||||
/* 789 */ { "TABLE_CHECKSUM", 14},
|
/* 789 */ { "TABLE", 5},
|
||||||
/* 790 */ { "TABLE_NAME", 10},
|
/* 790 */ { "TABLE_CHECKSUM", 14},
|
||||||
/* 791 */ { "TEMPORARY", 9},
|
/* 791 */ { "TABLE_NAME", 10},
|
||||||
/* 792 */ { "TEMPTABLE", 9},
|
/* 792 */ { "TEMPORARY", 9},
|
||||||
/* 793 */ { "TERMINATED", 10},
|
/* 793 */ { "TEMPTABLE", 9},
|
||||||
/* 794 */ { "(text)", 6},
|
/* 794 */ { "TERMINATED", 10},
|
||||||
/* 795 */ { "TEXT", 4},
|
/* 795 */ { "(text)", 6},
|
||||||
/* 796 */ { "THAN", 4},
|
/* 796 */ { "TEXT", 4},
|
||||||
/* 797 */ { "THEN", 4},
|
/* 797 */ { "THAN", 4},
|
||||||
/* 798 */ { "TIMESTAMP", 9},
|
/* 798 */ { "THEN", 4},
|
||||||
/* 799 */ { "TIMESTAMPADD", 12},
|
/* 799 */ { "TIMESTAMP", 9},
|
||||||
/* 800 */ { "TIMESTAMPDIFF", 13},
|
/* 800 */ { "TIMESTAMPADD", 12},
|
||||||
/* 801 */ { "TIME", 4},
|
/* 801 */ { "TIMESTAMPDIFF", 13},
|
||||||
/* 802 */ { "TINYBLOB", 8},
|
/* 802 */ { "TIME", 4},
|
||||||
/* 803 */ { "TINYINT", 7},
|
/* 803 */ { "TINYBLOB", 8},
|
||||||
/* 804 */ { "TINYTEXT", 8},
|
/* 804 */ { "TINYINT", 7},
|
||||||
/* 805 */ { "TO", 2},
|
/* 805 */ { "TINYTEXT", 8},
|
||||||
/* 806 */ { "TRAILING", 8},
|
/* 806 */ { "TO", 2},
|
||||||
/* 807 */ { "TRANSACTION", 11},
|
/* 807 */ { "TRAILING", 8},
|
||||||
/* 808 */ { "TRANSACTIONAL", 13},
|
/* 808 */ { "TRANSACTION", 11},
|
||||||
/* 809 */ { "TRIGGERS", 8},
|
/* 809 */ { "TRANSACTIONAL", 13},
|
||||||
/* 810 */ { "TRIGGER", 7},
|
/* 810 */ { "TRIGGERS", 8},
|
||||||
/* 811 */ { "TRIM", 4},
|
/* 811 */ { "TRIGGER", 7},
|
||||||
/* 812 */ { "TRUE", 4},
|
/* 812 */ { "TRIM", 4},
|
||||||
/* 813 */ { "TRUNCATE", 8},
|
/* 813 */ { "TRUE", 4},
|
||||||
/* 814 */ { "TYPES", 5},
|
/* 814 */ { "TRUNCATE", 8},
|
||||||
/* 815 */ { "TYPE", 4},
|
/* 815 */ { "TYPES", 5},
|
||||||
/* 816 */ { "UDF_RETURNS", 11},
|
/* 816 */ { "TYPE", 4},
|
||||||
/* 817 */ { "(ulonglong)", 11},
|
/* 817 */ { "UDF_RETURNS", 11},
|
||||||
/* 818 */ { "UNCOMMITTED", 11},
|
/* 818 */ { "(ulonglong)", 11},
|
||||||
/* 819 */ { "UNDEFINED", 9},
|
/* 819 */ { "UNCOMMITTED", 11},
|
||||||
/* 820 */ { "(_charset)", 10},
|
/* 820 */ { "UNDEFINED", 9},
|
||||||
/* 821 */ { "UNDOFILE", 8},
|
/* 821 */ { "(_charset)", 10},
|
||||||
/* 822 */ { "UNDO_BUFFER_SIZE", 16},
|
/* 822 */ { "UNDOFILE", 8},
|
||||||
/* 823 */ { "UNDO", 4},
|
/* 823 */ { "UNDO_BUFFER_SIZE", 16},
|
||||||
/* 824 */ { "UNICODE", 7},
|
/* 824 */ { "UNDO", 4},
|
||||||
/* 825 */ { "UNINSTALL", 9},
|
/* 825 */ { "UNICODE", 7},
|
||||||
/* 826 */ { "UNION", 5},
|
/* 826 */ { "UNINSTALL", 9},
|
||||||
/* 827 */ { "UNIQUE", 6},
|
/* 827 */ { "UNION", 5},
|
||||||
/* 828 */ { "UNKNOWN", 7},
|
/* 828 */ { "UNIQUE", 6},
|
||||||
/* 829 */ { "UNLOCK", 6},
|
/* 829 */ { "UNKNOWN", 7},
|
||||||
/* 830 */ { "UNSIGNED", 8},
|
/* 830 */ { "UNLOCK", 6},
|
||||||
/* 831 */ { "UNTIL", 5},
|
/* 831 */ { "UNSIGNED", 8},
|
||||||
/* 832 */ { "UPDATE", 6},
|
/* 832 */ { "UNTIL", 5},
|
||||||
/* 833 */ { "UPGRADE", 7},
|
/* 833 */ { "UPDATE", 6},
|
||||||
/* 834 */ { "USAGE", 5},
|
/* 834 */ { "UPGRADE", 7},
|
||||||
/* 835 */ { "SYSTEM_USER", 11},
|
/* 835 */ { "USAGE", 5},
|
||||||
/* 836 */ { "USER_STATISTICS", 15},
|
/* 836 */ { "SYSTEM_USER", 11},
|
||||||
/* 837 */ { "USE_FRM", 7},
|
/* 837 */ { "USER_STATISTICS", 15},
|
||||||
/* 838 */ { "USE", 3},
|
/* 838 */ { "USE_FRM", 7},
|
||||||
/* 839 */ { "USING", 5},
|
/* 839 */ { "USE", 3},
|
||||||
/* 840 */ { "UTC_DATE", 8},
|
/* 840 */ { "USING", 5},
|
||||||
/* 841 */ { "UTC_TIMESTAMP", 13},
|
/* 841 */ { "UTC_DATE", 8},
|
||||||
/* 842 */ { "UTC_TIME", 8},
|
/* 842 */ { "UTC_TIMESTAMP", 13},
|
||||||
/* 843 */ { "VALUES", 6},
|
/* 843 */ { "UTC_TIME", 8},
|
||||||
/* 844 */ { "VALUE", 5},
|
/* 844 */ { "VALUES", 6},
|
||||||
/* 845 */ { "VARBINARY", 9},
|
/* 845 */ { "VALUE", 5},
|
||||||
/* 846 */ { "VARCHARACTER", 12},
|
/* 846 */ { "VARBINARY", 9},
|
||||||
/* 847 */ { "VARIABLES", 9},
|
/* 847 */ { "VARCHARACTER", 12},
|
||||||
/* 848 */ { "VAR_POP", 7},
|
/* 848 */ { "VARIABLES", 9},
|
||||||
/* 849 */ { "VARYING", 7},
|
/* 849 */ { "VAR_POP", 7},
|
||||||
/* 850 */ { "VAR_SAMP", 8},
|
/* 850 */ { "VARYING", 7},
|
||||||
/* 851 */ { "VIA", 3},
|
/* 851 */ { "VAR_SAMP", 8},
|
||||||
/* 852 */ { "VIEW", 4},
|
/* 852 */ { "VIA", 3},
|
||||||
/* 853 */ { "VIRTUAL", 7},
|
/* 853 */ { "VIEW", 4},
|
||||||
/* 854 */ { "WAIT", 4},
|
/* 854 */ { "VIRTUAL", 7},
|
||||||
/* 855 */ { "WARNINGS", 8},
|
/* 855 */ { "WAIT", 4},
|
||||||
/* 856 */ { "WEEK", 4},
|
/* 856 */ { "WARNINGS", 8},
|
||||||
/* 857 */ { "WHEN", 4},
|
/* 857 */ { "WEEK", 4},
|
||||||
/* 858 */ { "WHERE", 5},
|
/* 858 */ { "WHEN", 4},
|
||||||
/* 859 */ { "WHILE", 5},
|
/* 859 */ { "WHERE", 5},
|
||||||
/* 860 */ { "WITH", 4},
|
/* 860 */ { "WHILE", 5},
|
||||||
/* 861 */ { "WITH CUBE", 9},
|
/* 861 */ { "WITH", 4},
|
||||||
/* 862 */ { "WITH ROLLUP", 11},
|
/* 862 */ { "WITH CUBE", 9},
|
||||||
/* 863 */ { "WORK", 4},
|
/* 863 */ { "WITH ROLLUP", 11},
|
||||||
/* 864 */ { "WRAPPER", 7},
|
/* 864 */ { "WORK", 4},
|
||||||
/* 865 */ { "WRITE", 5},
|
/* 865 */ { "WRAPPER", 7},
|
||||||
/* 866 */ { "X509", 4},
|
/* 866 */ { "WRITE", 5},
|
||||||
/* 867 */ { "XA", 2},
|
/* 867 */ { "X509", 4},
|
||||||
/* 868 */ { "XML", 3},
|
/* 868 */ { "XA", 2},
|
||||||
/* 869 */ { "XOR", 3},
|
/* 869 */ { "XML", 3},
|
||||||
/* 870 */ { "YEAR_MONTH", 10},
|
/* 870 */ { "XOR", 3},
|
||||||
/* 871 */ { "YEAR", 4},
|
/* 871 */ { "YEAR_MONTH", 10},
|
||||||
/* 872 */ { "ZEROFILL", 8},
|
/* 872 */ { "YEAR", 4},
|
||||||
/* 873 */ { "?", 1},
|
/* 873 */ { "ZEROFILL", 8},
|
||||||
/* 874 */ { "?, ...", 6},
|
/* 874 */ { "?", 1},
|
||||||
/* 875 */ { "(?)", 3},
|
/* 875 */ { "?, ...", 6},
|
||||||
/* 876 */ { "(?) /* , ... */", 15},
|
/* 876 */ { "(?)", 3},
|
||||||
/* 877 */ { "(...)", 5},
|
/* 877 */ { "(?) /* , ... */", 15},
|
||||||
/* 878 */ { "(...) /* , ... */", 17},
|
/* 878 */ { "(...)", 5},
|
||||||
/* 879 */ { "UNUSED", 6},
|
/* 879 */ { "(...) /* , ... */", 17},
|
||||||
|
/* 880 */ { "UNUSED", 6},
|
||||||
/* DUMMY */ { "", 0}
|
/* DUMMY */ { "", 0}
|
||||||
};
|
};
|
||||||
/* PFS specific tokens. */
|
/* PFS specific tokens. */
|
||||||
#define TOK_PFS_GENERIC_VALUE 873
|
#define TOK_PFS_GENERIC_VALUE 874
|
||||||
#define TOK_PFS_GENERIC_VALUE_LIST 874
|
#define TOK_PFS_GENERIC_VALUE_LIST 875
|
||||||
#define TOK_PFS_ROW_SINGLE_VALUE 875
|
#define TOK_PFS_ROW_SINGLE_VALUE 876
|
||||||
#define TOK_PFS_ROW_SINGLE_VALUE_LIST 876
|
#define TOK_PFS_ROW_SINGLE_VALUE_LIST 877
|
||||||
#define TOK_PFS_ROW_MULTIPLE_VALUE 877
|
#define TOK_PFS_ROW_MULTIPLE_VALUE 878
|
||||||
#define TOK_PFS_ROW_MULTIPLE_VALUE_LIST 878
|
#define TOK_PFS_ROW_MULTIPLE_VALUE_LIST 879
|
||||||
#define TOK_PFS_UNUSED 879
|
#define TOK_PFS_UNUSED 880
|
||||||
|
Reference in New Issue
Block a user