summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Shulga <dmitry.shulga@mariadb.com>2021-06-15 23:28:18 +0700
committerDmitry Shulga <dmitry.shulga@mariadb.com>2021-06-15 23:28:18 +0700
commitd907bc93a514ab1ba38d21c32338d6bd29373aed (patch)
tree487d1229fed3b865beba1c693ec330f02e1cd15d
parent6fbf978eec4506eb46737ac4da00ea04403ae855 (diff)
downloadmariadb-git-bb-10.6-MDEV-16708-3.tar.gz
MDEV-16708: Unsupported commands for prepared statementsbb-10.6-MDEV-16708-3
Within 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 implementation 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 to enable any statements except PREPARE FROM, EXECUTE, EXECUTE IMMEDIATE, DEALLOCATE to be run in PS mode. - 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 statement. - 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 initialisation of the data member 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 option --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 warning_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. - Some tests has been disabled by the reason that they contains multi-statements that not supported in PS mode. Unfortunately, some of these multi-statements can't be converted to a sequence of single-statements by the reason that multi-statementness is a requirement for tests. Therefore the whole test file will be skipped in case it is run with --ps-protocol
-rw-r--r--client/mysqltest.cc228
-rw-r--r--mysql-test/include/column_compression_syntax_varbinary.inc3
-rw-r--r--mysql-test/include/column_compression_syntax_varchar.inc3
-rw-r--r--mysql-test/include/ctype_numconv.inc4
-rw-r--r--mysql-test/include/explain_utils.inc4
-rw-r--r--mysql-test/main/bug12427262.test2
-rw-r--r--mysql-test/main/column_compression.test2
-rw-r--r--mysql-test/main/compound.result4
-rw-r--r--mysql-test/main/compound.test4
-rw-r--r--mysql-test/main/cte_recursive.test4
-rw-r--r--mysql-test/main/ctype_gbk.test2
-rw-r--r--mysql-test/main/ctype_ucs.test4
-rw-r--r--mysql-test/main/delayed.test2
-rw-r--r--mysql-test/main/derived.test2
-rw-r--r--mysql-test/main/derived_cond_pushdown.test3
-rw-r--r--mysql-test/main/events_logs_tests.result3
-rw-r--r--mysql-test/main/events_logs_tests.test3
-rw-r--r--mysql-test/main/events_restart.test3
-rw-r--r--mysql-test/main/features.test4
-rw-r--r--mysql-test/main/fetch_first.test4
-rw-r--r--mysql-test/main/func_group.test7
-rw-r--r--mysql-test/main/func_time.test7
-rw-r--r--mysql-test/main/get_diagnostics.result4
-rw-r--r--mysql-test/main/get_diagnostics.test4
-rw-r--r--mysql-test/main/grant.test2
-rw-r--r--mysql-test/main/grant2.test2
-rw-r--r--mysql-test/main/having_cond_pushdown.test4
-rw-r--r--mysql-test/main/information_schema_db.test2
-rw-r--r--mysql-test/main/innodb_mysql_lock2.test2
-rw-r--r--mysql-test/main/invisible_field.test2
-rw-r--r--mysql-test/main/join_cache.result4
-rw-r--r--mysql-test/main/join_cache.test4
-rw-r--r--mysql-test/main/limit_rows_examined.test5
-rw-r--r--mysql-test/main/lock_sync.test3
-rw-r--r--mysql-test/main/locking_clause.test2
-rw-r--r--mysql-test/main/log_tables.result18
-rw-r--r--mysql-test/main/log_tables.test3
-rw-r--r--mysql-test/main/merge.test4
-rw-r--r--mysql-test/main/myisam_debug.test2
-rw-r--r--mysql-test/main/mysqldump.test2
-rw-r--r--mysql-test/main/null.test2
-rw-r--r--mysql-test/main/opt_trace.test4
-rw-r--r--mysql-test/main/outfile_loaddata.test4
-rw-r--r--mysql-test/main/parser.test6
-rw-r--r--mysql-test/main/parser_stack.test4
-rw-r--r--mysql-test/main/partition.test2
-rw-r--r--mysql-test/main/partition_exchange.test2
-rw-r--r--mysql-test/main/partition_explicit_prune.test2
-rw-r--r--mysql-test/main/ps.result12
-rw-r--r--mysql-test/main/ps.test29
-rw-r--r--mysql-test/main/ps_1general.result6
-rw-r--r--mysql-test/main/ps_1general.test13
-rw-r--r--mysql-test/main/ps_ddl.result2
-rw-r--r--mysql-test/main/ps_ddl.test8
-rw-r--r--mysql-test/main/ps_ddl1.test2
-rw-r--r--mysql-test/main/ps_missed_cmds.result847
-rw-r--r--mysql-test/main/ps_missed_cmds.test694
-rw-r--r--mysql-test/main/ps_missed_cmds_bin_prot.result264
-rw-r--r--mysql-test/main/ps_missed_cmds_bin_prot.test298
-rw-r--r--mysql-test/main/query_cache.result8
-rw-r--r--mysql-test/main/query_cache.test12
-rw-r--r--mysql-test/main/select.test2
-rw-r--r--mysql-test/main/signal.result2
-rw-r--r--mysql-test/main/signal.test3
-rw-r--r--mysql-test/main/signal_demo1.test4
-rw-r--r--mysql-test/main/skip_grants.result2
-rw-r--r--mysql-test/main/skip_grants.test6
-rw-r--r--mysql-test/main/sp-anchor-row-type-cursor.test3
-rw-r--r--mysql-test/main/sp-anchor-row-type-table.test3
-rw-r--r--mysql-test/main/sp-anchor-type.test2
-rw-r--r--mysql-test/main/sp-big.test4
-rw-r--r--mysql-test/main/sp-dynamic.result16
-rw-r--r--mysql-test/main/sp-dynamic.test6
-rw-r--r--mysql-test/main/sp-error.result4
-rw-r--r--mysql-test/main/sp-error.test11
-rw-r--r--mysql-test/main/sp-row.test5
-rw-r--r--mysql-test/main/sp-security.result1
-rw-r--r--mysql-test/main/sp-security.test1
-rw-r--r--mysql-test/main/sp.test5
-rw-r--r--mysql-test/main/sp_gis.test4
-rw-r--r--mysql-test/main/sp_notembedded.test2
-rw-r--r--mysql-test/main/sp_trans.test2
-rw-r--r--mysql-test/main/sp_trans_log.test2
-rw-r--r--mysql-test/main/subselect.test10
-rw-r--r--mysql-test/main/subselect4.test2
-rw-r--r--mysql-test/main/subselect_exists2in_costmat.test2
-rw-r--r--mysql-test/main/subselect_mat_cost.test2
-rw-r--r--mysql-test/main/table_value_constr.test2
-rw-r--r--mysql-test/main/temporal_literal.test2
-rw-r--r--mysql-test/main/trigger.test4
-rw-r--r--mysql-test/main/type_blob.test4
-rw-r--r--mysql-test/main/type_newdecimal.test2
-rw-r--r--mysql-test/main/type_year.test4
-rw-r--r--mysql-test/main/union.test5
-rw-r--r--mysql-test/main/userstat.test2
-rw-r--r--mysql-test/main/view.test13
-rw-r--r--mysql-test/main/view_grant.test4
-rw-r--r--mysql-test/suite/compat/oracle/r/sp-package.result2
-rw-r--r--mysql-test/suite/compat/oracle/t/parser.test4
-rw-r--r--mysql-test/suite/compat/oracle/t/sp-package-innodb.test4
-rw-r--r--mysql-test/suite/compat/oracle/t/sp-package.test4
-rw-r--r--mysql-test/suite/compat/oracle/t/sp-row.test5
-rw-r--r--mysql-test/suite/compat/oracle/t/update_innodb.test3
-rw-r--r--mysql-test/suite/funcs_1/include/innodb_tb2.inc2
-rw-r--r--mysql-test/suite/funcs_1/include/innodb_tb4.inc2
-rw-r--r--mysql-test/suite/funcs_1/include/memory_tb2.inc5
-rw-r--r--mysql-test/suite/funcs_1/include/memory_tb4.inc2
-rw-r--r--mysql-test/suite/funcs_1/t/is_columns_memory.test4
-rw-r--r--mysql-test/suite/funcs_1/t/is_columns_myisam.test4
-rw-r--r--mysql-test/suite/funcs_1/t/storedproc.test2
-rw-r--r--mysql-test/suite/handler/handler.inc2
-rw-r--r--mysql-test/suite/innodb/t/data_types.test4
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug30919.test4
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug51920.test2
-rw-r--r--mysql-test/suite/perfschema/t/alter_table_progress.test2
-rw-r--r--mysql-test/suite/perfschema/t/dml_handler.test5
-rw-r--r--mysql-test/suite/perfschema/t/ortho_iter.test4
-rw-r--r--mysql-test/suite/perfschema/t/rpl_threads.test6
-rw-r--r--mysql-test/suite/perfschema/t/selects.test2
-rw-r--r--mysql-test/suite/plugins/t/test_sql_service.test4
-rw-r--r--mysql-test/suite/rpl/r/rpl_sp.result2
-rw-r--r--mysql-test/suite/rpl/t/rpl_bug31076.test5
-rw-r--r--mysql-test/suite/rpl/t/rpl_drop_db.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_events.test5
-rw-r--r--mysql-test/suite/rpl/t/rpl_gtid_stop_start.test4
-rw-r--r--mysql-test/suite/rpl/t/rpl_heartbeat.test3
-rw-r--r--mysql-test/suite/rpl/t/rpl_heartbeat_basic.test4
-rw-r--r--mysql-test/suite/rpl/t/rpl_innodb_bug30888.test3
-rw-r--r--mysql-test/suite/rpl/t/rpl_mdev12179.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_misc_functions.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_sp.test2
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_fil_make_page_dirty_debug_basic.test2
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_saved_page_number_debug_basic.test2
-rw-r--r--mysql-test/suite/sys_vars/t/secure_file_priv.test2
-rw-r--r--mysql-test/suite/sys_vars/t/stored_program_cache_func.test4
-rw-r--r--mysql-test/suite/versioning/t/alter.test2
-rw-r--r--mysql-test/suite/versioning/t/commit_id.test4
-rw-r--r--mysql-test/suite/versioning/t/create.test3
-rw-r--r--mysql-test/suite/versioning/t/cte.test4
-rw-r--r--mysql-test/suite/versioning/t/foreign.test2
-rw-r--r--mysql-test/suite/versioning/t/insert.test2
-rw-r--r--mysql-test/suite/versioning/t/load_data.test2
-rw-r--r--mysql-test/suite/versioning/t/partition.test4
-rw-r--r--mysql-test/suite/versioning/t/select.test6
-rw-r--r--mysql-test/suite/versioning/t/select2.test5
-rw-r--r--mysql-test/suite/versioning/t/sysvars.test6
-rw-r--r--mysql-test/suite/versioning/t/trx_id.test4
-rw-r--r--sql/item.cc10
-rw-r--r--sql/item_subselect.cc12
-rw-r--r--sql/protocol.h4
-rw-r--r--sql/set_var.cc11
-rw-r--r--sql/sp_head.h5
-rw-r--r--sql/sql_admin.cc50
-rw-r--r--sql/sql_admin.h2
-rw-r--r--sql/sql_binlog.cc22
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_class.h30
-rw-r--r--sql/sql_cursor.cc2
-rw-r--r--sql/sql_delete.cc2
-rw-r--r--sql/sql_help.cc344
-rw-r--r--sql/sql_help.h2
-rw-r--r--sql/sql_lex.h15
-rw-r--r--sql/sql_load.cc9
-rw-r--r--sql/sql_parse.cc20
-rw-r--r--sql/sql_parse.h2
-rw-r--r--sql/sql_prepare.cc368
-rw-r--r--sql/sql_table.cc36
-rw-r--r--sql/sql_table.h3
-rw-r--r--sql/sql_update.cc2
-rw-r--r--sql/sys_vars.cc12
-rw-r--r--sql/sys_vars.ic4
-rw-r--r--sql/xa.cc54
-rw-r--r--sql/xa.h3
173 files changed, 3449 insertions, 483 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 8d3046faae0..a3ca60819ce 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -8293,7 +8293,7 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command,
Get the warnings from mysql_stmt_prepare and keep them in a
separate string
*/
- if (!disable_warnings)
+ if (!disable_warnings && prepare_warnings_enabled)
append_warnings(&ds_prepare_warnings, mysql);
/*
@@ -8324,117 +8324,125 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command,
goto end;
}
- /*
- When running in cursor_protocol get the warnings from execute here
- and keep them in a separate string for later.
- */
- if (cursor_protocol_enabled && !disable_warnings)
- append_warnings(&ds_execute_warnings, mysql);
-
- /*
- We instruct that we want to update the "max_length" field in
- mysql_stmt_store_result(), this is our only way to know how much
- buffer to allocate for result data
- */
+ int err;
+ do
{
- my_bool one= 1;
- if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one))
- die("mysql_stmt_attr_set(STMT_ATTR_UPDATE_MAX_LENGTH) failed': %d %s",
- mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
- }
+ /*
+ When running in cursor_protocol get the warnings from execute here
+ and keep them in a separate string for later.
+ */
+ if (cursor_protocol_enabled && !disable_warnings)
+ append_warnings(&ds_execute_warnings, mysql);
- /*
- If we got here the statement succeeded and was expected to do so,
- get data. Note that this can still give errors found during execution!
- Store the result of the query if if will return any fields
- */
- if (mysql_stmt_field_count(stmt) && mysql_stmt_store_result(stmt))
- {
- handle_error(command, mysql_stmt_errno(stmt),
- mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
- goto end;
- }
+ /*
+ We instruct that we want to update the "max_length" field in
+ mysql_stmt_store_result(), this is our only way to know how much
+ buffer to allocate for result data
+ */
+ {
+ my_bool one= 1;
+ if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one))
+ die("mysql_stmt_attr_set(STMT_ATTR_UPDATE_MAX_LENGTH) failed': %d %s",
+ mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
+ }
- /* If we got here the statement was both executed and read successfully */
- handle_no_error(command);
- if (!disable_result_log)
- {
/*
- Not all statements creates a result set. If there is one we can
- now create another normal result set that contains the meta
- data. This set can be handled almost like any other non prepared
- statement result set.
+ If we got here the statement succeeded and was expected to do so,
+ get data. Note that this can still give errors found during execution!
+ Store the result of the query if if will return any fields
*/
- if ((res= mysql_stmt_result_metadata(stmt)) != NULL)
+ if (mysql_stmt_field_count(stmt) && mysql_stmt_store_result(stmt))
{
- /* Take the column count from meta info */
- MYSQL_FIELD *fields= mysql_fetch_fields(res);
- uint num_fields= mysql_num_fields(res);
+ handle_error(command, mysql_stmt_errno(stmt),
+ mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
+ goto end;
+ }
- if (display_metadata)
- append_metadata(ds, fields, num_fields);
+ if (!disable_result_log)
+ {
+ /*
+ Not all statements creates a result set. If there is one we can
+ now create another normal result set that contains the meta
+ data. This set can be handled almost like any other non prepared
+ statement result set.
+ */
+ if ((res= mysql_stmt_result_metadata(stmt)) != NULL)
+ {
+ /* Take the column count from meta info */
+ MYSQL_FIELD *fields= mysql_fetch_fields(res);
+ uint num_fields= mysql_num_fields(res);
- if (!display_result_vertically)
- append_table_headings(ds, fields, num_fields);
+ if (display_metadata)
+ append_metadata(ds, fields, num_fields);
- append_stmt_result(ds, stmt, fields, num_fields);
+ if (!display_result_vertically)
+ append_table_headings(ds, fields, num_fields);
- mysql_free_result(res); /* Free normal result set with meta data */
+ append_stmt_result(ds, stmt, fields, num_fields);
- /*
- Normally, if there is a result set, we do not show warnings from the
- prepare phase. This is because some warnings are generated both during
- prepare and execute; this would generate different warning output
- between normal and ps-protocol test runs.
+ mysql_free_result(res); /* Free normal result set with meta data */
- The --enable_prepare_warnings command can be used to change this so
- that warnings from both the prepare and execute phase are shown.
- */
- if (!disable_warnings && !prepare_warnings_enabled)
- dynstr_set(&ds_prepare_warnings, NULL);
- }
- else
- {
- /*
- This is a query without resultset
- */
- }
+ /*
+ Normally, if there is a result set, we do not show warnings from the
+ prepare phase. This is because some warnings are generated both during
+ prepare and execute; this would generate different warning output
+ between normal and ps-protocol test runs.
- /*
- Fetch info before fetching warnings, since it will be reset
- otherwise.
- */
- if (!disable_info)
- append_info(ds, mysql_stmt_affected_rows(stmt), mysql_info(mysql));
+ The --enable_prepare_warnings command can be used to change this so
+ that warnings from both the prepare and execute phase are shown.
+ */
+ if (!disable_warnings && !prepare_warnings_enabled)
+ dynstr_set(&ds_prepare_warnings, NULL);
+ }
+ else
+ {
+ /*
+ This is a query without resultset
+ */
+ }
- if (display_session_track_info)
- append_session_track_info(ds, mysql);
+ /*
+ Fetch info before fetching warnings, since it will be reset
+ otherwise.
+ */
+ if (!disable_info)
+ append_info(ds, mysql_stmt_affected_rows(stmt), mysql_info(mysql));
+ if (display_session_track_info)
+ append_session_track_info(ds, mysql);
- if (!disable_warnings)
- {
- /* Get the warnings from execute */
- /* Append warnings to ds - if there are any */
- if (append_warnings(&ds_execute_warnings, mysql) ||
- ds_execute_warnings.length ||
- ds_prepare_warnings.length ||
- ds_warnings->length)
+ if (!disable_warnings)
{
- dynstr_append_mem(ds, "Warnings:\n", 10);
- if (ds_warnings->length)
- dynstr_append_mem(ds, ds_warnings->str,
- ds_warnings->length);
- if (ds_prepare_warnings.length)
- dynstr_append_mem(ds, ds_prepare_warnings.str,
- ds_prepare_warnings.length);
- if (ds_execute_warnings.length)
- dynstr_append_mem(ds, ds_execute_warnings.str,
- ds_execute_warnings.length);
+ /* Get the warnings from execute */
+
+ /* Append warnings to ds - if there are any */
+ if (append_warnings(&ds_execute_warnings, mysql) ||
+ ds_execute_warnings.length ||
+ ds_prepare_warnings.length ||
+ ds_warnings->length)
+ {
+ dynstr_append_mem(ds, "Warnings:\n", 10);
+ if (ds_warnings->length)
+ dynstr_append_mem(ds, ds_warnings->str,
+ ds_warnings->length);
+ if (ds_prepare_warnings.length)
+ dynstr_append_mem(ds, ds_prepare_warnings.str,
+ ds_prepare_warnings.length);
+ if (ds_execute_warnings.length)
+ dynstr_append_mem(ds, ds_execute_warnings.str,
+ ds_execute_warnings.length);
+ }
}
}
- }
+ } while ( !(err= mysql_stmt_next_result(stmt)));
+ if (err > 0)
+ /* We got an error from mysql_next_result, maybe expected */
+ handle_error(command, mysql_errno(mysql), mysql_error(mysql),
+ mysql_sqlstate(mysql), ds);
+ else
+ handle_no_error(command);
end:
if (!disable_warnings)
{
@@ -8720,7 +8728,13 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
*/
if (ps_protocol_enabled &&
complete_query &&
- match_re(&ps_re, query))
+ /*
+ Check that a statement is not one of PREPARE FROM, EXECUTE,
+ DEALLOCATE PREPARE (possibly prefixed with the 'SET STATEMENT ... FOR'
+ clause. These statement shouldn't be run using prepared statement C API.
+ All other statements can be run using prepared statement C API.
+ */
+ !match_re(&ps_re, query))
run_query_stmt(cn, command, query, query_len, ds, &ds_warnings);
else
run_query_normal(cn, command, flags, query, query_len,
@@ -8794,10 +8808,30 @@ void init_re_comp(regex_t *re, const char* str)
void init_re(void)
{
/*
+ * Prior to the task MDEV-16708 a value of the string ps_re_str contained
+ * a regular expression to match statements that SHOULD BE run in PS mode.
+ * The task MDEV-16708 modifies interpretation of this regular expression
+ * and now it is used for matching statements that SHOULDN'T be run in
+ * PS mode. These statement are PREPARE FROM, EXECUTE, DEALLOCATE PREPARE
+ * possibly prefixed with the clause SET STATEMENT ... FOR
+ */
+ const char *ps_re_str =
+ "^("
+ "[[:space:]]*PREPARE[[:space:]]|"
+ "[[:space:]]*EXECUTE[[:space:]]|"
+ "[[:space:]]*DEALLOCATE[[:space:]]+PREPARE[[:space:]]|"
+ "[[:space:]]*DROP[[:space:]]+PREPARE[[:space:]]|"
+ "(SET[[:space:]]+STATEMENT[[:space:]]+.+[[:space:]]+FOR[[:space:]]+)?"
+ "EXECUTE[[:space:]]+|"
+ "(SET[[:space:]]+STATEMENT[[:space:]]+.+[[:space:]]+FOR[[:space:]]+)?"
+ "PREPARE[[:space:]]+"
+ ")";
+
+ /*
Filter for queries that can be run using the
- MySQL Prepared Statements C API
+ Stored procedures
*/
- const char *ps_re_str =
+ const char *sp_re_str =
"^("
"[[:space:]]*ALTER[[:space:]]+SEQUENCE[[:space:]]|"
"[[:space:]]*ALTER[[:space:]]+TABLE[[:space:]]|"
@@ -8851,12 +8885,6 @@ void init_re(void)
")";
/*
- Filter for queries that can be run using the
- Stored procedures
- */
- const char *sp_re_str =ps_re_str;
-
- /*
Filter for queries that can be run as views
*/
const char *view_re_str =
diff --git a/mysql-test/include/column_compression_syntax_varbinary.inc b/mysql-test/include/column_compression_syntax_varbinary.inc
index b609969fc14..e2f96c33d06 100644
--- a/mysql-test/include/column_compression_syntax_varbinary.inc
+++ b/mysql-test/include/column_compression_syntax_varbinary.inc
@@ -28,6 +28,8 @@ DROP TABLE t1;
--echo # The following statements return deprecated syntax warnings
--echo #
+--enable_prepare_warnings
+
--eval CREATE TABLE t1 (a $type DEFAULT '' COMPRESSED)
SHOW CREATE TABLE t1;
DROP TABLE t1;
@@ -35,6 +37,7 @@ DROP TABLE t1;
SHOW CREATE TABLE t1;
DROP TABLE t1;
+--disable_prepare_warnings
--echo #
--echo # The following statements fail by the grammar,
diff --git a/mysql-test/include/column_compression_syntax_varchar.inc b/mysql-test/include/column_compression_syntax_varchar.inc
index 6b96440c511..41ace4fe5f6 100644
--- a/mysql-test/include/column_compression_syntax_varchar.inc
+++ b/mysql-test/include/column_compression_syntax_varchar.inc
@@ -53,6 +53,8 @@ DROP TABLE t1;
--echo # The following statements return deprecated syntax warnings
--echo #
+--enable_prepare_warnings
+
--eval CREATE TABLE t1 (a $type BINARY COMPRESSED)
SHOW CREATE TABLE t1;
DROP TABLE t1;
@@ -63,6 +65,7 @@ DROP TABLE t1;
SHOW CREATE TABLE t1;
DROP TABLE t1;
+--disable_prepare_warnings
--echo #
--echo # The following statements fail by the grammar,
diff --git a/mysql-test/include/ctype_numconv.inc b/mysql-test/include/ctype_numconv.inc
index 889c80cc477..d99942c5d5f 100644
--- a/mysql-test/include/ctype_numconv.inc
+++ b/mysql-test/include/ctype_numconv.inc
@@ -1043,7 +1043,7 @@ update t1 set a= a + 0.1;
select a, hex(a) from t1;
drop table t1;
-
+--enable_prepare_warnings
#
# Columns
#
@@ -1203,7 +1203,6 @@ create table t2 as select concat(a) from t1;
show create table t2;
drop table t1, t2;
-
#
# create view with string functions with numeric input
#
@@ -1517,6 +1516,7 @@ select hex(a) from v1;
drop table t1;
drop view v1;
+--disable_prepare_warnings
#
# User defined function returning numeric result
#
diff --git a/mysql-test/include/explain_utils.inc b/mysql-test/include/explain_utils.inc
index 505798e432a..15376b76610 100644
--- a/mysql-test/include/explain_utils.inc
+++ b/mysql-test/include/explain_utils.inc
@@ -28,9 +28,11 @@
--echo #
if ($select) {
+--enable_prepare_warnings
--disable_query_log
--eval $select INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/before_explain.txt'
--enable_query_log
+--disable_prepare_warnings
}
if ($innodb) {
@@ -122,7 +124,9 @@ if ($validation) {
--disable_query_log
if ($select) {
+--enable_prepare_warnings
--eval $select INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/after_explain.txt'
+--disable_prepare_warnings
--diff_files '$MYSQLTEST_VARDIR/tmp/before_explain.txt' '$MYSQLTEST_VARDIR/tmp/after_explain.txt'
--remove_file '$MYSQLTEST_VARDIR/tmp/before_explain.txt'
--remove_file '$MYSQLTEST_VARDIR/tmp/after_explain.txt'
diff --git a/mysql-test/main/bug12427262.test b/mysql-test/main/bug12427262.test
index aca37a651c4..3a5642516a8 100644
--- a/mysql-test/main/bug12427262.test
+++ b/mysql-test/main/bug12427262.test
@@ -21,6 +21,7 @@ create table t10 (c1 int);
--enable_warnings
# Query PS to know initial read count for frm file.
+--enable_prepare_warnings
select Sum(ALL(COUNT_READ)) from performance_schema.file_summary_by_instance where FILE_NAME
like "%show_table_lw_db%" AND FILE_NAME like "%.frm%" AND EVENT_NAME='wait/io/file/sql/FRM'
into @count_read_before;
@@ -45,6 +46,7 @@ into @count_read_after;
select @count_read_after-@count_read_before;
+--disable_prepare_warnings
--disable_warnings
drop table t1;
drop database show_table_lw_db;
diff --git a/mysql-test/main/column_compression.test b/mysql-test/main/column_compression.test
index 2ae50be95d2..52235b07811 100644
--- a/mysql-test/main/column_compression.test
+++ b/mysql-test/main/column_compression.test
@@ -29,6 +29,7 @@ let $typec= BLOB COMPRESSED;
let $typeu= BLOB;
--source column_compression.inc
+--enable_prepare_warnings
--error ER_PARSE_ERROR
CREATE TABLE t1(a CHAR(100) COMPRESSED);
--error ER_WRONG_FIELD_SPEC
@@ -291,6 +292,7 @@ CREATE TABLE t1 (a VARCHAR(1000) COMPRESSED, FULLTEXT INDEX(a));
--error ER_COMPRESSED_COLUMN_USED_AS_KEY
CREATE TABLE t1 (a TEXT COMPRESSED, FULLTEXT INDEX(a));
+--disable_prepare_warnings
--echo #
--echo # End of 10.5 tests
--echo #
diff --git a/mysql-test/main/compound.result b/mysql-test/main/compound.result
index 18df4fd34e2..6efa23e833f 100644
--- a/mysql-test/main/compound.result
+++ b/mysql-test/main/compound.result
@@ -101,7 +101,7 @@ t1
t2
t3
t4
-set @a=0;
+set @a=0|
repeat
set @a = @a + 1;
until @a > 5
@@ -154,7 +154,7 @@ master-bin.000001 # Query # # use `test`; insert t1 values( NAME_CONST('a',4)+3)
master-bin.000001 # Query # # COMMIT
drop function fn|
drop table t1|
-set @@sql_mode="STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";
+set @@sql_mode="STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"|
begin not atomic select @@sql_mode; end|
@@sql_mode
STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
diff --git a/mysql-test/main/compound.test b/mysql-test/main/compound.test
index 1f901e2a2b3..c902ef77b52 100644
--- a/mysql-test/main/compound.test
+++ b/mysql-test/main/compound.test
@@ -94,7 +94,7 @@ end loop|
show tables|
# REPEAT
-set @a=0;
+set @a=0|
repeat
set @a = @a + 1;
until @a > 5
@@ -146,7 +146,7 @@ drop table t1|
# MDEV-6609 SQL inside an anonymous block is executed with wrong SQL_MODE
#
-set @@sql_mode="STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";
+set @@sql_mode="STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"|
begin not atomic select @@sql_mode; end|
create table t1 (a int)|
select a from t1 having a > 1|
diff --git a/mysql-test/main/cte_recursive.test b/mysql-test/main/cte_recursive.test
index 125e22ebfa6..dea7f6e8b8e 100644
--- a/mysql-test/main/cte_recursive.test
+++ b/mysql-test/main/cte_recursive.test
@@ -1,3 +1,7 @@
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Test temporary disabled for ps-protocol
+}
--source include/default_optimizer_switch.inc
create table t1 (a int, b varchar(32));
diff --git a/mysql-test/main/ctype_gbk.test b/mysql-test/main/ctype_gbk.test
index c63c331c643..d68b78f847c 100644
--- a/mysql-test/main/ctype_gbk.test
+++ b/mysql-test/main/ctype_gbk.test
@@ -63,8 +63,10 @@ CREATE TABLE t1(a MEDIUMTEXT CHARACTER SET gbk,
INSERT INTO t1 VALUES
(REPEAT(0x1125,200000), REPEAT(0x1125,200000)), ('', ''), ('', '');
+--enable_prepare_warnings
SELECT a FROM t1 GROUP BY 1 LIMIT 1 INTO @nullll;
SELECT b FROM t1 GROUP BY 1 LIMIT 1 INTO @nullll;
+--disable_prepare_warnings
DROP TABLES t1;
diff --git a/mysql-test/main/ctype_ucs.test b/mysql-test/main/ctype_ucs.test
index cdc86fa3283..7c798e0a201 100644
--- a/mysql-test/main/ctype_ucs.test
+++ b/mysql-test/main/ctype_ucs.test
@@ -75,7 +75,9 @@ DROP TABLE t1;
--echo # Problem # 1 (original report): wrong parsing of ucs2 data
SET character_set_connection=ucs2;
+--enable_prepare_warnings
SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp.txt';
+--disable_prepare_warnings
CREATE TABLE t1(a INT);
LOAD DATA INFILE 'tmpp.txt' INTO TABLE t1 CHARACTER SET ucs2
(@b) SET a=REVERSE(@b);
@@ -88,7 +90,9 @@ remove_file $MYSQLD_DATADIR/test/tmpp.txt;
--echo # Problem # 2 : if you write and read ucs2 data to a file they're lost
+--enable_prepare_warnings
SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp2.txt' CHARACTER SET ucs2;
+--disable_prepare_warnings
CREATE TABLE t1(a INT);
LOAD DATA INFILE 'tmpp2.txt' INTO TABLE t1 CHARACTER SET ucs2
(@b) SET a=REVERSE(@b);
diff --git a/mysql-test/main/delayed.test b/mysql-test/main/delayed.test
index a96ffdfcca9..862d30fe79f 100644
--- a/mysql-test/main/delayed.test
+++ b/mysql-test/main/delayed.test
@@ -636,8 +636,10 @@ insert into t1 values (1,1);
call mtr.add_suppression(" marked as crashed and should be repaired");
call mtr.add_suppression("Checking table");
+--enable_prepare_warnings
--replace_result '\\' '/'
insert delayed into t1 values (2,2);
+--disable_prepare_warnings
insert delayed into t1 values (3,3);
flush tables t1;
select * from t1;
diff --git a/mysql-test/main/derived.test b/mysql-test/main/derived.test
index 8c41f80ffbd..0d2efca1a26 100644
--- a/mysql-test/main/derived.test
+++ b/mysql-test/main/derived.test
@@ -475,8 +475,10 @@ CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (8);
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1),(7);
+--enable_prepare_warnings
EXPLAIN SELECT * FROM (SELECT * FROM t1) AS table1,
(SELECT DISTINCT * FROM t2) AS table2 WHERE b = a AND a <> ANY (SELECT 9);
+--disable_prepare_warnings
DROP TABLE t1, t2;
set optimizer_switch=@save_derived_optimizer_switch_bug;
diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test
index fb227e85ee6..e6ee05dd644 100644
--- a/mysql-test/main/derived_cond_pushdown.test
+++ b/mysql-test/main/derived_cond_pushdown.test
@@ -1064,9 +1064,10 @@ DROP TABLE t1,t2;
CREATE TABLE t1 (i INT);
CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
INSERT INTO t1 VALUES (1),(2);
-
+--enable_prepare_warnings
EXPLAIN FORMAT=JSON
SELECT * FROM v1 WHERE i <= ANY ( SELECT 3 );
+--disable_prepare_warnings
SELECT * FROM v1 WHERE i <= ANY ( SELECT 3 );
diff --git a/mysql-test/main/events_logs_tests.result b/mysql-test/main/events_logs_tests.result
index ac4a43118da..d332767a9f1 100644
--- a/mysql-test/main/events_logs_tests.result
+++ b/mysql-test/main/events_logs_tests.result
@@ -11,7 +11,8 @@ test suite is run in normal mode or with --ps-protocol
create procedure select_general_log()
begin
select user_host, argument from mysql.general_log
-where argument like '%events_logs_test%';
+where argument like '%events_logs_test%' AND
+(command_type = 'Query' OR command_type = 'Execute');
end|
Check that general query log works, but sub-statements
diff --git a/mysql-test/main/events_logs_tests.test b/mysql-test/main/events_logs_tests.test
index c4ef133f46b..7cd664b30df 100644
--- a/mysql-test/main/events_logs_tests.test
+++ b/mysql-test/main/events_logs_tests.test
@@ -17,7 +17,8 @@ delimiter |;
create procedure select_general_log()
begin
select user_host, argument from mysql.general_log
- where argument like '%events_logs_test%';
+ where argument like '%events_logs_test%' AND
+ (command_type = 'Query' OR command_type = 'Execute');
end|
delimiter ;|
--echo
diff --git a/mysql-test/main/events_restart.test b/mysql-test/main/events_restart.test
index f56bd32b71d..b96a3954e33 100644
--- a/mysql-test/main/events_restart.test
+++ b/mysql-test/main/events_restart.test
@@ -1,6 +1,6 @@
# Can't test with embedded server that doesn't support grants
-- source include/not_embedded.inc
-
+--disable_ps_protocol
call mtr.add_suppression("Column count of mysql.event is wrong. Expected .*, found .*\. The table is probably corrupted");
let $collation_server=`select @@collation_server`;
@@ -172,3 +172,4 @@ select name, originator, status from mysql.event;
# Cleanup
drop event ev;
+--enable_ps_protocol
diff --git a/mysql-test/main/features.test b/mysql-test/main/features.test
index d0f5263c5c3..0761380c812 100644
--- a/mysql-test/main/features.test
+++ b/mysql-test/main/features.test
@@ -1,4 +1,8 @@
# Testing of feature statistics
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Test temporary disabled for ps-protocol
+}
-- source include/have_geometry.inc
diff --git a/mysql-test/main/fetch_first.test b/mysql-test/main/fetch_first.test
index 76c0a8b8b39..61d681a9b28 100644
--- a/mysql-test/main/fetch_first.test
+++ b/mysql-test/main/fetch_first.test
@@ -1,3 +1,7 @@
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Test temporary disabled for ps-protocol
+}
--echo #
--echo # The following entries are meant for testing the parser, ensuring
--echo # the right values are passed down to the executor, for all possible
diff --git a/mysql-test/main/func_group.test b/mysql-test/main/func_group.test
index a28b39c28f6..94cb552aa8b 100644
--- a/mysql-test/main/func_group.test
+++ b/mysql-test/main/func_group.test
@@ -2,6 +2,11 @@
# simple test of all group functions
#
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Test temporary disabled for ps-protocol
+}
+
--disable_warnings
drop table if exists t1,t2,t3,t4,t5,t6;
--enable_warnings
@@ -1070,7 +1075,9 @@ DROP TABLE t1;
--echo #
--echo # Bug#43668: Wrong comparison and MIN/MAX for YEAR(2)
--echo #
+--enable_prepare_warnings
create table t1 (f1 year(2), f2 year(4), f3 date, f4 datetime);
+--disable_prepare_warnings
insert into t1 values
(98,1998,19980101,"1998-01-01 00:00:00"),
(00,2000,20000101,"2000-01-01 00:00:01"),
diff --git a/mysql-test/main/func_time.test b/mysql-test/main/func_time.test
index 970d3e44a77..f0bfb926f83 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);
@@ -2226,6 +2228,7 @@ SET @sav_slow_query_log= @@session.slow_query_log;
SET @@session.slow_query_log= ON;
SELECT current_timestamp(6),fn_sleep_before_now() INTO @ts_cur, @ts_func;
+--enable_prepare_warnings
SELECT a FROM t_ts LIMIT 1 into @ts_func;
SELECT a FROM t_trig LIMIT 1 into @ts_trig;
if (!`SELECT @ts_cur = @ts_func and @ts_func = @ts_trig`)
@@ -2241,6 +2244,8 @@ SET @@session.slow_query_log= OFF;
SELECT current_timestamp(6),fn_sleep_before_now() INTO @ts_cur, @func_ts;
SELECT a FROM t_ts LIMIT 1 into @ts_func;
SELECT a FROM t_trig LIMIT 1 into @ts_trig;
+--disable_prepare_warnings
+
if (!`SELECT @ts_cur = @ts_func and @ts_func = @ts_trig`)
{
SELECT @ts_cur, @ts_func, @ts_trig;
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/grant.test b/mysql-test/main/grant.test
index 82b68b3b6e6..c8ca440b3e8 100644
--- a/mysql-test/main/grant.test
+++ b/mysql-test/main/grant.test
@@ -1239,12 +1239,14 @@ drop function if exists test_function;
drop view if exists v1;
create table test (col1 varchar(30));
delimiter |;
+--enable_prepare_warnings
create function test_function() returns varchar(30)
begin
declare tmp varchar(30);
select col1 from test limit 1 into tmp;
return '1';
end|
+--disable_prepare_warnings
delimiter ;|
create view v1 as select test.* from test where test.col1=test_function();
grant update (col1) on v1 to 'greg'@'localhost';
diff --git a/mysql-test/main/grant2.test b/mysql-test/main/grant2.test
index f98af8d8630..b8098488709 100644
--- a/mysql-test/main/grant2.test
+++ b/mysql-test/main/grant2.test
@@ -524,8 +524,10 @@ INSERT INTO t2 VALUES (1);
DROP FUNCTION IF EXISTS f2;
--enable_warnings
delimiter //;
+--enable_prepare_warnings
CREATE FUNCTION f2 () RETURNS INT
BEGIN DECLARE v INT; SELECT s1 FROM t2 INTO v; RETURN v; END//
+--disable_prepare_warnings
delimiter ;//
SELECT f2();
diff --git a/mysql-test/main/having_cond_pushdown.test b/mysql-test/main/having_cond_pushdown.test
index fc75122615c..60ed7ebb660 100644
--- a/mysql-test/main/having_cond_pushdown.test
+++ b/mysql-test/main/having_cond_pushdown.test
@@ -73,14 +73,18 @@ GROUP BY t1.a
HAVING (t1.a>1) OR (a IN (SELECT 3));
eval $no_pushdown $query;
eval $query;
+--enable_prepare_warnings
eval explain $query;
eval explain format=json $query;
+--disable_prepare_warnings
let $query=
SELECT t1.a,MAX(t1.b)
FROM t1
WHERE (t1.a>1) OR (a IN (SELECT 3))
GROUP BY t1.a;
+--enable_prepare_warnings
eval $no_pushdown explain format=json $query;
+--disable_prepare_warnings
let $query=
SELECT t1.a,MAX(t1.b),MIN(t1.c)
diff --git a/mysql-test/main/information_schema_db.test b/mysql-test/main/information_schema_db.test
index 7cf8c0801e6..1dd0f84bc09 100644
--- a/mysql-test/main/information_schema_db.test
+++ b/mysql-test/main/information_schema_db.test
@@ -35,12 +35,14 @@ grant all privileges on `inf%`.* to 'mysqltest_1'@'localhost';
grant all privileges on `mbase`.* to 'mysqltest_1'@'localhost';
create table t1 (f1 int);
delimiter |;
+--enable_prepare_warnings
create function func1(curr_int int) returns int
begin
declare ret_val int;
select max(f1) from t1 into ret_val;
return ret_val;
end|
+--disable_prepare_warnings
delimiter ;|
create view v1 as select f1 from t1 where f1 = func1(f1);
create function func2() returns int return 1;
diff --git a/mysql-test/main/innodb_mysql_lock2.test b/mysql-test/main/innodb_mysql_lock2.test
index b983fd8dc7a..09298a900b1 100644
--- a/mysql-test/main/innodb_mysql_lock2.test
+++ b/mysql-test/main/innodb_mysql_lock2.test
@@ -71,6 +71,7 @@ insert into t5 values (1);
create view v1 as select i from t1;
create view v2 as select j from t2 where j in (select i from t1);
create procedure p1(k int) insert into t2 values (k);
+--enable_prepare_warnings
delimiter |;
create function f1() returns int
begin
@@ -192,6 +193,7 @@ begin
set new.l= j + 1;
end|
delimiter ;|
+--disable_prepare_warnings
--echo #
--echo # Set common variables to be used by scripts called below.
diff --git a/mysql-test/main/invisible_field.test b/mysql-test/main/invisible_field.test
index 7a48347ec29..f3f8fc8f19c 100644
--- a/mysql-test/main/invisible_field.test
+++ b/mysql-test/main/invisible_field.test
@@ -251,6 +251,7 @@ DROP TABLE t1;
create or replace table t1 (a int, b int invisible);
insert into t1 values (1),(2);
+--enable_prepare_warnings
select * from t1 into outfile 'f';
load data infile 'f' into table t1;
select a,b from t1;
@@ -277,5 +278,6 @@ drop table t1;
--echo #
create table t1 (a int, b int invisible);
insert delayed into t1 values (1);
+--disable_prepare_warnings
# cleanup
drop table t1;
diff --git a/mysql-test/main/join_cache.result b/mysql-test/main/join_cache.result
index 79c5b7923bd..0fbb73f56fe 100644
--- a/mysql-test/main/join_cache.result
+++ b/mysql-test/main/join_cache.result
@@ -5993,14 +5993,14 @@ create table t3 (c3 int);
insert into t1 values (1), (2);
insert into t2 values (1), (2);
insert into t3 values (2);
+set @counter=0;
explain
select count(*) from t1 straight_join t2
where c1 = c2-0 and c2 <= (select max(c3) from t3 where c3 = 2 and @counter:=@counter+1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
-2 UNCACHEABLE SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-set @counter=0;
+2 UNCACHEABLE SUBQUERY t3 system NULL NULL NULL NULL 1
select count(*) from t1 straight_join t2
where c1 = c2-0 and c2 <= (select max(c3) from t3 where c3 = 2 and @counter:=@counter+1);
count(*)
diff --git a/mysql-test/main/join_cache.test b/mysql-test/main/join_cache.test
index b4271f648e3..4b659345db4 100644
--- a/mysql-test/main/join_cache.test
+++ b/mysql-test/main/join_cache.test
@@ -3998,12 +3998,12 @@ insert into t1 values (1), (2);
insert into t2 values (1), (2);
insert into t3 values (2);
+set @counter=0;
+
explain
select count(*) from t1 straight_join t2
where c1 = c2-0 and c2 <= (select max(c3) from t3 where c3 = 2 and @counter:=@counter+1);
-set @counter=0;
-
select count(*) from t1 straight_join t2
where c1 = c2-0 and c2 <= (select max(c3) from t3 where c3 = 2 and @counter:=@counter+1);
diff --git a/mysql-test/main/limit_rows_examined.test b/mysql-test/main/limit_rows_examined.test
index 2315580410f..c2514ac70b3 100644
--- a/mysql-test/main/limit_rows_examined.test
+++ b/mysql-test/main/limit_rows_examined.test
@@ -2,6 +2,11 @@
# Tests for LIMIT ROWS EXAMINED, MDEV-28
#
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Test temporary disabled for ps-protocol
+}
+
--source include/default_optimizer_switch.inc
call mtr.add_suppression("Sort aborted.*");
diff --git a/mysql-test/main/lock_sync.test b/mysql-test/main/lock_sync.test
index 1a8cd7bdbd3..16367d74800 100644
--- a/mysql-test/main/lock_sync.test
+++ b/mysql-test/main/lock_sync.test
@@ -82,6 +82,7 @@ create view v1 as select i from t1;
create view v2 as select j from t2 where j in (select i from t1);
create procedure p1(k int) insert into t2 values (k);
delimiter |;
+--enable_prepare_warnings
create function f1() returns int
begin
declare j int;
@@ -223,6 +224,8 @@ begin
end|
delimiter ;|
+--disable_prepare_warnings
+
--echo #
--echo # Set common variables to be used by the scripts
--echo # called below.
diff --git a/mysql-test/main/locking_clause.test b/mysql-test/main/locking_clause.test
index a27546a5cab..acba190b29f 100644
--- a/mysql-test/main/locking_clause.test
+++ b/mysql-test/main/locking_clause.test
@@ -150,6 +150,7 @@ DROP USER test2@localhost;
--echo # MYSQL 8
--echo #
+--enable_prepare_warnings
SELECT 1 FROM DUAL LIMIT 1 INTO @var FOR UPDATE;
SELECT 1 FROM DUAL LIMIT 1 FOR UPDATE INTO @var;
@@ -159,3 +160,4 @@ SELECT 1 FROM DUAL LIMIT 1 INTO @var FOR UPDATE INTO @var;
SELECT 1 UNION SELECT 1 FOR UPDATE INTO @var;
SELECT 1 UNION SELECT 1 INTO @var FOR UPDATE;
+--disable_prepare_warnings
diff --git a/mysql-test/main/log_tables.result b/mysql-test/main/log_tables.result
index 4642b1c6876..e20d3db2daf 100644
--- a/mysql-test/main/log_tables.result
+++ b/mysql-test/main/log_tables.result
@@ -792,10 +792,11 @@ set @lparam = "000 001 002 003 004 005 006 007 008 009"
prepare long_query from "select ? as long_query";
execute long_query using @lparam;
set global general_log = off;
-select command_type, argument from mysql.general_log where thread_id = @thread_id;
-command_type argument
-Query set global general_log = on
-Query set @lparam = "000 001 002 003 004 005 006 007 008 009"
+select argument from mysql.general_log where thread_id = @thread_id
+AND (command_type = 'Query' OR command_type= 'Execute');
+argument
+set global general_log = on
+set @lparam = "000 001 002 003 004 005 006 007 008 009"
"010 011 012 013 014 015 016 017 018 019"
"020 021 022 023 024 025 026 027 028 029"
"030 031 032 033 034 035 036 037 038 039"
@@ -895,11 +896,10 @@ Query set @lparam = "000 001 002 003 004 005 006 007 008 009"
"970 971 972 973 974 975 976 977 978 979"
"980 981 982 983 984 985 986 987 988 989"
"990 991 992 993 994 995 996 997 998 999"
-Query prepare long_query from "select ? as long_query"
-Prepare select ? as long_query
-Query execute long_query using @lparam
-Execute select '000 001 002 003 004 005 006 007 008 009010 011 012 013 014 015 016 017 018 019020 021 022 023 024 025 026 027 028 029030 031 032 033 034 035 036 037 038 039040 041 042 043 044 045 046 047 048 049050 051 052 053 054 055 056 057 058 059060 061 062 063 064 065 066 067 068 069070 071 072 073 074 075 076 077 078 079080 081 082 083 084 085 086 087 088 089090 091 092 093 094 095 096 097 098 099100 101 102 103 104 105 106 107 108 109110 111 112 113 114 115 116 117 118 119120 121 122 123 124 125 126 127 128 129130 131 132 133 134 135 136 137 138 139140 141 142 143 144 145 146 147 148 149150 151 152 153 154 155 156 157 158 159160 161 162 163 164 165 166 167 168 169170 171 172 173 174 175 176 177 178 179180 181 182 183 184 185 186 187 188 189190 191 192 193 194 195 196 197 198 199200 201 202 203 204 205 206 207 208 209210 211 212 213 214 215 216 217 218 219220 221 222 223 224 225 226 227 228 229230 231 232 233 234 235 236 237 238 239240 241 242 243 244 245 246 247 248 249250 251 252 253 254 255 256 257 258 259260 261 262 263 264 265 266 267 268 269270 271 272 273 274 275 276 277 278 279280 281 282 283 284 285 286 287 288 289290 291 292 293 294 295 296 297 298 299300 301 302 303 304 305 306 307 308 309310 311 312 313 314 315 316 317 318 319320 321 322 323 324 325 326 327 328 329330 331 332 333 334 335 336 337 338 339340 341 342 343 344 345 346 347 348 349350 351 352 353 354 355 356 357 358 359360 361 362 363 364 365 366 367 368 369370 371 372 373 374 375 376 377 378 379380 381 382 383 384 385 386 387 388 389390 391 392 393 394 395 396 397 398 399400 401 402 403 404 405 406 407 408 409410 411 412 413 414 415 416 417 418 419420 421 422 423 424 425 426 427 428 429430 431 432 433 434 435 436 437 438 439440 441 442 443 444 445 446 447 448 449450 451 452 453 454 455 456 457 458 459460 461 462 463 464 465 466 467 468 469470 471 472 473 474 475 476 477 478 479480 481 482 483 484 485 486 487 488 489490 491 492 493 494 495 496 497 498 499500 501 502 503 504 505 506 507 508 509510 511 512 513 514 515 516 517 518 519520 521 522 523 524 525 526 527 528 529530 531 532 533 534 535 536 537 538 539540 541 542 543 544 545 546 547 548 549550 551 552 553 554 555 556 557 558 559560 561 562 563 564 565 566 567 568 569570 571 572 573 574 575 576 577 578 579580 581 582 583 584 585 586 587 588 589590 591 592 593 594 595 596 597 598 599600 601 602 603 604 605 606 607 608 609610 611 612 613 614 615 616 617 618 619620 621 622 623 624 625 626 627 628 629630 631 632 633 634 635 636 637 638 639640 641 642 643 644 645 646 647 648 649650 651 652 653 654 655 656 657 658 659660 661 662 663 664 665 666 667 668 669670 671 672 673 674 675 676 677 678 679680 681 682 683 684 685 686 687 688 689690 691 692 693 694 695 696 697 698 699700 701 702 703 704 705 706 707 708 709710 711 712 713 714 715 716 717 718 719720 721 722 723 724 725 726 727 728 729730 731 732 733 734 735 736 737 738 739740 741 742 743 744 745 746 747 748 749750 751 752 753 754 755 756 757 758 759760 761 762 763 764 765 766 767 768 769770 771 772 773 774 775 776 777 778 779780 781 782 783 784 785 786 787 788 789790 791 792 793 794 795 796 797 798 799800 801 802 803 804 805 806 807 808 809810 811 812 813 814 815 816 817 818 819820 821 822 823 824 825 826 827 828 829830 831 832 833 834 835 836 837 838 839840 841 842 843 844 845 846 847 848 849850 851 852 853 854 855 856 857 858 859860 861 862 863 864 865 866 867 868 869870 871 872 873 874 875 876 877 878 879880 881 882 883 884 885 886 887 888 889890 891 892 893 894 895 896 897 898 899900 901 902 903 904 905 906 907 908 909910 911 912 913 914 915 916 917 918 919920 921 922 923 924 925 926 927 928 929930 931 932 933 934 935 936 937 938 939940 941 942 943 944 945 946 947 948 949950 951 952 953 954 955 956 957 958 959960 961 962 963 964 965 966 967 968 969970 971 972 973 974 975 976 977 978 979980 981 982 983 984 985 986 987 988 989990 991 992 993 994 995 996 997 998 999' as long_query
-Query set global general_log = off
+prepare long_query from "select ? as long_query"
+execute long_query using @lparam
+select '000 001 002 003 004 005 006 007 008 009010 011 012 013 014 015 016 017 018 019020 021 022 023 024 025 026 027 028 029030 031 032 033 034 035 036 037 038 039040 041 042 043 044 045 046 047 048 049050 051 052 053 054 055 056 057 058 059060 061 062 063 064 065 066 067 068 069070 071 072 073 074 075 076 077 078 079080 081 082 083 084 085 086 087 088 089090 091 092 093 094 095 096 097 098 099100 101 102 103 104 105 106 107 108 109110 111 112 113 114 115 116 117 118 119120 121 122 123 124 125 126 127 128 129130 131 132 133 134 135 136 137 138 139140 141 142 143 144 145 146 147 148 149150 151 152 153 154 155 156 157 158 159160 161 162 163 164 165 166 167 168 169170 171 172 173 174 175 176 177 178 179180 181 182 183 184 185 186 187 188 189190 191 192 193 194 195 196 197 198 199200 201 202 203 204 205 206 207 208 209210 211 212 213 214 215 216 217 218 219220 221 222 223 224 225 226 227 228 229230 231 232 233 234 235 236 237 238 239240 241 242 243 244 245 246 247 248 249250 251 252 253 254 255 256 257 258 259260 261 262 263 264 265 266 267 268 269270 271 272 273 274 275 276 277 278 279280 281 282 283 284 285 286 287 288 289290 291 292 293 294 295 296 297 298 299300 301 302 303 304 305 306 307 308 309310 311 312 313 314 315 316 317 318 319320 321 322 323 324 325 326 327 328 329330 331 332 333 334 335 336 337 338 339340 341 342 343 344 345 346 347 348 349350 351 352 353 354 355 356 357 358 359360 361 362 363 364 365 366 367 368 369370 371 372 373 374 375 376 377 378 379380 381 382 383 384 385 386 387 388 389390 391 392 393 394 395 396 397 398 399400 401 402 403 404 405 406 407 408 409410 411 412 413 414 415 416 417 418 419420 421 422 423 424 425 426 427 428 429430 431 432 433 434 435 436 437 438 439440 441 442 443 444 445 446 447 448 449450 451 452 453 454 455 456 457 458 459460 461 462 463 464 465 466 467 468 469470 471 472 473 474 475 476 477 478 479480 481 482 483 484 485 486 487 488 489490 491 492 493 494 495 496 497 498 499500 501 502 503 504 505 506 507 508 509510 511 512 513 514 515 516 517 518 519520 521 522 523 524 525 526 527 528 529530 531 532 533 534 535 536 537 538 539540 541 542 543 544 545 546 547 548 549550 551 552 553 554 555 556 557 558 559560 561 562 563 564 565 566 567 568 569570 571 572 573 574 575 576 577 578 579580 581 582 583 584 585 586 587 588 589590 591 592 593 594 595 596 597 598 599600 601 602 603 604 605 606 607 608 609610 611 612 613 614 615 616 617 618 619620 621 622 623 624 625 626 627 628 629630 631 632 633 634 635 636 637 638 639640 641 642 643 644 645 646 647 648 649650 651 652 653 654 655 656 657 658 659660 661 662 663 664 665 666 667 668 669670 671 672 673 674 675 676 677 678 679680 681 682 683 684 685 686 687 688 689690 691 692 693 694 695 696 697 698 699700 701 702 703 704 705 706 707 708 709710 711 712 713 714 715 716 717 718 719720 721 722 723 724 725 726 727 728 729730 731 732 733 734 735 736 737 738 739740 741 742 743 744 745 746 747 748 749750 751 752 753 754 755 756 757 758 759760 761 762 763 764 765 766 767 768 769770 771 772 773 774 775 776 777 778 779780 781 782 783 784 785 786 787 788 789790 791 792 793 794 795 796 797 798 799800 801 802 803 804 805 806 807 808 809810 811 812 813 814 815 816 817 818 819820 821 822 823 824 825 826 827 828 829830 831 832 833 834 835 836 837 838 839840 841 842 843 844 845 846 847 848 849850 851 852 853 854 855 856 857 858 859860 861 862 863 864 865 866 867 868 869870 871 872 873 874 875 876 877 878 879880 881 882 883 884 885 886 887 888 889890 891 892 893 894 895 896 897 898 899900 901 902 903 904 905 906 907 908 909910 911 912 913 914 915 916 917 918 919920 921 922 923 924 925 926 927 928 929930 931 932 933 934 935 936 937 938 939940 941 942 943 944 945 946 947 948 949950 951 952 953 954 955 956 957 958 959960 961 962 963 964 965 966 967 968 969970 971 972 973 974 975 976 977 978 979980 981 982 983 984 985 986 987 988 989990 991 992 993 994 995 996 997 998 999' as long_query
+set global general_log = off
deallocate prepare long_query;
set global general_log = @old_general_log;
DROP TABLE IF EXISTS log_count;
diff --git a/mysql-test/main/log_tables.test b/mysql-test/main/log_tables.test
index 537bd843af8..22db93bd1ed 100644
--- a/mysql-test/main/log_tables.test
+++ b/mysql-test/main/log_tables.test
@@ -988,7 +988,8 @@ prepare long_query from "select ? as long_query";
execute long_query using @lparam;
--enable_result_log
set global general_log = off;
-select command_type, argument from mysql.general_log where thread_id = @thread_id;
+select argument from mysql.general_log where thread_id = @thread_id
+AND (command_type = 'Query' OR command_type= 'Execute');
deallocate prepare long_query;
set global general_log = @old_general_log;
diff --git a/mysql-test/main/merge.test b/mysql-test/main/merge.test
index 888b41b24bd..99cce370beb 100644
--- a/mysql-test/main/merge.test
+++ b/mysql-test/main/merge.test
@@ -2200,8 +2200,10 @@ DROP TABLE tm1, t1;
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
INSERT_METHOD=LAST;
+--enable_prepare_warnings
CREATE TRIGGER tm1_ai AFTER INSERT ON tm1
FOR EACH ROW SELECT max(c1) FROM t1 INTO @var;
+--disable_prepare_warnings
LOCK TABLE tm1 WRITE, t1 WRITE;
INSERT INTO tm1 VALUES (1);
SELECT * FROM tm1;
@@ -2223,8 +2225,10 @@ CREATE TABLE t4 (c1 INT) ENGINE=MyISAM;
CREATE TABLE t5 (c1 INT) ENGINE=MyISAM;
CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2,t3,t4,t5)
INSERT_METHOD=LAST;
+--enable_prepare_warnings
CREATE TRIGGER t2_au AFTER UPDATE ON t2
FOR EACH ROW SELECT MAX(c1) FROM t1 INTO @var;
+--disable_prepare_warnings
CREATE FUNCTION f1() RETURNS INT
RETURN (SELECT MAX(c1) FROM t4);
LOCK TABLE tm1 WRITE, t1 WRITE, t2 WRITE, t3 WRITE, t4 WRITE, t5 WRITE;
diff --git a/mysql-test/main/myisam_debug.test b/mysql-test/main/myisam_debug.test
index fcb134c0400..2659a3f9347 100644
--- a/mysql-test/main/myisam_debug.test
+++ b/mysql-test/main/myisam_debug.test
@@ -48,10 +48,12 @@ let $wait_condition=
INFO = "INSERT INTO t1(id) SELECT id FROM t2";
--source include/wait_condition.inc
+--enable_prepare_warnings
SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE STATE = 'wait_in_enable_indexes' AND
INFO = "INSERT INTO t1(id) SELECT id FROM t2"
INTO @thread_id;
+--disable_prepare_warnings
KILL QUERY @thread_id;
CHECK TABLE t1;
diff --git a/mysql-test/main/mysqldump.test b/mysql-test/main/mysqldump.test
index d2264d0a585..3b8130be5f8 100644
--- a/mysql-test/main/mysqldump.test
+++ b/mysql-test/main/mysqldump.test
@@ -1036,10 +1036,12 @@ begin
return f1;
end //
+--enable_prepare_warnings
CREATE PROCEDURE bug9056_proc2(OUT a INT)
BEGIN
select sum(id) from t1 into a;
END //
+--disable_prepare_warnings
DELIMITER ;//
diff --git a/mysql-test/main/null.test b/mysql-test/main/null.test
index 403790356ce..4e230f72543 100644
--- a/mysql-test/main/null.test
+++ b/mysql-test/main/null.test
@@ -318,7 +318,9 @@ SELECT NOT NOT NULLIF(2,3);
--echo #
--echo # MDEV-7146 NULLIF returns unexpected result with a YEAR field
--echo #
+--enable_prepare_warnings
CREATE TABLE t1 (a YEAR(2));
+--disable_prepare_warnings
INSERT INTO t1 VALUES (0);
SELECT a,NULLIF(a,2000),NULLIF(2000,a) FROM t1;
SELECT a,NULLIF(a,2001),NULLIF(2001,a) FROM t1;
diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test
index 8a9a618635b..be1b45465ab 100644
--- a/mysql-test/main/opt_trace.test
+++ b/mysql-test/main/opt_trace.test
@@ -1,3 +1,7 @@
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Test temporary disabled for ps-protocol
+}
--source include/not_embedded.inc
--source include/have_sequence.inc
SELECT table_name, column_name FROM information_schema.columns where table_name="OPTIMIZER_TRACE";
diff --git a/mysql-test/main/outfile_loaddata.test b/mysql-test/main/outfile_loaddata.test
index 745c75cb4de..85e26ac7b4e 100644
--- a/mysql-test/main/outfile_loaddata.test
+++ b/mysql-test/main/outfile_loaddata.test
@@ -2,6 +2,8 @@
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
+--enable_prepare_warnings
+
--echo #
--echo # Bug#31663 FIELDS TERMINATED BY special character
--echo #
@@ -289,6 +291,6 @@ SELECT LENGTH(a) FROM t2;
DROP TABLE t1, t2;
-
+--disable_prepare_warnings
###########################################################################
--echo # End of 5.1 tests.
diff --git a/mysql-test/main/parser.test b/mysql-test/main/parser.test
index 816e55435d1..61cea2e7fa4 100644
--- a/mysql-test/main/parser.test
+++ b/mysql-test/main/parser.test
@@ -885,6 +885,7 @@ SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1 FOR UPDATE;
--echo # "INTO" clause tests
+--enable_prepare_warnings
SELECT 1 FROM t1 INTO @var17727401;
SELECT 1 FROM DUAL INTO @var17727401;
SELECT 1 INTO @var17727401;
@@ -924,6 +925,7 @@ SELECT 1 FROM t1 INTO @var17727401 UNION SELECT 1 FROM t1 INTO t1;
SELECT 1 FROM t1 UNION SELECT 1 FROM t1 INTO @var17727401;
+--disable_prepare_warnings
--error ER_PARSE_ERROR
SELECT 1 INTO @var17727401 FROM t1 PROCEDURE ANALYSE();
@@ -1904,6 +1906,8 @@ drop table t1;
--echo # MDEV-19682 sql_mode="oracle" does not support sysdate
--echo #
+--enable_prepare_warnings
+
--error ER_BAD_FIELD_ERROR
SELECT sysdate LIKE '____-__-__ __:__:__';
--error ER_BAD_FIELD_ERROR
@@ -1949,6 +1953,8 @@ END;
$$
DELIMITER ;$$
+--disable_prepare_warnings
+
--echo #
--echo # End of 10.6 tests
--echo #
diff --git a/mysql-test/main/parser_stack.test b/mysql-test/main/parser_stack.test
index 8bc316da18e..93f44cc27b1 100644
--- a/mysql-test/main/parser_stack.test
+++ b/mysql-test/main/parser_stack.test
@@ -1,3 +1,7 @@
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Test temporary disabled for ps-protocol
+}
#
# These tests are designed to cause an internal parser stack overflow,
# and trigger my_yyoverflow().
diff --git a/mysql-test/main/partition.test b/mysql-test/main/partition.test
index 5d5dafdb206..5f4c5f659ca 100644
--- a/mysql-test/main/partition.test
+++ b/mysql-test/main/partition.test
@@ -350,10 +350,12 @@ ENGINE=Memory;
ALTER TABLE t1 ENGINE=NonExistentEngine;
# OK to only specify one partitions engine, since it is already assigned at
# table level (after create, it is specified on all levels and all parts).
+--enable_prepare_warnings
ALTER TABLE t1
PARTITION BY HASH (a)
(PARTITION p0 ENGINE=Memory,
PARTITION p1 ENGINE=NonExistentEngine);
+--disable_prepare_warnings
ALTER TABLE t1 ENGINE=NonExistentEngine;
SHOW CREATE TABLE t1;
DROP TABLE t1;
diff --git a/mysql-test/main/partition_exchange.test b/mysql-test/main/partition_exchange.test
index cb33b8dd857..e996866b1f9 100644
--- a/mysql-test/main/partition_exchange.test
+++ b/mysql-test/main/partition_exchange.test
@@ -5,6 +5,7 @@
DROP TABLE IF EXISTS t1, t2, t3, t, tp, tsp, tmp;
--enable_warnings
+--enable_prepare_warnings
--echo #
--echo # Bug#11894100: EXCHANGE PARTITION CAN'T BE EXECUTED IF
--echo # ROW_FORMAT WAS SET EXPLICITLY
@@ -536,3 +537,4 @@ ALTER TABLE t2 REMOVE PARTITIONING;
ALTER TABLE t1 EXCHANGE PARTITION pm WITH TABLE t2;
DROP TABLE t1, t2;
+--disable_prepare_warnings
diff --git a/mysql-test/main/partition_explicit_prune.test b/mysql-test/main/partition_explicit_prune.test
index fdbbcadd8cb..4dc3275394f 100644
--- a/mysql-test/main/partition_explicit_prune.test
+++ b/mysql-test/main/partition_explicit_prune.test
@@ -355,7 +355,9 @@ eval $get_handler_status_counts;
--echo #
SELECT * FROM t1 PARTITION (pNeg, `p10-99`);
FLUSH STATUS;
+--enable_prepare_warnings
SELECT * FROM t1 PARTITION (pNeg, `p10-99`) INTO OUTFILE 'loadtest.txt';
+--disable_prepare_warnings
eval $get_handler_status_counts;
--echo # 1 commit
--echo # 10 locks (1 ha_partition + 4 ha_innobase) x 2 (lock/unlock)
diff --git a/mysql-test/main/ps.result b/mysql-test/main/ps.result
index c1334b0b9a7..eb17def9a4b 100644
--- a/mysql-test/main/ps.result
+++ b/mysql-test/main/ps.result
@@ -2726,9 +2726,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 +2746,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 +2761,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 +3081,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;
@@ -4944,7 +4938,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..e5285022efd 100644
--- a/mysql-test/main/ps.test
+++ b/mysql-test/main/ps.test
@@ -37,14 +37,12 @@ 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:
+--error ER_UNSUPPORTED_PS
prepare stmt2 from 'prepare nested_stmt from "select 1"';
-
---error ER_UNSUPPORTED_PS
+--error ER_UNSUPPORTED_PS
prepare stmt2 from 'execute stmt1';
-
---error ER_UNSUPPORTED_PS
+--error ER_UNSUPPORTED_PS
prepare stmt2 from 'deallocate prepare z';
# PS insert
@@ -2763,12 +2761,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 +2784,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 +2805,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;
@@ -4414,7 +4410,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..05a40f54a52 100644
--- a/mysql-test/main/ps_1general.result
+++ b/mysql-test/main/ps_1general.result
@@ -387,9 +387,7 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye
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 +401,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 +411,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..b0f408e3bcf 100644
--- a/mysql-test/main/ps_1general.test
+++ b/mysql-test/main/ps_1general.test
@@ -406,19 +406,16 @@ deallocate prepare stmt_do ;
deallocate prepare stmt_set ;
## nonsense like prepare of prepare,execute or deallocate
---error ER_UNSUPPORTED_PS
+--error ER_UNSUPPORTED_PS
prepare stmt1 from ' prepare stmt2 from '' select 1 '' ' ;
---error ER_UNSUPPORTED_PS
+--error ER_UNSUPPORTED_PS
prepare stmt1 from ' execute stmt2 ' ;
---error ER_UNSUPPORTED_PS
+--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 +432,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 +441,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 +455,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..8d811ec00c0 100644
--- a/mysql-test/main/ps_ddl.test
+++ b/mysql-test/main/ps_ddl.test
@@ -63,6 +63,7 @@ drop view if exists v1, v2;
TRUNCATE TABLE mysql.general_log;
delimiter |;
+--enable_prepare_warnings
create procedure p_verify_reprepare_count(expected int)
begin
declare old_reprepare_count int default @reprepare_count;
@@ -80,6 +81,7 @@ begin
select '' as "SUCCESS";
end if;
end|
+--disable_prepare_warnings
delimiter ;|
set @reprepare_count= 0;
flush status;
@@ -902,14 +904,18 @@ begin
return x;
end|
delimiter ;|
+--enable_prepare_warnings
create procedure p1(out x int) select max(a) from t1 into x;
+--disable_prepare_warnings
prepare stmt from "select * from v1";
execute stmt;
execute stmt;
call p_verify_reprepare_count(0);
drop procedure p1;
+--enable_prepare_warnings
create procedure p1(out x int) select max(a) from t2 into x;
+--disable_prepare_warnings
--echo # XXX: used to be a bug. The prelocked list was not invalidated
--echo # and we kept opening table t1, whereas the procedure
--echo # is now referring to table t2
@@ -1880,7 +1886,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 +2207,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_ddl1.test b/mysql-test/main/ps_ddl1.test
index 0145d445a14..e0441cb0ab8 100644
--- a/mysql-test/main/ps_ddl1.test
+++ b/mysql-test/main/ps_ddl1.test
@@ -30,6 +30,7 @@ drop view if exists t1;
drop schema if exists mysqltest;
--enable_warnings
+--enable_prepare_warnings
delimiter |;
create procedure p_verify_reprepare_count(expected int)
begin
@@ -48,6 +49,7 @@ begin
select '' as "SUCCESS";
end if;
end|
+--disable_prepare_warnings
delimiter ;|
set @reprepare_count= 0;
flush status;
diff --git a/mysql-test/main/ps_missed_cmds.result b/mysql-test/main/ps_missed_cmds.result
new file mode 100644
index 00000000000..e016226bb17
--- /dev/null
+++ b/mysql-test/main/ps_missed_cmds.result
@@ -0,0 +1,847 @@
+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 '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 16: 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 17: 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 16.
+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 18: 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 19: 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 20: 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 21: 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 22: 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 23: 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 24: 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 25: 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..3aa14d5cce1
--- /dev/null
+++ b/mysql-test/main/ps_missed_cmds.test
@@ -0,0 +1,694 @@
+--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 '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 16: 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 17: 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 16.
+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 18: 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 19: 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 20: 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 21: 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 22: 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 23: 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 24: 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 25: 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..f8152945396 100644
--- a/mysql-test/main/query_cache.test
+++ b/mysql-test/main/query_cache.test
@@ -432,10 +432,12 @@ drop table t1;
create table t1 (a int);
insert into t1 values (1),(2),(3);
show status like "Qcache_queries_in_cache";
+--enable_prepare_warnings
select * from t1 into outfile "query_cache.out.file";
--error ER_FILE_EXISTS_ERROR
select * from t1 into outfile "query_cache.out.file";
select * from t1 limit 1 into dumpfile "query_cache.dump.file";
+--disable_prepare_warnings
show status like "Qcache_queries_in_cache";
drop table t1;
let $datadir=`select @@datadir`;
@@ -810,22 +812,24 @@ open c1;
select * from t1;
end//
call p1()//
-drop procedure p1;
+drop procedure p1//
+--enable_prepare_warnings
create function f1() returns int
begin
Declare var1 int;
select max(a) from t1 into var1;
return var1;
end//
+--disable_prepare_warnings
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/select.test b/mysql-test/main/select.test
index 22baccc625c..b9891280c45 100644
--- a/mysql-test/main/select.test
+++ b/mysql-test/main/select.test
@@ -3525,7 +3525,9 @@ CREATE VIEW v1 AS SELECT 1 AS ` `;
--error 1166
CREATE VIEW v1 AS SELECT (SELECT 1 AS ` `);
+--enable_prepare_warnings
CREATE VIEW v1 AS SELECT 1 AS ` x`;
+--disable_prepare_warnings
SELECT `x` FROM v1;
--error 1166
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/signal_demo1.test b/mysql-test/main/signal_demo1.test
index 62020b8f3fd..ff6a4437cdf 100644
--- a/mysql-test/main/signal_demo1.test
+++ b/mysql-test/main/signal_demo1.test
@@ -67,6 +67,8 @@ delimiter $$;
--echo # Schema integrity enforcement
--echo #
+--enable_prepare_warnings
+
create procedure check_pk_person(in person_type char, in id integer)
begin
declare x integer;
@@ -158,6 +160,8 @@ begin
end
$$
+--disable_prepare_warnings
+
create trigger po_order_bi before insert on po_order
for each row
begin
diff --git a/mysql-test/main/skip_grants.result b/mysql-test/main/skip_grants.result
index a8633807571..f21bfa1da41 100644
--- a/mysql-test/main/skip_grants.result
+++ b/mysql-test/main/skip_grants.result
@@ -52,8 +52,6 @@ DROP FUNCTION f3;
# Bug #26807 "set global event_scheduler=1" and --skip-grant-tables crashes server
#
set global event_scheduler=1;
-Warnings:
-Note 1408 Event Scheduler: Loaded 0 events
set global event_scheduler=0;
#
# Bug#26285 Selecting information_schema crahes server
diff --git a/mysql-test/main/skip_grants.test b/mysql-test/main/skip_grants.test
index eb8d3c3df88..7594285aed7 100644
--- a/mysql-test/main/skip_grants.test
+++ b/mysql-test/main/skip_grants.test
@@ -1,6 +1,6 @@
# This tests not performed with embedded server
-- source include/not_embedded.inc
-
+-- disable_ps_protocol
use test;
#
@@ -92,7 +92,9 @@ DROP FUNCTION f3;
--echo #
--echo # Bug #26807 "set global event_scheduler=1" and --skip-grant-tables crashes server
--echo #
+--disable_warnings
set global event_scheduler=1;
+--enable_warnings
set global event_scheduler=0;
--echo #
@@ -161,6 +163,8 @@ drop user baz@baz;
# need to restart the server to restore the --skip-grant state
--source include/restart_mysqld.inc
+--enable_ps_protocol
+
--echo #
--echo # End of 10.3 tests
--echo #
diff --git a/mysql-test/main/sp-anchor-row-type-cursor.test b/mysql-test/main/sp-anchor-row-type-cursor.test
index 7089175507c..bf4b6968458 100644
--- a/mysql-test/main/sp-anchor-row-type-cursor.test
+++ b/mysql-test/main/sp-anchor-row-type-cursor.test
@@ -1006,6 +1006,7 @@ DROP TABLE t1;
--echo # SELECT INTO + cursor ROW TYPE variable with a wrong column count
--echo #
+--enable_prepare_warnings
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
DELIMITER $$;
@@ -1068,6 +1069,8 @@ CALL p1();
DROP TABLE t1;
DROP PROCEDURE p1;
+--disable_prepare_warnings
+
--echo #
--echo # End of MDEV-12461 TYPE OF and ROW TYPE OF anchored data types
--echo #
diff --git a/mysql-test/main/sp-anchor-row-type-table.test b/mysql-test/main/sp-anchor-row-type-table.test
index 3f04dc68586..33b2d7487a4 100644
--- a/mysql-test/main/sp-anchor-row-type-table.test
+++ b/mysql-test/main/sp-anchor-row-type-table.test
@@ -11,6 +11,8 @@
--echo # Referring to a table in a non-existing database
--echo #
+--enable_prepare_warnings
+
DELIMITER $$;
CREATE PROCEDURE p1()
BEGIN
@@ -881,3 +883,4 @@ END;
$$
DELIMITER ;$$
DROP TABLE t1;
+--disable_prepare_warnings
diff --git a/mysql-test/main/sp-anchor-type.test b/mysql-test/main/sp-anchor-type.test
index b340cf776c5..56136c4bd63 100644
--- a/mysql-test/main/sp-anchor-type.test
+++ b/mysql-test/main/sp-anchor-type.test
@@ -659,6 +659,7 @@ DROP TABLE t1;
CREATE TABLE t1 (a INT, b VARCHAR(10),c DATETIME(3));
INSERT INTO t1 VALUES (1,'b1','2001-01-01 10:20:30.123');
DELIMITER $$;
+--enable_prepare_warnings
CREATE PROCEDURE p1()
BEGIN
DECLARE v_a TYPE OF t1.a;
@@ -669,6 +670,7 @@ BEGIN
END;
$$
DELIMITER ;$$
+--disable_prepare_warnings
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1;
diff --git a/mysql-test/main/sp-big.test b/mysql-test/main/sp-big.test
index 043e737105a..ff091c0a883 100644
--- a/mysql-test/main/sp-big.test
+++ b/mysql-test/main/sp-big.test
@@ -8,6 +8,7 @@ insert into t1 values (1),(2),(3);
let $body=`select repeat('select count(*) into out1 from t1;\n', 3072)`;
+--enable_prepare_warnings
delimiter //;
--disable_query_log
eval select length('$body') as length//
@@ -16,6 +17,7 @@ begin
$body
end//
--enable_query_log
+--disable_prepare_warnings
delimiter ;//
@@ -98,6 +100,7 @@ create table t1 (
) default collate=latin1_bin;
delimiter //;
+--enable_prepare_warnings
create procedure select_test()
begin
declare id1_cond int;
@@ -107,6 +110,7 @@ begin
set id1_cond = id1_cond + 1;
end while;
end//
+--disable_prepare_warnings
delimiter ;//
insert t1 select seq, seq, 1, 1, seq, seq, seq from seq_1_to_2000;
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-error.result b/mysql-test/main/sp-error.result
index f64735f8006..3832d63c073 100644
--- a/mysql-test/main/sp-error.result
+++ b/mysql-test/main/sp-error.result
@@ -2771,7 +2771,7 @@ DROP TABLE t2;
DROP PROCEDURE IF EXISTS p1;
DROP PROCEDURE IF EXISTS p2;
-SET sql_mode = '';
+SET sql_mode = ''|
CREATE PROCEDURE p1()
BEGIN
DECLARE var1 INTEGER DEFAULT 'string';
@@ -2782,7 +2782,7 @@ CALL p1()|
Warnings:
Warning 1366 Incorrect integer value: 'string' for column ``.``.`var1` at row 1
-SET sql_mode = DEFAULT;
+SET sql_mode = DEFAULT|
CREATE PROCEDURE p2()
BEGIN
DECLARE EXIT HANDLER FOR SQLWARNING SELECT 'H2';
diff --git a/mysql-test/main/sp-error.test b/mysql-test/main/sp-error.test
index d2af9834823..9b0213a1f91 100644
--- a/mysql-test/main/sp-error.test
+++ b/mysql-test/main/sp-error.test
@@ -9,9 +9,10 @@ drop table if exists t1, t2;
--enable_warnings
# Backup the mysql.proc table
+--enable_prepare_warnings
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval SELECT * FROM mysql.proc INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/proc.txt';
-
+--disable_prepare_warnings
# Make sure we don't have any procedures left.
delete from mysql.proc;
@@ -42,8 +43,10 @@ drop table if exists t3|
create table t3 ( x int )|
insert into t3 values (2), (3)|
+--enable_prepare_warnings
create procedure bad_into(out param int)
select x from t3 into param|
+--disable_prepare_warnings
--error 1172
call bad_into(@x)|
@@ -3711,7 +3714,7 @@ DROP PROCEDURE IF EXISTS p2;
delimiter |;
-SET sql_mode = '';
+SET sql_mode = ''|
CREATE PROCEDURE p1()
BEGIN
DECLARE var1 INTEGER DEFAULT 'string';
@@ -3721,7 +3724,7 @@ END|
--echo
CALL p1()|
--echo
-SET sql_mode = DEFAULT;
+SET sql_mode = DEFAULT|
CREATE PROCEDURE p2()
BEGIN
@@ -3797,12 +3800,14 @@ delimiter |;
--echo # because SIGNAL would raise SQL-error in that case.
--echo
+--enable_prepare_warnings
CREATE FUNCTION f1() RETURNS INTEGER
BEGIN
DECLARE v VARCHAR(5) DEFAULT -1;
SELECT b FROM t1 WHERE a = 2 INTO v;
RETURN v;
END|
+--disable_prepare_warnings
--echo
--echo # Here we check that the NOT_FOUND condition raised in f1()
diff --git a/mysql-test/main/sp-row.test b/mysql-test/main/sp-row.test
index b9143b1113b..2dfb81cadc5 100644
--- a/mysql-test/main/sp-row.test
+++ b/mysql-test/main/sp-row.test
@@ -2,7 +2,10 @@
--echo # MDEV-10914 ROW data type for stored routine variables
--echo #
-
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Test temporary disabled for ps-protocol
+}
--echo #
--echo # ROW of ROWs is not supported yet
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)|
diff --git a/mysql-test/main/sp.test b/mysql-test/main/sp.test
index 8157f18aad1..888cc569d6c 100644
--- a/mysql-test/main/sp.test
+++ b/mysql-test/main/sp.test
@@ -15,6 +15,11 @@
# Tests that require multibyte character sets, which are not always available,
# go into separate files (e.g. sp-ucs2.test)
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Need regular protocol but ps-protocol was specified
+}
+
--source include/default_charset.inc
set @save_character_set_client=@@character_set_client;
set @save_userstat=@@global.userstat, @@global.userstat= 0;
diff --git a/mysql-test/main/sp_gis.test b/mysql-test/main/sp_gis.test
index 4148a4ec423..749586854a3 100644
--- a/mysql-test/main/sp_gis.test
+++ b/mysql-test/main/sp_gis.test
@@ -12,6 +12,8 @@ drop function if exists x;
drop function if exists y;
--enable_warnings
+--enable_prepare_warnings
+
create function a() returns int
return 1;
@@ -97,6 +99,8 @@ SELECT geometrycollection();
--enable_warnings
DROP FUNCTION geometrycollection;
+--disable_prepare_warnings
+
--echo #
--echo # End of 10.5 tests
--echo #
diff --git a/mysql-test/main/sp_notembedded.test b/mysql-test/main/sp_notembedded.test
index 29901c1221b..12bacff4e87 100644
--- a/mysql-test/main/sp_notembedded.test
+++ b/mysql-test/main/sp_notembedded.test
@@ -185,6 +185,7 @@ set @@max_sp_recursion_depth=255|
set @var=1|
# disable log because error about stack overrun contains numbers which
# depend on a system
+-- disable_ps_protocol
-- disable_result_log
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100p(255, @var)|
@@ -197,6 +198,7 @@ call bug10100pd(1,255)|
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100pc(1,255)|
-- enable_result_log
+-- enable_ps_protocol
set @@max_sp_recursion_depth=0|
deallocate prepare stmt2|
diff --git a/mysql-test/main/sp_trans.test b/mysql-test/main/sp_trans.test
index b39c13287ed..abc308a26d8 100644
--- a/mysql-test/main/sp_trans.test
+++ b/mysql-test/main/sp_trans.test
@@ -522,6 +522,7 @@ select @@session.max_heap_table_size|
--disable_warnings
create table t3 (a char(255)) engine=InnoDB|
--enable_warnings
+--enable_prepare_warnings
create procedure bug14210_fill_table()
begin
declare table_size, max_table_size int default 0;
@@ -533,6 +534,7 @@ begin
select count(*)*255 from t3 into table_size;
until table_size > max_table_size*2 end repeat;
end|
+--disable_prepare_warnings
--disable_warnings
call bug14210_fill_table()|
--enable_warnings
diff --git a/mysql-test/main/sp_trans_log.test b/mysql-test/main/sp_trans_log.test
index deea6e6d9b6..12efcc46ada 100644
--- a/mysql-test/main/sp_trans_log.test
+++ b/mysql-test/main/sp_trans_log.test
@@ -22,6 +22,7 @@ CREATE TABLE t2 (a int NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=
insert into t2 values (1,1)|
+--enable_prepare_warnings
create function bug23333()
RETURNS int(11)
DETERMINISTIC
@@ -31,6 +32,7 @@ begin
return @a;
end|
delimiter ;|
+--disable_prepare_warnings
reset master;
--error ER_DUP_ENTRY
diff --git a/mysql-test/main/subselect.test b/mysql-test/main/subselect.test
index a58a08e1a58..19c30bd6dc8 100644
--- a/mysql-test/main/subselect.test
+++ b/mysql-test/main/subselect.test
@@ -30,11 +30,15 @@ SET optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
SET optimizer_use_condition_selectivity=4;
select (select 2);
+
+--enable_prepare_warnings
explain extended select (select 2);
SELECT (SELECT 1) UNION SELECT (SELECT 2);
explain extended SELECT (SELECT 1) UNION SELECT (SELECT 2);
SELECT (SELECT (SELECT 0 UNION SELECT 0));
explain extended SELECT (SELECT (SELECT 0 UNION SELECT 0));
+--disable_prepare_warnings
+
-- error ER_ILLEGAL_REFERENCE
SELECT (SELECT 1 FROM (SELECT 1) as b HAVING a=1) as a;
-- error ER_ILLEGAL_REFERENCE
@@ -441,11 +445,15 @@ SELECT * FROM (SELECT 1) b WHERE 1 IN (SELECT *);
CREATE TABLE t2 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t2 VALUES (1),(2);
SELECT * FROM t2 WHERE id IN (SELECT 1);
+--enable_prepare_warnings
EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1);
+--disable_prepare_warnings
SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+--enable_prepare_warnings
EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+--disable_prepare_warnings
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
-- error ER_UPDATE_TABLE_USED
@@ -501,7 +509,9 @@ select 1.5 > ALL (SELECT * from t1);
select 10.5 > ALL (SELECT * from t1);
select 1.5 > ANY (SELECT * from t1);
select 10.5 > ANY (SELECT * from t1);
+--enable_prepare_warnings
explain extended select (select a+1) from t1;
+--disable_prepare_warnings
select (select a+1) from t1;
drop table t1;
diff --git a/mysql-test/main/subselect4.test b/mysql-test/main/subselect4.test
index 2f65db875f8..8be44f214f0 100644
--- a/mysql-test/main/subselect4.test
+++ b/mysql-test/main/subselect4.test
@@ -104,8 +104,10 @@ DROP TABLE t1,t2;
--echo # Bug#54568: create view cause Assertion failed: 0,
--echo # file .\item_subselect.cc, line 836
--echo #
+--enable_prepare_warnings
EXPLAIN SELECT 1 LIKE ( 1 IN ( SELECT 1 ) );
DESCRIBE SELECT 1 LIKE ( 1 IN ( SELECT 1 ) );
+--disable_prepare_warnings
--echo # None of the below should crash
CREATE VIEW v1 AS SELECT 1 LIKE ( 1 IN ( SELECT 1 ) );
CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) );
diff --git a/mysql-test/main/subselect_exists2in_costmat.test b/mysql-test/main/subselect_exists2in_costmat.test
index 5d5eeaee268..371f0936d1a 100644
--- a/mysql-test/main/subselect_exists2in_costmat.test
+++ b/mysql-test/main/subselect_exists2in_costmat.test
@@ -47,7 +47,9 @@ create index Language on CountryLanguage(Language);
create index CityName on City(Name);
alter table City change population population int(11) null default 0;
+--enable_prepare_warnings
select max(id) from City into @max_city_id;
+--disable_prepare_warnings
insert into City values (@max_city_id + 1,'Kilifarevo','BGR',NULL);
diff --git a/mysql-test/main/subselect_mat_cost.test b/mysql-test/main/subselect_mat_cost.test
index 73ba717a8dc..8fe38849735 100644
--- a/mysql-test/main/subselect_mat_cost.test
+++ b/mysql-test/main/subselect_mat_cost.test
@@ -53,7 +53,9 @@ create index Language on CountryLanguage(Language);
create index CityName on City(Name);
alter table City change population population int(11) null default 0;
+--enable_prepare_warnings
select max(id) from City into @max_city_id;
+--disable_prepare_warnings
insert into City values (@max_city_id + 1,'Kilifarevo','BGR',NULL);
diff --git a/mysql-test/main/table_value_constr.test b/mysql-test/main/table_value_constr.test
index ddc949d8c00..9f06be800e6 100644
--- a/mysql-test/main/table_value_constr.test
+++ b/mysql-test/main/table_value_constr.test
@@ -1471,7 +1471,9 @@ insert into t2 values (1), (2);
let $q1=
select (values ((select 2))) from t2;
eval $q1;
+--enable_prepare_warnings
eval explain $q1;
+--disable_prepare_warnings
eval prepare stmt from "$q1";
execute stmt;
execute stmt;
diff --git a/mysql-test/main/temporal_literal.test b/mysql-test/main/temporal_literal.test
index 6783b19a7d4..5126796dc33 100644
--- a/mysql-test/main/temporal_literal.test
+++ b/mysql-test/main/temporal_literal.test
@@ -243,7 +243,9 @@ SELECT TIMESTAMP('2001-01-01 10:10:10.123456xyz');
SELECT TIMESTAMP('2001-01-01 10:10:10.1234567xyz');
CREATE TABLE t1 (a TIME(6));
+--enable_prepare_warnings
INSERT INTO t1 VALUES (TIME'10:20:30.1234567');
+--disable_prepare_warnings
INSERT INTO t1 VALUES (TIME('10:20:30.1234567'));
SELECT * FROM t1;
DROP TABLE t1;
diff --git a/mysql-test/main/trigger.test b/mysql-test/main/trigger.test
index 086912000d9..6fb194ed8dd 100644
--- a/mysql-test/main/trigger.test
+++ b/mysql-test/main/trigger.test
@@ -761,6 +761,7 @@ drop table t1;
create table t1 (id int, data int, username varchar(16));
insert into t1 (id, data) values (1, 0);
+--enable_prepare_warnings
delimiter |;
create trigger t1_whoupdated before update on t1 for each row
begin
@@ -771,6 +772,7 @@ begin
select count(*) from ((select 1) union (select 2)) as d1 into i;
end|
delimiter ;|
+--disable_prepare_warnings
update t1 set data = 1;
connection addconroot1;
@@ -2343,6 +2345,7 @@ DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1 (b VARCHAR(50) NOT NULL);
CREATE TABLE t2 (a VARCHAR(10) NOT NULL DEFAULT '');
+--enable_prepare_warnings
delimiter //;
CREATE TRIGGER trg1 AFTER INSERT ON t2
FOR EACH ROW BEGIN
@@ -2350,6 +2353,7 @@ FOR EACH ROW BEGIN
(@bug51650 IS NULL OR @bug51650 != c.b) AND c.b = NEW.a LIMIT 1 INTO @foo;
END//
delimiter ;//
+--disable_prepare_warnings
SET @bug51650 = 1;
INSERT IGNORE INTO t2 VALUES();
diff --git a/mysql-test/main/type_blob.test b/mysql-test/main/type_blob.test
index 38c8b9a83ca..c61ed124139 100644
--- a/mysql-test/main/type_blob.test
+++ b/mysql-test/main/type_blob.test
@@ -526,14 +526,18 @@ CREATE TABLE b15776 (a char(4294967296));
## When we complain about it, we say that the max is 255. We may be
## talking about different things. It's confusing.
--replace_result 4294967295 ? 0 ?
+--enable_prepare_warnings
CREATE TABLE b15776 (a year(4294967295));
+--disable_prepare_warnings
INSERT INTO b15776 VALUES (42);
SELECT * FROM b15776;
DROP TABLE b15776;
CREATE TABLE b15776 (a year(4294967296));
SHOW CREATE TABLE b15776;
DROP TABLE b15776;
+--enable_prepare_warnings
CREATE TABLE b15776 (a year(0)); # 0 is special case, means default size
+--disable_prepare_warnings
DROP TABLE b15776;
--error ER_PARSE_ERROR
CREATE TABLE b15776 (a year(-2));
diff --git a/mysql-test/main/type_newdecimal.test b/mysql-test/main/type_newdecimal.test
index 5b7ecf89a07..5e4d3b4b84b 100644
--- a/mysql-test/main/type_newdecimal.test
+++ b/mysql-test/main/type_newdecimal.test
@@ -1339,9 +1339,11 @@ DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
+--enable_prepare_warnings
CREATE TABLE t1 SELECT
/* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001
AS c1;
+--disable_prepare_warnings
DESC t1;
SELECT * FROM t1;
DROP TABLE t1;
diff --git a/mysql-test/main/type_year.test b/mysql-test/main/type_year.test
index 0f1f49be5d0..09538fab805 100644
--- a/mysql-test/main/type_year.test
+++ b/mysql-test/main/type_year.test
@@ -2,6 +2,8 @@
# Test year
#
+--enable_prepare_warnings
+
create table t1 (y year,y2 year(2));
insert into t1 values (0,0),(1999,1999),(2000,2000),(2001,2001),(70,70),(69,69);
select * from t1;
@@ -372,7 +374,7 @@ SELECT MAX(NULLIF(a, 1970)) AS f FROM t1;
--enable_ps_protocol
DROP TABLE t1;
-
+--disable_prepare_warnings
--echo #
--echo # End of 10.5 tests
--echo #
diff --git a/mysql-test/main/union.test b/mysql-test/main/union.test
index 2e5a04a27f4..7e0147cd337 100644
--- a/mysql-test/main/union.test
+++ b/mysql-test/main/union.test
@@ -93,6 +93,7 @@ select 1 as a,(select a union select a);
SELECT @a:=1 UNION SELECT @a:=@a+1;
--error 1054
(SELECT 1) UNION (SELECT 2) ORDER BY (SELECT a);
+--sorted_result
(SELECT 1,3) UNION (SELECT 2,1) ORDER BY (SELECT 2);
#
@@ -986,7 +987,9 @@ DROP TABLE t1;
(select 1) union (select 1 into @var);
--error ER_PARSE_ERROR
(select 2) union (select 1 into @var);
+--enable_prepare_warnings
(select 1) union (select 1) into @var;
+--disable_prepare_warnings
--error ER_TOO_MANY_ROWS
(select 2) union (select 1) into @var;
@@ -1114,9 +1117,11 @@ SELECT a FROM t1 UNION SELECT a INTO @v FROM t1;
SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1;
--error ER_PARSE_ERROR
SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1;
+--enable_prepare_warnings
SELECT a FROM t1 UNION SELECT a FROM t1 INTO @v ;
SELECT a FROM t1 UNION SELECT a FROM t1 INTO OUTFILE 'union.out.file5';
SELECT a FROM t1 UNION SELECT a FROM t1 INTO OUTFILE 'union.out.file6';
+--disable_prepare_warnings
--error ER_PARSE_ERROR
SELECT a INTO @v FROM t1 UNION SELECT a FROM t1;
--error ER_PARSE_ERROR
diff --git a/mysql-test/main/userstat.test b/mysql-test/main/userstat.test
index 6d486810db1..5691a2dc890 100644
--- a/mysql-test/main/userstat.test
+++ b/mysql-test/main/userstat.test
@@ -7,7 +7,9 @@
-- source include/have_log_bin.inc
-- source include/have_perfschema.inc
+--enable_prepare_warnings
select variable_value from information_schema.global_status where variable_name="handler_read_key" into @global_read_key;
+--disable_prepare_warnings
show columns from information_schema.client_statistics;
show columns from information_schema.user_statistics;
show columns from information_schema.index_statistics;
diff --git a/mysql-test/main/view.test b/mysql-test/main/view.test
index 805afedc8ae..74f80919333 100644
--- a/mysql-test/main/view.test
+++ b/mysql-test/main/view.test
@@ -2292,6 +2292,7 @@ CREATE VIEW v1 AS SELECT 42 AS Meaning;
DROP FUNCTION IF EXISTS f1;
--enable_warnings
DELIMITER //;
+--enable_prepare_warnings
CREATE FUNCTION f1() RETURNS INTEGER
BEGIN
DECLARE retn INTEGER;
@@ -2300,6 +2301,7 @@ BEGIN
END
//
DELIMITER ;//
+--disable_prepare_warnings
CREATE VIEW v2 AS SELECT f1();
select * from v2;
drop view v2,v1;
@@ -2476,6 +2478,7 @@ drop view t1, v1;
# using SP function
create table t1 (a int);
delimiter //;
+--enable_prepare_warnings
create function f1() returns int
begin
declare mx int;
@@ -2483,6 +2486,7 @@ begin
return mx;
end//
delimiter ;//
+--disable_prepare_warnings
create view v1 as select f1() as a;
create view v2 as select * from v1;
drop table t1;
@@ -3081,7 +3085,9 @@ create view v1 as select * from t1 order by f2;
select * from v1;
explain extended select * from v1;
select * from v1 order by f1;
+--enable_prepare_warnings
explain extended select * from v1 order by f1;
+--disable_prepare_warnings
drop view v1;
drop table t1;
@@ -3115,12 +3121,13 @@ DROP VIEW IF EXISTS v1;
let $query = SELECT * FROM (SELECT 1) AS t into @w;
+--enable_prepare_warnings
eval $query;
--error ER_PARSE_ERROR
eval CREATE VIEW v1 AS $query;
--echo # Previously the following would fail.
eval $query;
-
+--disable_prepare_warnings
#
# Bug#24532 The return data type of IS TRUE is different from similar operations
@@ -3883,11 +3890,13 @@ CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a INT);
delimiter //;
+--enable_prepare_warnings
CREATE FUNCTION f1() RETURNS INT
BEGIN
SELECT a FROM v2 INTO @a;
RETURN @a;
END//
+--disable_prepare_warnings
delimiter ;//
--echo # Trigger pre-locking when opening v2.
@@ -4421,7 +4430,9 @@ CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT f1 FROM t1;
CREATE ALGORITHM=MERGE VIEW v2 AS SELECT f1 FROM v1 ORDER BY f1;
SELECT * FROM v2 AS a1, v2 AS a2;
+--enable_prepare_warnings
EXPLAIN EXTENDED SELECT * FROM v2 AS a1, v2 AS a2;
+--disable_prepare_warnings
DROP VIEW v1, v2;
DROP TABLE t1;
diff --git a/mysql-test/main/view_grant.test b/mysql-test/main/view_grant.test
index 18ff8aaf4fc..83bbeb3be77 100644
--- a/mysql-test/main/view_grant.test
+++ b/mysql-test/main/view_grant.test
@@ -494,10 +494,12 @@ create table t2 (s1 int);
--disable_warnings
drop function if exists f2;
--enable_warnings
+--enable_prepare_warnings
delimiter //;
create function f2 () returns int begin declare v int; select s1 from t2
into v; return v; end//
delimiter ;//
+--disable_prepare_warnings
create algorithm=TEMPTABLE view v1 as select f2() from t1;
create algorithm=MERGE view v2 as select f2() from t1;
create algorithm=TEMPTABLE SQL SECURITY INVOKER view v3 as select f2() from t1;
@@ -548,10 +550,12 @@ create table t2 (s1 int);
--disable_warnings
drop function if exists f2;
--enable_warnings
+--enable_prepare_warnings
delimiter //;
create function f2 () returns int begin declare v int; select s1 from t2
into v; return v; end//
delimiter ;//
+--disable_prepare_warnings
create user mysqltest_1@localhost;
grant select on t1 to mysqltest_1@localhost;
grant execute on function f2 to mysqltest_1@localhost;
diff --git a/mysql-test/suite/compat/oracle/r/sp-package.result b/mysql-test/suite/compat/oracle/r/sp-package.result
index e7ab4eaa4a2..cffb3ce7857 100644
--- a/mysql-test/suite/compat/oracle/r/sp-package.result
+++ b/mysql-test/suite/compat/oracle/r/sp-package.result
@@ -34,7 +34,6 @@ ERROR HY000: Incorrect usage of OR REPLACE and IF NOT EXISTS
# PACKAGE and PS
#
PREPARE stmt FROM 'CREATE PACKAGE test2 AS FUNCTION f1 RETURN INT; END test2';
-ERROR HY000: This command is not supported in the prepared statement protocol yet
CREATE PACKAGE test2 AS
FUNCTION f1 RETURN INT;
END;
@@ -42,7 +41,6 @@ $$
PREPARE stmt FROM 'CREATE PACKAGE BODY test2 AS'
' FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END;'
'END test2';
-ERROR HY000: This command is not supported in the prepared statement protocol yet
DROP PACKAGE test2;
#
# Package and READ ONLY transactions
diff --git a/mysql-test/suite/compat/oracle/t/parser.test b/mysql-test/suite/compat/oracle/t/parser.test
index c2019f258ce..40b4e297e93 100644
--- a/mysql-test/suite/compat/oracle/t/parser.test
+++ b/mysql-test/suite/compat/oracle/t/parser.test
@@ -247,6 +247,7 @@ CALL comment();
CALL comment;
DROP PROCEDURE comment;
+enable_prepare_warnings;
DELIMITER /;
CREATE FUNCTION comment RETURN INT COMMENT 'test' AS
BEGIN
@@ -254,7 +255,6 @@ BEGIN
END;
/
DELIMITER ;/
-enable_prepare_warnings;
SELECT test.comment() FROM DUAL;
disable_prepare_warnings;
DROP FUNCTION comment;
@@ -570,8 +570,8 @@ call p1(1,2);
drop procedure p1;
-delimiter //;
set sql_mode=ORACLE;
+delimiter //;
create or replace procedure p1(id int, dt int) as
begin
while (1)
diff --git a/mysql-test/suite/compat/oracle/t/sp-package-innodb.test b/mysql-test/suite/compat/oracle/t/sp-package-innodb.test
index f4cd05b7112..94c7b714fb7 100644
--- a/mysql-test/suite/compat/oracle/t/sp-package-innodb.test
+++ b/mysql-test/suite/compat/oracle/t/sp-package-innodb.test
@@ -9,6 +9,8 @@ SELECT ENGINE FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1';
INSERT INTO t1 VALUES (10,'none');
+--enable_prepare_warnings
+
DELIMITER $$;
CREATE PACKAGE pkg1 AS
PROCEDURE p1;
@@ -58,5 +60,7 @@ ROLLBACK;
SELECT * FROM t1 ORDER BY a;
DELETE FROM t1;
+--disable_prepare_warnings
+
DROP PACKAGE pkg1;
DROP TABLE t1;
diff --git a/mysql-test/suite/compat/oracle/t/sp-package.test b/mysql-test/suite/compat/oracle/t/sp-package.test
index 96420c18820..edad90e547f 100644
--- a/mysql-test/suite/compat/oracle/t/sp-package.test
+++ b/mysql-test/suite/compat/oracle/t/sp-package.test
@@ -2,6 +2,7 @@
SET sql_mode=ORACLE;
+--enable_prepare_warnings
--echo #
--echo # Creating a body of a non-existing package
@@ -49,7 +50,6 @@ DELIMITER ;$$
--echo # PACKAGE and PS
--echo #
---error ER_UNSUPPORTED_PS
PREPARE stmt FROM 'CREATE PACKAGE test2 AS FUNCTION f1 RETURN INT; END test2';
DELIMITER $$;
@@ -58,7 +58,6 @@ CREATE PACKAGE test2 AS
END;
$$
DELIMITER ;$$
---error ER_UNSUPPORTED_PS
PREPARE stmt FROM 'CREATE PACKAGE BODY test2 AS'
' FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END;'
'END test2';
@@ -2689,3 +2688,4 @@ DELIMITER ;$$
CALL xyz.xyz123(17,18,@R);
DROP PACKAGE xyz;
DROP TABLE t1;
+--disable_prepare_warnings
diff --git a/mysql-test/suite/compat/oracle/t/sp-row.test b/mysql-test/suite/compat/oracle/t/sp-row.test
index 8abf317708a..230400ed754 100644
--- a/mysql-test/suite/compat/oracle/t/sp-row.test
+++ b/mysql-test/suite/compat/oracle/t/sp-row.test
@@ -1,3 +1,8 @@
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Test temporary disabled for ps-protocol
+}
+
SET sql_mode=ORACLE;
diff --git a/mysql-test/suite/compat/oracle/t/update_innodb.test b/mysql-test/suite/compat/oracle/t/update_innodb.test
index 8af219584d6..79660920901 100644
--- a/mysql-test/suite/compat/oracle/t/update_innodb.test
+++ b/mysql-test/suite/compat/oracle/t/update_innodb.test
@@ -8,6 +8,7 @@ SET sql_mode='ORACLE';
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY) engine=innodb;
INSERT INTO t1 VALUES (1);
START TRANSACTION;
+--enable_prepare_warnings
SELECT a AS a_con1 FROM t1 INTO @a FOR UPDATE;
--connect(con2,localhost,root,,)
@@ -24,5 +25,7 @@ COMMIT;
SELECT a AS con2 FROM t1;
COMMIT;
+--disable_prepare_warnings
+
--connection default
DROP TABLE t1;
diff --git a/mysql-test/suite/funcs_1/include/innodb_tb2.inc b/mysql-test/suite/funcs_1/include/innodb_tb2.inc
index 4e5ee091c74..1a5896cb003 100644
--- a/mysql-test/suite/funcs_1/include/innodb_tb2.inc
+++ b/mysql-test/suite/funcs_1/include/innodb_tb2.inc
@@ -3,6 +3,7 @@
--disable_warnings
drop table if exists tb2 ;
--enable_warnings
+--enable_prepare_warnings
create table tb2 (
f59 numeric (0) unsigned,
f60 numeric (64) unsigned,
@@ -61,3 +62,4 @@ f109 set("1set","2set") not null default "1set"
eval
load data infile '$MYSQLTEST_VARDIR/std_data/funcs_1/innodb_tb2.txt'
into table tb2;
+--disable_prepare_warnings
diff --git a/mysql-test/suite/funcs_1/include/innodb_tb4.inc b/mysql-test/suite/funcs_1/include/innodb_tb4.inc
index b3e94fce80e..95a0b8afb86 100644
--- a/mysql-test/suite/funcs_1/include/innodb_tb4.inc
+++ b/mysql-test/suite/funcs_1/include/innodb_tb4.inc
@@ -3,6 +3,7 @@
--disable_warnings
drop table if exists tb4;
--enable_warnings
+--enable_prepare_warnings
create table tb4 (
f176 numeric (0) unsigned not null DEFAULT 9,
f177 numeric (64) unsigned not null DEFAULT 9,
@@ -68,3 +69,4 @@ f241 char(100)
eval
load data infile '$MYSQLTEST_VARDIR/std_data/funcs_1/innodb_tb4.txt'
into table tb4;
+--disable_prepare_warnings
diff --git a/mysql-test/suite/funcs_1/include/memory_tb2.inc b/mysql-test/suite/funcs_1/include/memory_tb2.inc
index 272b86b9f03..b9e6bd72e95 100644
--- a/mysql-test/suite/funcs_1/include/memory_tb2.inc
+++ b/mysql-test/suite/funcs_1/include/memory_tb2.inc
@@ -3,6 +3,9 @@
--disable_warnings
drop table if exists tb2 ;
--enable_warnings
+
+--enable_prepare_warnings
+
create table tb2 (
f59 numeric (0) unsigned,
f60 numeric (64) unsigned,
@@ -61,3 +64,5 @@ f109 set("1set","2set") not null default "1set"
eval
load data infile '$MYSQLTEST_VARDIR/std_data/funcs_1/memory_tb2.txt'
into table tb2 ;
+
+--disable_prepare_warnings
diff --git a/mysql-test/suite/funcs_1/include/memory_tb4.inc b/mysql-test/suite/funcs_1/include/memory_tb4.inc
index 3a4fc861f28..786e2772b44 100644
--- a/mysql-test/suite/funcs_1/include/memory_tb4.inc
+++ b/mysql-test/suite/funcs_1/include/memory_tb4.inc
@@ -3,6 +3,7 @@
--disable_warnings
drop table if exists tb4 ;
--enable_warnings
+--enable_prepare_warnings
create table tb4 (
f176 numeric (0) unsigned not null DEFAULT 9,
f177 numeric (64) unsigned not null DEFAULT 9,
@@ -67,3 +68,4 @@ f240 varchar(1200)
eval
load data infile '$MYSQLTEST_VARDIR/std_data/funcs_1/memory_tb4.txt'
into table tb4;
+--disable_prepare_warnings
diff --git a/mysql-test/suite/funcs_1/t/is_columns_memory.test b/mysql-test/suite/funcs_1/t/is_columns_memory.test
index 8ec32895217..f5ed6b6e40a 100644
--- a/mysql-test/suite/funcs_1/t/is_columns_memory.test
+++ b/mysql-test/suite/funcs_1/t/is_columns_memory.test
@@ -15,6 +15,8 @@
--source include/not_embedded.inc
--source include/default_charset.inc
+--enable_prepare_warnings
+
let $engine_type= MEMORY;
SET @@session.sql_mode = 'NO_ENGINE_SUBSTITUTION';
--source suite/funcs_1/datadict/datadict_load.inc
@@ -23,4 +25,6 @@ SET @@session.sql_mode = 'NO_ENGINE_SUBSTITUTION';
let $my_where = WHERE table_schema LIKE 'test%';
--source suite/funcs_1/datadict/columns.inc
+--disable_prepare_warnings
+
--source suite/funcs_1/include/cleanup.inc
diff --git a/mysql-test/suite/funcs_1/t/is_columns_myisam.test b/mysql-test/suite/funcs_1/t/is_columns_myisam.test
index 9b9974044aa..97a23717b1c 100644
--- a/mysql-test/suite/funcs_1/t/is_columns_myisam.test
+++ b/mysql-test/suite/funcs_1/t/is_columns_myisam.test
@@ -15,6 +15,8 @@
--source include/not_embedded.inc
--source include/default_charset.inc
+--enable_prepare_warnings
+
let $engine_type= MyISAM;
SET @@session.sql_mode = 'NO_ENGINE_SUBSTITUTION';
--source suite/funcs_1/datadict/datadict_load.inc
@@ -23,4 +25,6 @@ SET @@session.sql_mode = 'NO_ENGINE_SUBSTITUTION';
let $my_where = WHERE table_schema LIKE 'test%';
--source suite/funcs_1/datadict/columns.inc
+--disable_prepare_warnings
+
--source suite/funcs_1/include/cleanup.inc
diff --git a/mysql-test/suite/funcs_1/t/storedproc.test b/mysql-test/suite/funcs_1/t/storedproc.test
index dde624bd0b9..8712919e430 100644
--- a/mysql-test/suite/funcs_1/t/storedproc.test
+++ b/mysql-test/suite/funcs_1/t/storedproc.test
@@ -10,6 +10,7 @@
#
############################################################################
+--disable_ps_protocol
--source include/default_charset.inc
set sql_mode="";
@@ -29547,3 +29548,4 @@ DROP TABLE IF EXISTS res_t1;
let $message= . +++ END OF SCRIPT +++;
--source include/show_msg80.inc
# ==============================================================================
+--enable_ps_protocol
diff --git a/mysql-test/suite/handler/handler.inc b/mysql-test/suite/handler/handler.inc
index f4c677adc90..c83e7e5d0b2 100644
--- a/mysql-test/suite/handler/handler.inc
+++ b/mysql-test/suite/handler/handler.inc
@@ -1293,6 +1293,7 @@ DROP TABLE IF EXISTS t1, t2;
DROP FUNCTION IF EXISTS f1;
--enable_warnings
+--enable_prepare_warnings
delimiter |;
CREATE FUNCTION f1() RETURNS INTEGER
BEGIN
@@ -1300,6 +1301,7 @@ BEGIN
RETURN 1;
END|
delimiter ;|
+--disable_prepare_warnings
# Get f1() parsed and cached
--error ER_NO_SUCH_TABLE
diff --git a/mysql-test/suite/innodb/t/data_types.test b/mysql-test/suite/innodb/t/data_types.test
index cfdd5201af2..2856650dad1 100644
--- a/mysql-test/suite/innodb/t/data_types.test
+++ b/mysql-test/suite/innodb/t/data_types.test
@@ -11,6 +11,8 @@
--source include/have_innodb.inc
+--enable_prepare_warnings
+
CREATE TABLE t1
(
t1_BIGINT BIGINT,
@@ -95,6 +97,8 @@ CREATE TABLE t1
t1_VARMYSQL_0 VARCHAR(0) CHARACTER SET utf8
) ENGINE=InnoDB;
+--disable_prepare_warnings
+
INSERT INTO t1 () VALUES ();
SELECT
diff --git a/mysql-test/suite/innodb/t/innodb_bug30919.test b/mysql-test/suite/innodb/t/innodb_bug30919.test
index 56b2c7bc03d..b80da1244fb 100644
--- a/mysql-test/suite/innodb/t/innodb_bug30919.test
+++ b/mysql-test/suite/innodb/t/innodb_bug30919.test
@@ -22,6 +22,8 @@ eval CREATE TABLE test.part_tbl(id MEDIUMINT NOT NULL AUTO_INCREMENT,
######## Create SPs, Functions, Views and Triggers Section ##############
+--enable_prepare_warnings
+
delimiter |;
CREATE PROCEDURE test.proc_part()
@@ -52,6 +54,8 @@ END|
delimiter ;|
+--disable_prepare_warnings
+
############ Finish Setup Section ###################
############ Test Section ###################
diff --git a/mysql-test/suite/innodb/t/innodb_bug51920.test b/mysql-test/suite/innodb/t/innodb_bug51920.test
index c83e00db22a..0a9839b612a 100644
--- a/mysql-test/suite/innodb/t/innodb_bug51920.test
+++ b/mysql-test/suite/innodb/t/innodb_bug51920.test
@@ -22,9 +22,11 @@ let $wait_condition =
WHERE INFO="UPDATE bug51920 SET i=2";
-- source include/wait_condition.inc
+--enable_prepare_warnings
SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE INFO="UPDATE bug51920 SET i=2"
INTO @thread_id;
+--disable_prepare_warnings
KILL @thread_id;
let $wait_condition =
diff --git a/mysql-test/suite/perfschema/t/alter_table_progress.test b/mysql-test/suite/perfschema/t/alter_table_progress.test
index d0a4055ad0e..d4933ac9006 100644
--- a/mysql-test/suite/perfschema/t/alter_table_progress.test
+++ b/mysql-test/suite/perfschema/t/alter_table_progress.test
@@ -52,8 +52,10 @@ SET DEBUG_SYNC='copy_data_between_tables_before SIGNAL found_row WAIT_FOR wait_r
SET DEBUG_SYNC='now WAIT_FOR found_row';
# Find the statement id of the ALTER TABLE
+--enable_prepare_warnings
select event_id from performance_schema.events_statements_current
where thread_id = @con1_thread_id into @con1_stmt_id;
+--disable_prepare_warnings
# completed 0
select EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED
diff --git a/mysql-test/suite/perfschema/t/dml_handler.test b/mysql-test/suite/perfschema/t/dml_handler.test
index 16810fcba82..d289d89ce50 100644
--- a/mysql-test/suite/perfschema/t/dml_handler.test
+++ b/mysql-test/suite/perfschema/t/dml_handler.test
@@ -21,6 +21,8 @@ CREATE TEMPORARY TABLE table_list (id INT AUTO_INCREMENT, PRIMARY KEY (id)) AS
WHERE TABLE_SCHEMA='performance_schema'
ORDER BY TABLE_NAME;
+--enable_prepare_warnings
+
SELECT COUNT(*) FROM table_list INTO @table_count;
let $count=`SELECT @table_count`;
@@ -39,5 +41,6 @@ while ($count > 0)
dec $count;
}
-DROP TEMPORARY TABLE table_list;
+--disable_prepare_warnings
+DROP TEMPORARY TABLE table_list;
diff --git a/mysql-test/suite/perfschema/t/ortho_iter.test b/mysql-test/suite/perfschema/t/ortho_iter.test
index fe1d916b6a0..d577b6dba5b 100644
--- a/mysql-test/suite/perfschema/t/ortho_iter.test
+++ b/mysql-test/suite/perfschema/t/ortho_iter.test
@@ -25,6 +25,8 @@ flush status;
# (select event_name from
# performance_schema.memory_summary_by_account_by_event_name));
+--enable_prepare_warnings
+
delimiter $;
create procedure check_instrument(in instr_name varchar(128))
begin
@@ -274,6 +276,8 @@ end
$
delimiter ;$
+--disable_prepare_warnings
+
# Check the configuration is ok
show global variables like "performance_schema%";
diff --git a/mysql-test/suite/perfschema/t/rpl_threads.test b/mysql-test/suite/perfschema/t/rpl_threads.test
index 984939c21f8..a5ca51a94a4 100644
--- a/mysql-test/suite/perfschema/t/rpl_threads.test
+++ b/mysql-test/suite/perfschema/t/rpl_threads.test
@@ -29,9 +29,11 @@ connection master;
# Read the ID of the binlog dump connection,
# as exposed in PROCESSLIST.
+--enable_prepare_warnings
select ID from INFORMATION_SCHEMA.PROCESSLIST
where COMMAND = "Binlog Dump"
into @master_dump_pid;
+--disable_prepare_warnings
select COMMAND, STATE
from INFORMATION_SCHEMA.PROCESSLIST
@@ -47,9 +49,11 @@ sync_slave_with_master;
# Read the ID of the SLAVE IO thread,
# as exposed in PROCESSLIST.
+--enable_prepare_warnings
select ID from INFORMATION_SCHEMA.PROCESSLIST
where STATE like "Waiting for master to send event%"
into @slave_io_pid;
+--disable_prepare_warnings
select COMMAND, STATE
from INFORMATION_SCHEMA.PROCESSLIST
@@ -62,9 +66,11 @@ select NAME, TYPE, PROCESSLIST_COMMAND, PROCESSLIST_STATE
# Read the ID of the SLAVE SQL thread,
# as exposed in PROCESSLIST.
+--enable_prepare_warnings
select ID from INFORMATION_SCHEMA.PROCESSLIST
where STATE like "Slave has read all relay log%"
into @slave_sql_pid;
+--disable_prepare_warnings
select COMMAND, STATE
from INFORMATION_SCHEMA.PROCESSLIST
diff --git a/mysql-test/suite/perfschema/t/selects.test b/mysql-test/suite/perfschema/t/selects.test
index d2d447bd77e..c67cb4b286c 100644
--- a/mysql-test/suite/perfschema/t/selects.test
+++ b/mysql-test/suite/perfschema/t/selects.test
@@ -126,6 +126,7 @@ DROP TRIGGER t_ps_trigger;
--disable_warnings
DROP PROCEDURE IF EXISTS t_ps_proc;
--enable_warnings
+--enable_prepare_warnings
delimiter |;
CREATE PROCEDURE t_ps_proc(IN conid INT, OUT pid INT)
@@ -140,6 +141,7 @@ delimiter ;|
CALL t_ps_proc(connection_id(), @p_id);
+--disable_prepare_warnings
# FUNCTION
--disable_warnings
diff --git a/mysql-test/suite/plugins/t/test_sql_service.test b/mysql-test/suite/plugins/t/test_sql_service.test
index 3384b523bda..26c53b01d91 100644
--- a/mysql-test/suite/plugins/t/test_sql_service.test
+++ b/mysql-test/suite/plugins/t/test_sql_service.test
@@ -1,3 +1,7 @@
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Test temporary disabled for ps-protocol
+}
--source include/not_embedded.inc
diff --git a/mysql-test/suite/rpl/r/rpl_sp.result b/mysql-test/suite/rpl/r/rpl_sp.result
index 2fc2f5ba236..dad89db8135 100644
--- a/mysql-test/suite/rpl/r/rpl_sp.result
+++ b/mysql-test/suite/rpl/r/rpl_sp.result
@@ -188,7 +188,7 @@ select * from t2;
a
23
connection master;
-drop function fn1;
+drop function fn1|
create function fn1()
returns int
no sql
diff --git a/mysql-test/suite/rpl/t/rpl_bug31076.test b/mysql-test/suite/rpl/t/rpl_bug31076.test
index 4e9517fbf2a..5ef2b345eab 100644
--- a/mysql-test/suite/rpl/t/rpl_bug31076.test
+++ b/mysql-test/suite/rpl/t/rpl_bug31076.test
@@ -1,3 +1,8 @@
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Need regular protocol but ps-protocol was specified
+}
+
source include/have_binlog_format_mixed_or_row.inc;
source include/master-slave.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_drop_db.test b/mysql-test/suite/rpl/t/rpl_drop_db.test
index 372afaa63c6..f67f422c36f 100644
--- a/mysql-test/suite/rpl/t/rpl_drop_db.test
+++ b/mysql-test/suite/rpl/t/rpl_drop_db.test
@@ -10,7 +10,9 @@ drop database if exists mysqltest1;
create database mysqltest1;
create table mysqltest1.t1 (n int);
insert into mysqltest1.t1 values (1);
+--enable_prepare_warnings
select * from mysqltest1.t1 into outfile 'mysqltest1/f1.txt';
+--disable_prepare_warnings
create table mysqltest1.t2 (n int);
create table mysqltest1.t3 (n int);
--replace_result \\ / 66 39 93 39 17 39 247 39 41 39 "File exists" "Directory not empty"
diff --git a/mysql-test/suite/rpl/t/rpl_events.test b/mysql-test/suite/rpl/t/rpl_events.test
index 3e73fc7a3ee..1d66c327633 100644
--- a/mysql-test/suite/rpl/t/rpl_events.test
+++ b/mysql-test/suite/rpl/t/rpl_events.test
@@ -4,6 +4,11 @@
# Purpose: To test that event effects are replicated. #
##################################################################
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Need regular protocol but ps-protocol was specified
+}
+
--source include/master-slave.inc
SET @old_event_scheduler = @@global.event_scheduler;
diff --git a/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test
index fd4cdf71f6f..81d0925c195 100644
--- a/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test
+++ b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test
@@ -1,3 +1,7 @@
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Test temporary disabled for ps-protocol
+}
--let $rpl_topology=1->2
--source include/rpl_init.inc
--source include/have_innodb.inc
diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat.test b/mysql-test/suite/rpl/t/rpl_heartbeat.test
index 77c05a60c0a..e4753b7be07 100644
--- a/mysql-test/suite/rpl/t/rpl_heartbeat.test
+++ b/mysql-test/suite/rpl/t/rpl_heartbeat.test
@@ -21,6 +21,7 @@ set @restore_slave_net_timeout= @@global.slave_net_timeout;
set @@global.slave_net_timeout= 10;
--enable_warnings
+--enable_prepare_warnings
###
### Checking the range
###
@@ -167,6 +168,8 @@ drop table t1;
sync_slave_with_master;
set @@global.slave_net_timeout= @restore_slave_net_timeout;
+--disable_prepare_warnings
+
--source include/stop_slave.inc
--echo End of tests
diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test
index f12c5921ba2..45b5d48c13b 100644
--- a/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test
+++ b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test
@@ -18,6 +18,8 @@
--source include/have_binlog_format_mixed.inc
--echo
+--enable_prepare_warnings
+
# Set number of retries to connect to master
let $connect_retry= 20;
@@ -561,5 +563,7 @@ DROP TABLE t1;
--sync_slave_with_master
SET @@global.slave_net_timeout=@restore_slave_net_timeout;
+--disable_prepare_warnings
+
#--let $rpl_only_running_threads= 1
--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_innodb_bug30888.test b/mysql-test/suite/rpl/t/rpl_innodb_bug30888.test
index 9bfce61804b..a18b09981ef 100644
--- a/mysql-test/suite/rpl/t/rpl_innodb_bug30888.test
+++ b/mysql-test/suite/rpl/t/rpl_innodb_bug30888.test
@@ -19,6 +19,7 @@ eval CREATE TABLE test.regular_tbl(id MEDIUMINT NOT NULL AUTO_INCREMENT,
######## Create SPs, Functions, Views and Triggers Section ##############
+--enable_prepare_warnings
delimiter |;
CREATE PROCEDURE test.proc_norm()
BEGIN
@@ -46,7 +47,7 @@ BEGIN
END|
delimiter ;|
-
+--disable_prepare_warnings
############ Finish Setup Section ###################
diff --git a/mysql-test/suite/rpl/t/rpl_mdev12179.test b/mysql-test/suite/rpl/t/rpl_mdev12179.test
index e3caccde6b4..2afcbf7b1e1 100644
--- a/mysql-test/suite/rpl/t/rpl_mdev12179.test
+++ b/mysql-test/suite/rpl/t/rpl_mdev12179.test
@@ -285,8 +285,10 @@ EOF
--connection server_2
--enable_reconnect
+--enable_prepare_warnings
--source include/wait_until_connected_again.inc
SELECT max(seq_no) FROM mysql.gtid_slave_pos_InnoDB into @seq_no;
+--disable_prepare_warnings
--connection server_1
INSERT INTO t2(a) SELECT 1+MAX(a) FROM t2;
diff --git a/mysql-test/suite/rpl/t/rpl_misc_functions.test b/mysql-test/suite/rpl/t/rpl_misc_functions.test
index 7189e5c44ba..4b140c9588a 100644
--- a/mysql-test/suite/rpl/t/rpl_misc_functions.test
+++ b/mysql-test/suite/rpl/t/rpl_misc_functions.test
@@ -89,8 +89,10 @@ INSERT INTO t1 (col_a) VALUES (test_replication_sf());
--sync_slave_with_master
+--enable_prepare_warnings
# Dump table on slave
select * from t1 into outfile "../../tmp/t1_slave.txt";
+--disable_prepare_warnings
# Load data from slave into temp table on master
connection master;
diff --git a/mysql-test/suite/rpl/t/rpl_sp.test b/mysql-test/suite/rpl/t/rpl_sp.test
index 637dda47489..c68c76caf41 100644
--- a/mysql-test/suite/rpl/t/rpl_sp.test
+++ b/mysql-test/suite/rpl/t/rpl_sp.test
@@ -208,7 +208,7 @@ select * from t2;
connection master;
delimiter |;
-drop function fn1;
+drop function fn1|
create function fn1()
returns int
diff --git a/mysql-test/suite/sys_vars/t/innodb_fil_make_page_dirty_debug_basic.test b/mysql-test/suite/sys_vars/t/innodb_fil_make_page_dirty_debug_basic.test
index 950dbabd1bd..396d30c76c8 100644
--- a/mysql-test/suite/sys_vars/t/innodb_fil_make_page_dirty_debug_basic.test
+++ b/mysql-test/suite/sys_vars/t/innodb_fil_make_page_dirty_debug_basic.test
@@ -23,8 +23,10 @@ set innodb_fil_make_page_dirty_debug = ON;
--echo # An example usage.
create table t1 (f1 int primary key) engine = innodb;
+--enable_prepare_warnings
select space from information_schema.innodb_sys_tables
where name = 'test/t1' into @space_id;
+--disable_prepare_warnings
set global innodb_saved_page_number_debug = 0;
set global innodb_fil_make_page_dirty_debug = @space_id;
drop table t1;
diff --git a/mysql-test/suite/sys_vars/t/innodb_saved_page_number_debug_basic.test b/mysql-test/suite/sys_vars/t/innodb_saved_page_number_debug_basic.test
index 74ce3ffc049..d0996ae9a24 100644
--- a/mysql-test/suite/sys_vars/t/innodb_saved_page_number_debug_basic.test
+++ b/mysql-test/suite/sys_vars/t/innodb_saved_page_number_debug_basic.test
@@ -23,8 +23,10 @@ set innodb_saved_page_number_debug = ON;
--echo # An example usage.
create table t1 (f1 int primary key) engine = innodb;
+--enable_prepare_warnings
select space from information_schema.innodb_sys_tables
where name = 'test/t1' into @space_id;
+--disable_prepare_warnings
set global innodb_saved_page_number_debug = 0;
set global innodb_fil_make_page_dirty_debug = @space_id;
drop table t1;
diff --git a/mysql-test/suite/sys_vars/t/secure_file_priv.test b/mysql-test/suite/sys_vars/t/secure_file_priv.test
index a5a465d8c98..a8565375e45 100644
--- a/mysql-test/suite/sys_vars/t/secure_file_priv.test
+++ b/mysql-test/suite/sys_vars/t/secure_file_priv.test
@@ -33,7 +33,9 @@ print FILE "SELECT load_file('",$protected_file,"') AS loaded_file;\n";
close(FILE);
EOF
+--enable_prepare_warnings
--source $MYSQL_TMP_DIR/bug50373.inc
+--disable_prepare_warnings
--remove_file $MYSQL_TMP_DIR/bug50373.inc
--enable_query_log
diff --git a/mysql-test/suite/sys_vars/t/stored_program_cache_func.test b/mysql-test/suite/sys_vars/t/stored_program_cache_func.test
index f85fc8eb1bf..d131b416af9 100644
--- a/mysql-test/suite/sys_vars/t/stored_program_cache_func.test
+++ b/mysql-test/suite/sys_vars/t/stored_program_cache_func.test
@@ -1,3 +1,7 @@
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Test temporary disabled for ps-protocol
+}
create procedure p1() select 1;
flush status;
diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test
index 9d3101fb4ad..53f0537ff92 100644
--- a/mysql-test/suite/versioning/t/alter.test
+++ b/mysql-test/suite/versioning/t/alter.test
@@ -139,7 +139,9 @@ select * from t;
update t set a=3 where a=1;
select * from t;
select * from t for system_time all;
+--enable_prepare_warnings
select row_start from t where a=3 into @tm;
+--disable_prepare_warnings
alter table t add column b int;
select @tm=row_start from t where a=3;
show create table t;
diff --git a/mysql-test/suite/versioning/t/commit_id.test b/mysql-test/suite/versioning/t/commit_id.test
index 0f9cf1eb391..96461f5c299 100644
--- a/mysql-test/suite/versioning/t/commit_id.test
+++ b/mysql-test/suite/versioning/t/commit_id.test
@@ -17,6 +17,9 @@ insert into t1 values ();
--real_sleep 0.01
set @ts0= now(6);
insert into t1 values ();
+
+--enable_prepare_warnings
+
select sys_trx_start from t1 where id = last_insert_id() into @tx0;
select transaction_id = @tx0 from mysql.transaction_registry
order by transaction_id desc limit 1;
@@ -87,6 +90,7 @@ insert into t1 values ();
select sys_trx_start from t1 where id = last_insert_id() into @tx6;
select isolation_level = 'REPEATABLE-READ' from mysql.transaction_registry where transaction_id = @tx6;
+--disable_prepare_warnings
drop table t1;
call verify_trt;
diff --git a/mysql-test/suite/versioning/t/create.test b/mysql-test/suite/versioning/t/create.test
index 1f016fed871..62f09b255f2 100644
--- a/mysql-test/suite/versioning/t/create.test
+++ b/mysql-test/suite/versioning/t/create.test
@@ -5,6 +5,8 @@
drop table if exists t1;
--enable_warnings
+--enable_prepare_warnings
+
--replace_result $default_engine DEFAULT_ENGINE $sys_datatype_expl SYS_DATATYPE NULL ''
eval create table t1 (
x1 int unsigned,
@@ -439,3 +441,4 @@ show create table t1;
show create table t2;
drop temporary table t2;
drop table t1;
+--disable_prepare_warnings
diff --git a/mysql-test/suite/versioning/t/cte.test b/mysql-test/suite/versioning/t/cte.test
index 5a8fb1f8211..b1a2e214927 100644
--- a/mysql-test/suite/versioning/t/cte.test
+++ b/mysql-test/suite/versioning/t/cte.test
@@ -1,3 +1,7 @@
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Test temporary disabled for ps-protocol
+}
--source include/have_innodb.inc
--source include/default_optimizer_switch.inc
diff --git a/mysql-test/suite/versioning/t/foreign.test b/mysql-test/suite/versioning/t/foreign.test
index ed2ed4dd122..138698b6306 100644
--- a/mysql-test/suite/versioning/t/foreign.test
+++ b/mysql-test/suite/versioning/t/foreign.test
@@ -314,7 +314,9 @@ create or replace table subchild (
) engine=innodb;
insert into parent (value) values (23);
+--enable_prepare_warnings
select id, value from parent into @id, @value;
+--disable_prepare_warnings
insert into child values (default, @id, @value);
insert into subchild values (default, @id, @value);
diff --git a/mysql-test/suite/versioning/t/insert.test b/mysql-test/suite/versioning/t/insert.test
index 0324df64d0c..4e8c91315c6 100644
--- a/mysql-test/suite/versioning/t/insert.test
+++ b/mysql-test/suite/versioning/t/insert.test
@@ -52,7 +52,9 @@ drop view vt1_1;
replace_result $sys_datatype_expl SYS_DATATYPE;
eval create or replace table t1( id bigint primary key, a int, b int) with system versioning;
insert into t1 values(1, 1, 1);
+--enable_prepare_warnings
select row_start, row_end from t1 into @sys_start, @sys_end;
+--disable_prepare_warnings
select id, a, b from t1;
insert into t1 values(2, 2, 2);
select id, a, b, row_start > @sys_start as C, row_end = @sys_end as D from t1 where id = 2;
diff --git a/mysql-test/suite/versioning/t/load_data.test b/mysql-test/suite/versioning/t/load_data.test
index 4db6eee6c4d..3bac2942a81 100644
--- a/mysql-test/suite/versioning/t/load_data.test
+++ b/mysql-test/suite/versioning/t/load_data.test
@@ -4,7 +4,9 @@
CREATE TABLE t1 (a INT, b INT, c INT, vc INT AS (c), UNIQUE(a), UNIQUE(b)) WITH SYSTEM VERSIONING;
INSERT IGNORE INTO t1 (a,b,c) VALUES (1,2,3);
+--enable_prepare_warnings
SELECT a, b, c FROM t1 INTO OUTFILE '15330.data';
+--disable_prepare_warnings
LOAD DATA INFILE '15330.data' IGNORE INTO TABLE t1 (a,b,c);
LOAD DATA INFILE '15330.data' REPLACE INTO TABLE t1 (a,b,c);
diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test
index 445f5844630..006a65e1a16 100644
--- a/mysql-test/suite/versioning/t/partition.test
+++ b/mysql-test/suite/versioning/t/partition.test
@@ -4,6 +4,8 @@
call mtr.add_suppression("need more HISTORY partitions");
+--enable_prepare_warnings
+
set system_versioning_alter_history=keep;
--echo # Check conventional partitioning on temporal tables
@@ -1073,6 +1075,8 @@ show create table t1;
drop tables t1;
+--disable_prepare_warnings
+
--echo #
--echo # End of 10.5 tests
--echo #
diff --git a/mysql-test/suite/versioning/t/select.test b/mysql-test/suite/versioning/t/select.test
index d2615940ac8..bf27723adee 100644
--- a/mysql-test/suite/versioning/t/select.test
+++ b/mysql-test/suite/versioning/t/select.test
@@ -1,7 +1,12 @@
+if (`SELECT $PS_PROTOCOL != 0`)
+{
+ --skip Need regular protocol but ps-protocol was specified
+}
--source suite/versioning/engines.inc
--source suite/versioning/common.inc
--source include/default_optimizer_switch.inc
+--enable_prepare_warnings
# test_01
--replace_result $sys_datatype_expl SYS_DATATYPE
@@ -475,5 +480,6 @@ drop table tmp1;
drop tables x, x_p;
call verify_trt_dummy(34);
+--disable_prepare_warnings
-- source suite/versioning/common_finish.inc
diff --git a/mysql-test/suite/versioning/t/select2.test b/mysql-test/suite/versioning/t/select2.test
index 1ab7bcf27c1..53840b390b6 100644
--- a/mysql-test/suite/versioning/t/select2.test
+++ b/mysql-test/suite/versioning/t/select2.test
@@ -22,13 +22,16 @@ insert into t1 (x, y) values
(8, 108),
(9, 109);
set @t0= now(6);
+--enable_prepare_warnings
select sys_start from t1 limit 1 into @x0;
-
+--disable_prepare_warnings
delete from t1 where x = 3;
delete from t1 where x > 7;
insert into t1(x, y) values(3, 33);
+--enable_prepare_warnings
select sys_start from t1 where x = 3 and y = 33 into @t1;
+--disable_prepare_warnings
if($MTR_COMBINATION_TRX_ID) {
set @x1= @t1;
select trt_commit_ts(@x1) into @t1;
diff --git a/mysql-test/suite/versioning/t/sysvars.test b/mysql-test/suite/versioning/t/sysvars.test
index a1026418e98..34c98c48ff7 100644
--- a/mysql-test/suite/versioning/t/sysvars.test
+++ b/mysql-test/suite/versioning/t/sysvars.test
@@ -57,7 +57,9 @@ show global variables like 'system_versioning_asof';
set global system_versioning_asof= '1900-01-01 00:00:00';
show global variables like 'system_versioning_asof';
+--enable_prepare_warnings
set global system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
+--disable_prepare_warnings
show global variables like 'system_versioning_asof';
set @ts= timestamp'1900-01-01 00:00:00';
@@ -74,7 +76,9 @@ show variables like 'system_versioning_asof';
set system_versioning_asof= '1900-01-01 00:00:00';
show variables like 'system_versioning_asof';
+--enable_prepare_warnings
set system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
+--disable_prepare_warnings
show variables like 'system_versioning_asof';
set @ts= timestamp'1900-01-01 00:00:00';
@@ -134,7 +138,9 @@ drop tables t1, t2;
--echo #
SET sql_mode=TIME_ROUND_FRACTIONAL;
+--enable_prepare_warnings
SET @@global.system_versioning_asof= timestamp'2001-12-31 23:59:59.9999999';
+--disable_prepare_warnings
SELECT @@global.system_versioning_asof;
SET @@global.system_versioning_asof= DEFAULT;
diff --git a/mysql-test/suite/versioning/t/trx_id.test b/mysql-test/suite/versioning/t/trx_id.test
index 23c65b2525c..4728ce9b2d0 100644
--- a/mysql-test/suite/versioning/t/trx_id.test
+++ b/mysql-test/suite/versioning/t/trx_id.test
@@ -18,6 +18,8 @@ create or replace table t1 (
period for system_time (sys_trx_start, sys_trx_end)
) with system versioning;
+--enable_prepare_warnings
+
--echo # No history inside the transaction
start transaction;
insert into t1 (x) values (1);
@@ -511,3 +513,5 @@ drop table t;
uninstall plugin test_versioning;
--error ER_SP_DOES_NOT_EXIST
select trt_begin_ts(0);
+
+--disable_prepare_warnings
diff --git a/sql/item.cc b/sql/item.cc
index 90ab78cec0a..a016f04953c 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -5531,13 +5531,11 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
*/
Name_resolution_context *last_checked_context= context;
Item **ref= (Item **) not_found_item;
- SELECT_LEX *current_sel= thd->lex->current_select;
+ SELECT_LEX *current_sel= context->select_lex;
Name_resolution_context *outer_context= 0;
SELECT_LEX *select= 0;
- /* Currently derived tables cannot be correlated */
- if ((current_sel->master_unit()->first_select()->get_linkage() !=
- DERIVED_TABLE_TYPE) &&
- current_sel->master_unit()->outer_select())
+
+ if (current_sel->master_unit()->outer_select())
outer_context= context->outer_context;
/*
@@ -5870,7 +5868,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
DBUG_ASSERT(fixed() == 0);
Field *from_field= (Field *)not_found_field;
bool outer_fixed= false;
- SELECT_LEX *select= thd->lex->current_select;
+ SELECT_LEX *select= context->select_lex;
if (select && select->in_tvc)
{
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index c39fbf54f13..381f015ca96 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1270,7 +1270,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
DBUG_ASSERT(join->thd == thd);
SELECT_LEX *select_lex= join->select_lex;
- Query_arena *arena= thd->stmt_arena;
+ Query_arena *arena, backup;
+ arena= thd->activate_stmt_arena_if_needed(&backup);
if (!select_lex->master_unit()->is_unit_op() &&
!select_lex->table_list.elements &&
@@ -1286,12 +1287,7 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
!(select_lex->item_list.head()->type() == FIELD_ITEM ||
select_lex->item_list.head()->type() == REF_ITEM) &&
!join->conds && !join->having &&
- /*
- switch off this optimization for prepare statement,
- because we do not rollback this changes
- TODO: make rollback for it, or special name resolving mode in 5.0.
- */
- !arena->is_stmt_prepare_or_first_sp_execute()
+ thd->stmt_arena->state != Query_arena::STMT_INITIALIZED_FOR_SP
)
{
have_to_be_excluded= 1;
@@ -1310,6 +1306,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
substitution->fix_after_pullout(select_lex->outer_select(),
&substitution, TRUE);
}
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
DBUG_RETURN(false);
}
diff --git a/sql/protocol.h b/sql/protocol.h
index 1beb1175a11..7305d8dcadc 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -188,10 +188,6 @@ public:
bool net_send_error(THD *thd, uint sql_errno, const char *err,
const char* sqlstate);
void end_statement();
-
- friend int send_answer_1(Protocol *protocol, String *s1, String *s2,
- String *s3);
- friend int send_header_2(Protocol *protocol, bool for_category);
};
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 8e2e8b12a06..f03152ace03 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -825,15 +825,20 @@ int set_var::check(THD *thd)
*/
int set_var::light_check(THD *thd)
{
+ if (var->is_readonly())
+ {
+ my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->name.str, "read only");
+ return -1;
+ }
if (var->check_type(type))
{
int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
my_error(err, MYF(0), var->name.str);
return -1;
}
- if (type == OPT_GLOBAL &&
- check_global_access(thd, PRIV_SET_GLOBAL_SYSTEM_VARIABLE))
- return 1;
+
+ if (type == OPT_GLOBAL && var->on_check_access_global(thd))
+ return 1;
if (value && value->fix_fields_if_needed_for_scalar(thd, &value))
return -1;
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 34dd09fd88f..601d41ab04a 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -1041,7 +1041,7 @@ public:
Query_arena(thd->lex->sphead->get_main_mem_root(), STMT_INITIALIZED_FOR_SP)
{ }
~sp_lex_cursor() { free_items(); }
- void cleanup_stmt() { }
+ void cleanup_stmt(bool /*restore_set_statement_vars*/) { }
Query_arena *query_arena() { return this; }
bool validate()
{
@@ -1831,7 +1831,8 @@ public:
cursor is closed. For now stored procedures always use materialized
cursors and the call is not used.
*/
- virtual void cleanup_stmt() { /* no op */ }
+ virtual void cleanup_stmt(bool /*restore_set_statement_vars*/)
+ { /* no op */ }
private:
sp_lex_keeper m_lex_keeper;
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index aa66291929c..1c32e9d57cc 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -489,6 +489,38 @@ static bool wsrep_toi_replication(THD *thd, TABLE_LIST *tables)
}
#endif /* WITH_WSREP */
+
+/**
+ Collect field names of result set that will be sent to a client
+
+ @param thd Thread data object
+ @param[out] fields List of fields whose metadata should be collected for
+ sending to client
+*/
+
+void fill_check_table_metadata_fields(THD *thd, List<Item>* fields)
+{
+ Item *item;
+
+ item= new (thd->mem_root) Item_empty_string(thd, "Table", NAME_CHAR_LEN * 2);
+ item->set_maybe_null();
+ fields->push_back(item, thd->mem_root);
+
+ item= new (thd->mem_root) Item_empty_string(thd, "Op", 10);
+ item->set_maybe_null();
+ fields->push_back(item, thd->mem_root);
+
+ item= new (thd->mem_root) Item_empty_string(thd, "Msg_type", 10);
+ item->set_maybe_null();
+ fields->push_back(item, thd->mem_root);
+
+ item= new (thd->mem_root) Item_empty_string(thd, "Msg_text",
+ SQL_ADMIN_MSG_TEXT_SIZE);
+ item->set_maybe_null();
+ fields->push_back(item, thd->mem_root);
+}
+
+
/*
RETURN VALUES
FALSE Message sent to net (admin operation went ok)
@@ -512,7 +544,6 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
{
TABLE_LIST *table;
List<Item> field_list;
- Item *item;
Protocol *protocol= thd->protocol;
LEX *lex= thd->lex;
int result_code;
@@ -524,21 +555,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
DBUG_ENTER("mysql_admin_table");
DBUG_PRINT("enter", ("extra_open_options: %u", extra_open_options));
- field_list.push_back(item= new (thd->mem_root)
- Item_empty_string(thd, "Table",
- NAME_CHAR_LEN * 2), thd->mem_root);
- item->set_maybe_null();
- field_list.push_back(item= new (thd->mem_root)
- Item_empty_string(thd, "Op", 10), thd->mem_root);
- item->set_maybe_null();
- field_list.push_back(item= new (thd->mem_root)
- Item_empty_string(thd, "Msg_type", 10), thd->mem_root);
- item->set_maybe_null();
- field_list.push_back(item= new (thd->mem_root)
- Item_empty_string(thd, "Msg_text",
- SQL_ADMIN_MSG_TEXT_SIZE),
- thd->mem_root);
- item->set_maybe_null();
+ fill_check_table_metadata_fields(thd, &field_list);
+
if (protocol->send_result_set_metadata(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
diff --git a/sql/sql_admin.h b/sql/sql_admin.h
index d31726d32a4..0c7f1c3cee5 100644
--- a/sql/sql_admin.h
+++ b/sql/sql_admin.h
@@ -24,7 +24,7 @@ bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* table_list,
bool mysql_preload_keys(THD* thd, TABLE_LIST* table_list);
int reassign_keycache_tables(THD* thd, KEY_CACHE *src_cache,
KEY_CACHE *dst_cache);
-
+void fill_check_table_metadata_fields(THD *thd, List<Item>* fields);
/**
Sql_cmd_analyze_table represents the ANALYZE TABLE statement.
*/
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index 5cd70199645..bab2afb957a 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -354,8 +354,28 @@ void mysql_client_binlog_statement(THD* thd)
(ev->flags & LOG_EVENT_SKIP_REPLICATION_F ?
OPTION_SKIP_REPLICATION : 0);
- err= ev->apply_event(rgi);
+ {
+ /*
+ For conventional statements thd->lex points to thd->main_lex, that is
+ thd->lex == &thd->main_lex. On the other hand, for prepared statement
+ thd->lex points to the LEX object explicitly allocated for execution
+ of the prepared statement and in this case thd->lex != &thd->main_lex.
+ On handling the BINLOG statement, invocation of ev->apply_event(rgi)
+ initiates the following sequence of calls
+ Rows_log_event::do_apply_event -> THD::reset_for_next_command
+ Since the method THD::reset_for_next_command() contains assert
+ DBUG_ASSERT(lex == &main_lex)
+ this sequence of calls results in crash when a binlog event is
+ applied in PS mode. So, reset the current lex temporary to point to
+ thd->main_lex before running ev->apply_event() and restore its
+ original value on return.
+ */
+ LEX *backup_lex;
+ thd->backup_and_reset_current_lex(&backup_lex);
+ err= ev->apply_event(rgi);
+ thd->restore_current_lex(backup_lex);
+ }
thd->variables.option_bits=
(thd->variables.option_bits & ~OPTION_SKIP_REPLICATION) |
save_skip_replication;
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 1d27854dc82..b59bcc9c1af 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -3823,7 +3823,7 @@ void Query_arena::set_query_arena(Query_arena *set)
}
-void Query_arena::cleanup_stmt()
+void Query_arena::cleanup_stmt(bool /*restore_set_statement_vars*/)
{
DBUG_ASSERT(! "Query_arena::cleanup_stmt() not implemented");
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 0f85da68c8e..c4b7628aaf3 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1212,7 +1212,7 @@ public:
void free_items();
/* Close the active state associated with execution of this statement */
- virtual void cleanup_stmt();
+ virtual void cleanup_stmt(bool /*restore_set_statement_vars*/);
};
@@ -5453,6 +5453,34 @@ public:
return (variables.old_behavior & OLD_MODE_UTF8_IS_UTF8MB3 ?
MY_UTF8_IS_UTF8MB3 : 0);
}
+
+
+ /**
+ Save current lex to the output parameter and reset it to point to
+ main_lex. This method is called from mysql_client_binlog_statement()
+ to temporary
+
+ @param[out] backup_lex original value of current lex
+ */
+
+ void backup_and_reset_current_lex(LEX **backup_lex)
+ {
+ *backup_lex= lex;
+ lex= &main_lex;
+ }
+
+
+ /**
+ Restore current lex to its original value it had before calling the method
+ backup_and_reset_current_lex().
+
+ @param backup_lex original value of current lex
+ */
+
+ void restore_current_lex(LEX *backup_lex)
+ {
+ lex= backup_lex;
+ }
};
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index b995a841a74..0324e9691e8 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -197,7 +197,7 @@ int mysql_open_cursor(THD *thd, select_result *result,
}
*pcursor= materialized_cursor;
- thd->stmt_arena->cleanup_stmt();
+ thd->stmt_arena->cleanup_stmt(true);
}
end:
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index c54851c295b..0c7cb2aa12c 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -366,6 +366,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
query_plan.select_lex= thd->lex->first_select_lex();
query_plan.table= table;
+ thd->lex->promote_select_describe_flag_if_needed();
+
promote_select_describe_flag_if_needed(thd->lex);
if (mysql_prepare_delete(thd, table_list, &conds, &delete_while_scanning))
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index ce29846e2f8..f9932f11798 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -430,6 +430,46 @@ void get_all_items_for_category(THD *thd, TABLE *items, Field *pfname,
DBUG_VOID_RETURN;
}
+
+/**
+ Collect field names of HELP header that will be sent to a client
+
+ @param thd Thread data object
+ @param[out] field_list List of fields whose metadata should be collected for
+ sending to client
+*/
+
+static void fill_answer_1_fields(THD *thd, List<Item> *field_list)
+{
+ MEM_ROOT *mem_root= thd->mem_root;
+
+ field_list->push_back(new (mem_root) Item_empty_string(thd, "name", 64),
+ mem_root);
+ field_list->push_back(new (mem_root) Item_empty_string(thd, "description",
+ 1000),
+ mem_root);
+ field_list->push_back(new (mem_root) Item_empty_string(thd, "example", 1000),
+ mem_root);
+}
+
+
+/**
+ Send metadata of an answer on help request to a client
+
+ @param protocol protocol for sending
+*/
+
+static bool send_answer_1_metadata(Protocol *protocol)
+{
+ List<Item> field_list;
+
+ fill_answer_1_fields(protocol->thd, &field_list);
+ return protocol->send_result_set_metadata(&field_list,
+ Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF);
+}
+
+
/*
Send to client answer for help request
@@ -455,22 +495,11 @@ void get_all_items_for_category(THD *thd, TABLE *items, Field *pfname,
0 Successeful send
*/
-int send_answer_1(Protocol *protocol, String *s1, String *s2, String *s3)
+static int send_answer_1(Protocol *protocol, String *s1, String *s2, String *s3)
{
- THD *thd= protocol->thd;
- MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("send_answer_1");
- List<Item> field_list;
- field_list.push_back(new (mem_root) Item_empty_string(thd, "name", 64),
- mem_root);
- field_list.push_back(new (mem_root) Item_empty_string(thd, "description", 1000),
- mem_root);
- field_list.push_back(new (mem_root) Item_empty_string(thd, "example", 1000),
- mem_root);
-
- if (protocol->send_result_set_metadata(&field_list,
- Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+ if (send_answer_1_metadata(protocol))
DBUG_RETURN(1);
protocol->prepare_for_resend();
@@ -483,13 +512,39 @@ int send_answer_1(Protocol *protocol, String *s1, String *s2, String *s3)
}
+/**
+ Collect field names of HELP header that will be sent to a client
+
+ @param thd Thread data object
+ @param[out] field_list List of fields whose metadata should be collected for
+ sending to client
+ @param for_category need column 'source_category_name'
+*/
+
+static void fill_header_2_fields(THD *thd, List<Item> *field_list,
+ bool for_category)
+{
+ MEM_ROOT *mem_root= thd->mem_root;
+ if (for_category)
+ field_list->push_back(new (mem_root)
+ Item_empty_string(thd, "source_category_name", 64),
+ mem_root);
+ field_list->push_back(new (mem_root)
+ Item_empty_string(thd, "name", 64),
+ mem_root);
+ field_list->push_back(new (mem_root)
+ Item_empty_string(thd, "is_it_category", 1),
+ mem_root);
+}
+
+
/*
Send to client help header
SYNOPSIS
send_header_2()
protocol - protocol for sending
- is_it_category - need column 'source_category_name'
+ for_category - need column 'source_category_name'
IMPLEMENTATION
+- -+
@@ -504,22 +559,12 @@ int send_answer_1(Protocol *protocol, String *s1, String *s2, String *s3)
result of protocol->send_result_set_metadata
*/
-int send_header_2(Protocol *protocol, bool for_category)
+static int send_header_2(Protocol *protocol, bool for_category)
{
- THD *thd= protocol->thd;
- MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("send_header_2");
List<Item> field_list;
- if (for_category)
- field_list.push_back(new (mem_root)
- Item_empty_string(thd, "source_category_name", 64),
- mem_root);
- field_list.push_back(new (mem_root)
- Item_empty_string(thd, "name", 64),
- mem_root);
- field_list.push_back(new (mem_root)
- Item_empty_string(thd, "is_it_category", 1),
- mem_root);
+
+ fill_header_2_fields(protocol->thd, &field_list, for_category);
DBUG_RETURN(protocol->send_result_set_metadata(&field_list,
Protocol::SEND_NUM_ROWS |
Protocol::SEND_EOF));
@@ -639,7 +684,6 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond,
thd Thread handler
mask mask for compare with name
mlen length of mask
- tables list of tables, used in WHERE
table goal table
pfname field "name" in table
@@ -650,8 +694,7 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond,
*/
SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, size_t mlen,
- TABLE_LIST *tables, TABLE *table,
- Field *pfname, int *error)
+ TABLE *table, Field *pfname, int *error)
{
MEM_ROOT *mem_root= thd->mem_root;
Item *cond= new (mem_root)
@@ -668,6 +711,205 @@ SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, size_t mlen,
}
+/**
+ Initialize the TABLE_LIST with tables used in HELP statement handling.
+
+ @param thd Thread handler
+ @param tables Array of four TABLE_LIST objects to initialize with data
+ about the tables help_topic, help_category, help_relation,
+ help_keyword
+*/
+
+static void initialize_tables_for_help_command(THD *thd, TABLE_LIST *tables)
+{
+ LEX_CSTRING MYSQL_HELP_TOPIC_NAME= {STRING_WITH_LEN("help_topic") };
+ LEX_CSTRING MYSQL_HELP_CATEGORY_NAME= {STRING_WITH_LEN("help_category") };
+ LEX_CSTRING MYSQL_HELP_RELATION_NAME= {STRING_WITH_LEN("help_relation") };
+ LEX_CSTRING MYSQL_HELP_KEYWORD_NAME= {STRING_WITH_LEN("help_keyword") };
+
+ tables[0].init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_HELP_TOPIC_NAME, 0,
+ TL_READ);
+ tables[1].init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_HELP_CATEGORY_NAME, 0,
+ TL_READ);
+ tables[2].init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_HELP_RELATION_NAME, 0,
+ TL_READ);
+ tables[3].init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_HELP_KEYWORD_NAME, 0,
+ TL_READ);
+ tables[0].next_global= tables[0].next_local=
+ tables[0].next_name_resolution_table= &tables[1];
+ tables[1].next_global= tables[1].next_local=
+ tables[1].next_name_resolution_table= &tables[2];
+ tables[2].next_global= tables[2].next_local=
+ tables[2].next_name_resolution_table= &tables[3];
+}
+
+
+/**
+ Setup tables and fields for query.
+
+ @param thd Thread handler
+ @param first_select_lex SELECT_LEX of the parsed statement
+ @param tables Array of tables used in handling of the HELP
+ statement
+ @param used_fields Array of fields used in handling of the HELP
+ statement
+
+ @return false on success, else true.
+*/
+
+template <size_t M, size_t N>
+static bool init_items_for_help_command(THD *thd,
+ SELECT_LEX *first_select_lex,
+ TABLE_LIST (&tables)[M],
+ st_find_field (& used_fields)[N])
+{
+ List<TABLE_LIST> leaves;
+
+ /*
+ Initialize tables and fields to be usable from items.
+ tables do not contain VIEWs => we can pass 0 as conds
+ */
+ first_select_lex->context.table_list=
+ first_select_lex->context.first_name_resolution_table=
+ &tables[0];
+
+ if (setup_tables(thd, &first_select_lex->context,
+ &first_select_lex->top_join_list,
+ &tables[0], leaves, false, false))
+ return true;
+
+ memcpy((char*) used_fields, (char*) init_used_fields,
+ sizeof(used_fields[0]) * N);
+ if (init_fields(thd, &tables[0], used_fields, N))
+ return true;
+
+ for (size_t i= 0; i < M; i++)
+ tables[i].table->file->init_table_handle_for_HANDLER();
+
+ return false;
+}
+
+
+/**
+ Prepare (in the sense of prepared statement) the HELP statement.
+
+ @param thd Thread handler
+ @param mask string value passed to the HELP statement
+ @oaram[out] fields fields for result set metadata
+
+ @return false on success, else true.
+*/
+
+bool mysqld_help_prepare(THD *thd, const char *mask, List<Item> *fields)
+{
+ TABLE_LIST tables[4];
+ st_find_field used_fields[array_elements(init_used_fields)];
+ SQL_SELECT *select;
+
+ List<String> topics_list;
+
+ Sql_mode_instant_remove sms(thd, MODE_PAD_CHAR_TO_FULL_LENGTH);
+ initialize_tables_for_help_command(thd, tables);
+
+ /*
+ HELP must be available under LOCK TABLES.
+ Reset and backup the current open tables state to
+ make it possible.
+ */
+ start_new_trans new_trans(thd);
+
+ if (open_system_tables_for_read(thd, tables))
+ return true;
+
+ auto cleanup_and_return= [&](bool ret)
+ {
+ thd->commit_whole_transaction_and_close_tables();
+ new_trans.restore_old_transaction();
+ return ret;
+ };
+
+ if (init_items_for_help_command(thd, thd->lex->first_select_lex(),
+ tables, used_fields))
+ return cleanup_and_return(false);
+
+ size_t mlen= strlen(mask);
+ int error;
+
+ /*
+ Prepare the query 'SELECT * FROM help_topic WHERE name LIKE mask'
+ for execution
+ */
+ if (!(select=
+ prepare_select_for_name(thd,mask, mlen, tables[0].table,
+ used_fields[help_topic_name].field, &error)))
+ return cleanup_and_return(true);
+
+ String name, description, example;
+ /*
+ Run the query 'SELECT * FROM help_topic WHERE name LIKE mask'
+ */
+ int count_topics= search_topics(thd, tables[0].table, used_fields,
+ select, &topics_list,
+ &name, &description, &example);
+ delete select;
+
+ if (thd->is_error())
+ return cleanup_and_return(true);
+
+ if (count_topics == 0)
+ {
+ int UNINIT_VAR(key_id);
+ /*
+ Prepare the query 'SELECT * FROM help_keyword WHERE name LIKE mask'
+ for execution
+ */
+ if (!(select=
+ prepare_select_for_name(thd, mask, mlen, tables[3].table,
+ used_fields[help_keyword_name].field,
+ &error)))
+ return cleanup_and_return(true);
+
+ /*
+ Run the query 'SELECT * FROM help_keyword WHERE name LIKE mask'
+ */
+ count_topics= search_keyword(thd,tables[3].table, used_fields, select,
+ &key_id);
+ delete select;
+ count_topics= (count_topics != 1) ? 0 :
+ get_topics_for_keyword(thd, tables[0].table, tables[2].table,
+ used_fields, key_id, &topics_list, &name,
+ &description, &example);
+
+ }
+
+ if (count_topics == 0)
+ {
+ if (!(select=
+ prepare_select_for_name(thd, mask, mlen, tables[1].table,
+ used_fields[help_category_name].field,
+ &error)))
+ return cleanup_and_return(true);
+
+ List<String> categories_list;
+ int16 category_id;
+ int count_categories= search_categories(thd, tables[1].table, used_fields,
+ select,
+ &categories_list,&category_id);
+ delete select;
+ if (count_categories == 1)
+ fill_header_2_fields(thd, fields, true);
+ else
+ fill_header_2_fields(thd, fields, false);
+ }
+ else if (count_topics == 1)
+ fill_answer_1_fields(thd, fields);
+ else
+ fill_header_2_fields(thd, fields, false);
+
+ return cleanup_and_return(false);
+}
+
+
/*
Server-side function 'help'
@@ -685,30 +927,15 @@ static bool mysqld_help_internal(THD *thd, const char *mask)
Protocol *protocol= thd->protocol;
SQL_SELECT *select;
st_find_field used_fields[array_elements(init_used_fields)];
- List<TABLE_LIST> leaves;
TABLE_LIST tables[4];
List<String> topics_list, categories_list, subcategories_list;
String name, description, example;
int count_topics, count_categories, error;
size_t mlen= strlen(mask);
- size_t i;
MEM_ROOT *mem_root= thd->mem_root;
- LEX_CSTRING MYSQL_HELP_TOPIC_NAME= {STRING_WITH_LEN("help_topic") };
- LEX_CSTRING MYSQL_HELP_CATEGORY_NAME= {STRING_WITH_LEN("help_category") };
- LEX_CSTRING MYSQL_HELP_RELATION_NAME= {STRING_WITH_LEN("help_relation") };
- LEX_CSTRING MYSQL_HELP_KEYWORD_NAME= {STRING_WITH_LEN("help_keyword") };
DBUG_ENTER("mysqld_help");
- tables[0].init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_HELP_TOPIC_NAME, 0, TL_READ);
- tables[1].init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_HELP_CATEGORY_NAME, 0, TL_READ);
- tables[2].init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_HELP_RELATION_NAME, 0, TL_READ);
- tables[3].init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_HELP_KEYWORD_NAME, 0, TL_READ);
- tables[0].next_global= tables[0].next_local=
- tables[0].next_name_resolution_table= &tables[1];
- tables[1].next_global= tables[1].next_local=
- tables[1].next_name_resolution_table= &tables[2];
- tables[2].next_global= tables[2].next_local=
- tables[2].next_name_resolution_table= &tables[3];
+ initialize_tables_for_help_command(thd, tables);
/*
HELP must be available under LOCK TABLES.
@@ -720,25 +947,12 @@ static bool mysqld_help_internal(THD *thd, const char *mask)
if (open_system_tables_for_read(thd, tables))
goto error2;
- /*
- Init tables and fields to be usable from items
- tables do not contain VIEWs => we can pass 0 as conds
- */
- thd->lex->first_select_lex()->context.table_list=
- thd->lex->first_select_lex()->context.first_name_resolution_table=
- &tables[0];
- if (setup_tables(thd, &thd->lex->first_select_lex()->context,
- &thd->lex->first_select_lex()->top_join_list,
- tables, leaves, FALSE, FALSE))
+ if (init_items_for_help_command(thd, thd->lex->first_select_lex(),
+ tables, used_fields))
goto error;
- memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
- if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
- goto error;
- for (i=0; i<sizeof(tables)/sizeof(TABLE_LIST); i++)
- tables[i].table->file->init_table_handle_for_HANDLER();
if (!(select=
- prepare_select_for_name(thd,mask,mlen,tables,tables[0].table,
+ prepare_select_for_name(thd,mask,mlen,tables[0].table,
used_fields[help_topic_name].field,&error)))
goto error;
@@ -754,7 +968,7 @@ static bool mysqld_help_internal(THD *thd, const char *mask)
{
int UNINIT_VAR(key_id);
if (!(select=
- prepare_select_for_name(thd,mask,mlen,tables,tables[3].table,
+ prepare_select_for_name(thd,mask,mlen,tables[3].table,
used_fields[help_keyword_name].field,
&error)))
goto error;
@@ -773,7 +987,7 @@ static bool mysqld_help_internal(THD *thd, const char *mask)
int16 category_id;
Field *cat_cat_id= used_fields[help_category_parent_category_id].field;
if (!(select=
- prepare_select_for_name(thd,mask,mlen,tables,tables[1].table,
+ prepare_select_for_name(thd,mask,mlen,tables[1].table,
used_fields[help_category_name].field,
&error)))
goto error;
@@ -841,7 +1055,7 @@ static bool mysqld_help_internal(THD *thd, const char *mask)
send_variant_2_list(mem_root,protocol, &topics_list, "N", 0))
goto error;
if (!(select=
- prepare_select_for_name(thd,mask,mlen,tables,tables[1].table,
+ prepare_select_for_name(thd,mask,mlen,tables[1].table,
used_fields[help_category_name].field,&error)))
goto error;
search_categories(thd, tables[1].table, used_fields,
diff --git a/sql/sql_help.h b/sql/sql_help.h
index cb3314b756c..b0117649f03 100644
--- a/sql/sql_help.h
+++ b/sql/sql_help.h
@@ -25,4 +25,6 @@ class THD;
bool mysqld_help (THD *thd, const char *text);
+bool mysqld_help_prepare(THD *thd, const char *text, List<Item> *fields);
+
#endif /* SQL_HELP_INCLUDED */
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 94575c074ef..b9f7d9cc2c8 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -869,7 +869,7 @@ public:
// Ensures that at least all members used during cleanup() are initialized.
st_select_lex_unit()
: union_result(NULL), table(NULL), result(NULL), fake_select_lex(NULL),
- cleaned(false), bag_set_op_optimized(false),
+ last_procedure(NULL), cleaned(false), bag_set_op_optimized(false),
have_except_all_or_intersect_all(false)
{
}
@@ -4773,6 +4773,19 @@ public:
bool resolve_references_to_cte(TABLE_LIST *tables,
TABLE_LIST **tables_last);
+ /**
+ Turn on the SELECT_DESCRIBE flag for every SELECT_LEX involved into
+ the statement being processed in case the statement is EXPLAIN UPDATE/DELETE.
+
+ @param lex current LEX
+ */
+
+ void promote_select_describe_flag_if_needed()
+ {
+ if (describe)
+ builtin_select.options |= SELECT_DESCRIBE;
+ }
+
};
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 0e3cdaac569..a478d84d071 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -44,6 +44,8 @@
#include "wsrep_mysqld.h"
+#include "scope.h" // scope_exit
+
extern "C" int _my_b_net_read(IO_CACHE *info, uchar *Buffer, size_t Count);
class XML_TAG {
@@ -444,6 +446,12 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list,
if (check_duplic_insert_without_overlaps(thd, table, handle_duplicates) != 0)
DBUG_RETURN(true);
+ auto scope_cleaner = make_scope_exit(
+ [&fields_vars]() {
+ fields_vars.empty();
+ }
+ );
+
if (!fields_vars.elements)
{
Field_iterator_table_ref field_iterator;
@@ -471,6 +479,7 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list,
}
else
{ // Part field list
+ scope_cleaner.release();
/* TODO: use this conds for 'WITH CHECK OPTIONS' */
if (setup_fields(thd, Ref_ptr_array(),
fields_vars, MARK_COLUMNS_WRITE, 0, NULL, 0) ||
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 04af54ae8d9..ef7f9ac5b1f 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1672,7 +1672,8 @@ dispatch_command_return dispatch_command(enum enum_server_command command, THD *
command != COM_PING &&
command != COM_QUIT &&
command != COM_STMT_PREPARE &&
- command != COM_STMT_EXECUTE))
+ command != COM_STMT_EXECUTE &&
+ command != COM_STMT_CLOSE))
{
my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
goto dispatch_end;
@@ -2418,7 +2419,18 @@ resume:
thd->update_all_stats();
- log_slow_statement(thd);
+ /*
+ Write to slow query log only those statements that received via the text
+ protocol except the EXECUTE statement. The reason we do that way is
+ that for statements received via binary protocol and for the EXECUTE
+ statement, the slow statements have been already written to slow query log
+ inside the method Prepared_statement::execute().
+ */
+ if(command == COM_QUERY &&
+ thd->lex->sql_command != SQLCOM_EXECUTE)
+ log_slow_statement(thd);
+ else
+ delete_explain_query(thd->lex);
THD_STAGE_INFO(thd, stage_cleaning_up);
thd->reset_query();
@@ -3432,7 +3444,7 @@ bool run_set_statement_if_requested(THD *thd, LEX *lex)
*/
int
-mysql_execute_command(THD *thd)
+mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt)
{
int res= 0;
int up_result= 0;
@@ -5259,7 +5271,7 @@ mysql_execute_command(THD *thd)
} while (0);
/* Don't do it, if we are inside a SP */
- if (!thd->spcont)
+ if (!thd->spcont && !is_called_from_prepared_stmt)
{
sp_head::destroy(lex->sphead);
lex->sphead= NULL;
diff --git a/sql/sql_parse.h b/sql/sql_parse.h
index eddaa9d87e1..ebe3fe97114 100644
--- a/sql/sql_parse.h
+++ b/sql/sql_parse.h
@@ -100,7 +100,7 @@ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
void create_table_set_open_action_and_adjust_tables(LEX *lex);
int bootstrap(MYSQL_FILE *file);
bool run_set_statement_if_requested(THD *thd, LEX *lex);
-int mysql_execute_command(THD *thd);
+int mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt=false);
enum dispatch_command_return
{
DISPATCH_COMMAND_SUCCESS=0,
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 1db04c4656f..22b5e1aa326 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -89,6 +89,7 @@ When one supplies long data for a placeholder:
#include "unireg.h"
#include "sql_class.h" // set_var.h: THD
#include "set_var.h"
+#include "sql_admin.h" // fill_check_table_metadata_fields
#include "sql_prepare.h"
#include "sql_parse.h" // insert_precheck, update_precheck, delete_precheck
#include "sql_base.h" // open_normal_and_derived_tables
@@ -105,6 +106,8 @@ When one supplies long data for a placeholder:
#include "sql_cursor.h"
#include "sql_show.h"
#include "sql_repl.h"
+#include "sql_help.h" // mysqld_help_prepare
+#include "sql_table.h" // fill_checksum_table_metadata_fields
#include "slave.h"
#include "sp_head.h"
#include "sp.h"
@@ -129,6 +132,7 @@ static const uint PARAMETER_FLAG_UNSIGNED= 128U << 8;
#include "wsrep_mysqld.h"
#include "wsrep_trans_observer.h"
#endif /* WITH_WSREP */
+#include "xa.h" // xa_recover_get_fields
/**
A result class used to send cursor rows using the binary protocol.
@@ -179,6 +183,7 @@ public:
my_bool iterations;
my_bool start_param;
my_bool read_types;
+
#ifndef EMBEDDED_LIBRARY
bool (*set_params)(Prepared_statement *st, uchar *data, uchar *data_end,
uchar *read_pos, String *expanded_query);
@@ -196,7 +201,7 @@ public:
virtual ~Prepared_statement();
void setup_set_params();
virtual Query_arena::Type type() const;
- virtual void cleanup_stmt();
+ virtual void cleanup_stmt(bool restore_set_statement_vars);
bool set_name(const LEX_CSTRING *name);
inline void close_cursor() { delete cursor; cursor= 0; }
inline bool is_in_use() { return flags & (uint) IS_IN_USE; }
@@ -1255,11 +1260,17 @@ insert_params_from_actual_params_with_log(Prepared_statement *stmt,
DBUG_RETURN(0);
}
-/**
+
+/*
Validate INSERT statement.
@param stmt prepared statement
- @param tables global/local table list
+ @param table_list global/local table list
+ @param fields list of the table's fields to insert values
+ @param values_list values to be inserted into the table
+ @param update_fields the update fields.
+ @param update_values the update values.
+ @param duplic a way to handle duplicates
@retval
FALSE success
@@ -1267,29 +1278,18 @@ insert_params_from_actual_params_with_log(Prepared_statement *stmt,
TRUE error, error message is set in THD
*/
-static bool mysql_test_insert(Prepared_statement *stmt,
- TABLE_LIST *table_list,
- List<Item> &fields,
- List<List_item> &values_list,
- List<Item> &update_fields,
- List<Item> &update_values,
- enum_duplicates duplic)
+static bool mysql_test_insert_common(Prepared_statement *stmt,
+ TABLE_LIST *table_list,
+ List<Item> &fields,
+ List<List_item> &values_list,
+ List<Item> &update_fields,
+ List<Item> &update_values,
+ enum_duplicates duplic)
{
THD *thd= stmt->thd;
List_iterator_fast<List_item> its(values_list);
List_item *values;
- DBUG_ENTER("mysql_test_insert");
-
- /*
- Since INSERT DELAYED doesn't support temporary tables, we could
- not pre-open temporary tables for SQLCOM_INSERT / SQLCOM_REPLACE.
- Open them here instead.
- */
- if (table_list->lock_type != TL_WRITE_DELAYED)
- {
- if (thd->open_temporary_tables(table_list))
- goto error;
- }
+ DBUG_ENTER("mysql_test_insert_common");
if (insert_precheck(thd, table_list))
goto error;
@@ -1357,6 +1357,44 @@ error:
/**
+ Open temporary tables if required and validate INSERT statement.
+
+ @param stmt prepared statement
+ @param tables global/local table list
+
+ @retval
+ FALSE success
+ @retval
+ TRUE error, error message is set in THD
+*/
+
+static bool mysql_test_insert(Prepared_statement *stmt,
+ TABLE_LIST *table_list,
+ List<Item> &fields,
+ List<List_item> &values_list,
+ List<Item> &update_fields,
+ List<Item> &update_values,
+ enum_duplicates duplic)
+{
+ THD *thd= stmt->thd;
+
+ /*
+ Since INSERT DELAYED doesn't support temporary tables, we could
+ not pre-open temporary tables for SQLCOM_INSERT / SQLCOM_REPLACE.
+ Open them here instead.
+ */
+ if (table_list->lock_type != TL_WRITE_DELAYED)
+ {
+ if (thd->open_temporary_tables(table_list))
+ return true;
+ }
+
+ return mysql_test_insert_common(stmt, table_list, fields, values_list,
+ update_fields, update_values, duplic);
+}
+
+
+/**
Validate UPDATE statement.
@param stmt prepared statement
@@ -2274,6 +2312,83 @@ static int mysql_test_handler_read(Prepared_statement *stmt,
/**
+ Send metadata to a client on PREPARE phase of XA RECOVER statement
+ processing
+
+ @param stmt prepared statement
+
+ @return 0 on success, 1 on failure, 2 in case metadata was already sent
+*/
+
+static int mysql_test_xa_recover(Prepared_statement *stmt)
+{
+ THD *thd= stmt->thd;
+ List<Item> field_list;
+
+ xa_recover_get_fields(thd, &field_list, nullptr);
+ return send_stmt_metadata(thd, stmt, &field_list);
+}
+
+
+/**
+ Send metadata to a client on PREPARE phase of HELP statement processing
+
+ @param stmt prepared statement
+
+ @return 0 on success, 1 on failure, 2 in case metadata was already sent
+*/
+
+static int mysql_test_help(Prepared_statement *stmt)
+{
+ THD *thd= stmt->thd;
+ List<Item> fields;
+
+ if (mysqld_help_prepare(thd, stmt->lex->help_arg, &fields))
+ return 1;
+
+ return send_stmt_metadata(thd, stmt, &fields);
+}
+
+
+/**
+ Send metadata to a client on PREPARE phase of admin related statements
+ processing
+
+ @param stmt prepared statement
+
+ @return 0 on success, 1 on failure, 2 in case metadata was already sent
+*/
+
+static int mysql_test_admin_table(Prepared_statement *stmt)
+{
+ THD *thd= stmt->thd;
+ List<Item> fields;
+
+ fill_check_table_metadata_fields(thd, &fields);
+ return send_stmt_metadata(thd, stmt, &fields);
+}
+
+
+/**
+ Send metadata to a client on PREPARE phase of CHECKSUM TABLE statement
+ processing
+
+ @param stmt prepared statement
+
+ @return 0 on success, 1 on failure, 2 in case metadata was already sent
+*/
+
+static int mysql_test_checksum_table(Prepared_statement *stmt)
+{
+ THD *thd= stmt->thd;
+ List<Item> fields;
+
+ fill_checksum_table_metadata_fields(thd, &fields);
+ return send_stmt_metadata(thd, stmt, &fields);
+}
+
+
+/**
Perform semantic analysis of the parsed tree and send a response packet
to the client.
@@ -2347,6 +2462,13 @@ static bool check_prepared_statement(Prepared_statement *stmt)
lex->duplicates);
break;
+ case SQLCOM_LOAD:
+ res= mysql_test_insert_common(stmt, tables, lex->field_list,
+ lex->many_values,
+ lex->update_list, lex->value_list,
+ lex->duplicates);
+ break;
+
case SQLCOM_UPDATE:
res= mysql_test_update(stmt, tables);
/* mysql_test_update returns 2 if we need to switch to multi-update */
@@ -2483,11 +2605,6 @@ static bool check_prepared_statement(Prepared_statement *stmt)
}
break;
case SQLCOM_CREATE_VIEW:
- if (lex->create_view->mode == VIEW_ALTER)
- {
- my_message(ER_UNSUPPORTED_PS, ER_THD(thd, ER_UNSUPPORTED_PS), MYF(0));
- goto error;
- }
res= mysql_test_create_view(stmt);
break;
case SQLCOM_DO:
@@ -2515,71 +2632,47 @@ static bool check_prepared_statement(Prepared_statement *stmt)
/* Statement and field info has already been sent */
DBUG_RETURN(res == 1 ? TRUE : FALSE);
- /*
- Note that we don't need to have cases in this list if they are
- marked with CF_STATUS_COMMAND in sql_command_flags
- */
- case SQLCOM_SHOW_EXPLAIN:
- case SQLCOM_DROP_TABLE:
- case SQLCOM_DROP_SEQUENCE:
- case SQLCOM_RENAME_TABLE:
- case SQLCOM_ALTER_TABLE:
- case SQLCOM_ALTER_SEQUENCE:
- case SQLCOM_COMMIT:
- case SQLCOM_CREATE_INDEX:
- case SQLCOM_DROP_INDEX:
- case SQLCOM_ROLLBACK:
- case SQLCOM_ROLLBACK_TO_SAVEPOINT:
- case SQLCOM_TRUNCATE:
- case SQLCOM_DROP_VIEW:
- case SQLCOM_REPAIR:
+ case SQLCOM_XA_RECOVER:
+ res= mysql_test_xa_recover(stmt);
+ if (res == 2)
+ /* Statement and field info has already been sent */
+ DBUG_RETURN(false);
+ break;
+
+ case SQLCOM_HELP:
+ res= mysql_test_help(stmt);
+ if (res == 2)
+ /* Statement and field info has already been sent */
+ DBUG_RETURN(false);
+ break;
+
case SQLCOM_ANALYZE:
- case SQLCOM_OPTIMIZE:
- case SQLCOM_CHANGE_MASTER:
- case SQLCOM_RESET:
- case SQLCOM_FLUSH:
- case SQLCOM_SLAVE_START:
- case SQLCOM_SLAVE_STOP:
- case SQLCOM_SLAVE_ALL_START:
- case SQLCOM_SLAVE_ALL_STOP:
- case SQLCOM_INSTALL_PLUGIN:
- case SQLCOM_UNINSTALL_PLUGIN:
- case SQLCOM_CREATE_DB:
- case SQLCOM_DROP_DB:
- case SQLCOM_ALTER_DB_UPGRADE:
- case SQLCOM_CHECKSUM:
- case SQLCOM_CREATE_USER:
- case SQLCOM_ALTER_USER:
- case SQLCOM_RENAME_USER:
- case SQLCOM_DROP_USER:
- case SQLCOM_CREATE_ROLE:
- case SQLCOM_DROP_ROLE:
case SQLCOM_ASSIGN_TO_KEYCACHE:
+ case SQLCOM_CHECK:
+ case SQLCOM_OPTIMIZE:
case SQLCOM_PRELOAD_KEYS:
- case SQLCOM_GRANT:
- case SQLCOM_GRANT_ROLE:
- case SQLCOM_REVOKE:
- case SQLCOM_REVOKE_ALL:
- case SQLCOM_REVOKE_ROLE:
- case SQLCOM_KILL:
- case SQLCOM_COMPOUND:
- case SQLCOM_SHUTDOWN:
+ case SQLCOM_REPAIR:
+ res= mysql_test_admin_table(stmt);
+ if (res == 2)
+ /* Statement and field info has already been sent */
+ DBUG_RETURN(false);
+ break;
+
+ case SQLCOM_CHECKSUM:
+ res= mysql_test_checksum_table(stmt);
+ if (res == 2)
+ /* Statement and field info has already been sent */
+ DBUG_RETURN(false);
break;
case SQLCOM_PREPARE:
case SQLCOM_EXECUTE:
+ case SQLCOM_EXECUTE_IMMEDIATE:
case SQLCOM_DEALLOCATE_PREPARE:
+ my_message(ER_UNSUPPORTED_PS, ER_THD(thd, ER_UNSUPPORTED_PS), MYF(0));
+ goto error;
+
default:
- /*
- Trivial check of all status commands. This is easier than having
- things in the above case list, as it's less chance for mistakes.
- */
- if (!(sql_command_flags[sql_command] & CF_STATUS_COMMAND))
- {
- /* All other statements are not supported yet. */
- my_message(ER_UNSUPPORTED_PS, ER_THD(thd, ER_UNSUPPORTED_PS), MYF(0));
- goto error;
- }
break;
}
if (res == 0)
@@ -3484,7 +3577,7 @@ static void mysql_stmt_execute_common(THD *thd,
SQLCOM_EXECUTE implementation.
Execute prepared statement using parameter values from
- lex->prepared_stmt_params and send result to the client using
+ lex->prepared_stmt.params() and send result to the client using
text protocol. This is called from mysql_execute_command and
therefore should behave like an ordinary query (e.g. not change
global THD data, such as warning count, server status, etc).
@@ -4100,11 +4193,14 @@ Query_arena::Type Prepared_statement::type() const
}
-void Prepared_statement::cleanup_stmt()
+void Prepared_statement::cleanup_stmt(bool restore_set_statement_vars)
{
DBUG_ENTER("Prepared_statement::cleanup_stmt");
DBUG_PRINT("enter",("stmt: %p", this));
- lex->restore_set_statement_var();
+
+ if (restore_set_statement_vars)
+ lex->restore_set_statement_var();
+
thd->rollback_item_tree_changes();
cleanup_items(free_list);
thd->cleanup_after_query();
@@ -4249,7 +4345,10 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
init_param_array(this));
if (thd->security_ctx->password_expired &&
- lex->sql_command != SQLCOM_SET_OPTION)
+ lex->sql_command != SQLCOM_SET_OPTION &&
+ lex->sql_command != SQLCOM_PREPARE &&
+ lex->sql_command != SQLCOM_EXECUTE &&
+ lex->sql_command != SQLCOM_DEALLOCATE_PREPARE)
{
thd->restore_backup_statement(this, &stmt_backup);
thd->restore_active_arena(this, &stmt_backup);
@@ -4310,12 +4409,6 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_PREPARE;
}
- /*
- Restore original values of variables modified on handling
- SET STATEMENT clause.
- */
- thd->lex->restore_set_statement_var();
-
/* The order is important */
lex->unit.cleanup();
@@ -4344,7 +4437,11 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
if (lex->sql_command != SQLCOM_SET_OPTION)
lex_unlock_plugins(lex);
- cleanup_stmt();
+ /*
+ Pass the value true to restore original values of variables modified
+ on handling SET STATEMENT clause.
+ */
+ cleanup_stmt(true);
thd->restore_backup_statement(this, &stmt_backup);
thd->stmt_arena= old_stmt_arena;
thd->cur_stmt= save_cur_stmt;
@@ -5028,6 +5125,25 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
/* Go! */
+ /*
+ Log COM_EXECUTE to the general log. Note, that in case of SQL
+ prepared statements this causes two records to be output:
+
+ Query EXECUTE <statement name>
+ Execute <statement SQL text>
+
+ This is considered user-friendly, since in the
+ second log entry we output values of parameter markers.
+
+ Do not print anything if this is an SQL prepared statement and
+ we're inside a stored procedure (also called Dynamic SQL) --
+ sub-statements inside stored procedures are not logged into
+ the general log.
+ */
+
+ if (thd->spcont == nullptr)
+ general_log_write(thd, COM_STMT_EXECUTE, thd->query(), thd->query_length());
+
if (open_cursor)
error= mysql_open_cursor(thd, &result, &cursor);
else
@@ -5046,8 +5162,9 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
&thd->security_ctx->priv_user[0],
(char *) thd->security_ctx->host_or_ip,
1);
- error= mysql_execute_command(thd);
+ error= mysql_execute_command(thd, true);
MYSQL_QUERY_EXEC_DONE(error);
+ thd->update_server_status();
}
else
{
@@ -5073,8 +5190,47 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
DBUG_ASSERT(! (error && cursor));
if (! cursor)
- cleanup_stmt();
-
+ /*
+ Pass the value false to don't restore set statement variables.
+ See the next comment block for more details.
+ */
+ cleanup_stmt(false);
+
+ /*
+ Log the statement to slow query log if it passes filtering.
+ We do it here for prepared statements despite of the fact that the function
+ log_slow_statement() is also called upper the stack from the function
+ dispatch_command(). The reason for logging slow queries here is that
+ the function log_slow_statement() must be called before restoring system
+ variables that could be set on execution of SET STATEMENT clause. Since
+ for prepared statement restoring of system variables set on execution of
+ SET STATEMENT clause is performed on return from the method
+ Prepared_statement::execute(), by the time the function log_slow_statement()
+ be invoked from the function dispatch_command() all variables set by
+ the SET STATEMEN clause would be already reset to their original values
+ that break semantic of the SET STATEMENT clause.
+
+ E.g., lets consider the following statements
+ SET slow_query_log= 1;
+ SET @@long_query_time=0.01;
+ PREPARE stmt FROM 'set statement slow_query_log=0 for select sleep(0.1)';
+ EXECUTE stmt;
+
+ It's expected that the above statements don't write any record
+ to slow query log since the system variable slow_query_log is set to 0
+ during execution of the whole statement
+ 'set statement slow_query_log=0 for select sleep(0.1)'
+
+ However, if the function log_slow_statement wasn't called here the record
+ for the statement would be written to slow query log since the variable
+ slow_query_log is restored to its original value by the time the function
+ log_slow_statement is called from disptach_command() to write a record
+ into slow query log.
+ */
+ log_slow_statement(thd);
+
+ lex->restore_set_statement_var();
+
/*
EXECUTE command has its own dummy "explain data". We don't need it,
instead, we want to keep the query plan of the statement that was
@@ -5116,24 +5272,6 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
thd->protocol->send_out_parameters(&this->lex->param_list);
}
- /*
- Log COM_EXECUTE to the general log. Note, that in case of SQL
- prepared statements this causes two records to be output:
-
- Query EXECUTE <statement name>
- Execute <statement SQL text>
-
- This is considered user-friendly, since in the
- second log entry we output values of parameter markers.
-
- Do not print anything if this is an SQL prepared statement and
- we're inside a stored procedure (also called Dynamic SQL) --
- sub-statements inside stored procedures are not logged into
- the general log.
- */
- if (likely(error == 0 && thd->spcont == NULL))
- general_log_write(thd, COM_STMT_EXECUTE, thd->query(), thd->query_length());
-
error:
thd->lex->restore_set_statement_var();
flags&= ~ (uint) IS_IN_USE;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index e637d680973..c21c88ef5d2 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -11266,12 +11266,35 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool table_copy)
}
+/**
+ Collect field names of result set that will be sent to a client in result of
+ handling the CHECKSUM TABLE statement.
+
+ @param thd Thread data object
+ @param[out] fields List of fields whose metadata should be collected for
+ sending to client
+ */
+
+void fill_checksum_table_metadata_fields(THD *thd, List<Item> *fields)
+{
+ Item *item;
+
+ item= new (thd->mem_root) Item_empty_string(thd, "Table", NAME_LEN*2);
+ item->set_maybe_null();
+ fields->push_back(item, thd->mem_root);
+
+ item= new (thd->mem_root) Item_int(thd, "Checksum", (longlong) 1,
+ MY_INT64_NUM_DECIMAL_DIGITS);
+ item->set_maybe_null();
+ fields->push_back(item, thd->mem_root);
+}
+
+
bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
HA_CHECK_OPT *check_opt)
{
TABLE_LIST *table;
List<Item> field_list;
- Item *item;
Protocol *protocol= thd->protocol;
DBUG_ENTER("mysql_checksum_table");
@@ -11281,15 +11304,8 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
*/
DBUG_ASSERT(! thd->in_sub_stmt);
- field_list.push_back(item= new (thd->mem_root)
- Item_empty_string(thd, "Table", NAME_LEN*2),
- thd->mem_root);
- item->set_maybe_null();
- field_list.push_back(item= new (thd->mem_root)
- Item_int(thd, "Checksum", (longlong) 1,
- MY_INT64_NUM_DECIMAL_DIGITS),
- thd->mem_root);
- item->set_maybe_null();
+ fill_checksum_table_metadata_fields(thd, &field_list);
+
if (protocol->send_result_set_metadata(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
diff --git a/sql/sql_table.h b/sql/sql_table.h
index 81894999aac..aacb6c99f15 100644
--- a/sql/sql_table.h
+++ b/sql/sql_table.h
@@ -176,6 +176,8 @@ bool mysql_rename_table(handlerton *base, const LEX_CSTRING *old_db,
bool mysql_backup_table(THD* thd, TABLE_LIST* table_list);
bool mysql_restore_table(THD* thd, TABLE_LIST* table_list);
+template<typename T> class List;
+void fill_checksum_table_metadata_fields(THD *thd, List<Item> *fields);
bool mysql_checksum_table(THD* thd, TABLE_LIST* table_list,
HA_CHECK_OPT* check_opt);
bool mysql_rm_table(THD *thd,TABLE_LIST *tables, bool if_exists,
@@ -204,7 +206,6 @@ int write_bin_log(THD *thd, bool clear_error,
int write_bin_log_with_if_exists(THD *thd, bool clear_error,
bool is_trans, bool add_if_exists);
-template<typename T> class List;
void promote_first_timestamp_column(List<Create_field> *column_definitions);
/*
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 738b3e0781a..07171485da4 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -468,7 +468,7 @@ int mysql_update(THD *thd,
want_privilege= (table_list->view ? UPDATE_ACL :
table_list->grant.want_privilege);
#endif
- promote_select_describe_flag_if_needed(thd->lex);
+ thd->lex->promote_select_describe_flag_if_needed();
if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
DBUG_RETURN(1);
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index fa4e769232d..7427bbca0ba 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1955,6 +1955,15 @@ Sys_var_gtid_slave_pos::do_check(THD *thd, set_var *var)
return true;
}
var->save_result.string_value.length= res->length();
+ /*
+ Clear the member THD::m_reprepare_observer to avoid spurious
+ ER_NEED_REPREPARE errors that could happened on opening rpl-related system
+ tables (these tables are not subject to metadata version tracking).
+ The member THD::m_reprepare_observer is restored to its original value
+ on return from the method Sys_var_gtid_slave_pos::global_update().
+ */
+ save_reprepare_observer= thd->m_reprepare_observer;
+ thd->m_reprepare_observer= NULL;
return false;
}
@@ -1969,6 +1978,7 @@ Sys_var_gtid_slave_pos::global_update(THD *thd, set_var *var)
if (!var->value)
{
my_error(ER_NO_DEFAULT, MYF(0), var->var->name.str);
+ thd->m_reprepare_observer= save_reprepare_observer;
return true;
}
@@ -1981,6 +1991,8 @@ Sys_var_gtid_slave_pos::global_update(THD *thd, set_var *var)
var->save_result.string_value.length);
mysql_mutex_unlock(&LOCK_active_mi);
mysql_mutex_lock(&LOCK_global_system_variables);
+ thd->m_reprepare_observer= save_reprepare_observer;
+
return err;
}
diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic
index 2bd6ee6467d..6483ce0c865 100644
--- a/sql/sys_vars.ic
+++ b/sql/sys_vars.ic
@@ -2527,13 +2527,15 @@ public:
*/
class Sys_var_gtid_slave_pos: public sys_var
{
+ Reprepare_observer *save_reprepare_observer;
+
public:
Sys_var_gtid_slave_pos(const char *name_arg,
const char *comment, int flag_args, ptrdiff_t off, size_t size,
CMD_LINE getopt)
: sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id,
getopt.arg_type, SHOW_CHAR, 0, NULL, VARIABLE_NOT_IN_BINLOG,
- NULL, NULL, NULL)
+ NULL, NULL, NULL), save_reprepare_observer(NULL)
{
option.var_type|= GET_STR;
}
diff --git a/sql/xa.cc b/sql/xa.cc
index e0defcb92ed..af7c7388c57 100644
--- a/sql/xa.cc
+++ b/sql/xa.cc
@@ -1001,23 +1001,29 @@ static my_bool xa_recover_callback_verbose(XID_cache_element *xs,
}
-bool mysql_xa_recover(THD *thd)
+/**
+ Collect field names of result set that will be sent to a client in result of
+ handling XA RECOVER statement.
+
+ @param thd Thread data object
+ @param[out] fields List of fields whose metadata should be collected for
+ sending to client
+*/
+
+void xa_recover_get_fields(THD *thd, List<Item> *field_list,
+ my_hash_walk_action *action)
{
- List<Item> field_list;
- Protocol *protocol= thd->protocol;
MEM_ROOT *mem_root= thd->mem_root;
- my_hash_walk_action action;
- DBUG_ENTER("mysql_xa_recover");
- field_list.push_back(new (mem_root)
- Item_int(thd, "formatID", 0,
- MY_INT32_NUM_DECIMAL_DIGITS), mem_root);
- field_list.push_back(new (mem_root)
- Item_int(thd, "gtrid_length", 0,
- MY_INT32_NUM_DECIMAL_DIGITS), mem_root);
- field_list.push_back(new (mem_root)
- Item_int(thd, "bqual_length", 0,
- MY_INT32_NUM_DECIMAL_DIGITS), mem_root);
+ field_list->push_back(new (mem_root)
+ Item_int(thd, "formatID", 0,
+ MY_INT32_NUM_DECIMAL_DIGITS), mem_root);
+ field_list->push_back(new (mem_root)
+ Item_int(thd, "gtrid_length", 0,
+ MY_INT32_NUM_DECIMAL_DIGITS), mem_root);
+ field_list->push_back(new (mem_root)
+ Item_int(thd, "bqual_length", 0,
+ MY_INT32_NUM_DECIMAL_DIGITS), mem_root);
{
uint len;
CHARSET_INFO *cs;
@@ -1026,18 +1032,30 @@ bool mysql_xa_recover(THD *thd)
{
len= SQL_XIDSIZE;
cs= &my_charset_utf8mb3_general_ci;
- action= (my_hash_walk_action) xa_recover_callback_verbose;
+ if (action)
+ *action= (my_hash_walk_action) xa_recover_callback_verbose;
}
else
{
len= XIDDATASIZE;
cs= &my_charset_bin;
- action= (my_hash_walk_action) xa_recover_callback_short;
+ if (action)
+ *action= (my_hash_walk_action) xa_recover_callback_short;
}
- field_list.push_back(new (mem_root)
- Item_empty_string(thd, "data", len, cs), mem_root);
+ field_list->push_back(new (mem_root)
+ Item_empty_string(thd, "data", len, cs), mem_root);
}
+}
+
+bool mysql_xa_recover(THD *thd)
+{
+ List<Item> field_list;
+ Protocol *protocol= thd->protocol;
+ my_hash_walk_action action;
+ DBUG_ENTER("mysql_xa_recover");
+
+ xa_recover_get_fields(thd, &field_list, &action);
if (protocol->send_result_set_metadata(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
diff --git a/sql/xa.h b/sql/xa.h
index 0b2d0696642..a9b06e427c6 100644
--- a/sql/xa.h
+++ b/sql/xa.h
@@ -53,4 +53,7 @@ bool trans_xa_rollback(THD *thd);
bool trans_xa_detach(THD *thd);
bool mysql_xa_recover(THD *thd);
+void xa_recover_get_fields(THD *thd, List<Item> *field_list,
+ my_hash_walk_action *action);
+
#endif /* XA_INCLUDED */