summaryrefslogtreecommitdiff
path: root/sql/sql_class.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_class.h')
-rw-r--r--sql/sql_class.h213
1 files changed, 156 insertions, 57 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 05082a8e8fe..9280fbd0640 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -111,6 +111,41 @@ extern MYSQL_PLUGIN_IMPORT const char **errmesg;
extern bool volatile shutdown_in_progress;
+extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd);
+extern "C" char **thd_query(MYSQL_THD thd);
+
+/**
+ @class CSET_STRING
+ @brief Character set armed LEX_STRING
+*/
+class CSET_STRING
+{
+private:
+ LEX_STRING string;
+ CHARSET_INFO *cs;
+public:
+ CSET_STRING() : cs(&my_charset_bin)
+ {
+ string.str= NULL;
+ string.length= 0;
+ }
+ CSET_STRING(char *str_arg, size_t length_arg, CHARSET_INFO *cs_arg) :
+ cs(cs_arg)
+ {
+ DBUG_ASSERT(cs_arg != NULL);
+ string.str= str_arg;
+ string.length= length_arg;
+ }
+
+ inline char *str() const { return string.str; }
+ inline uint32 length() const { return string.length; }
+ CHARSET_INFO *charset() const { return cs; }
+
+ friend LEX_STRING * thd_query_string (MYSQL_THD thd);
+ friend char **thd_query(MYSQL_THD thd);
+};
+
+
#define TC_LOG_PAGE_SIZE 8192
#define TC_LOG_MIN_SIZE (3*TC_LOG_PAGE_SIZE)
@@ -630,14 +665,14 @@ public:
/*
The states relfects three diffrent life cycles for three
different types of statements:
- Prepared statement: INITIALIZED -> PREPARED -> EXECUTED.
- Stored procedure: INITIALIZED_FOR_SP -> EXECUTED.
- Other statements: CONVENTIONAL_EXECUTION never changes.
+ Prepared statement: STMT_INITIALIZED -> STMT_PREPARED -> STMT_EXECUTED.
+ Stored procedure: STMT_INITIALIZED_FOR_SP -> STMT_EXECUTED.
+ Other statements: STMT_CONVENTIONAL_EXECUTION never changes.
*/
enum enum_state
{
- INITIALIZED= 0, INITIALIZED_FOR_SP= 1, PREPARED= 2,
- CONVENTIONAL_EXECUTION= 3, EXECUTED= 4, ERROR= -1
+ STMT_INITIALIZED= 0, STMT_INITIALIZED_FOR_SP= 1, STMT_PREPARED= 2,
+ STMT_CONVENTIONAL_EXECUTION= 3, STMT_EXECUTED= 4, STMT_ERROR= -1
};
enum_state state;
@@ -660,18 +695,13 @@ public:
virtual Type type() const;
virtual ~Query_arena() {};
- inline bool is_stmt_prepare() const { return state == INITIALIZED; }
- inline bool is_first_sp_execute() const
- { return state == INITIALIZED_FOR_SP; }
+ inline bool is_stmt_prepare() const { return state == STMT_INITIALIZED; }
inline bool is_stmt_prepare_or_first_sp_execute() const
- { return (int)state < (int)PREPARED; }
+ { return (int)state < (int)STMT_PREPARED; }
inline bool is_stmt_prepare_or_first_stmt_execute() const
- { return (int)state <= (int)PREPARED; }
- inline bool is_first_stmt_execute() const { return state == PREPARED; }
- inline bool is_stmt_execute() const
- { return state == PREPARED || state == EXECUTED; }
+ { return (int)state <= (int)STMT_PREPARED; }
inline bool is_conventional() const
- { return state == CONVENTIONAL_EXECUTION; }
+ { return state == STMT_CONVENTIONAL_EXECUTION; }
inline void* alloc(size_t size) { return alloc_root(mem_root,size); }
inline void* calloc(size_t size)
@@ -763,12 +793,24 @@ public:
This printing is needed at least in SHOW PROCESSLIST and SHOW
ENGINE INNODB STATUS.
*/
- LEX_STRING query_string;
-
- inline char *query() { return query_string.str; }
- inline uint32 query_length() { return query_string.length; }
- void set_query_inner(char *query_arg, uint32 query_length_arg);
+ CSET_STRING query_string;
+ inline char *query() const { return query_string.str(); }
+ inline uint32 query_length() const { return query_string.length(); }
+ CHARSET_INFO *query_charset() const { return query_string.charset(); }
+ void set_query_inner(const CSET_STRING &string_arg)
+ {
+ query_string= string_arg;
+ }
+ void set_query_inner(char *query_arg, uint32 query_length_arg,
+ CHARSET_INFO *cs_arg)
+ {
+ set_query_inner(CSET_STRING(query_arg, query_length_arg, cs_arg));
+ }
+ void reset_query_inner()
+ {
+ set_query_inner(CSET_STRING());
+ }
/**
Name of the current (default) database.
@@ -863,8 +905,8 @@ struct st_savepoint {
char *name;
uint length;
Ha_trx_info *ha_list;
- /** Last acquired lock before this savepoint was set. */
- MDL_ticket *mdl_savepoint;
+ /** State of metadata locks before this savepoint was set. */
+ MDL_savepoint mdl_savepoint;
};
enum xa_states {XA_NOTR=0, XA_ACTIVE, XA_IDLE, XA_PREPARED, XA_ROLLBACK_ONLY};
@@ -905,8 +947,11 @@ public:
*/
char *host, *user, *ip;
char priv_user[USERNAME_LENGTH];
+ char proxy_user[USERNAME_LENGTH + MAX_HOSTNAME + 5];
/* The host privilege we are using */
char priv_host[MAX_HOSTNAME];
+ /* The external user (if available) */
+ char *external_user;
/* points to host if host is available, otherwise points to ip */
const char *host_or_ip;
ulong master_access; /* Global privileges from mysql.user */
@@ -1096,12 +1141,12 @@ class Open_tables_backup: public Open_tables_state
public:
/**
When we backup the open tables state to open a system
- table or tables, points at the last metadata lock
- acquired before the backup. Is used to release
- metadata locks on system tables after they are
+ table or tables, we want to save state of metadata
+ locks which were acquired before the backup. It is used
+ to release metadata locks on system tables after they are
no longer used.
*/
- MDL_ticket *mdl_system_tables_svp;
+ MDL_savepoint mdl_system_tables_svp;
};
/**
@@ -1376,26 +1421,43 @@ public:
};
Global_read_lock()
- :m_protection_count(0), m_state(GRL_NONE), m_mdl_global_shared_lock(NULL)
+ : m_state(GRL_NONE),
+ m_mdl_global_shared_lock(NULL),
+ m_mdl_blocks_commits_lock(NULL)
{}
bool lock_global_read_lock(THD *thd);
void unlock_global_read_lock(THD *thd);
- bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
- bool is_not_commit);
- void start_waiting_global_read_lock(THD *thd);
+ /**
+ Check if this connection can acquire protection against GRL and
+ emit error if otherwise.
+ */
+ bool can_acquire_protection() const
+ {
+ if (m_state)
+ {
+ my_error(ER_CANT_UPDATE_WITH_READLOCK, MYF(0));
+ return TRUE;
+ }
+ return FALSE;
+ }
bool make_global_read_lock_block_commit(THD *thd);
bool is_acquired() const { return m_state != GRL_NONE; }
- bool has_protection() const { return m_protection_count > 0; }
- MDL_ticket *global_shared_lock() const { return m_mdl_global_shared_lock; }
+ void set_explicit_lock_duration(THD *thd);
private:
- uint m_protection_count; // GRL protection count
+ enum_grl_state m_state;
/**
In order to acquire the global read lock, the connection must
- acquire a global shared metadata lock, to prohibit all DDL.
+ acquire shared metadata lock in GLOBAL namespace, to prohibit
+ all DDL.
*/
- enum_grl_state m_state;
MDL_ticket *m_mdl_global_shared_lock;
+ /**
+ Also in order to acquire the global read lock, the connection
+ must acquire a shared metadata lock in COMMIT namespace, to
+ prohibit commits.
+ */
+ MDL_ticket *m_mdl_blocks_commits_lock;
};
@@ -1410,6 +1472,19 @@ extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
class THD :public Statement,
public Open_tables_state
{
+private:
+ inline bool is_stmt_prepare() const
+ { DBUG_ASSERT(0); return Statement::is_stmt_prepare(); }
+
+ inline bool is_stmt_prepare_or_first_sp_execute() const
+ { DBUG_ASSERT(0); return Statement::is_stmt_prepare_or_first_sp_execute(); }
+
+ inline bool is_stmt_prepare_or_first_stmt_execute() const
+ { DBUG_ASSERT(0); return Statement::is_stmt_prepare_or_first_stmt_execute(); }
+
+ inline bool is_conventional() const
+ { DBUG_ASSERT(0); return Statement::is_conventional(); }
+
public:
MDL_context mdl_context;
@@ -2008,6 +2083,12 @@ public:
DYNAMIC_ARRAY user_var_events; /* For user variables replication */
MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */
+ /*
+ If checking this in conjunction with a wait condition, please
+ include a check after enter_cond() if you want to avoid a race
+ condition. For details see the implementation of awake(),
+ especially the "broadcast" part.
+ */
enum killed_state
{
NOT_KILLED=0,
@@ -2025,6 +2106,9 @@ public:
bool no_errors, password;
bool extra_port; /* If extra connection */
+ bool no_errors;
+ uint8 password;
+
/**
Set to TRUE if execution of the current compound statement
can not continue. In particular, disables activation of
@@ -2075,7 +2159,6 @@ public:
bool enable_slow_log; /* enable slow log for current statement */
bool abort_on_warning;
bool got_warning; /* Set on call to push_warning() */
- bool no_warnings_for_error; /* no warnings on call to my_error() */
/* set during loop of derived table processing */
bool derived_tables_processing;
bool tablespace_op; /* This is TRUE in DISCARD/IMPORT TABLESPACE */
@@ -2213,6 +2296,9 @@ public:
#endif
void awake(THD::killed_state state_to_set);
+ /** Disconnect the associated communication endpoint. */
+ void disconnect();
+
#ifndef MYSQL_CLIENT
enum enum_binlog_query_type {
/* The query can be logged in row format or in statement format. */
@@ -2281,10 +2367,24 @@ public:
/*TODO: this will be obsolete when we have support for 64 bit my_time_t */
inline bool is_valid_time()
{
- return (start_time < (time_t) MY_TIME_T_MAX);
+ return (IS_TIME_T_VALID_FOR_TIMESTAMP(start_time));
}
void set_time_after_lock() { utime_after_lock= my_micro_time(); }
ulonglong current_utime() { return my_micro_time(); }
+ /**
+ Update server status after execution of a top level statement.
+
+ Currently only checks if a query was slow, and assigns
+ the status accordingly.
+ Evaluate the current time, and if it exceeds the long-query-time
+ setting, mark the query as slow.
+ */
+ void update_server_status()
+ {
+ ulonglong end_utime_of_query= current_utime();
+ if (end_utime_of_query > utime_after_lock + variables.long_query_time)
+ server_status|= SERVER_QUERY_WAS_SLOW;
+ }
inline ulonglong found_rows(void)
{
return limit_found_rows;
@@ -2493,8 +2593,6 @@ public:
(variables.sql_mode & MODE_STRICT_ALL_TABLES)));
}
void set_status_var_init();
- bool is_context_analysis_only()
- { return stmt_arena->is_stmt_prepare() || lex->view_prepare_mode; }
void reset_n_backup_open_tables_state(Open_tables_backup *backup);
void restore_backup_open_tables_state(Open_tables_backup *backup);
void reset_sub_statement_state(Sub_statement_state *backup, uint new_state);
@@ -2750,9 +2848,20 @@ public:
Assign a new value to thd->query and thd->query_id and mysys_var.
Protected with LOCK_thd_data mutex.
*/
- void set_query(char *query_arg, uint32 query_length_arg);
+ void set_query(char *query_arg, uint32 query_length_arg,
+ CHARSET_INFO *cs_arg)
+ {
+ set_query(CSET_STRING(query_arg, query_length_arg, cs_arg));
+ }
+ void set_query(char *query_arg, uint32 query_length_arg) /*Mutex protected*/
+ {
+ set_query(CSET_STRING(query_arg, query_length_arg, charset()));
+ }
+ void set_query(const CSET_STRING &str); /* Mutex protected */
+ void reset_query() /* Mutex protected */
+ { set_query(CSET_STRING()); }
void set_query_and_id(char *query_arg, uint32 query_length_arg,
- query_id_t new_query_id);
+ CHARSET_INFO *cs, query_id_t new_query_id);
void set_query_id(query_id_t new_query_id);
void set_open_tables(TABLE *open_tables_arg)
{
@@ -2765,14 +2874,13 @@ public:
{
DBUG_ASSERT(locked_tables_mode == LTM_NONE);
- mdl_context.set_trans_sentinel();
+ mdl_context.set_explicit_duration_for_all_locks();
locked_tables_mode= mode_arg;
}
void leave_locked_tables_mode();
int decide_logging_format(TABLE_LIST *tables);
- void set_current_user_used() { current_user_used= TRUE; }
- bool is_current_user_used() { return current_user_used; }
- void clean_current_user_used() { current_user_used= FALSE; }
+ void binlog_invoker() { m_binlog_invoker= TRUE; }
+ bool need_binlog_invoker() { return m_binlog_invoker; }
void get_definer(LEX_USER *definer);
void set_invoker(const LEX_STRING *user, const LEX_STRING *host)
{
@@ -2807,6 +2915,7 @@ private:
/** The current internal error handler for this thread, or NULL. */
Internal_error_handler *m_internal_handler;
+
/**
The lex to hold the parsed tree of conventional (non-prepared) queries.
Whereas for prepared and stored procedure statements we use an own lex
@@ -2834,7 +2943,7 @@ private:
Current user will be binlogged into Query_log_event if current_user_used
is TRUE; It will be stored into invoker_host and invoker_user by SQL thread.
*/
- bool current_user_used;
+ bool m_binlog_invoker;
/**
It points to the invoker in the Query_log_event.
@@ -3738,20 +3847,10 @@ public:
#define CF_DIAGNOSTIC_STMT (1U << 8)
/**
- SQL statements that must be protected against impending global read lock
- to prevent deadlock. This deadlock could otherwise happen if the statement
- starts waiting for the GRL to go away inside mysql_lock_tables while at the
- same time having "old" opened tables. The thread holding the GRL can be
- waiting for these "old" opened tables to be closed, causing a deadlock
- (FLUSH TABLES WITH READ LOCK).
- */
-#define CF_PROTECT_AGAINST_GRL (1U << 10)
-
-/**
Identifies statements that may generate row events
and that may end up in the binary log.
*/
-#define CF_CAN_GENERATE_ROW_EVENTS (1U << 11)
+#define CF_CAN_GENERATE_ROW_EVENTS (1U << 9)
/* Bits in server_command_flags */