diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index d48d842d2e7..cf6e51e4a35 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -1340,7 +1340,7 @@ performance-schema-max-rwlock-instances -1 performance-schema-max-socket-classes 10 performance-schema-max-socket-instances -1 performance-schema-max-stage-classes 150 -performance-schema-max-statement-classes 180 +performance-schema-max-statement-classes 181 performance-schema-max-table-handles -1 performance-schema-max-table-instances -1 performance-schema-max-thread-classes 50 diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 60c12276d69..eea45ec1e3a 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -2965,9 +2965,9 @@ READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STATEMENT_CLASSES SESSION_VALUE NULL -GLOBAL_VALUE 180 +GLOBAL_VALUE 181 GLOBAL_VALUE_ORIGIN COMPILE-TIME -DEFAULT_VALUE 180 +DEFAULT_VALUE 181 VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Maximum number of statement instruments. diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 38289b188b2..63a300269dd 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1426,6 +1426,7 @@ void THD::init(void) bzero((char *) &org_status_var, sizeof(org_status_var)); start_bytes_received= 0; last_commit_gtid.seq_no= 0; + last_stmt= NULL; status_in_global= 0; #ifdef WITH_WSREP wsrep_exec_mode= wsrep_applier ? REPL_RECV : LOCAL_STATE; diff --git a/sql/sql_class.h b/sql/sql_class.h index 6c73aeec4bb..933815a00ce 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1965,6 +1965,13 @@ public: /* all prepared statements and cursors of this connection */ Statement_map stmt_map; + + /* Last created prepared statement */ + Statement *last_stmt; + inline void set_last_stmt(Statement *stmt) + { last_stmt= (is_error() ? NULL : stmt); } + inline void clear_last_stmt() { last_stmt= NULL; } + /* A pointer to the stack frame of handle_one_connection(), which is called first in the thread for handling a client diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 00b451c8821..c315f3cfa4e 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -326,8 +326,14 @@ find_prepared_statement(THD *thd, ulong id) To strictly separate namespaces of SQL prepared statements and C API prepared statements find() will return 0 if there is a named prepared statement with such id. + + LAST_STMT_ID is special value which mean last prepared statement ID + (it was made for COM_MULTI to allow prepare and execute a statement + in the same command but usage is not limited by COM_MULTI only). */ - Statement *stmt= thd->stmt_map.find(id); + Statement *stmt= ((id == LAST_STMT_ID) ? + thd->last_stmt : + thd->stmt_map.find(id)); if (stmt == 0 || stmt->type() != Query_arena::PREPARED_STATEMENT) return NULL; @@ -2569,7 +2575,10 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length) { /* Statement map deletes statement on erase */ thd->stmt_map.erase(stmt); + thd->clear_last_stmt(); } + else + thd->set_last_stmt(stmt); thd->protocol= save_protocol; @@ -3155,6 +3164,9 @@ void mysqld_stmt_close(THD *thd, char *packet) stmt->deallocate(); general_log_print(thd, thd->get_command(), NullS); + if (thd->last_stmt == stmt) + thd->clear_last_stmt(); + DBUG_VOID_RETURN; } @@ -3417,7 +3429,8 @@ end: Prepared_statement::Prepared_statement(THD *thd_arg) :Statement(NULL, &main_mem_root, - STMT_INITIALIZED, ++thd_arg->statement_id_counter), + STMT_INITIALIZED, + ((++thd_arg->statement_id_counter) & STMT_ID_MASK)), thd(thd_arg), result(thd_arg), param_array(0), diff --git a/sql/sql_prepare.h b/sql/sql_prepare.h index b468ac1bf9b..aec4ac40036 100644 --- a/sql/sql_prepare.h +++ b/sql/sql_prepare.h @@ -18,6 +18,10 @@ #include "sql_error.h" + +#define LAST_STMT_ID 0xFFFFFFFF +#define STMT_ID_MASK 0x7FFFFFFF + class THD; struct LEX;