diff options
Diffstat (limited to 'sql/sql_class.h')
-rw-r--r-- | sql/sql_class.h | 213 |
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 */ |