diff options
author | Dmitry Shulga <dmitry.shulga@mariadb.com> | 2021-04-22 14:52:19 +0700 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2021-06-17 19:30:24 +0200 |
commit | 9370c6e83c148b4a5d4f08de7778e6a02da6adcb (patch) | |
tree | 6ac6bc49f94378351383cd7bf3b3462f52de613e /mysql-test | |
parent | f778a5d5e2aaff7c58000f9e2423a809db14747c (diff) | |
download | mariadb-git-9370c6e83c148b4a5d4f08de7778e6a02da6adcb.tar.gz |
MDEV-16708: Unsupported commands for prepared statements
Withing this task the following changes were made:
- Added sending of metadata info in prepare phase for the admin related
command (check table, checksum table, repair, optimize, analyze).
- Refactored implmentation of HELP command to support its execution in
PS mode
- Added support for execution of LOAD INTO and XA- related statements
in PS mode
- Modified mysqltest.cc to run statements in PS mode unconditionally
in case the option --ps-protocol is set. Formerly, only those statements
were executed using PS protocol that matched the hard-coded regular expression
- Fixed the following issues:
The statement
explain select (select 2)
executed in regular and PS mode produces different results:
MariaDB [test]> prepare stmt from "explain select (select 2)";
Query OK, 0 rows affected (0,000 sec)
Statement prepared
MariaDB [test]> execute stmt;
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
| 1 | PRIMARY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
| 2 | SUBQUERY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
2 rows in set (0,000 sec)
MariaDB [test]> explain select (select 2);
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set, 1 warning (0,000 sec)
In case the statement
CREATE TABLE t1 SELECT * FROM (SELECT 1 AS a, (SELECT a+0)) a
is run in PS mode it fails with the error
ERROR 1054 (42S22): Unknown column 'a' in 'field list'.
- Uniform handling of read-only variables both in case the SET var=val
statement is executed as regular or prepared statememt.
- Fixed assertion firing on handling LOAD DATA statement for temporary tables
- Relaxed assert condition in the function lex_end_stage1() by adding
the commands SQLCOM_ALTER_EVENT, SQLCOM_CREATE_PACKAGE,
SQLCOM_CREATE_PACKAGE_BODY to a list of supported command
- Removed raising of the error ER_UNSUPPORTED_PS in the function
check_prepared_statement() for the ALTER VIEW command
- Added initialization of the data memember st_select_lex_unit::last_procedure
(assign NULL value) in the constructor
Without this change the test case main.ctype_utf8 fails with the following
report in case it is run with the optoin --ps-protocol.
mysqltest: At line 2278: query 'VALUES (_latin1 0xDF) UNION VALUES(_utf8'a' COLLATE utf8_bin)' failed: 2013: Lost connection
- The following bug reports were fixed:
MDEV-24460: Multiple rows result set returned from stored
routine over prepared statement binary protocol is
handled incorrectly
CONC-519: mariadb client library doesn't handle server_status and
warnign_count fields received in the packet
COM_STMT_EXECUTE_RESPONSE.
Reasons for these bug reports have the same nature and caused by
missing loop iteration on results sent by server in response to
COM_STMT_EXECUTE packet.
Enclosing of statements for processing of COM_STMT_EXECUTE response
in the construct like
do
{
...
} while (!mysql_stmt_next_result());
fixes the above mentioned bug reports.
Diffstat (limited to 'mysql-test')
-rw-r--r-- | mysql-test/main/func_time.test | 4 | ||||
-rw-r--r-- | mysql-test/main/get_diagnostics.result | 4 | ||||
-rw-r--r-- | mysql-test/main/get_diagnostics.test | 4 | ||||
-rw-r--r-- | mysql-test/main/ps.result | 24 | ||||
-rw-r--r-- | mysql-test/main/ps.test | 31 | ||||
-rw-r--r-- | mysql-test/main/ps_1general.result | 9 | ||||
-rw-r--r-- | mysql-test/main/ps_1general.test | 10 | ||||
-rw-r--r-- | mysql-test/main/ps_ddl.result | 2 | ||||
-rw-r--r-- | mysql-test/main/ps_ddl.test | 2 | ||||
-rw-r--r-- | mysql-test/main/ps_missed_cmds.result | 910 | ||||
-rw-r--r-- | mysql-test/main/ps_missed_cmds.test | 758 | ||||
-rw-r--r-- | mysql-test/main/ps_missed_cmds_bin_prot.result | 264 | ||||
-rw-r--r-- | mysql-test/main/ps_missed_cmds_bin_prot.test | 298 | ||||
-rw-r--r-- | mysql-test/main/query_cache.result | 8 | ||||
-rw-r--r-- | mysql-test/main/query_cache.test | 8 | ||||
-rw-r--r-- | mysql-test/main/signal.result | 2 | ||||
-rw-r--r-- | mysql-test/main/signal.test | 3 | ||||
-rw-r--r-- | mysql-test/main/sp-dynamic.result | 16 | ||||
-rw-r--r-- | mysql-test/main/sp-dynamic.test | 6 | ||||
-rw-r--r-- | mysql-test/main/sp-security.result | 1 | ||||
-rw-r--r-- | mysql-test/main/sp-security.test | 1 |
21 files changed, 2275 insertions, 90 deletions
diff --git a/mysql-test/main/func_time.test b/mysql-test/main/func_time.test index 970d3e44a77..ccec4d18ea3 100644 --- a/mysql-test/main/func_time.test +++ b/mysql-test/main/func_time.test @@ -621,8 +621,10 @@ SET GLOBAL log_bin_trust_function_creators = 1; create table t1 (a timestamp default '2005-05-05 01:01:01', b timestamp default '2005-05-05 01:01:01'); -delimiter //; +--disable_warnings drop function if exists t_slow_sysdate; +--enable_warnings +delimiter //; create function t_slow_sysdate() returns timestamp begin do sleep(2); diff --git a/mysql-test/main/get_diagnostics.result b/mysql-test/main/get_diagnostics.result index bcecce95a00..fbd25dc603c 100644 --- a/mysql-test/main/get_diagnostics.result +++ b/mysql-test/main/get_diagnostics.result @@ -258,12 +258,10 @@ DROP PROCEDURE p1; # Test GET DIAGNOSTICS runtime # -# GET DIAGNOSTICS cannot be the object of a PREPARE statement. +# GET DIAGNOSTICS can be the object of a PREPARE statement. PREPARE stmt FROM "GET DIAGNOSTICS CONDITION 1 @var = CLASS_ORIGIN"; -ERROR HY000: This command is not supported in the prepared statement protocol yet PREPARE stmt FROM "GET DIAGNOSTICS @var = NUMBER"; -ERROR HY000: This command is not supported in the prepared statement protocol yet # GET DIAGNOSTICS does not clear the diagnostics area. diff --git a/mysql-test/main/get_diagnostics.test b/mysql-test/main/get_diagnostics.test index 4667ec727dd..d9faf184a62 100644 --- a/mysql-test/main/get_diagnostics.test +++ b/mysql-test/main/get_diagnostics.test @@ -331,12 +331,10 @@ DROP PROCEDURE p1; --echo # --echo ---echo # GET DIAGNOSTICS cannot be the object of a PREPARE statement. +--echo # GET DIAGNOSTICS can be the object of a PREPARE statement. --echo ---error ER_UNSUPPORTED_PS PREPARE stmt FROM "GET DIAGNOSTICS CONDITION 1 @var = CLASS_ORIGIN"; ---error ER_UNSUPPORTED_PS PREPARE stmt FROM "GET DIAGNOSTICS @var = NUMBER"; --echo diff --git a/mysql-test/main/ps.result b/mysql-test/main/ps.result index c1334b0b9a7..70ea6870368 100644 --- a/mysql-test/main/ps.result +++ b/mysql-test/main/ps.result @@ -28,11 +28,9 @@ ERROR HY000: Unknown prepared statement handler (no_such_statement) given to DEA execute stmt1; ERROR HY000: Incorrect arguments to EXECUTE prepare stmt2 from 'prepare nested_stmt from "select 1"'; -ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt2 from 'execute stmt1'; -ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt2 from 'deallocate prepare z'; -ERROR HY000: This command is not supported in the prepared statement protocol yet +deallocate prepare stmt2; prepare stmt3 from 'insert into t1 values (?,?)'; set @arg1=5, @arg2='five'; execute stmt3 using @arg1, @arg2; @@ -2726,9 +2724,7 @@ ERROR 42000: FUNCTION test.func_1 does not exist drop function func_1; ERROR 42000: FUNCTION test.func_1 does not exist prepare abc from "create event xyz on schedule at now() do select 123"; -ERROR HY000: This command is not supported in the prepared statement protocol yet deallocate prepare abc; -ERROR HY000: Unknown prepared statement handler (abc) given to DEALLOCATE PREPARE drop event if exists xyz; create event xyz on schedule every 5 minute disable do select 123; create procedure proc_1() alter event xyz comment 'xyz'; @@ -2748,9 +2744,7 @@ drop procedure proc_1; create function func_1() returns int begin alter event xyz comment 'xyz'; return 1; end| ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger prepare abc from "alter event xyz comment 'xyz'"; -ERROR HY000: This command is not supported in the prepared statement protocol yet deallocate prepare abc; -ERROR HY000: Unknown prepared statement handler (abc) given to DEALLOCATE PREPARE drop event if exists xyz; create event xyz on schedule every 5 minute disable do select 123; create procedure proc_1() drop event xyz; @@ -2765,9 +2759,7 @@ drop procedure proc_1; create function func_1() returns int begin drop event xyz; return 1; end| ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger prepare abc from "drop event xyz"; -ERROR HY000: This command is not supported in the prepared statement protocol yet deallocate prepare abc; -ERROR HY000: Unknown prepared statement handler (abc) given to DEALLOCATE PREPARE drop table if exists t1; create table t1 (a int, b char(5)) engine=myisam; insert into t1 values (1, "one"), (2, "two"), (3, "three"); @@ -3087,15 +3079,15 @@ DROP TABLE t1; CREATE TABLE t1(f1 INT); INSERT INTO t1 VALUES (1),(1); PREPARE stmt FROM 'EXPLAIN SELECT 1 FROM t1 WHERE (SELECT (SELECT 1 FROM t1 GROUP BY f1))'; +Warnings: +Note 1249 Select 2 was reduced during optimization EXECUTE stmt; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used 3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort EXECUTE stmt; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used 3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort DEALLOCATE PREPARE stmt; DROP TABLE t1; @@ -4727,13 +4719,13 @@ ERROR HY000: Incorrect arguments to EXECUTE EXECUTE IMMEDIATE 'SELECT ?'; ERROR HY000: Incorrect arguments to EXECUTE EXECUTE IMMEDIATE 'EXECUTE IMMEDIATE "SELECT 1"'; -ERROR HY000: This command is not supported in the prepared statement protocol yet +1 +1 EXECUTE IMMEDIATE 'PREPARE stmt FROM "SELECT 1"'; -ERROR HY000: This command is not supported in the prepared statement protocol yet EXECUTE IMMEDIATE 'EXECUTE stmt'; -ERROR HY000: This command is not supported in the prepared statement protocol yet +1 +1 EXECUTE IMMEDIATE 'DEALLOCATE PREPARE stmt'; -ERROR HY000: This command is not supported in the prepared statement protocol yet EXECUTE IMMEDIATE 'SELECT ?' USING _latin1'a'=_latin2'a'; ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation '=' EXECUTE IMMEDIATE 'SELECT ?' USING ROW(1,2); @@ -4944,7 +4936,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp PREPARE stmt FROM CONCAT(NULL); 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 'NULL' at line 1 EXECUTE IMMEDIATE ? USING 'SELECT 1'; -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 '? USING 'SELECT 1'' at line 1 +Got one of the listed errors EXECUTE IMMEDIATE 10; 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 '10' at line 1 EXECUTE IMMEDIATE TIME'10:20:30'; diff --git a/mysql-test/main/ps.test b/mysql-test/main/ps.test index 837fa6f2b6e..5933aea4a03 100644 --- a/mysql-test/main/ps.test +++ b/mysql-test/main/ps.test @@ -37,15 +37,11 @@ deallocate prepare no_such_statement; --error 1210 execute stmt1; -# Nesting ps commands is not allowed: ---error ER_UNSUPPORTED_PS +# Nesting ps commands is now allowed: prepare stmt2 from 'prepare nested_stmt from "select 1"'; - ---error ER_UNSUPPORTED_PS prepare stmt2 from 'execute stmt1'; - ---error ER_UNSUPPORTED_PS prepare stmt2 from 'deallocate prepare z'; +deallocate prepare stmt2; # PS insert prepare stmt3 from 'insert into t1 values (?,?)'; @@ -2763,12 +2759,11 @@ delimiter ;| select func_1(), func_1(), func_1() from dual; --error ER_SP_DOES_NOT_EXIST drop function func_1; ---error ER_UNSUPPORTED_PS + +# CREATE EVENT is now supported by prepared statements prepare abc from "create event xyz on schedule at now() do select 123"; ---error ER_UNKNOWN_STMT_HANDLER deallocate prepare abc; - --disable_warnings drop event if exists xyz; create event xyz on schedule every 5 minute disable do select 123; @@ -2787,9 +2782,9 @@ delimiter |; --error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin alter event xyz comment 'xyz'; return 1; end| delimiter ;| ---error ER_UNSUPPORTED_PS + +# ALTER EVENT is now supported by prepared statements prepare abc from "alter event xyz comment 'xyz'"; ---error ER_UNKNOWN_STMT_HANDLER deallocate prepare abc; @@ -2808,9 +2803,8 @@ delimiter |; --error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin drop event xyz; return 1; end| delimiter ;| ---error ER_UNSUPPORTED_PS +# DROP EVENT is now supported by prepared statements prepare abc from "drop event xyz"; ---error ER_UNKNOWN_STMT_HANDLER deallocate prepare abc; @@ -4199,16 +4193,12 @@ EXECUTE IMMEDIATE 'SELECT 1' USING @a; --error ER_WRONG_ARGUMENTS EXECUTE IMMEDIATE 'SELECT ?'; ---error ER_UNSUPPORTED_PS EXECUTE IMMEDIATE 'EXECUTE IMMEDIATE "SELECT 1"'; ---error ER_UNSUPPORTED_PS EXECUTE IMMEDIATE 'PREPARE stmt FROM "SELECT 1"'; ---error ER_UNSUPPORTED_PS EXECUTE IMMEDIATE 'EXECUTE stmt'; ---error ER_UNSUPPORTED_PS EXECUTE IMMEDIATE 'DEALLOCATE PREPARE stmt'; --error ER_CANT_AGGREGATE_2COLLATIONS @@ -4414,7 +4404,12 @@ EXECUTE IMMEDIATE CONCAT(NULL); --error ER_PARSE_ERROR PREPARE stmt FROM CONCAT(NULL); ---error ER_PARSE_ERROR +# Expects any of the following errors CR_PARAMS_NOT_BOUND, ER_PARSE_ERROR. +# ER_PARSE_ERROR is generated in case the EXECUTE IMMEDIATE statement +# is sent as a regular statement via text protocol. The error +# CR_PARAMS_NOT_BOUND is generated by the MySQL API function mysql_stmt_execute +# when this test file is run with the option --ps-protocol +--error 2031,ER_PARSE_ERROR EXECUTE IMMEDIATE ? USING 'SELECT 1'; --error ER_PARSE_ERROR diff --git a/mysql-test/main/ps_1general.result b/mysql-test/main/ps_1general.result index 149c297621b..c42b3d07bbc 100644 --- a/mysql-test/main/ps_1general.result +++ b/mysql-test/main/ps_1general.result @@ -381,15 +381,10 @@ drop table t5 ; deallocate prepare stmt_do ; deallocate prepare stmt_set ; prepare stmt1 from ' prepare stmt2 from '' select 1 '' ' ; -ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt1 from ' execute stmt2 ' ; -ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt1 from ' deallocate prepare never_prepared ' ; -ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt1 from 'alter view v1 as select 2'; -ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt4 from ' use test ' ; -ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt3 from ' create database mysqltest '; create database mysqltest ; prepare stmt3 from ' drop database mysqltest '; @@ -403,12 +398,9 @@ drop table t2 ; execute stmt3; ERROR 42S02: Table 'test.t2' doesn't exist prepare stmt3 from ' lock tables t1 read ' ; -ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt3 from ' unlock tables ' ; -ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt1 from ' load data infile ''<MYSQLTEST_VARDIR>/tmp/data.txt'' into table t1 fields terminated by ''\t'' '; -ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt1 from ' select * into outfile ''<MYSQLTEST_VARDIR>/tmp/data.txt'' from t1 '; execute stmt1 ; prepare stmt1 from ' optimize table t1 ' ; @@ -416,7 +408,6 @@ prepare stmt1 from ' analyze table t1 ' ; prepare stmt1 from ' checksum table t1 ' ; prepare stmt1 from ' repair table t1 ' ; prepare stmt1 from ' handler t1 open '; -ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt3 from ' commit ' ; prepare stmt3 from ' rollback ' ; prepare stmt4 from ' SET sql_mode=ansi '; diff --git a/mysql-test/main/ps_1general.test b/mysql-test/main/ps_1general.test index 47db79cb6c6..f98c05a69fb 100644 --- a/mysql-test/main/ps_1general.test +++ b/mysql-test/main/ps_1general.test @@ -406,19 +406,13 @@ deallocate prepare stmt_do ; deallocate prepare stmt_set ; ## nonsense like prepare of prepare,execute or deallocate ---error ER_UNSUPPORTED_PS prepare stmt1 from ' prepare stmt2 from '' select 1 '' ' ; ---error ER_UNSUPPORTED_PS prepare stmt1 from ' execute stmt2 ' ; ---error ER_UNSUPPORTED_PS prepare stmt1 from ' deallocate prepare never_prepared ' ; -## We don't support alter view as prepared statements ---error ER_UNSUPPORTED_PS prepare stmt1 from 'alter view v1 as select 2'; ## switch the database connection ---error ER_UNSUPPORTED_PS prepare stmt4 from ' use test ' ; ## create/drop database @@ -435,9 +429,7 @@ drop table t2 ; --error ER_NO_SUCH_TABLE execute stmt3; ## lock/unlock ---error ER_UNSUPPORTED_PS prepare stmt3 from ' lock tables t1 read ' ; ---error ER_UNSUPPORTED_PS prepare stmt3 from ' unlock tables ' ; ## Load/Unload table contents @@ -446,7 +438,6 @@ prepare stmt3 from ' unlock tables ' ; --remove_file $datafile --replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> ---error ER_UNSUPPORTED_PS eval prepare stmt1 from ' load data infile ''$datafile'' into table t1 fields terminated by ''\t'' '; --replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR> @@ -461,7 +452,6 @@ prepare stmt1 from ' repair table t1 ' ; --remove_file $datafile ## handler ---error ER_UNSUPPORTED_PS prepare stmt1 from ' handler t1 open '; diff --git a/mysql-test/main/ps_ddl.result b/mysql-test/main/ps_ddl.result index 86a294b732d..d99aeb0fa54 100644 --- a/mysql-test/main/ps_ddl.result +++ b/mysql-test/main/ps_ddl.result @@ -2244,7 +2244,6 @@ SUCCESS drop table if exists t1; create table t1 (a varchar(20)); prepare stmt from "load data infile '../std_data_ln/words.dat' into table t1"; -ERROR HY000: This command is not supported in the prepared statement protocol yet drop table t1; # # SQLCOM_SHOW_DATABASES @@ -2516,7 +2515,6 @@ SUCCESS drop view if exists v1; create view v1 as select 1; prepare stmt from "alter view v1 as select 2"; -ERROR HY000: This command is not supported in the prepared statement protocol yet drop view v1; # Cleanup # diff --git a/mysql-test/main/ps_ddl.test b/mysql-test/main/ps_ddl.test index 694ee61fd0c..5a2a0f60a70 100644 --- a/mysql-test/main/ps_ddl.test +++ b/mysql-test/main/ps_ddl.test @@ -1880,7 +1880,6 @@ call p_verify_reprepare_count(8); drop table if exists t1; --enable_warnings create table t1 (a varchar(20)); ---error ER_UNSUPPORTED_PS prepare stmt from "load data infile '../std_data_ln/words.dat' into table t1"; drop table t1; @@ -2202,7 +2201,6 @@ call p_verify_reprepare_count(17); drop view if exists v1; --enable_warnings create view v1 as select 1; ---error ER_UNSUPPORTED_PS prepare stmt from "alter view v1 as select 2"; drop view v1; diff --git a/mysql-test/main/ps_missed_cmds.result b/mysql-test/main/ps_missed_cmds.result new file mode 100644 index 00000000000..f16cae445fb --- /dev/null +++ b/mysql-test/main/ps_missed_cmds.result @@ -0,0 +1,910 @@ +SET @save_storage_engine= @@default_storage_engine; +SET default_storage_engine= InnoDB; +# +# MDEV-16708: Unsupported commands for prepared statements +# +# Disable ps-protocol explicitly in order to test support of +# prepared statements for use case when statements passed +# to the server via text client-server protocol (in contrast +# with binary protocol used in the test file +# ps_missed_cmds_bin_prot.test) +# Test case 1: Check that the statement 'LOAD DATA' is supported +# by prepared statements +# First, set up environment for use by the 'LOAD DATA' statement +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +COMMIT; +SELECT * INTO OUTFILE 'load.data' FROM t1; +PREPARE stmt_1 FROM "LOAD DATA INFILE 'load.data' INTO TABLE t1"; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'LOAD DATA' statement +# were damaged. +EXECUTE stmt_1; +SELECT * FROM t1; +a +1 +1 +1 +# Clean up +DEALLOCATE PREPARE stmt_1; +DROP TABLE t1; +# Test case 2: Check that the 'LOCK TABLE', 'UNLOCK TABLES' statements +# are supported by prepared statements +CREATE TABLE t1 (a INT); +PREPARE stmt_1 FROM "LOCK TABLE t1 READ"; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'LOCK TABLE READ' +# statement were damaged. +EXECUTE stmt_1; +PREPARE stmt_1 FROM "UNLOCK TABLE"; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'UNLOCK TABLE' statement +# were damaged. +EXECUTE stmt_1; +PREPARE stmt_1 FROM "LOCK TABLE t1 WRITE"; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'LOCK TABLE WRITE' +# statement were damaged. +EXECUTE stmt_1; +# Clean up +DEALLOCATE PREPARE stmt_1; +UNLOCK TABLE; +DROP TABLE t1; +# Test case 3: Check that the 'USE' statement is supported by +# prepared statements +CREATE DATABASE mdev_16708_db; +PREPARE stmt_1 FROM 'USE mdev_16708_db'; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'USE' statement +# were damaged. +EXECUTE stmt_1; +# Check that the current database has been changed +SELECT DATABASE(); +DATABASE() +mdev_16708_db +# Clean up +DEALLOCATE PREPARE stmt_1; +USE test; +DROP DATABASE mdev_16708_db; +# Test case 4: Check that the 'ALTER DATABASE' statement is supported +# by prepared statements +CREATE DATABASE mdev_16708_db; +PREPARE stmt_1 FROM "ALTER DATABASE mdev_16708_db COMMENT 'New comment'"; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'ALTER DATABASE' statement +# were damaged. +EXECUTE stmt_1; +# Clean up +DEALLOCATE PREPARE stmt_1; +USE test; +DROP DATABASE mdev_16708_db; +# Test case 5: Check that the 'CREATE FUNCTION/ALTER FUNCTION/ +# DROP FUNCTION' statements are supported by prepared statements +PREPARE stmt_1 FROM 'CREATE FUNCTION f1() RETURNS INT RETURN 1'; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'CREATE FUNCTION' +# statement were damaged. The second attempt to execute the prepared +# statement stmt_1 results in error ER_SP_ALREADY_EXISTS since +# the stored function f() has been created on first run of stmt1. +EXECUTE stmt_1; +ERROR 42000: FUNCTION f1 already exists +PREPARE stmt_1 FROM 'ALTER FUNCTION f1 SQL SECURITY INVOKER'; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'ALTER FUNCTION' +# statement were damaged. +EXECUTE stmt_1; +PREPARE stmt_1 FROM 'DROP FUNCTION f1'; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling 'DROP FUNCTION' statement +# were damaged. The second attempt to run 'DROP FUNCTION f1' using +# prepared statement expectedly results in issuing the error +# ER_SP_DOES_NOT_EXIST since the stored function was dropped on first +# executuon of the prepared statement stmt_1. +EXECUTE stmt_1; +ERROR 42000: FUNCTION test.f1 does not exist +# Test case 6: Check that the 'CHECK TABLE' statement is supported +# by prepared statements +CREATE TABLE t1 (a INT); +PREPARE stmt_1 FROM 'CHECK TABLE t1'; +EXECUTE stmt_1; +Table Op Msg_type Msg_text +test.t1 check status OK +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'CHECK TABLE' statement +# were damaged. +EXECUTE stmt_1; +Table Op Msg_type Msg_text +test.t1 check status OK +# Clean up +DEALLOCATE PREPARE stmt_1; +DROP TABLE t1; +# Test case 7: Check that the BEGIN/SAVEPOINT/RELEASE SAVEPOINT +# statements are supported by prepared statements +# Set up environmentr for the test case +CREATE TABLE t1 (a INT); +PREPARE stmt_1 FROM 'BEGIN'; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'BEGIN' statement +# were damaged. +EXECUTE stmt_1; +INSERT INTO t1 VALUES (1); +# Run 'SAVEPOINT s1' using prepared statements +PREPARE stmt_2 FROM 'SAVEPOINT s1'; +EXECUTE stmt_2; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'SAVEPOINT' statement +# were damaged. +EXECUTE stmt_2; +INSERT INTO t1 VALUES (2); +# Expected rows: '1' and '2' +SELECT * FROM t1; +a +1 +2 +# Rollback the last row inserted ('2') +ROLLBACK TO SAVEPOINT s1; +# Expected output from t1 after transaction has been rolled back +# to the savepoint is '1'. If it is case then the statement SAVEPOINT +# was handled successfully with prepared statement +SELECT * FROM t1; +a +1 +PREPARE stmt_3 FROM 'RELEASE SAVEPOINT s1'; +EXECUTE stmt_3; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'RELEASE' statement +# were damaged. The second attempt to release the same savepoint +# expectedly lead to error 'SAVEPOINT s1 does not exist' +# that's just ignored. +EXECUTE stmt_3; +ERROR 42000: SAVEPOINT s1 does not exist +# Clean up +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; +DEALLOCATE PREPARE stmt_3; +DROP TABLE t1; +# Test case 8: Check that the 'PURGE BINARY LOGS BEFORE' statement +# is supported by prepared statements +PREPARE stmt_1 FROM "PURGE BINARY LOGS BEFORE '2020-11-17'"; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'PURGE BINARY LOGS BEFORE' +# statement were damaged. +EXECUTE stmt_1; +# Check that the 'PURGE BINARY LOGS TO' statement is supported by +# prepared statements +PREPARE stmt_1 FROM "PURGE BINARY LOGS TO 'mariadb-bin.000063'"; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'PURGE BINARY LOGS TO' +# statement were damaged. +EXECUTE stmt_1; +# Test case 9: Check that the 'HANDLER OPEN/HANDLER READ/ +# HANDLER CLOSE' statements are supported by prepared statements +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (1); +COMMIT; +PREPARE stmt_1 FROM 'HANDLER t1 OPEN'; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'HANDLER OPEN' +# statement were damaged. Execution of this statement the second +# time expectedly results in emitting the error ER_NONUNIQ_TABLE. +# The same error is issued in case the statement 'HANDLER t1 OPEN' is +# executed twice using a regular statement. +EXECUTE stmt_1; +ERROR 42000: Not unique table/alias: 't1' +PREPARE stmt_2 FROM 'HANDLER t1 READ FIRST'; +PREPARE stmt_3 FROM 'HANDLER t1 READ NEXT'; +PREPARE stmt_4 FROM 'HANDLER t1 CLOSE'; +EXECUTE stmt_2; +a +1 +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'HANDLER READ FIRST' +# statement were damaged. +EXECUTE stmt_2; +a +1 +EXECUTE stmt_3; +a +1 +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'HANDLER READ NEXT' +# statement were damaged. +EXECUTE stmt_3; +a +EXECUTE stmt_4; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'HANDLER CLOSE' +# statement were damaged. Execution of this statement the second +# time results in emitting the error ER_UNKNOWN_TABLE. The same error +# is issued in case the statement 'HANDLER t1 CLOSE' executed twice +# using a regular statement. +EXECUTE stmt_4; +ERROR 42S02: Unknown table 't1' in HANDLER +# Clean up +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; +DEALLOCATE PREPARE stmt_3; +DEALLOCATE PREPARE stmt_4; +DROP TABLE t1; +# Test case 10: Check that the HELP statement +# is supported by prepared statements +PREPARE stmt_1 FROM "HELP `UPDATE`"; +EXECUTE stmt_1; +name description example +UPDATE Syntax +------ +Single-table syntax: + +UPDATE [LOW_PRIORITY] [IGNORE] table_reference + [PARTITION (partition_list)] + SET col1={expr1|DEFAULT} [,col2={expr2|DEFAULT}] ... + [WHERE where_condition] + [ORDER BY ...] + [LIMIT row_count] + +Multiple-table syntax: + +UPDATE [LOW_PRIORITY] [IGNORE] table_references + SET col1={expr1|DEFAULT} [, col2={expr2|DEFAULT}] ... + [WHERE where_condition] + +Description +----------- +For the single-table syntax, the UPDATE statement updates +columns of existing rows in the named table with new values. +The +SET clause indicates which columns to modify and the values +they should be given. Each value can be given as an +expression, or the keyword +DEFAULT to set a column explicitly to its default value. The +WHERE clause, if given, specifies the conditions that +identify +which rows to update. With no WHERE clause, all rows are +updated. If the ORDER BY clause is specified, the rows are +updated in the order that is specified. The LIMIT clause +places a limit on the number of rows that can be updated. + +The PARTITION clause was introduced in MariaDB 10.0. See +Partition Pruning and Selection for details. + +Until MariaDB 10.3.2, for the multiple-table syntax, UPDATE +updates rows in each +table named in table_references that satisfy the conditions. +In this case, +ORDER BY and LIMIT cannot be used. This restriction was +lifted in MariaDB 10.3.2 and both clauses can be used with +multiple-table updates. An UPDATE can also reference tables +which are located in different databases; see Identifier +Qualifiers for the syntax. + +where_condition is an expression that evaluates to true for +each row to be updated. + +table_references and where_condition are as +specified as described in SELECT. + +Assignments are evaluated in left-to-right order, unless the +SIMULTANEOUS_ASSIGNMENT sql_mode (available from MariaDB +10.3.5) is set, in which case the UPDATE statement evaluates +all assignments simultaneously. + +You need the UPDATE privilege only for columns referenced in +an UPDATE that are actually updated. You need only the +SELECT privilege for any columns that are read but +not modified. See GRANT. + +The UPDATE statement supports the following modifiers: +If you use the LOW_PRIORITY keyword, execution of + the UPDATE is delayed until no other clients are reading +from + the table. This affects only storage engines that use only +table-level + locking (MyISAM, MEMORY, MERGE). See HIGH_PRIORITY and +LOW_PRIORITY clauses for details. +If you use the IGNORE keyword, the update statement does + not abort even if errors occur during the update. Rows for +which + duplicate-key conflicts occur are not updated. Rows for +which columns are + updated to values that would cause data conversion errors +are updated to the + closest valid values instead. + +UPDATE Statements With the Same Source and Target + +From MariaDB 10.3.2, UPDATE statements may have the same +source and target. + +For example, given the following table: + +DROP TABLE t1; + +CREATE TABLE t1 (c1 INT, c2 INT); +INSERT INTO t1 VALUES (10,10), (20,20); + +Until MariaDB 10.3.1, the following UPDATE statement would +not work: + +UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1); +ERROR 1093 (HY000): Table 't1' is specified twice, + both as a target for 'UPDATE' and as a separate source +for data + +From MariaDB 10.3.2, the statement executes successfully: + +UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1); + +SELECT * FROM t1; + ++------+------+ +| c1 | c2 | ++------+------+ +| 10 | 10 | +| 21 | 20 | ++------+------+ + +Example + +Single-table syntax: + +UPDATE table_name SET column1 = value1, column2 = value2 +WHERE id=100; + +Multiple-table syntax: + +UPDATE tab1, tab2 SET tab1.column1 = value1, tab1.column2 = +value2 WHERE tab1.id = tab2.id; + + + +URL: https://mariadb.com/kb/en/library/update/ +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'HELP' statement +# were damaged. +EXECUTE stmt_1; +name description example +UPDATE Syntax +------ +Single-table syntax: + +UPDATE [LOW_PRIORITY] [IGNORE] table_reference + [PARTITION (partition_list)] + SET col1={expr1|DEFAULT} [,col2={expr2|DEFAULT}] ... + [WHERE where_condition] + [ORDER BY ...] + [LIMIT row_count] + +Multiple-table syntax: + +UPDATE [LOW_PRIORITY] [IGNORE] table_references + SET col1={expr1|DEFAULT} [, col2={expr2|DEFAULT}] ... + [WHERE where_condition] + +Description +----------- +For the single-table syntax, the UPDATE statement updates +columns of existing rows in the named table with new values. +The +SET clause indicates which columns to modify and the values +they should be given. Each value can be given as an +expression, or the keyword +DEFAULT to set a column explicitly to its default value. The +WHERE clause, if given, specifies the conditions that +identify +which rows to update. With no WHERE clause, all rows are +updated. If the ORDER BY clause is specified, the rows are +updated in the order that is specified. The LIMIT clause +places a limit on the number of rows that can be updated. + +The PARTITION clause was introduced in MariaDB 10.0. See +Partition Pruning and Selection for details. + +Until MariaDB 10.3.2, for the multiple-table syntax, UPDATE +updates rows in each +table named in table_references that satisfy the conditions. +In this case, +ORDER BY and LIMIT cannot be used. This restriction was +lifted in MariaDB 10.3.2 and both clauses can be used with +multiple-table updates. An UPDATE can also reference tables +which are located in different databases; see Identifier +Qualifiers for the syntax. + +where_condition is an expression that evaluates to true for +each row to be updated. + +table_references and where_condition are as +specified as described in SELECT. + +Assignments are evaluated in left-to-right order, unless the +SIMULTANEOUS_ASSIGNMENT sql_mode (available from MariaDB +10.3.5) is set, in which case the UPDATE statement evaluates +all assignments simultaneously. + +You need the UPDATE privilege only for columns referenced in +an UPDATE that are actually updated. You need only the +SELECT privilege for any columns that are read but +not modified. See GRANT. + +The UPDATE statement supports the following modifiers: +If you use the LOW_PRIORITY keyword, execution of + the UPDATE is delayed until no other clients are reading +from + the table. This affects only storage engines that use only +table-level + locking (MyISAM, MEMORY, MERGE). See HIGH_PRIORITY and +LOW_PRIORITY clauses for details. +If you use the IGNORE keyword, the update statement does + not abort even if errors occur during the update. Rows for +which + duplicate-key conflicts occur are not updated. Rows for +which columns are + updated to values that would cause data conversion errors +are updated to the + closest valid values instead. + +UPDATE Statements With the Same Source and Target + +From MariaDB 10.3.2, UPDATE statements may have the same +source and target. + +For example, given the following table: + +DROP TABLE t1; + +CREATE TABLE t1 (c1 INT, c2 INT); +INSERT INTO t1 VALUES (10,10), (20,20); + +Until MariaDB 10.3.1, the following UPDATE statement would +not work: + +UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1); +ERROR 1093 (HY000): Table 't1' is specified twice, + both as a target for 'UPDATE' and as a separate source +for data + +From MariaDB 10.3.2, the statement executes successfully: + +UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1); + +SELECT * FROM t1; + ++------+------+ +| c1 | c2 | ++------+------+ +| 10 | 10 | +| 21 | 20 | ++------+------+ + +Example + +Single-table syntax: + +UPDATE table_name SET column1 = value1, column2 = value2 +WHERE id=100; + +Multiple-table syntax: + +UPDATE tab1, tab2 SET tab1.column1 = value1, tab1.column2 = +value2 WHERE tab1.id = tab2.id; + + + +URL: https://mariadb.com/kb/en/library/update/ +# Test case 11: Check that the 'CREATE PROCEDURE' statement +# is supported by prepared statements +PREPARE stmt_1 FROM 'CREATE PROCEDURE p1() SET @a=1'; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'CREATE PROCEDURE' +# statement were damaged. Execution of this statement the second +# time expectedly results in emitting the error ER_SP_ALREADY_EXISTS. +# The same error is issued in case the 'HANDLER t1 OPEN' statement +# is executed twice using a regular statement. +EXECUTE stmt_1; +ERROR 42000: PROCEDURE p1 already exists +# Test case 12: Check that the 'ALTER PROCEDURE' statement is supported +# by prepared statements. +PREPARE stmt_1 FROM 'ALTER PROCEDURE p1 SQL SECURITY INVOKER'; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'ALTER PROCEDURE' +# statement were damaged. +EXECUTE stmt_1; +# Test case 13: Check that the 'DROP PROCEDURE' statement is supported +# by prepared statements. +PREPARE stmt_1 FROM 'DROP PROCEDURE p1'; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'DROP PROCEDURE' statement +# were damaged. Execution of this statement the second time expectedly +# results in emitting the error ER_SP_DOES_NOT_EXIST. +EXECUTE stmt_1; +ERROR 42000: PROCEDURE test.p1 does not exist +# Test case 14: Check that the 'CALL' statement is supported +# by prepared statements. +CREATE PROCEDURE p1() SET @a=1; +PREPARE stmt_1 FROM 'CALL p1()'; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'CALL' statement +# were damaged. +EXECUTE stmt_1; +# Clean up +DEALLOCATE PREPARE stmt_1; +DROP PROCEDURE p1; +# Test case 15: Check that the 'PREPARE FROM' statement can be executed +# as a prepared statement. +PREPARE stmt_1 FROM 'PREPARE stmt_2 FROM "SELECT 1"'; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'PREPARE' statement +# were damaged. +EXECUTE stmt_1; +# Now execute the prepared statement with the name stmt_2 +# It is expected that output contains the single row '1' +EXECUTE stmt_2; +1 +1 +# Clean up +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; +# Test case 16: Check that the 'EXECUTE' statement can be executed +# as a prepared statement. +PREPARE stmt_1 FROM 'SELECT 1'; +PREPARE stmt_2 FROM 'EXECUTE stmt_1'; +# Execute the statement stmt_2. Expected result is output of one row '1' +EXECUTE stmt_2; +1 +1 +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'EXECUTE' statement +# were damaged. +EXECUTE stmt_2; +1 +1 +# Clean up +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; +# Test case 17: Check that the statement 'DEALLOCATE PREPARE' +# can be executed as a prepared statement. +PREPARE stmt_1 FROM 'SELECT 1'; +PREPARE stmt_2 FROM 'DEALLOCATE PREPARE stmt_1'; +# After the prepared statement 'stmt_2' be executed +# the prepared statement stmt_1 will be deallocated. +EXECUTE stmt_2; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'DEALLOCATE PREPARE' +# statement were damaged. This time invocation results in the error +# ER_UNKNOWN_STMT_HANDLER since the prepared statement stmt_1 +# has just been released. So, just ignore this error. +EXECUTE stmt_2; +ERROR HY000: Unknown prepared statement handler (stmt_1) given to DEALLOCATE PREPARE +# Check that the stmt_1 doesn't no longer exist +EXECUTE stmt_1; +ERROR HY000: Unknown prepared statement handler (stmt_1) given to EXECUTE +# Clean up +DEALLOCATE PREPARE stmt_2; +# Test case 18: Check that the 'CREATE VIEW' statement can be executed +# as a prepared statement. +# Create environment for the test case +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +COMMIT; +PREPARE stmt_1 FROM 'CREATE VIEW v1 AS SELECT * FROM t1'; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'CREATE VIEW' +# statement were damaged. The second execution of the prepared +# statement stmt_1 results in error ER_TABLE_EXISTS_ERROR since +# the view v1 does already exist. It is expected behaviour. +EXECUTE stmt_1; +ERROR 42S01: Table 'v1' already exists +# Clean up +DEALLOCATE PREPARE stmt_1; +DROP VIEW v1; +DROP TABLE t1; +# Test case 19: Check that the 'CREATE TRIGGER' statement can be executed +# as a prepared statement. +CREATE TABLE t1 (a INT); +PREPARE stmt_1 FROM 'CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW SET @a=1'; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'CREATE VIEW' statement +# were damaged. The second execution of the prepared statement stmt_1 +# results in error ER_TRG_ALREADY_EXISTS since the trigger trg1 does +# already exist. It is expected behaviour. +EXECUTE stmt_1; +ERROR HY000: Trigger 'test.trg1' already exists +# Test case 20: Check that the 'DROP TRIGGER' statement can be executed +# as a prepared statement. +# This test relies on presence of the trigger trg1 created by +# the test case 19. +PREPARE stmt_1 FROM 'DROP TRIGGER trg1'; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'DROP TRIGGER' statement +# were damaged. Execution of this statement the second time expectedly +# results in emitting the error ER_TRG_DOES_NOT_EXIST. +EXECUTE stmt_1; +ERROR HY000: Trigger does not exist +# Clean up +DEALLOCATE PREPARE stmt_1; +DROP TABLE t1; +# Test case 21: Check that XA related SQL statements can be executed +# as prepared statements. +# Create the table t1 used by XA transaction. +CREATE TABLE t1 (a INT); +PREPARE stmt_1 FROM "XA START 'xid1'"; +PREPARE stmt_2 FROM "XA END 'xid1'"; +PREPARE stmt_3 FROM "XA PREPARE 'xid1'"; +PREPARE stmt_4 FROM "XA RECOVER"; +PREPARE stmt_5 FROM "XA COMMIT 'xid1'"; +PREPARE stmt_6 FROM "XA ROLLBACK 'xid1'"; +# Start a new XA transaction +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'XA START' statement +# were damaged. Execution of this statement the second time expectedly +# results in emitting the error XAER_RMFAIL since there is active +# XA transaction that has just been already. +EXECUTE stmt_1; +ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state +INSERT INTO t1 VALUES (1); +# End the current XA transaction +EXECUTE stmt_2; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'XA END' statement +# were damaged. Execution of this statement the second time expectedly +# results in emitting the error XAER_RMFAIL since the XA transaction +# with XID 'xid1' has been already ended. +EXECUTE stmt_2; +ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the IDLE state +# Prepare the current XA transaction for finalization +EXECUTE stmt_3; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'XA END' statement +# were damaged. Execution of this statement the second time expectedly +# results in emitting the error XAER_RMFAIL since the XA transaction +# with XID 'xid1' has been already ended. +EXECUTE stmt_3; +ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the PREPARED state +# Run XA RECOVER as a prepared statement +EXECUTE stmt_4; +formatID gtrid_length bqual_length data +1 4 0 xid1 +# And execute it yet another time to check that no internal structures +# used for handling the statement 'XA RECOVER' were damaged. +EXECUTE stmt_4; +formatID gtrid_length bqual_length data +1 4 0 xid1 +# Commit the current XA transaction +EXECUTE stmt_5; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'XA COMMIT' statement +# were damaged. Execution of this statement the second time expectedly +# results in emitting the error XAER_NOTA since the XA transaction +# with XID 'xid1' has been finalized and no more exists. +EXECUTE stmt_5; +ERROR XAE04: XAER_NOTA: Unknown XID +# Query the table t1 to check that it contains a record inserted by +# the XA transaction just finished. +SELECT * FROM t1; +a +1 +# Using prepared statements start a new XA transaction, INSERT a row +# into the table t1, prepare the XA transaction and rollback it. +# This use case is similar to precedence one except it does rollback +# XA transaction instead commit it. Therefore every prepared statement +# is executed only once except the last XA ROLLBACK. +# Start a new XA transaction +EXECUTE stmt_1; +INSERT INTO t1 VALUES (1); +# End the current XA transaction +EXECUTE stmt_2; +# Prepare the current XA transaction for finalization +EXECUTE stmt_3; +# Rolback the current XA transaction +EXECUTE stmt_6; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the statement 'XA ROLLBACK' +# were damaged. Execution of this statement the second time expectedly +# results in emitting the error XAER_NOTA since the XA transaction +# with XID 'xid1' has been finalized and no more exists. +EXECUTE stmt_6; +ERROR XAE04: XAER_NOTA: Unknown XID +# Clean up +DROP TABLE t1; +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; +DEALLOCATE PREPARE stmt_3; +DEALLOCATE PREPARE stmt_4; +DEALLOCATE PREPARE stmt_5; +DEALLOCATE PREPARE stmt_6; +# Test case 22: Check that the CREATE SERVER/ALTER SERVER/DROP SERVER +# statements can be executed as prepared statements. +PREPARE stmt_1 FROM "CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (USER 'u1', HOST '127.0.0.1')"; +PREPARE stmt_2 FROM "ALTER SERVER s OPTIONS (USER 'u2')"; +PREPARE stmt_3 FROM "DROP SERVER s"; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'CREATE SERVER' statement +# were damaged. Execution of this statement the second time expectedly +# results in emitting the error ER_FOREIGN_SERVER_EXISTS +# since a server with same has just been created. +EXECUTE stmt_1; +ERROR HY000: The foreign server, s, you are trying to create already exists +EXECUTE stmt_2; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'ALTER SERVER' statement +# were damaged. +EXECUTE stmt_2; +EXECUTE stmt_3; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'DROP SERVER' statement +# were damaged. Execution of this statement the second time expectedly +# results in emitting the error ER_FOREIGN_SERVER_DOESNT_EXIST +# since the server with same has just been dropped. +EXECUTE stmt_3; +ERROR HY000: The foreign server name you are trying to reference does not exist. Data source error: s +# Clean up +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; +DEALLOCATE PREPARE stmt_3; +# Test case 23: Check that the CREATE EVENT/ALTER EVENT/DROP EVENT +# statements can be executed as a prepared statement +PREPARE stmt_1 FROM "CREATE EVENT e1 ON SCHEDULE AT CURRENT_TIMESTAMP - INTERVAL 1 DAY ON COMPLETION PRESERVE DO SET @a=1"; +PREPARE stmt_2 FROM "ALTER EVENT e1 COMMENT 'New comment'"; +PREPARE stmt_3 FROM "DROP EVENT e1"; +# Create the event e1 that specifies time in past. Such event is created +# just for the sake of its existence and never will be triggered. +# Disable warnings temprorary in order to hide the following warnings +# generated in result of execution the 'CREATE EVENT' statement: +# "1544 | Event execution time is in the past. Event has been disabled" +# "1105 | Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it." +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'CREATE EVENT' statement +# were damaged. Execution of this statement the second time expectedly +# results in emitting the error ER_EVENT_ALREADY_EXISTS since the event +# with the same name has just been created. +EXECUTE stmt_1; +ERROR HY000: Event 'e1' already exists +# Alter event e1 +EXECUTE stmt_2; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'ALTER EVENT' statement +# were damaged. +EXECUTE stmt_2; +# Drop event e1 +EXECUTE stmt_3; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'DROP EVENT' statement +# were damaged. Execution of this statement the second time expectedly +# results in emitting the error ER_EVENT_DOESNT_EXIST since the event +# with the same name has just been dropped. +EXECUTE stmt_3; +ERROR HY000: Unknown event 'e1' +# Clean up +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; +DEALLOCATE PREPARE stmt_3; +# Test case 24: Check that the SIGNAL and RESIGNAL statements +# can be executed as a prepared statement +PREPARE stmt_1 FROM "SIGNAL SQLSTATE '45000' SET MYSQL_ERRNO=30001, MESSAGE_TEXT='Hello, world!'"; +EXECUTE stmt_1; +ERROR 45000: Hello, world! +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'SIGNAL' statement +# were damaged. +EXECUTE stmt_1; +ERROR 45000: Hello, world! +PREPARE stmt_1 FROM 'RESIGNAL SET MYSQL_ERRNO = 5'; +EXECUTE stmt_1; +ERROR 0K000: RESIGNAL when handler not active +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'RESIGNAL' statement +# were damaged. +EXECUTE stmt_1; +ERROR 0K000: RESIGNAL when handler not active +# Clean up +DEALLOCATE PREPARE stmt_1; +# Test case 25: Check that the 'SHOW RELAYLOG EVENTS' statement can be +# executed as a prepared statement. +PREPARE stmt_1 FROM 'SHOW RELAYLOG EVENTS'; +EXECUTE stmt_1; +Log_name Pos Event_type Server_id End_log_pos Info +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'SHOW RELAYLOG EVENTS' +# statement were damaged. +EXECUTE stmt_1; +Log_name Pos Event_type Server_id End_log_pos Info +# Clean up +DEALLOCATE PREPARE stmt_1; +# Test case 26: Check the 'GET DIAGNOSTICS' statement +# can be executed as a prepared statement +PREPARE stmt_1 FROM 'GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT'; +# Query from non existent table to fill the diagnostics area +# with information +SELECT * FROM non_existent_table_1; +ERROR 42S02: Table 'test.non_existent_table_1' doesn't exist +EXECUTE stmt_1; +# Check that information from diagnostics area has been retrieved +SELECT @sqlstate, @errno, @text; +@sqlstate @errno @text +42S02 1146 Table 'test.non_existent_table_1' doesn't exist +SELECT * FROM non_existent_table_1; +ERROR 42S02: Table 'test.non_existent_table_1' doesn't exist +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the +# 'GET DIAGNOSTICS CONDITION' statement were damaged. +EXECUTE stmt_1; +# Clean up +DEALLOCATE PREPARE stmt_1; +# Test case 27: Check the the statement 'EXECUTE IMMEDIATE' +# can be executed as a prepared statement +PREPARE stmt_1 FROM "EXECUTE IMMEDIATE 'SELECT 1'"; +EXECUTE stmt_1; +1 +1 +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'EXECUTE IMMEDIATE' +# statement were damaged. +# Clean up +DEALLOCATE PREPARE stmt_1; +# Test Test case 28: Check the statements 'BACKUP'/'BACKUP UNLOCK' +# can be executed as a prepared statement +CREATE TABLE t1 (a INT); +PREPARE stmt_1 FROM 'BACKUP LOCK t1'; +PREPARE stmt_2 FROM 'BACKUP UNLOCK'; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'BACKUP LOCK' +# statement were damaged. +EXECUTE stmt_1; +EXECUTE stmt_2; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'BACKUP UNLOCK' +# statement were damaged. +EXECUTE stmt_2; +# Clean up +DROP TABLE t1; +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; +# Test Test case 29: Check the statements 'CREATE/ALTER/DROP TABLEPSPACE' +# can be executed as a prepared statement +PREPARE stmt_1 FROM "CREATE TABLESPACE ts1 ADD DATAFILE 'ts1.ibd' ENGINE=InnoDB"; +PREPARE stmt_2 FROM "ALTER TABLESPACE ts1 ADD DATAFILE 'ts1_1.ibd' ENGINE=InnoDB"; +PREPARE stmt_3 FROM "DROP TABLESPACE ts1 ENGINE=InnoDB"; +EXECUTE stmt_1; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'CREATE TABLESPACE' +# statement were damaged. +EXECUTE stmt_1; +EXECUTE stmt_2; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'ALTER TABLESPACE' +# statement were damaged. +EXECUTE stmt_2; +EXECUTE stmt_3; +# Execute the same prepared statement the second time to check that +# no internal structures used for handling the 'DROP TABLESPACE' +# statement were damaged. +EXECUTE stmt_3; +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; +DEALLOCATE PREPARE stmt_3; +SET default_storage_engine= @save_storage_engine; diff --git a/mysql-test/main/ps_missed_cmds.test b/mysql-test/main/ps_missed_cmds.test new file mode 100644 index 00000000000..b621ef6d611 --- /dev/null +++ b/mysql-test/main/ps_missed_cmds.test @@ -0,0 +1,758 @@ +--source include/have_innodb.inc + +if (`SELECT $PS_PROTOCOL != 0`) +{ + --skip Need regular protocol but ps-protocol was specified +} + +SET @save_storage_engine= @@default_storage_engine; +SET default_storage_engine= InnoDB; + +--echo # +--echo # MDEV-16708: Unsupported commands for prepared statements +--echo # + +--echo # Disable ps-protocol explicitly in order to test support of +--echo # prepared statements for use case when statements passed +--echo # to the server via text client-server protocol (in contrast +--echo # with binary protocol used in the test file +--echo # ps_missed_cmds_bin_prot.test) +--disable_ps_protocol + +--echo # Test case 1: Check that the statement 'LOAD DATA' is supported +--echo # by prepared statements + +--echo # First, set up environment for use by the 'LOAD DATA' statement +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +COMMIT; +SELECT * INTO OUTFILE 'load.data' FROM t1; + +PREPARE stmt_1 FROM "LOAD DATA INFILE 'load.data' INTO TABLE t1"; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'LOAD DATA' statement +--echo # were damaged. +EXECUTE stmt_1; +SELECT * FROM t1; +--echo # Clean up +DEALLOCATE PREPARE stmt_1; +DROP TABLE t1; +--let $datadir= `select @@datadir` +--remove_file $datadir/test/load.data + +--echo # Test case 2: Check that the 'LOCK TABLE', 'UNLOCK TABLES' statements +--echo # are supported by prepared statements +CREATE TABLE t1 (a INT); + +PREPARE stmt_1 FROM "LOCK TABLE t1 READ"; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'LOCK TABLE READ' +--echo # statement were damaged. +EXECUTE stmt_1; + +PREPARE stmt_1 FROM "UNLOCK TABLE"; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'UNLOCK TABLE' statement +--echo # were damaged. +EXECUTE stmt_1; + +PREPARE stmt_1 FROM "LOCK TABLE t1 WRITE"; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'LOCK TABLE WRITE' +--echo # statement were damaged. +EXECUTE stmt_1; +--echo # Clean up +DEALLOCATE PREPARE stmt_1; +UNLOCK TABLE; +DROP TABLE t1; + +--echo # Test case 3: Check that the 'USE' statement is supported by +--echo # prepared statements + +CREATE DATABASE mdev_16708_db; +PREPARE stmt_1 FROM 'USE mdev_16708_db'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'USE' statement +--echo # were damaged. +EXECUTE stmt_1; + +--echo # Check that the current database has been changed +SELECT DATABASE(); + +--echo # Clean up +DEALLOCATE PREPARE stmt_1; +USE test; +DROP DATABASE mdev_16708_db; + +--echo # Test case 4: Check that the 'ALTER DATABASE' statement is supported +--echo # by prepared statements +CREATE DATABASE mdev_16708_db; +PREPARE stmt_1 FROM "ALTER DATABASE mdev_16708_db COMMENT 'New comment'"; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'ALTER DATABASE' statement +--echo # were damaged. +EXECUTE stmt_1; + +--echo # Clean up +DEALLOCATE PREPARE stmt_1; +USE test; +DROP DATABASE mdev_16708_db; + +--echo # Test case 5: Check that the 'CREATE FUNCTION/ALTER FUNCTION/ +--echo # DROP FUNCTION' statements are supported by prepared statements +PREPARE stmt_1 FROM 'CREATE FUNCTION f1() RETURNS INT RETURN 1'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'CREATE FUNCTION' +--echo # statement were damaged. The second attempt to execute the prepared +--echo # statement stmt_1 results in error ER_SP_ALREADY_EXISTS since +--echo # the stored function f() has been created on first run of stmt1. +--error ER_SP_ALREADY_EXISTS +EXECUTE stmt_1; + +PREPARE stmt_1 FROM 'ALTER FUNCTION f1 SQL SECURITY INVOKER'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'ALTER FUNCTION' +--echo # statement were damaged. +EXECUTE stmt_1; + +PREPARE stmt_1 FROM 'DROP FUNCTION f1'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling 'DROP FUNCTION' statement +--echo # were damaged. The second attempt to run 'DROP FUNCTION f1' using +--echo # prepared statement expectedly results in issuing the error +--echo # ER_SP_DOES_NOT_EXIST since the stored function was dropped on first +--echo # executuon of the prepared statement stmt_1. +--error ER_SP_DOES_NOT_EXIST +EXECUTE stmt_1; + +--echo # Test case 6: Check that the 'CHECK TABLE' statement is supported +--echo # by prepared statements +CREATE TABLE t1 (a INT); +PREPARE stmt_1 FROM 'CHECK TABLE t1'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'CHECK TABLE' statement +--echo # were damaged. +EXECUTE stmt_1; + +--echo # Clean up +DEALLOCATE PREPARE stmt_1; +DROP TABLE t1; + +--echo # Test case 7: Check that the BEGIN/SAVEPOINT/RELEASE SAVEPOINT +--echo # statements are supported by prepared statements + +--echo # Set up environmentr for the test case +CREATE TABLE t1 (a INT); + +PREPARE stmt_1 FROM 'BEGIN'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'BEGIN' statement +--echo # were damaged. +EXECUTE stmt_1; + +INSERT INTO t1 VALUES (1); +--echo # Run 'SAVEPOINT s1' using prepared statements +PREPARE stmt_2 FROM 'SAVEPOINT s1'; +EXECUTE stmt_2; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'SAVEPOINT' statement +--echo # were damaged. +EXECUTE stmt_2; + +INSERT INTO t1 VALUES (2); +--echo # Expected rows: '1' and '2' +SELECT * FROM t1; +--echo # Rollback the last row inserted ('2') +ROLLBACK TO SAVEPOINT s1; +--echo # Expected output from t1 after transaction has been rolled back +--echo # to the savepoint is '1'. If it is case then the statement SAVEPOINT +--echo # was handled successfully with prepared statement +SELECT * FROM t1; + +PREPARE stmt_3 FROM 'RELEASE SAVEPOINT s1'; +EXECUTE stmt_3; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'RELEASE' statement +--echo # were damaged. The second attempt to release the same savepoint +--echo # expectedly lead to error 'SAVEPOINT s1 does not exist' +--echo # that's just ignored. +--error ER_SP_DOES_NOT_EXIST +EXECUTE stmt_3; + +--echo # Clean up +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; +DEALLOCATE PREPARE stmt_3; +DROP TABLE t1; + +--echo # Test case 8: Check that the 'PURGE BINARY LOGS BEFORE' statement +--echo # is supported by prepared statements +PREPARE stmt_1 FROM "PURGE BINARY LOGS BEFORE '2020-11-17'"; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'PURGE BINARY LOGS BEFORE' +--echo # statement were damaged. +EXECUTE stmt_1; + +--echo # Check that the 'PURGE BINARY LOGS TO' statement is supported by +--echo # prepared statements +PREPARE stmt_1 FROM "PURGE BINARY LOGS TO 'mariadb-bin.000063'"; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'PURGE BINARY LOGS TO' +--echo # statement were damaged. +EXECUTE stmt_1; + +--echo # Test case 9: Check that the 'HANDLER OPEN/HANDLER READ/ +--echo # HANDLER CLOSE' statements are supported by prepared statements +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (1); +COMMIT; + +PREPARE stmt_1 FROM 'HANDLER t1 OPEN'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'HANDLER OPEN' +--echo # statement were damaged. Execution of this statement the second +--echo # time expectedly results in emitting the error ER_NONUNIQ_TABLE. +--echo # The same error is issued in case the statement 'HANDLER t1 OPEN' is +--echo # executed twice using a regular statement. +--error ER_NONUNIQ_TABLE +EXECUTE stmt_1; + +PREPARE stmt_2 FROM 'HANDLER t1 READ FIRST'; +PREPARE stmt_3 FROM 'HANDLER t1 READ NEXT'; +PREPARE stmt_4 FROM 'HANDLER t1 CLOSE'; + +EXECUTE stmt_2; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'HANDLER READ FIRST' +--echo # statement were damaged. +EXECUTE stmt_2; + +EXECUTE stmt_3; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'HANDLER READ NEXT' +--echo # statement were damaged. +EXECUTE stmt_3; + +EXECUTE stmt_4; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'HANDLER CLOSE' +--echo # statement were damaged. Execution of this statement the second +--echo # time results in emitting the error ER_UNKNOWN_TABLE. The same error +--echo # is issued in case the statement 'HANDLER t1 CLOSE' executed twice +--echo # using a regular statement. +--error ER_UNKNOWN_TABLE +EXECUTE stmt_4; + +--echo # Clean up +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; +DEALLOCATE PREPARE stmt_3; +DEALLOCATE PREPARE stmt_4; +DROP TABLE t1; + +--echo # Test case 10: Check that the HELP statement +--echo # is supported by prepared statements +PREPARE stmt_1 FROM "HELP `UPDATE`"; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'HELP' statement +--echo # were damaged. + +EXECUTE stmt_1; + +--echo # Test case 11: Check that the 'CREATE PROCEDURE' statement +--echo # is supported by prepared statements +PREPARE stmt_1 FROM 'CREATE PROCEDURE p1() SET @a=1'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'CREATE PROCEDURE' +--echo # statement were damaged. Execution of this statement the second +--echo # time expectedly results in emitting the error ER_SP_ALREADY_EXISTS. +--echo # The same error is issued in case the 'HANDLER t1 OPEN' statement +--echo # is executed twice using a regular statement. +--error ER_SP_ALREADY_EXISTS +EXECUTE stmt_1; + +--echo # Test case 12: Check that the 'ALTER PROCEDURE' statement is supported +--echo # by prepared statements. +# This test case relies on artefacts of the test case 11 (the procedure p1) + +PREPARE stmt_1 FROM 'ALTER PROCEDURE p1 SQL SECURITY INVOKER'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'ALTER PROCEDURE' +--echo # statement were damaged. +EXECUTE stmt_1; + +--echo # Test case 13: Check that the 'DROP PROCEDURE' statement is supported +--echo # by prepared statements. +# This test case relies on artefacts of the test case 11 (the procedure p1) +PREPARE stmt_1 FROM 'DROP PROCEDURE p1'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'DROP PROCEDURE' statement +--echo # were damaged. Execution of this statement the second time expectedly +--echo # results in emitting the error ER_SP_DOES_NOT_EXIST. + +--error ER_SP_DOES_NOT_EXIST +EXECUTE stmt_1; + +--echo # Test case 14: Check that the 'CALL' statement is supported +--echo # by prepared statements. + +CREATE PROCEDURE p1() SET @a=1; +PREPARE stmt_1 FROM 'CALL p1()'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'CALL' statement +--echo # were damaged. +EXECUTE stmt_1; + +--echo # Clean up +DEALLOCATE PREPARE stmt_1; +DROP PROCEDURE p1; + +--echo # Test case 15: Check that the 'PREPARE FROM' statement can be executed +--echo # as a prepared statement. +PREPARE stmt_1 FROM 'PREPARE stmt_2 FROM "SELECT 1"'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'PREPARE' statement +--echo # were damaged. +EXECUTE stmt_1; +--echo # Now execute the prepared statement with the name stmt_2 +--echo # It is expected that output contains the single row '1' +EXECUTE stmt_2; +--echo # Clean up +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; + +--echo # Test case 16: Check that the 'EXECUTE' statement can be executed +--echo # as a prepared statement. +PREPARE stmt_1 FROM 'SELECT 1'; +PREPARE stmt_2 FROM 'EXECUTE stmt_1'; +--echo # Execute the statement stmt_2. Expected result is output of one row '1' +EXECUTE stmt_2; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'EXECUTE' statement +--echo # were damaged. +EXECUTE stmt_2; + +--echo # Clean up +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; + +--echo # Test case 17: Check that the statement 'DEALLOCATE PREPARE' +--echo # can be executed as a prepared statement. +PREPARE stmt_1 FROM 'SELECT 1'; +PREPARE stmt_2 FROM 'DEALLOCATE PREPARE stmt_1'; +--echo # After the prepared statement 'stmt_2' be executed +--echo # the prepared statement stmt_1 will be deallocated. +EXECUTE stmt_2; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'DEALLOCATE PREPARE' +--echo # statement were damaged. This time invocation results in the error +--echo # ER_UNKNOWN_STMT_HANDLER since the prepared statement stmt_1 +--echo # has just been released. So, just ignore this error. +--error ER_UNKNOWN_STMT_HANDLER +EXECUTE stmt_2; + +--echo # Check that the stmt_1 doesn't no longer exist +--error ER_UNKNOWN_STMT_HANDLER +EXECUTE stmt_1; + +--echo # Clean up +DEALLOCATE PREPARE stmt_2; + +--echo # Test case 18: Check that the 'CREATE VIEW' statement can be executed +--echo # as a prepared statement. +--echo # Create environment for the test case +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +COMMIT; + +PREPARE stmt_1 FROM 'CREATE VIEW v1 AS SELECT * FROM t1'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'CREATE VIEW' +--echo # statement were damaged. The second execution of the prepared +--echo # statement stmt_1 results in error ER_TABLE_EXISTS_ERROR since +--echo # the view v1 does already exist. It is expected behaviour. + +--error ER_TABLE_EXISTS_ERROR +EXECUTE stmt_1; + +--echo # Clean up +DEALLOCATE PREPARE stmt_1; + +DROP VIEW v1; +DROP TABLE t1; + +--echo # Test case 19: Check that the 'CREATE TRIGGER' statement can be executed +--echo # as a prepared statement. +CREATE TABLE t1 (a INT); +PREPARE stmt_1 FROM 'CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW SET @a=1'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'CREATE VIEW' statement +--echo # were damaged. The second execution of the prepared statement stmt_1 +--echo # results in error ER_TRG_ALREADY_EXISTS since the trigger trg1 does +--echo # already exist. It is expected behaviour. +--error ER_TRG_ALREADY_EXISTS +EXECUTE stmt_1; + +--echo # Test case 20: Check that the 'DROP TRIGGER' statement can be executed +--echo # as a prepared statement. +--echo # This test relies on presence of the trigger trg1 created by +--echo # the test case 19. +PREPARE stmt_1 FROM 'DROP TRIGGER trg1'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'DROP TRIGGER' statement +--echo # were damaged. Execution of this statement the second time expectedly +--echo # results in emitting the error ER_TRG_DOES_NOT_EXIST. +--error ER_TRG_DOES_NOT_EXIST +EXECUTE stmt_1; + +--echo # Clean up +DEALLOCATE PREPARE stmt_1; +DROP TABLE t1; + +--echo # Test case 21: Check that XA related SQL statements can be executed +--echo # as prepared statements. +--echo # Create the table t1 used by XA transaction. +CREATE TABLE t1 (a INT); +PREPARE stmt_1 FROM "XA START 'xid1'"; +PREPARE stmt_2 FROM "XA END 'xid1'"; +PREPARE stmt_3 FROM "XA PREPARE 'xid1'"; +PREPARE stmt_4 FROM "XA RECOVER"; +PREPARE stmt_5 FROM "XA COMMIT 'xid1'"; +PREPARE stmt_6 FROM "XA ROLLBACK 'xid1'"; + +--echo # Start a new XA transaction +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'XA START' statement +--echo # were damaged. Execution of this statement the second time expectedly +--echo # results in emitting the error XAER_RMFAIL since there is active +--echo # XA transaction that has just been already. +--error ER_XAER_RMFAIL +EXECUTE stmt_1; + +INSERT INTO t1 VALUES (1); + +--echo # End the current XA transaction +EXECUTE stmt_2; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'XA END' statement +--echo # were damaged. Execution of this statement the second time expectedly +--echo # results in emitting the error XAER_RMFAIL since the XA transaction +--echo # with XID 'xid1' has been already ended. +--error ER_XAER_RMFAIL +EXECUTE stmt_2; + +--echo # Prepare the current XA transaction for finalization +EXECUTE stmt_3; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'XA END' statement +--echo # were damaged. Execution of this statement the second time expectedly +--echo # results in emitting the error XAER_RMFAIL since the XA transaction +--echo # with XID 'xid1' has been already ended. +--error ER_XAER_RMFAIL +EXECUTE stmt_3; + +--echo # Run XA RECOVER as a prepared statement +EXECUTE stmt_4; +--echo # And execute it yet another time to check that no internal structures +--echo # used for handling the statement 'XA RECOVER' were damaged. +EXECUTE stmt_4; + +--echo # Commit the current XA transaction +EXECUTE stmt_5; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'XA COMMIT' statement +--echo # were damaged. Execution of this statement the second time expectedly +--echo # results in emitting the error XAER_NOTA since the XA transaction +--echo # with XID 'xid1' has been finalized and no more exists. +--error ER_XAER_NOTA +EXECUTE stmt_5; + +--echo # Query the table t1 to check that it contains a record inserted by +--echo # the XA transaction just finished. +SELECT * FROM t1; + +--echo # Using prepared statements start a new XA transaction, INSERT a row +--echo # into the table t1, prepare the XA transaction and rollback it. +--echo # This use case is similar to precedence one except it does rollback +--echo # XA transaction instead commit it. Therefore every prepared statement +--echo # is executed only once except the last XA ROLLBACK. + +--echo # Start a new XA transaction +EXECUTE stmt_1; + +INSERT INTO t1 VALUES (1); + +--echo # End the current XA transaction +EXECUTE stmt_2; + +--echo # Prepare the current XA transaction for finalization +EXECUTE stmt_3; + +--echo # Rolback the current XA transaction +EXECUTE stmt_6; + +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the statement 'XA ROLLBACK' +--echo # were damaged. Execution of this statement the second time expectedly +--echo # results in emitting the error XAER_NOTA since the XA transaction +--echo # with XID 'xid1' has been finalized and no more exists. +--error ER_XAER_NOTA +EXECUTE stmt_6; + +--echo # Clean up +DROP TABLE t1; +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; +DEALLOCATE PREPARE stmt_3; +DEALLOCATE PREPARE stmt_4; +DEALLOCATE PREPARE stmt_5; +DEALLOCATE PREPARE stmt_6; + +--echo # Test case 22: Check that the CREATE SERVER/ALTER SERVER/DROP SERVER +--echo # statements can be executed as prepared statements. + +PREPARE stmt_1 FROM "CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (USER 'u1', HOST '127.0.0.1')"; +PREPARE stmt_2 FROM "ALTER SERVER s OPTIONS (USER 'u2')"; +PREPARE stmt_3 FROM "DROP SERVER s"; + +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'CREATE SERVER' statement +--echo # were damaged. Execution of this statement the second time expectedly +--echo # results in emitting the error ER_FOREIGN_SERVER_EXISTS +--echo # since a server with same has just been created. +--error ER_FOREIGN_SERVER_EXISTS +EXECUTE stmt_1; + +EXECUTE stmt_2; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'ALTER SERVER' statement +--echo # were damaged. +EXECUTE stmt_2; + +EXECUTE stmt_3; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'DROP SERVER' statement +--echo # were damaged. Execution of this statement the second time expectedly +--echo # results in emitting the error ER_FOREIGN_SERVER_DOESNT_EXIST +--echo # since the server with same has just been dropped. +--error ER_FOREIGN_SERVER_DOESNT_EXIST +EXECUTE stmt_3; + +--echo # Clean up +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; +DEALLOCATE PREPARE stmt_3; + +--echo # Test case 23: Check that the CREATE EVENT/ALTER EVENT/DROP EVENT +--echo # statements can be executed as a prepared statement + +PREPARE stmt_1 FROM "CREATE EVENT e1 ON SCHEDULE AT CURRENT_TIMESTAMP - INTERVAL 1 DAY ON COMPLETION PRESERVE DO SET @a=1"; + +PREPARE stmt_2 FROM "ALTER EVENT e1 COMMENT 'New comment'"; + +PREPARE stmt_3 FROM "DROP EVENT e1"; +--echo # Create the event e1 that specifies time in past. Such event is created +--echo # just for the sake of its existence and never will be triggered. +--echo # Disable warnings temprorary in order to hide the following warnings +--echo # generated in result of execution the 'CREATE EVENT' statement: +--echo # "1544 | Event execution time is in the past. Event has been disabled" +--echo # "1105 | Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it." + +--disable_warnings +EXECUTE stmt_1; + +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'CREATE EVENT' statement +--echo # were damaged. Execution of this statement the second time expectedly +--echo # results in emitting the error ER_EVENT_ALREADY_EXISTS since the event +--echo # with the same name has just been created. +--error ER_EVENT_ALREADY_EXISTS +EXECUTE stmt_1; + +--enable_warnings + +--echo # Alter event e1 +EXECUTE stmt_2; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'ALTER EVENT' statement +--echo # were damaged. +EXECUTE stmt_2; + +--echo # Drop event e1 +EXECUTE stmt_3; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'DROP EVENT' statement +--echo # were damaged. Execution of this statement the second time expectedly +--echo # results in emitting the error ER_EVENT_DOESNT_EXIST since the event +--echo # with the same name has just been dropped. +--error ER_EVENT_DOES_NOT_EXIST +EXECUTE stmt_3; +--echo # Clean up +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; +DEALLOCATE PREPARE stmt_3; + +--echo # Test case 24: Check that the SIGNAL and RESIGNAL statements +--echo # can be executed as a prepared statement +PREPARE stmt_1 FROM "SIGNAL SQLSTATE '45000' SET MYSQL_ERRNO=30001, MESSAGE_TEXT='Hello, world!'"; +--error 30001 +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'SIGNAL' statement +--echo # were damaged. +--error 30001 +EXECUTE stmt_1; + +PREPARE stmt_1 FROM 'RESIGNAL SET MYSQL_ERRNO = 5'; +--error ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'RESIGNAL' statement +--echo # were damaged. +--error ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER +EXECUTE stmt_1; + +--echo # Clean up +DEALLOCATE PREPARE stmt_1; + +--echo # Test case 25: Check that the 'SHOW RELAYLOG EVENTS' statement can be +--echo # executed as a prepared statement. +PREPARE stmt_1 FROM 'SHOW RELAYLOG EVENTS'; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'SHOW RELAYLOG EVENTS' +--echo # statement were damaged. +EXECUTE stmt_1; +--echo # Clean up +DEALLOCATE PREPARE stmt_1; + +--echo # Test case 26: Check the 'GET DIAGNOSTICS' statement +--echo # can be executed as a prepared statement +PREPARE stmt_1 FROM 'GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT'; + +--echo # Query from non existent table to fill the diagnostics area +--echo # with information +--error ER_NO_SUCH_TABLE +SELECT * FROM non_existent_table_1; +EXECUTE stmt_1; +--echo # Check that information from diagnostics area has been retrieved +SELECT @sqlstate, @errno, @text; + +--error ER_NO_SUCH_TABLE +SELECT * FROM non_existent_table_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the +--echo # 'GET DIAGNOSTICS CONDITION' statement were damaged. +EXECUTE stmt_1; + +--echo # Clean up +DEALLOCATE PREPARE stmt_1; + +--echo # Test case 27: Check the the statement 'EXECUTE IMMEDIATE' +--echo # can be executed as a prepared statement + +PREPARE stmt_1 FROM "EXECUTE IMMEDIATE 'SELECT 1'"; +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'EXECUTE IMMEDIATE' +--echo # statement were damaged. + +--echo # Clean up +DEALLOCATE PREPARE stmt_1; + +--echo # Test Test case 28: Check the statements 'BACKUP'/'BACKUP UNLOCK' +--echo # can be executed as a prepared statement +CREATE TABLE t1 (a INT); +PREPARE stmt_1 FROM 'BACKUP LOCK t1'; +PREPARE stmt_2 FROM 'BACKUP UNLOCK'; + +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'BACKUP LOCK' +--echo # statement were damaged. +EXECUTE stmt_1; + +EXECUTE stmt_2; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'BACKUP UNLOCK' +--echo # statement were damaged. +EXECUTE stmt_2; + +--echo # Clean up +DROP TABLE t1; +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; + +--echo # Test Test case 29: Check the statements 'CREATE/ALTER/DROP TABLEPSPACE' +--echo # can be executed as a prepared statement + +PREPARE stmt_1 FROM "CREATE TABLESPACE ts1 ADD DATAFILE 'ts1.ibd' ENGINE=InnoDB"; +PREPARE stmt_2 FROM "ALTER TABLESPACE ts1 ADD DATAFILE 'ts1_1.ibd' ENGINE=InnoDB"; +PREPARE stmt_3 FROM "DROP TABLESPACE ts1 ENGINE=InnoDB"; + +# Since MariaDB supports for tablespaces only on syntax level disable warnings +# before run CREATE/ALTER/DROP TABLESPACE statements in order to exclude +# the following in result output +# Warning 1478 Table storage engine 'InnoDB' does not support the create option 'TABLESPACE +--disable_warnings + +EXECUTE stmt_1; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'CREATE TABLESPACE' +--echo # statement were damaged. +# Since the 'CREATE TABLESPACE' statement is supported by MariaDB on syntax +# level only the second invocation of the CREATE TABLESPACE statement for +# the same tablespace name doesn't lead to error. +EXECUTE stmt_1; + +EXECUTE stmt_2; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'ALTER TABLESPACE' +--echo # statement were damaged. +EXECUTE stmt_2; + +EXECUTE stmt_3; +--echo # Execute the same prepared statement the second time to check that +--echo # no internal structures used for handling the 'DROP TABLESPACE' +--echo # statement were damaged. + +# Since the 'DROP TABLESPACE' statement is supported by MariaDB on syntax +# level only the second invocation of the DROP TABLESPACE statement for +# the same tablespace name doesn't lead to an error that tablespace +# doesn't exist. +EXECUTE stmt_3; + +--enable_warnings + +DEALLOCATE PREPARE stmt_1; +DEALLOCATE PREPARE stmt_2; +DEALLOCATE PREPARE stmt_3; + +--enable_ps_protocol +SET default_storage_engine= @save_storage_engine; diff --git a/mysql-test/main/ps_missed_cmds_bin_prot.result b/mysql-test/main/ps_missed_cmds_bin_prot.result new file mode 100644 index 00000000000..3b56d9a1a5b --- /dev/null +++ b/mysql-test/main/ps_missed_cmds_bin_prot.result @@ -0,0 +1,264 @@ +# +# MDEV-16708: Unsupported commands for prepared statements +# +SET @save_storage_engine= @@default_storage_engine; +SET default_storage_engine= InnoDB; +# Test case 1: Check that the statement 'LOAD DATA' is supported +# by prepared statements +# First, set up environment for use by the statement 'LOAD DATA' +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +COMMIT; +SELECT * INTO OUTFILE 'load.data' FROM t1; +LOAD DATA INFILE 'load.data' INTO TABLE t1; +SELECT * FROM t1; +a +1 +1 +# Clean up +DROP TABLE t1; +# Test case 2: Check that the statements 'LOCK TABLE', 'UNLOCK TABLES' +# are supported by prepared statements +CREATE TABLE t1 (a INT); +LOCK TABLE t1 READ; +UNLOCK TABLE; +LOCK TABLE t1 WRITE; +# Clean up +UNLOCK TABLE; +DROP TABLE t1; +# Test case 3: Check that the statement 'USE' is supported by +# prepared statements +CREATE DATABASE mdev_16708_db; +USE mdev_16708_db; +# Check that the current database has been changed +SELECT DATABASE(); +DATABASE() +mdev_16708_db +# Clean up +USE test; +DROP DATABASE mdev_16708_db; +# Test case 4: Check that the statement 'ALTER DATABASE' is supported +# by prepared statements +CREATE DATABASE mdev_16708_db; +ALTER DATABASE mdev_16708_db COMMENT 'New comment on database'; +# Clean up +DROP DATABASE mdev_16708_db; +# Test case 5: Check that the statements 'CREATE FUNCTION/ALTER FUNCTION/ +# DROP FUNCTION' are supported by prepared statements +CREATE FUNCTION f1() RETURNS INT RETURN 1; +ALTER FUNCTION f1 SQL SECURITY INVOKER; +DROP FUNCTION f1; +# Test case 6: Check that the statements 'CHECK TABLE' is supported +# by prepared statements +CREATE TABLE t1 (a INT); +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +# Clean up +DROP TABLE t1; +# Test case 7: Check that the statements BEGIN/SAVEPOINT/ +# RELEASE SAVEPOINT is supported by prepared statements +# Set up environmentr for the test case +CREATE TABLE t1 (a INT); +BEGIN; +INSERT INTO t1 VALUES (1); +SAVEPOINT s1; +INSERT INTO t1 VALUES (2); +# Expected rows: '1' and '2' +SELECT * FROM t1; +a +1 +2 +# Rollback the last row inserted ('2') +ROLLBACK TO SAVEPOINT s1; +# Expected output from t1 after transaction was rolled back +# to the savepoint is '1'. If it is case then the statement SAVEPOINT +# was handled successfully with prepared statement +SELECT * FROM t1; +a +1 +RELEASE SAVEPOINT s1; +# Clean up +DROP TABLE t1; +# Test case 8: Check that the statements 'PURGE BINARY LOGS BEFORE' +# is supported by prepared statements +PURGE BINARY LOGS BEFORE '2020-11-17'; +# Check that the statements 'PURGE BINARY LOGS TO' is supported by +# prepared statements +PURGE BINARY LOGS TO 'mariadb-bin.000063'; +# Test case 9: Check that the statements 'HANDLER OPEN/HANDLER READ/ +# HANDLER CLOSE' are supported by prepared statements +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (1); +COMMIT; +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +a +1 +HANDLER t1 READ NEXT; +a +1 +HANDLER t1 CLOSE; +# Clean up +DROP TABLE t1; +# Test case 10: Check that the statements 'HELP' +# is supported by prepared statements +HELP `ALTER SERVER`; +name description example +ALTER SERVER Syntax +------ +ALTER SERVER server_name + OPTIONS (option [, option] ...) + +Description +----------- +Alters the server information for server_name, adjusting the +specified +options as per the CREATE SERVER command. The corresponding +fields in the mysql.servers table are updated accordingly. +This statement requires the SUPER privilege. + +Examples +-------- +ALTER SERVER s OPTIONS (USER 'sally'); + + + +URL: https://mariadb.com/kb/en/library/alter-server/ +# Test case 11: Check that the statements CREATE/ALTER/DROP PROCEDURE +# are supported by prepared statements +CREATE PROCEDURE p1() SET @a=1; +ALTER PROCEDURE p1 SQL SECURITY INVOKER; +DROP PROCEDURE p1; +# Test case 12: Check that the statement 'CALL' is supported +# by prepared statements. +CREATE PROCEDURE p1() SET @a=1; +CALL p1(); +# Check that the @a variable has been set +SELECT @a; +@a +1 +DROP PROCEDURE p1; +# Test case 13: Check that the statements PREPARE FROM/EXECUTE/ +# DEALLOCAT PREPARE can be executed as prepared statements. +PREPARE stmt_1 FROM 'SELECT 1'; +# Now execute the prepared statement with the name stmt_1 +# It is expected that output contains the single row '1' +EXECUTE stmt_1; +1 +1 +DEALLOCATE PREPARE stmt_1; +# Test case 14: Check that the statement 'CREATE VIEW' can be executed +# as a prepared statement. +# Create environment for the test case +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +COMMIT; +CREATE VIEW v1 AS SELECT * FROM t1; +# Query the view. Expected result is the row '1' +SELECT * FROM v1; +a +1 +# Clean up +DROP VIEW v1; +DROP TABLE t1; +# Test case 15: Check that the statements CREATE/DROP TRIGGER can be executed +# as prepared statements. +CREATE TABLE t1 (a INT); +CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW SET @a=1; +DROP TRIGGER trg1; +DROP TABLE t1; +# Test case 16: Check that XA related SQL statements can be executed in +# as prepared statements. +# Create the table t1 used by XA transaction. +CREATE TABLE t1 (a INT); +XA START 'xid1'; +INSERT INTO t1 VALUES (1); +XA END 'xid1'; +XA PREPARE 'xid1'; +XA RECOVER; +formatID gtrid_length bqual_length data +1 4 0 xid1 +XA COMMIT 'xid1'; +# Query the table t1 to check that it contains a record inserted by XA +# transaction just committed. +SELECT * FROM t1; +a +1 +# Check that XA ROLLBACK is supported by prepared statements +# First, clean up the table t1 that was filled by just +# committed XA transaction +TRUNCATE TABLE t1; +XA START 'xid1'; +INSERT INTO t1 VALUES (1); +XA END 'xid1'; +XA PREPARE 'xid1'; +XA RECOVER; +formatID gtrid_length bqual_length data +1 4 0 xid1 +XA ROLLBACK 'xid1'; +# Query the table t1 to check that it doesn't contain a record +# inserted by XA transaction just rollbacked. +SELECT * FROM t1; +a +# Clean up +DROP TABLE t1; +# Test case 17: Check that the statements CREATE SERVER/ALTER SERVER/ +# DROP SERVER can be executed +# as a prepared statement. +CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (USER 'u1', HOST '127.0.0.1'); +ALTER SERVER s OPTIONS (USER 'u2'); +DROP SERVER s; +# Test case 18: Check that the statements CREATE EVENT/ALTER EVENT/ +# DROP EVENT can be executed as a prepared statement +# Create the event e1 that specifies time in past. Such event is created +# just for the sake of its existence and never will be triggered. +# Disable warnings temprorary in order to hide the following warnings +# generated in result of execution the 'CREATE EVENT' statement: +# "1544 | Event execution time is in the past. Event has been disabled" +# "1105 | Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it." +CREATE EVENT e1 ON SCHEDULE AT CURRENT_TIMESTAMP - INTERVAL 1 DAY ON COMPLETION PRESERVE DO SET @a=1; +ALTER EVENT e1 COMMENT 'New comment'; +DROP EVENT IF EXISTS e1; +# Test case 19: Check that the statement 'SHOW RELAYLOG EVENTS' can be +# executed as a prepared statement. +SHOW RELAYLOG EVENTS; +Log_name Pos Event_type Server_id End_log_pos Info +# Test case 20: Check the the statement 'EXECUTE IMMEDIATE' +# can be executed as a prepared statement +EXECUTE IMMEDIATE 'SELECT 1'; +1 +1 +# Test Test case 21: Check the statements 'BACKUP'/'BACKUP STAGE' +# can be executed as a prepared statement +CREATE TABLE t1 (a INT); +BACKUP LOCK t1; +BACKUP UNLOCK; +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +BACKUP STAGE END; +DROP TABLE t1; +# Test case 22: Check the the statement 'GET DIAGNOSTICS' +# can be executed as a prepared statement +# Query from non existent table to fill the diagnostics area with information +SELECT * FROM non_existent_table_1; +ERROR 42S02: Table 'test.non_existent_table_1' doesn't exist +GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT; +# Check that information from diagnostics area has been retrieved +SELECT @sqlstate, @errno, @text; +@sqlstate @errno @text +42S02 1146 Table 'test.non_existent_table_1' doesn't exist +# Clean up +# Test case 23: Check that the statements SIGNAL and RESIGNAL can be executed as +# a prepared statement +SIGNAL SQLSTATE '45000' SET MYSQL_ERRNO=30001, MESSAGE_TEXT='Hello, world!'; +ERROR 45000: Hello, world! +RESIGNAL SET MESSAGE_TEXT = 'New error message'; +ERROR 0K000: RESIGNAL when handler not active +# Test Test case 29: Check the statements 'CREATE/ALTER/DROP TABLEPSPACE' +# can be executed as a prepared statement +CREATE TABLESPACE ts1 ADD DATAFILE 'ts1.ibd' ENGINE=InnoDB; +ALTER TABLESPACE ts1 ADD DATAFILE 'ts1_1.ibd' ENGINE=InnoDB; +DROP TABLESPACE ts1 ENGINE=InnoDB; +SET default_storage_engine= @save_storage_engine; diff --git a/mysql-test/main/ps_missed_cmds_bin_prot.test b/mysql-test/main/ps_missed_cmds_bin_prot.test new file mode 100644 index 00000000000..10ce9ebd60a --- /dev/null +++ b/mysql-test/main/ps_missed_cmds_bin_prot.test @@ -0,0 +1,298 @@ +--echo # +--echo # MDEV-16708: Unsupported commands for prepared statements +--echo # + +if (`SELECT $PS_PROTOCOL = 0`) +{ + --skip Need ps-protocol +} + +--source include/have_innodb.inc + +SET @save_storage_engine= @@default_storage_engine; +SET default_storage_engine= InnoDB; + +--echo # Test case 1: Check that the statement 'LOAD DATA' is supported +--echo # by prepared statements + +--echo # First, set up environment for use by the statement 'LOAD DATA' +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +COMMIT; +SELECT * INTO OUTFILE 'load.data' FROM t1; + +LOAD DATA INFILE 'load.data' INTO TABLE t1; +SELECT * FROM t1; +--echo # Clean up +DROP TABLE t1; +--let $datadir= `select @@datadir` +--remove_file $datadir/test/load.data + +--echo # Test case 2: Check that the statements 'LOCK TABLE', 'UNLOCK TABLES' +--echo # are supported by prepared statements +CREATE TABLE t1 (a INT); + +LOCK TABLE t1 READ; +UNLOCK TABLE; + +LOCK TABLE t1 WRITE; +--echo # Clean up +UNLOCK TABLE; +DROP TABLE t1; + +--echo # Test case 3: Check that the statement 'USE' is supported by +--echo # prepared statements + +CREATE DATABASE mdev_16708_db; +USE mdev_16708_db; + +--echo # Check that the current database has been changed +SELECT DATABASE(); + +--echo # Clean up +USE test; +DROP DATABASE mdev_16708_db; + +--echo # Test case 4: Check that the statement 'ALTER DATABASE' is supported +--echo # by prepared statements +CREATE DATABASE mdev_16708_db; +ALTER DATABASE mdev_16708_db COMMENT 'New comment on database'; + +--echo # Clean up +DROP DATABASE mdev_16708_db; + +--echo # Test case 5: Check that the statements 'CREATE FUNCTION/ALTER FUNCTION/ +--echo # DROP FUNCTION' are supported by prepared statements +CREATE FUNCTION f1() RETURNS INT RETURN 1; + +ALTER FUNCTION f1 SQL SECURITY INVOKER; + +DROP FUNCTION f1; + +--echo # Test case 6: Check that the statements 'CHECK TABLE' is supported +--echo # by prepared statements +CREATE TABLE t1 (a INT); +CHECK TABLE t1; +--echo # Clean up +DROP TABLE t1; + +--echo # Test case 7: Check that the statements BEGIN/SAVEPOINT/ +--echo # RELEASE SAVEPOINT is supported by prepared statements + +--echo # Set up environmentr for the test case +CREATE TABLE t1 (a INT); + +BEGIN; + +INSERT INTO t1 VALUES (1); + +SAVEPOINT s1; + +INSERT INTO t1 VALUES (2); +--echo # Expected rows: '1' and '2' +SELECT * FROM t1; +--echo # Rollback the last row inserted ('2') +ROLLBACK TO SAVEPOINT s1; +--echo # Expected output from t1 after transaction was rolled back +--echo # to the savepoint is '1'. If it is case then the statement SAVEPOINT +--echo # was handled successfully with prepared statement +SELECT * FROM t1; + +RELEASE SAVEPOINT s1; + +--echo # Clean up +DROP TABLE t1; + +--echo # Test case 8: Check that the statements 'PURGE BINARY LOGS BEFORE' +--echo # is supported by prepared statements +PURGE BINARY LOGS BEFORE '2020-11-17'; + +--echo # Check that the statements 'PURGE BINARY LOGS TO' is supported by +--echo # prepared statements +PURGE BINARY LOGS TO 'mariadb-bin.000063'; + +--echo # Test case 9: Check that the statements 'HANDLER OPEN/HANDLER READ/ +--echo # HANDLER CLOSE' are supported by prepared statements +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (1); +COMMIT; + +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +HANDLER t1 READ NEXT; +HANDLER t1 CLOSE; + +--echo # Clean up +DROP TABLE t1; + +--echo # Test case 10: Check that the statements 'HELP' +--echo # is supported by prepared statements +HELP `ALTER SERVER`; + +--echo # Test case 11: Check that the statements CREATE/ALTER/DROP PROCEDURE +--echo # are supported by prepared statements +CREATE PROCEDURE p1() SET @a=1; +ALTER PROCEDURE p1 SQL SECURITY INVOKER; +DROP PROCEDURE p1; + +--echo # Test case 12: Check that the statement 'CALL' is supported +--echo # by prepared statements. + +CREATE PROCEDURE p1() SET @a=1; +CALL p1(); + +--echo # Check that the @a variable has been set +SELECT @a; +DROP PROCEDURE p1; + +--echo # Test case 13: Check that the statements PREPARE FROM/EXECUTE/ +--echo # DEALLOCAT PREPARE can be executed as prepared statements. +PREPARE stmt_1 FROM 'SELECT 1'; + +--echo # Now execute the prepared statement with the name stmt_1 +--echo # It is expected that output contains the single row '1' +EXECUTE stmt_1; + +DEALLOCATE PREPARE stmt_1; + +--echo # Test case 14: Check that the statement 'CREATE VIEW' can be executed +--echo # as a prepared statement. +--echo # Create environment for the test case +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +COMMIT; + +CREATE VIEW v1 AS SELECT * FROM t1; +--echo # Query the view. Expected result is the row '1' +SELECT * FROM v1; +--echo # Clean up +DROP VIEW v1; +DROP TABLE t1; + +--echo # Test case 15: Check that the statements CREATE/DROP TRIGGER can be executed +--echo # as prepared statements. +CREATE TABLE t1 (a INT); +CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW SET @a=1; + +DROP TRIGGER trg1; +DROP TABLE t1; + +--echo # Test case 16: Check that XA related SQL statements can be executed in +--echo # as prepared statements. +--echo # Create the table t1 used by XA transaction. +CREATE TABLE t1 (a INT); +XA START 'xid1'; +INSERT INTO t1 VALUES (1); +XA END 'xid1'; +XA PREPARE 'xid1'; +XA RECOVER; +XA COMMIT 'xid1'; +--echo # Query the table t1 to check that it contains a record inserted by XA +--echo # transaction just committed. +SELECT * FROM t1; + +--echo # Check that XA ROLLBACK is supported by prepared statements + +--echo # First, clean up the table t1 that was filled by just +--echo # committed XA transaction +TRUNCATE TABLE t1; +XA START 'xid1'; +INSERT INTO t1 VALUES (1); +XA END 'xid1'; +XA PREPARE 'xid1'; +XA RECOVER; +XA ROLLBACK 'xid1'; + +--echo # Query the table t1 to check that it doesn't contain a record +--echo # inserted by XA transaction just rollbacked. +SELECT * FROM t1; + +--echo # Clean up +DROP TABLE t1; + +--echo # Test case 17: Check that the statements CREATE SERVER/ALTER SERVER/ +--echo # DROP SERVER can be executed +--echo # as a prepared statement. + +CREATE SERVER s FOREIGN DATA WRAPPER mysql OPTIONS (USER 'u1', HOST '127.0.0.1'); +ALTER SERVER s OPTIONS (USER 'u2'); +DROP SERVER s; + +--echo # Test case 18: Check that the statements CREATE EVENT/ALTER EVENT/ +--echo # DROP EVENT can be executed as a prepared statement + +--echo # Create the event e1 that specifies time in past. Such event is created +--echo # just for the sake of its existence and never will be triggered. +--echo # Disable warnings temprorary in order to hide the following warnings +--echo # generated in result of execution the 'CREATE EVENT' statement: +--echo # "1544 | Event execution time is in the past. Event has been disabled" +--echo # "1105 | Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it." + +--disable_warnings + +CREATE EVENT e1 ON SCHEDULE AT CURRENT_TIMESTAMP - INTERVAL 1 DAY ON COMPLETION PRESERVE DO SET @a=1; + +ALTER EVENT e1 COMMENT 'New comment'; + +DROP EVENT IF EXISTS e1; + +--enable_warnings + +--echo # Test case 19: Check that the statement 'SHOW RELAYLOG EVENTS' can be +--echo # executed as a prepared statement. +SHOW RELAYLOG EVENTS; + +--echo # Test case 20: Check the the statement 'EXECUTE IMMEDIATE' +--echo # can be executed as a prepared statement + +EXECUTE IMMEDIATE 'SELECT 1'; + +--echo # Test Test case 21: Check the statements 'BACKUP'/'BACKUP STAGE' +--echo # can be executed as a prepared statement +CREATE TABLE t1 (a INT); +BACKUP LOCK t1; +BACKUP UNLOCK; + +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +BACKUP STAGE END; + +DROP TABLE t1; + +--echo # Test case 22: Check the the statement 'GET DIAGNOSTICS' +--echo # can be executed as a prepared statement + +--echo # Query from non existent table to fill the diagnostics area with information +--error ER_NO_SUCH_TABLE +SELECT * FROM non_existent_table_1; +GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT; +--echo # Check that information from diagnostics area has been retrieved +SELECT @sqlstate, @errno, @text; +--echo # Clean up + +--echo # Test case 23: Check that the statements SIGNAL and RESIGNAL can be executed as +--echo # a prepared statement + +--error 30001 +SIGNAL SQLSTATE '45000' SET MYSQL_ERRNO=30001, MESSAGE_TEXT='Hello, world!'; + +--error ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER +RESIGNAL SET MESSAGE_TEXT = 'New error message'; + +--echo # Test Test case 29: Check the statements 'CREATE/ALTER/DROP TABLEPSPACE' +--echo # can be executed as a prepared statement + +# Since MariaDB supports for tablespaces only on syntax level disable warnings +# before run CREATE/ALTER/DROP TABLESPACE statements in order to exclude +# the following in result output +# Warning 1478 Table storage engine 'InnoDB' does not support the create option 'TABLESPACE +--disable_warnings + +CREATE TABLESPACE ts1 ADD DATAFILE 'ts1.ibd' ENGINE=InnoDB; +ALTER TABLESPACE ts1 ADD DATAFILE 'ts1_1.ibd' ENGINE=InnoDB; +DROP TABLESPACE ts1 ENGINE=InnoDB; + +--enable_warnings + +SET default_storage_engine= @save_storage_engine; diff --git a/mysql-test/main/query_cache.result b/mysql-test/main/query_cache.result index 33e41a760f2..3a81b648171 100644 --- a/mysql-test/main/query_cache.result +++ b/mysql-test/main/query_cache.result @@ -1098,7 +1098,7 @@ call p1()// a 1 2 -drop procedure p1; +drop procedure p1// create function f1() returns int begin Declare var1 int; @@ -1111,13 +1111,13 @@ create procedure `p1`() begin select a, f1() from t1; end// -SET @old_log_bin_trust_function_creators= @@global.log_bin_trust_function_creators; -SET GLOBAL log_bin_trust_function_creators = 1; +SET @old_log_bin_trust_function_creators= @@global.log_bin_trust_function_creators// +SET GLOBAL log_bin_trust_function_creators = 1// call p1()// a f1() 1 2 2 2 -SET GLOBAL log_bin_trust_function_creators = @old_log_bin_trust_function_creators; +SET GLOBAL log_bin_trust_function_creators = @old_log_bin_trust_function_creators// drop procedure p1// drop function f1// drop table t1// diff --git a/mysql-test/main/query_cache.test b/mysql-test/main/query_cache.test index 939bf738fce..e49387dcaf4 100644 --- a/mysql-test/main/query_cache.test +++ b/mysql-test/main/query_cache.test @@ -810,7 +810,7 @@ open c1; select * from t1; end// call p1()// -drop procedure p1; +drop procedure p1// create function f1() returns int begin @@ -822,10 +822,10 @@ create procedure `p1`() begin select a, f1() from t1; end// -SET @old_log_bin_trust_function_creators= @@global.log_bin_trust_function_creators; -SET GLOBAL log_bin_trust_function_creators = 1; +SET @old_log_bin_trust_function_creators= @@global.log_bin_trust_function_creators// +SET GLOBAL log_bin_trust_function_creators = 1// call p1()// -SET GLOBAL log_bin_trust_function_creators = @old_log_bin_trust_function_creators; +SET GLOBAL log_bin_trust_function_creators = @old_log_bin_trust_function_creators// drop procedure p1// drop function f1// diff --git a/mysql-test/main/signal.result b/mysql-test/main/signal.result index b5b479db017..6a7f1c1e750 100644 --- a/mysql-test/main/signal.result +++ b/mysql-test/main/signal.result @@ -561,9 +561,7 @@ ERROR 42000: Bad SQLSTATE: '00001' # PART 2: non preparable statements # prepare stmt from 'SIGNAL SQLSTATE \'23000\''; -ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt from 'RESIGNAL SQLSTATE \'23000\''; -ERROR HY000: This command is not supported in the prepared statement protocol yet # # PART 3: runtime execution # diff --git a/mysql-test/main/signal.test b/mysql-test/main/signal.test index 22cfc080895..97cd4d9a5d0 100644 --- a/mysql-test/main/signal.test +++ b/mysql-test/main/signal.test @@ -669,10 +669,7 @@ delimiter ;$$ --echo # PART 2: non preparable statements --echo # ---error ER_UNSUPPORTED_PS prepare stmt from 'SIGNAL SQLSTATE \'23000\''; - ---error ER_UNSUPPORTED_PS prepare stmt from 'RESIGNAL SQLSTATE \'23000\''; --echo # diff --git a/mysql-test/main/sp-dynamic.result b/mysql-test/main/sp-dynamic.result index 9fa3bea1108..ad11763b523 100644 --- a/mysql-test/main/sp-dynamic.result +++ b/mysql-test/main/sp-dynamic.result @@ -64,9 +64,8 @@ execute stmt; deallocate prepare stmt; end| call p1()| -ERROR HY000: This command is not supported in the prepared statement protocol yet call p1()| -ERROR HY000: This command is not supported in the prepared statement protocol yet +ERROR 42000: PROCEDURE p2 already exists drop procedure p1| create procedure p1() begin @@ -75,9 +74,8 @@ execute stmt; deallocate prepare stmt; end| call p1()| -ERROR HY000: This command is not supported in the prepared statement protocol yet call p1()| -ERROR HY000: This command is not supported in the prepared statement protocol yet +ERROR 42000: PROCEDURE test.p2 does not exist drop procedure p1| create procedure p1() begin @@ -295,15 +293,15 @@ select * from t1| id stmt_text status 1 select 1 supported 2 flush tables supported -3 handler t1 open as ha not supported +3 handler t1 open as ha supported 4 analyze table t1 supported -5 check table t1 not supported +5 check table t1 supported 6 checksum table t1 supported -7 check table t1 not supported +7 check table t1 supported 8 optimize table t1 supported 9 repair table t1 supported 10 describe extended select * from t1 supported -11 help help not supported +11 help help supported 12 show databases supported 13 show tables supported 14 show table status supported @@ -316,7 +314,7 @@ id stmt_text status 21 call p1() supported 22 foo bar syntax error 23 create view v1 as select 1 supported -24 alter view v1 as select 2 not supported +24 alter view v1 as select 2 supported 25 drop view v1 supported 26 create table t2 (a int) supported 27 alter table t2 add (b int) supported diff --git a/mysql-test/main/sp-dynamic.test b/mysql-test/main/sp-dynamic.test index 3a467e26818..5749a83a27b 100644 --- a/mysql-test/main/sp-dynamic.test +++ b/mysql-test/main/sp-dynamic.test @@ -68,9 +68,8 @@ begin execute stmt; deallocate prepare stmt; end| ---error ER_UNSUPPORTED_PS call p1()| ---error ER_UNSUPPORTED_PS +--error ER_SP_ALREADY_EXISTS call p1()| drop procedure p1| create procedure p1() @@ -79,9 +78,8 @@ begin execute stmt; deallocate prepare stmt; end| ---error ER_UNSUPPORTED_PS call p1()| ---error ER_UNSUPPORTED_PS +--error ER_SP_DOES_NOT_EXIST call p1()| drop procedure p1| # diff --git a/mysql-test/main/sp-security.result b/mysql-test/main/sp-security.result index 2c48883a509..2571f9d8696 100644 --- a/mysql-test/main/sp-security.result +++ b/mysql-test/main/sp-security.result @@ -347,6 +347,7 @@ create function bug12812() returns char(2) begin return 'ok'; end; +| create user user_bug12812@localhost IDENTIFIED BY 'ABC'| connect test_user_12812,localhost,user_bug12812,ABC,test; SELECT test.bug12812()| diff --git a/mysql-test/main/sp-security.test b/mysql-test/main/sp-security.test index e7790bf703a..e11e8911b60 100644 --- a/mysql-test/main/sp-security.test +++ b/mysql-test/main/sp-security.test @@ -465,6 +465,7 @@ create function bug12812() returns char(2) begin return 'ok'; end; +| create user user_bug12812@localhost IDENTIFIED BY 'ABC'| --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (test_user_12812,localhost,user_bug12812,ABC,test)| |