summaryrefslogtreecommitdiff
path: root/sql/sql_prepare.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_prepare.cc')
-rw-r--r--sql/sql_prepare.cc26
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),