diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_func.cc | 6 | ||||
-rw-r--r-- | sql/session_tracker.cc | 33 | ||||
-rw-r--r-- | sql/session_tracker.h | 34 | ||||
-rw-r--r-- | sql/sql_base.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 3 | ||||
-rw-r--r-- | sql/sql_hset.h | 18 | ||||
-rw-r--r-- | sql/sys_vars.cc | 16 |
8 files changed, 101 insertions, 11 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc index 10ac0f74644..2eb7250ebc7 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4671,6 +4671,10 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, size_t length, entry->unsigned_flag= unsigned_arg; } entry->type=type; +#ifndef EMBEDDED_LIBRARY + THD *thd= current_thd; + thd->session_tracker.user_variables.mark_as_changed(thd, entry); +#endif return 0; } @@ -4760,7 +4764,7 @@ longlong user_var_entry::val_int(bool *null_value) const /** Get the value of a variable as a string. */ String *user_var_entry::val_str(bool *null_value, String *str, - uint decimals) + uint decimals) const { if ((*null_value= (value == 0))) return (String*) 0; diff --git a/sql/session_tracker.cc b/sql/session_tracker.cc index fe5cd3a5d61..dc22d6dc9a3 100644 --- a/sql/session_tracker.cc +++ b/sql/session_tracker.cc @@ -16,7 +16,6 @@ #include "sql_plugin.h" -#include "hash.h" #include "table.h" #include "rpl_gtid.h" #include "sql_class.h" @@ -1182,6 +1181,38 @@ bool Session_state_change_tracker::store(THD *thd, String *buf) return false; } + +bool User_variables_tracker::update(THD *thd, set_var *) +{ + m_enabled= thd->variables.session_track_user_variables; + return false; +} + + +bool User_variables_tracker::store(THD *thd, String *buf) +{ + for (ulong i= 0; i < m_changed_user_variables.size(); i++) + { + auto var= m_changed_user_variables.at(i); + String value_str; + bool null_value; + + var->val_str(&null_value, &value_str, DECIMAL_MAX_SCALE); + buf->q_append(static_cast<char>(SESSION_TRACK_USER_VARIABLES)); + ulonglong length= net_length_size(var->name.length) + var->name.length; + if (!null_value) + length+= net_length_size(value_str.length()) + value_str.length(); + buf->q_net_store_length(length); + buf->q_net_store_data(reinterpret_cast<const uchar*>(var->name.str), + var->name.length); + if (!null_value) + buf->q_net_store_data(reinterpret_cast<const uchar*>(value_str.ptr()), + value_str.length()); + } + m_changed_user_variables.clear(); + return false; +} + /////////////////////////////////////////////////////////////////////////////// /** diff --git a/sql/session_tracker.h b/sql/session_tracker.h index 269b1bd2359..b91e588a34e 100644 --- a/sql/session_tracker.h +++ b/sql/session_tracker.h @@ -19,12 +19,14 @@ #include "m_string.h" #include "thr_lock.h" +#include "sql_hset.h" #ifndef EMBEDDED_LIBRARY /* forward declarations */ class THD; class set_var; class String; +class user_var_entry; enum enum_session_tracker @@ -33,6 +35,7 @@ enum enum_session_tracker CURRENT_SCHEMA_TRACKER, /* Current schema */ SESSION_STATE_CHANGE_TRACKER, TRANSACTION_INFO_TRACKER, /* Transaction state */ + USER_VARIABLES_TRACKER, SESSION_TRACKER_END /* must be the last */ }; @@ -388,6 +391,35 @@ private: /** + User_variables_tracker + + This is a tracker class that enables & manages the tracking of user variables. +*/ + +class User_variables_tracker: public State_tracker +{ + Hash_set<const user_var_entry> m_changed_user_variables; +public: + User_variables_tracker(): + m_changed_user_variables(&my_charset_bin, 0, 0, + sizeof(const user_var_entry*), 0, 0, + HASH_UNIQUE | (mysqld_server_initialized ? + HASH_THREAD_SPECIFIC : 0)) {} + bool update(THD *thd, set_var *var); + bool store(THD *thd, String *buf); + void mark_as_changed(THD *thd, const user_var_entry *var) + { + if (is_enabled()) + { + m_changed_user_variables.insert(var); + set_changed(thd); + } + } + void deinit() { m_changed_user_variables.~Hash_set(); } +}; + + +/** Session_tracker This class holds an object each for all tracker classes and provides @@ -415,6 +447,7 @@ public: Session_state_change_tracker state_change; Transaction_state_tracker transaction_info; Session_sysvars_tracker sysvars; + User_variables_tracker user_variables; Session_tracker() { @@ -422,6 +455,7 @@ public: m_trackers[CURRENT_SCHEMA_TRACKER]= ¤t_schema; m_trackers[SESSION_STATE_CHANGE_TRACKER]= &state_change; m_trackers[TRANSACTION_INFO_TRACKER]= &transaction_info; + m_trackers[USER_VARIABLES_TRACKER]= &user_variables; } void enable(THD *thd) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 54491c2362b..aa13f8a24db 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -56,7 +56,6 @@ #include "rpl_filter.h" #include "sql_table.h" // build_table_filename #include "datadict.h" // dd_frm_is_view() -#include "sql_hset.h" // Hash_set #include "rpl_rli.h" // rpl_group_info #ifdef __WIN__ #include <io.h> diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 91fc482978d..93f1ae7c1eb 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1750,6 +1750,7 @@ THD::~THD() /* trick to make happy memory accounting system */ #ifndef EMBEDDED_LIBRARY session_tracker.sysvars.deinit(); + session_tracker.user_variables.deinit(); #endif //EMBEDDED_LIBRARY if (status_var.local_memory_used != 0) diff --git a/sql/sql_class.h b/sql/sql_class.h index a3d4b4e87d4..f6434605a74 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -766,6 +766,7 @@ typedef struct system_variables ulong session_track_transaction_info; my_bool session_track_schema; my_bool session_track_state_change; + my_bool session_track_user_variables; my_bool tcp_nodelay; ulong threadpool_priority; @@ -6319,7 +6320,7 @@ class user_var_entry double val_real(bool *null_value); longlong val_int(bool *null_value) const; - String *val_str(bool *null_value, String *str, uint decimals); + String *val_str(bool *null_value, String *str, uint decimals) const; my_decimal *val_decimal(bool *null_value, my_decimal *result); CHARSET_INFO *charset() const { return m_charset; } void set_charset(CHARSET_INFO *cs) { m_charset= cs; } diff --git a/sql/sql_hset.h b/sql/sql_hset.h index 7834349a2f7..aaecef9f0d4 100644 --- a/sql/sql_hset.h +++ b/sql/sql_hset.h @@ -38,6 +38,13 @@ public: m_hash.get_key= (my_hash_get_key)K; m_hash.charset= cs; } + Hash_set(CHARSET_INFO *charset, ulong default_array_elements, + size_t key_offset, size_t key_length, my_hash_get_key get_key, + void (*free_element)(void*), uint flags) + { + my_hash_init(&m_hash, charset, default_array_elements, key_offset, + key_length, get_key, free_element, flags); + } /** Destroy the hash by freeing the buckets table. Does not call destructors for the elements. @@ -58,13 +65,8 @@ public: bool insert(T *value) { my_hash_init_opt(&m_hash, m_hash.charset, START_SIZE, 0, 0, - m_hash.get_key, 0, MYF(0)); - size_t key_len; - uchar *v= reinterpret_cast<uchar *>(value); - const uchar *key= m_hash.get_key(v, &key_len, FALSE); - if (find(key, key_len) == NULL) - return my_hash_insert(&m_hash, v); - return FALSE; + m_hash.get_key, 0, HASH_UNIQUE); + return my_hash_insert(&m_hash, reinterpret_cast<const uchar*>(value)); } bool remove(T *value) { @@ -78,6 +80,8 @@ public: bool is_empty() const { return m_hash.records == 0; } /** Returns the number of unique elements. */ size_t size() const { return static_cast<size_t>(m_hash.records); } + /** Erases all elements from the container */ + void clear() { my_hash_reset(&m_hash); } const T* at(size_t i) const { return reinterpret_cast<T*>(my_hash_element(const_cast<HASH*>(&m_hash), i)); diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 1ba58bf71c4..1adc20af657 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -6378,6 +6378,22 @@ static Sys_var_mybool Sys_session_track_state_change( ON_CHECK(0), ON_UPDATE(update_session_track_state_change)); + +static bool update_session_track_user_variables(sys_var *self, THD *thd, + enum_var_type type) +{ + return thd->session_tracker.user_variables.update(thd, 0); +} + +static Sys_var_mybool Sys_session_track_user_variables( + "session_track_user_variables", + "Track changes to user variables.", + SESSION_VAR(session_track_user_variables), + CMD_LINE(OPT_ARG), DEFAULT(FALSE), + NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(0), + ON_UPDATE(update_session_track_user_variables)); + #endif //EMBEDDED_LIBRARY static Sys_var_uint Sys_in_subquery_conversion_threshold( |