diff options
Diffstat (limited to 'sql/sql_prepare.cc')
-rw-r--r-- | sql/sql_prepare.cc | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 00b451c8821..8e5ab71288d 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -102,6 +102,7 @@ When one supplies long data for a placeholder: #include "sql_acl.h" // *_ACL #include "sql_derived.h" // mysql_derived_prepare, // mysql_handle_derived +#include "sql_cte.h" #include "sql_cursor.h" #include "sql_show.h" #include "sql_repl.h" @@ -326,8 +327,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; @@ -1500,6 +1507,8 @@ static int mysql_test_select(Prepared_statement *stmt, lex->select_lex.context.resolve_in_select_list= TRUE; ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL; + if (check_dependencies_in_with_clauses(lex->with_clauses_list)) + goto error; if (tables) { if (check_table_access(thd, privilege, tables, FALSE, UINT_MAX, FALSE)) @@ -1995,7 +2004,7 @@ static int mysql_test_show_create_routine(Prepared_statement *stmt, int type) @note This function handles create view commands. @retval FALSE Operation was a success. - @retval TRUE An error occured. + @retval TRUE An error occurred. */ static bool mysql_test_create_view(Prepared_statement *stmt) @@ -2446,10 +2455,14 @@ static bool check_prepared_statement(Prepared_statement *stmt) case SQLCOM_CREATE_USER: case SQLCOM_RENAME_USER: case SQLCOM_DROP_USER: + case SQLCOM_CREATE_ROLE: + case SQLCOM_DROP_ROLE: case SQLCOM_ASSIGN_TO_KEYCACHE: case SQLCOM_PRELOAD_KEYS: case SQLCOM_GRANT: + case SQLCOM_GRANT_ROLE: case SQLCOM_REVOKE: + case SQLCOM_REVOKE_ROLE: case SQLCOM_KILL: case SQLCOM_COMPOUND: case SQLCOM_SHUTDOWN: @@ -2569,7 +2582,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 +3171,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 +3436,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), |