diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2016-04-15 20:47:45 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2016-08-31 17:17:46 +0200 |
commit | c8948b0d0db4c182a744bc8bdbde7cbccff3d57d (patch) | |
tree | 00997abdab43192464c9d5d861d7b659797fd448 /sql/sys_vars.ic | |
parent | e7608a78ef45cc46f4e4d5abbda788ad54e80e71 (diff) | |
download | mariadb-git-c8948b0d0db4c182a744bc8bdbde7cbccff3d57d.tar.gz |
MDEV-8931: (server part of) session state tracking
System variables tracking
Diffstat (limited to 'sql/sys_vars.ic')
-rw-r--r-- | sql/sys_vars.ic | 129 |
1 files changed, 115 insertions, 14 deletions
diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic index ca6634849a1..dbe84d3efcc 100644 --- a/sql/sys_vars.ic +++ b/sql/sys_vars.ic @@ -438,10 +438,10 @@ public: does not destroy individual members of SV, there's no way to free allocated string variables for every thread. */ -class Sys_var_charptr: public sys_var +class Sys_var_charptr_base: public sys_var { public: - Sys_var_charptr(const char *name_arg, + Sys_var_charptr_base(const char *name_arg, const char *comment, int flag_args, ptrdiff_t off, size_t size, CMD_LINE getopt, enum charset_enum is_os_charset_arg, @@ -463,8 +463,6 @@ public: */ option.var_type|= (flags & ALLOCATED) ? GET_STR_ALLOC : GET_STR; global_var(const char*)= def_val; - SYSVAR_ASSERT(scope() == GLOBAL); - SYSVAR_ASSERT(size == sizeof(char *)); } void cleanup() { @@ -503,31 +501,35 @@ public: } bool do_check(THD *thd, set_var *var) { return do_string_check(thd, var, charset(thd)); } - bool session_update(THD *thd, set_var *var) - { - DBUG_ASSERT(FALSE); - return true; - } - bool global_update(THD *thd, set_var *var) + bool session_update(THD *thd, set_var *var)= 0; + char *global_update_prepare(THD *thd, set_var *var) { char *new_val, *ptr= var->save_result.string_value.str; size_t len=var->save_result.string_value.length; if (ptr) { new_val= (char*)my_memdup(ptr, len+1, MYF(MY_WME)); - if (!new_val) return true; + if (!new_val) return 0; new_val[len]=0; } else new_val= 0; + return new_val; + } + void global_update_finish(char *new_val) + { if (flags & ALLOCATED) my_free(global_var(char*)); flags|= ALLOCATED; global_var(char*)= new_val; - return false; } - void session_save_default(THD *thd, set_var *var) - { DBUG_ASSERT(FALSE); } + bool global_update(THD *thd, set_var *var) + { + char *new_val= global_update_prepare(thd, var); + global_update_finish(new_val); + return (new_val == 0 && var->save_result.string_value.str != 0); + } + void session_save_default(THD *thd, set_var *var)= 0; void global_save_default(THD *thd, set_var *var) { char *ptr= (char*)(intptr)option.def_value; @@ -536,6 +538,105 @@ public: } }; +class Sys_var_charptr: public Sys_var_charptr_base +{ +public: + Sys_var_charptr(const char *name_arg, + const char *comment, int flag_args, ptrdiff_t off, size_t size, + CMD_LINE getopt, + enum charset_enum is_os_charset_arg, + const char *def_val, PolyLock *lock=0, + enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, + on_check_function on_check_func=0, + on_update_function on_update_func=0, + const char *substitute=0) : + Sys_var_charptr_base(name_arg, comment, flag_args, off, size, getopt, + is_os_charset_arg, def_val, lock, binlog_status_arg, + on_check_func, on_update_func, substitute) + { + SYSVAR_ASSERT(scope() == GLOBAL); + SYSVAR_ASSERT(size == sizeof(char *)); + } + + bool session_update(THD *thd, set_var *var) + { + DBUG_ASSERT(FALSE); + return true; + } + void session_save_default(THD *thd, set_var *var) + { DBUG_ASSERT(FALSE); } +}; + +class Sys_var_sesvartrack: public Sys_var_charptr_base +{ +public: + Sys_var_sesvartrack(const char *name_arg, + const char *comment, + CMD_LINE getopt, + enum charset_enum is_os_charset_arg, + const char *def_val, PolyLock *lock) : + Sys_var_charptr_base(name_arg, comment, + SESSION_VAR(session_track_system_variables), + getopt, is_os_charset_arg, def_val, lock, + VARIABLE_NOT_IN_BINLOG, 0, 0, 0) + {} + bool do_check(THD *thd, set_var *var) + { + if (Sys_var_charptr_base::do_check(thd, var) || + sysvartrack_validate_value(thd, var->save_result.string_value.str, + var->save_result.string_value.length)) + return TRUE; + return FALSE; + } + bool global_update(THD *thd, set_var *var) + { + char *new_val= global_update_prepare(thd, var); + if (new_val) + { + if (sysvartrack_reprint_value(thd, new_val, + var->save_result.string_value.length)) + new_val= 0; + } + global_update_finish(new_val); + return (new_val == 0 && var->save_result.string_value.str != 0); + } + bool session_update(THD *thd, set_var *var) + { + return sysvartrack_update(thd); + } + void session_save_default(THD *thd, set_var *var) + { + var->save_result.string_value.str= global_var(char*); + var->save_result.string_value.length= + strlen(var->save_result.string_value.str); + /* parse and feel list with default values */ + if (thd) + { + bool res= + sysvartrack_validate_value(thd, + var->save_result.string_value.str, + var->save_result.string_value.length); + DBUG_ASSERT(res == 0); + } + } + uchar *session_value_ptr(THD *thd, const LEX_STRING *base) + { + DBUG_ASSERT(thd != NULL); + size_t len= sysvartrack_value_len(thd); + char *res= 0; + char *buf= (char *)my_safe_alloca(len); + if (buf && !sysvartrack_value_construct(thd, buf, len)) + { + size_t len= strlen(buf) + 1; + res= (char*) thd->alloc(len + sizeof(char *)); + if (res) + memcpy((*((char**) res)= res + sizeof(char *)), buf, len); + my_safe_afree(buf, len); + } + return (uchar *)res; + } +}; + class Sys_var_proxy_user: public sys_var { |