1 #ifndef SET_VAR_INCLUDED 2 #define SET_VAR_INCLUDED 3 /* Copyright (c) 2002, 2021, Oracle and/or its affiliates. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License, version 2.0, 7 as published by the Free Software Foundation. 8 9 This program is also distributed with certain software (including 10 but not limited to OpenSSL) that is licensed under separate terms, 11 as designated in a particular file or component or in included license 12 documentation. The authors of MySQL hereby grant you an additional 13 permission to link the program and your derivative works with the 14 separately licensed software that they have included with MySQL. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License, version 2.0, for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program; if not, write to the Free Software 23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 24 25 /** 26 @file 27 "public" interface to sys_var - server configuration variables. 28 */ 29 #include "my_global.h" 30 31 #include "m_string.h" // LEX_CSTRING 32 #include "my_getopt.h" // get_opt_arg_type 33 #include "mysql_com.h" // Item_result 34 #include "typelib.h" // TYPELIB 35 #include "mysql/plugin.h" // enum_mysql_show_type 36 #include "sql_alloc.h" // Sql_alloc 37 #include "sql_const.h" // SHOW_COMP_OPTION 38 #include "sql_plugin_ref.h" // plugin_ref 39 #include "prealloced_array.h" // Prealloced_array 40 41 #include <vector> 42 43 class sys_var; 44 class set_var; 45 class sys_var_pluginvar; 46 class PolyLock; 47 class Item_func_set_user_var; 48 class String; 49 class Time_zone; 50 class THD; 51 struct st_lex_user; 52 typedef ulonglong sql_mode_t; 53 typedef enum enum_mysql_show_type SHOW_TYPE; 54 typedef enum enum_mysql_show_scope SHOW_SCOPE; 55 typedef struct st_mysql_show_var SHOW_VAR; 56 template <class T> class List; 57 58 extern TYPELIB bool_typelib; 59 60 /* Number of system variable elements to preallocate. */ 61 #define SHOW_VAR_PREALLOC 200 62 typedef Prealloced_array<SHOW_VAR, SHOW_VAR_PREALLOC, false> Show_var_array; 63 64 struct sys_var_chain 65 { 66 sys_var *first; 67 sys_var *last; 68 }; 69 70 int mysql_add_sys_var_chain(sys_var *chain); 71 int mysql_del_sys_var_chain(sys_var *chain); 72 73 enum enum_var_type 74 { 75 OPT_DEFAULT= 0, OPT_SESSION, OPT_GLOBAL 76 }; 77 78 /** 79 A class representing one system variable - that is something 80 that can be accessed as @@global.variable_name or @@session.variable_name, 81 visible in SHOW xxx VARIABLES and in INFORMATION_SCHEMA.xxx_VARIABLES, 82 optionally it can be assigned to, optionally it can have a command-line 83 counterpart with the same name. 84 */ 85 class sys_var 86 { 87 public: 88 sys_var *next; 89 LEX_CSTRING name; 90 enum flag_enum 91 { 92 GLOBAL= 0x0001, 93 SESSION= 0x0002, 94 ONLY_SESSION= 0x0004, 95 SCOPE_MASK= 0x03FF, // 1023 96 READONLY= 0x0400, // 1024 97 ALLOCATED= 0x0800, // 2048 98 INVISIBLE= 0x1000, // 4096 99 TRI_LEVEL= 0x2000 // 8192 - default is neither GLOBAL nor SESSION 100 }; 101 static const int PARSE_EARLY= 1; 102 static const int PARSE_NORMAL= 2; 103 /** 104 Enumeration type to indicate for a system variable whether 105 it will be written to the binlog or not. 106 */ 107 enum binlog_status_enum { VARIABLE_NOT_IN_BINLOG, 108 SESSION_VARIABLE_IN_BINLOG } binlog_status; 109 110 protected: 111 typedef bool (*on_check_function)(sys_var *self, THD *thd, set_var *var); 112 typedef bool (*pre_update_function)(sys_var *self, THD *thd, set_var *var); 113 typedef bool (*on_update_function)(sys_var *self, THD *thd, enum_var_type type); 114 115 int flags; ///< or'ed flag_enum values 116 int m_parse_flag; ///< either PARSE_EARLY or PARSE_NORMAL. 117 const SHOW_TYPE show_val_type; ///< what value_ptr() returns for sql_show.cc 118 my_option option; ///< min, max, default values are stored here 119 PolyLock *guard; ///< *second* lock that protects the variable 120 ptrdiff_t offset; ///< offset to the value from global_system_variables 121 on_check_function on_check; 122 /** 123 Pointer to function to be invoked before updating system variable (but 124 after calling on_check hook), while we do not hold any locks yet. 125 */ 126 pre_update_function pre_update; 127 on_update_function on_update; 128 const char *const deprecation_substitute; 129 bool is_os_charset; ///< true if the value is in character_set_filesystem 130 131 public: 132 sys_var(sys_var_chain *chain, const char *name_arg, const char *comment, 133 int flag_args, ptrdiff_t off, int getopt_id, 134 enum get_opt_arg_type getopt_arg_type, SHOW_TYPE show_val_type_arg, 135 longlong def_val, PolyLock *lock, enum binlog_status_enum binlog_status_arg, 136 on_check_function on_check_func, on_update_function on_update_func, 137 const char *substitute, int parse_flag); 138 ~sys_var()139 virtual ~sys_var() {} 140 141 /** 142 All the cleanup procedures should be performed here 143 */ cleanup()144 virtual void cleanup() {} 145 /** 146 downcast for sys_var_pluginvar. Returns this if it's an instance 147 of sys_var_pluginvar, and 0 otherwise. 148 */ cast_pluginvar()149 virtual sys_var_pluginvar *cast_pluginvar() { return 0; } 150 151 bool check(THD *thd, set_var *var); 152 uchar *value_ptr(THD *running_thd, THD *target_thd, enum_var_type type, LEX_STRING *base); 153 uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); update_default(longlong new_def_value)154 virtual void update_default(longlong new_def_value) 155 { option.def_value= new_def_value; } 156 157 /** 158 Update the system variable with the default value from either 159 session or global scope. The default value is stored in the 160 'var' argument. Return false when successful. 161 */ 162 bool set_default(THD *thd, set_var *var); 163 bool update(THD *thd, set_var *var); stmt_update(THD * thd)164 void stmt_update(THD *thd) { 165 on_update && on_update(this, thd, OPT_SESSION); 166 } 167 show_type()168 SHOW_TYPE show_type() { return show_val_type; } scope()169 int scope() const { return flags & SCOPE_MASK; } 170 const CHARSET_INFO *charset(THD *thd); is_readonly()171 bool is_readonly() const 172 { 173 const my_bool *readonly= getopt_constraint_get_readonly_value(option.name, 174 0, FALSE); 175 if (readonly && *readonly) 176 return TRUE; 177 178 return flags & READONLY; 179 } not_visible()180 bool not_visible() const { return flags & INVISIBLE; } is_trilevel()181 bool is_trilevel() const { return flags & TRI_LEVEL; } 182 /** 183 the following is only true for keycache variables, 184 that support the syntax @@keycache_name.variable_name 185 */ is_struct()186 bool is_struct() { return option.var_type & GET_ASK_ADDR; } 187 /** 188 Indicates whether this system variable is written to the binlog or not. 189 190 Variables are written to the binlog as part of "status_vars" in 191 Query_log_event, as an Intvar_log_event, or a Rand_log_event. 192 193 @param type Scope of the system variable. 194 195 @return true if the variable is written to the binlog, false otherwise. 196 */ is_written_to_binlog(enum_var_type type)197 bool is_written_to_binlog(enum_var_type type) 198 { return type != OPT_GLOBAL && binlog_status == SESSION_VARIABLE_IN_BINLOG; } 199 virtual bool check_update_type(Item_result type) = 0; 200 201 /** 202 Return TRUE for success if: 203 Global query and variable scope is GLOBAL or SESSION, or 204 Session query and variable scope is SESSION or ONLY_SESSION. 205 */ check_scope(enum_var_type query_type)206 bool check_scope(enum_var_type query_type) 207 { 208 switch (query_type) 209 { 210 case OPT_GLOBAL: return scope() & (GLOBAL | SESSION); 211 case OPT_SESSION: return scope() & (SESSION | ONLY_SESSION); 212 case OPT_DEFAULT: return scope() & (SESSION | ONLY_SESSION); 213 } 214 return false; 215 } 216 register_option(std::vector<my_option> * array,int parse_flags)217 bool register_option(std::vector<my_option> *array, int parse_flags) 218 { 219 return (option.id != -1) && (m_parse_flag & parse_flags) && 220 (array->push_back(option), false); 221 } 222 void do_deprecated_warning(THD *thd); 223 224 private: 225 virtual bool do_check(THD *thd, set_var *var) = 0; 226 /** 227 save the session default value of the variable in var 228 */ 229 virtual void session_save_default(THD *thd, set_var *var) = 0; 230 /** 231 save the global default value of the variable in var 232 */ 233 virtual void global_save_default(THD *thd, set_var *var) = 0; 234 virtual bool session_update(THD *thd, set_var *var) = 0; 235 virtual bool global_update(THD *thd, set_var *var) = 0; 236 protected: 237 /** 238 A pointer to a value of the variable for SHOW. 239 It must be of show_val_type type (bool for SHOW_BOOL, int for SHOW_INT, 240 longlong for SHOW_LONGLONG, etc). 241 */ 242 virtual uchar *session_value_ptr(THD *running_thd, THD *target_thd, LEX_STRING *base); 243 virtual uchar *global_value_ptr(THD *thd, LEX_STRING *base); 244 245 /** 246 A pointer to a storage area of the variable, to the raw data. 247 Typically it's the same as session_value_ptr(), but it's different, 248 for example, for ENUM, that is printed as a string, but stored as a number. 249 */ 250 uchar *session_var_ptr(THD *thd); 251 252 uchar *global_var_ptr(); 253 }; 254 255 class Sys_var_tracker 256 { 257 public: 258 explicit Sys_var_tracker(sys_var *var); 259 260 sys_var *bind_system_variable(THD *thd); 261 262 bool operator==(const Sys_var_tracker &x) const { 263 return m_var && m_var == x.m_var; 264 } 265 is_sys_var(sys_var * x)266 bool is_sys_var(sys_var *x) const { return m_var == x; } 267 268 private: 269 bool m_is_dynamic; ///< true if dynamic variable 270 LEX_CSTRING m_name; ///< variable name 271 272 sys_var *m_var; ///< variable pointer 273 }; 274 275 /**************************************************************************** 276 Classes for parsing of the SET command 277 ****************************************************************************/ 278 279 /** 280 A base class for everything that can be set with SET command. 281 It's similar to Items, an instance of this is created by the parser 282 for every assigmnent in SET (or elsewhere, e.g. in SELECT). 283 */ 284 class set_var_base :public Sql_alloc 285 { 286 public: set_var_base()287 set_var_base() {} ~set_var_base()288 virtual ~set_var_base() {} 289 virtual int check(THD *thd)=0; /* To check privileges etc. */ 290 virtual int update(THD *thd)=0; /* To set the value */ light_check(THD * thd)291 virtual int light_check(THD *thd) { return check(thd); } /* for PS */ 292 virtual void print(THD *thd, String *str)=0; /* To self-print */ 293 /// @returns whether this variable is @@@@optimizer_trace. is_var_optimizer_trace()294 virtual bool is_var_optimizer_trace() const { return false; } cleanup()295 virtual void cleanup() {} 296 }; 297 298 299 /** 300 set_var_base descendant for assignments to the system variables. 301 */ 302 class set_var :public set_var_base 303 { 304 public: 305 sys_var *var; ///< system variable to be updated 306 Item *value; ///< the expression that provides the new value of the variable 307 enum_var_type type; 308 union ///< temp storage to hold a value between sys_var::check and ::update 309 { 310 ulonglong ulonglong_value; ///< for all integer, set, enum sysvars 311 double double_value; ///< for Sys_var_double 312 plugin_ref plugin; ///< for Sys_var_plugin 313 Time_zone *time_zone; ///< for Sys_var_tz 314 LEX_STRING string_value; ///< for Sys_var_charptr and others 315 const void *ptr; ///< for Sys_var_struct 316 } save_result; 317 LEX_STRING base; /**< for structured variables, like keycache_name.variable_name */ 318 319 private: 320 Sys_var_tracker var_tracker; 321 322 public: 323 set_var(enum_var_type type_arg, sys_var *var_arg, 324 const LEX_STRING *base_name_arg, Item *value_arg); 325 326 int check(THD *thd); 327 int update(THD *thd); 328 int light_check(THD *thd); 329 void print(THD *thd, String *str); /* To self-print */ 330 #ifdef OPTIMIZER_TRACE is_var_optimizer_trace()331 virtual bool is_var_optimizer_trace() const 332 { 333 extern sys_var *Sys_optimizer_trace_ptr; 334 return var_tracker.is_sys_var(Sys_optimizer_trace_ptr); 335 } 336 #endif cleanup()337 virtual void cleanup() { var= NULL; } 338 int populate_sys_var(THD *thd); 339 }; 340 341 342 /* User variables like @my_own_variable */ 343 class set_var_user: public set_var_base 344 { 345 Item_func_set_user_var *user_var_item; 346 public: set_var_user(Item_func_set_user_var * item)347 set_var_user(Item_func_set_user_var *item) 348 :user_var_item(item) 349 {} 350 int check(THD *thd); 351 int update(THD *thd); 352 int light_check(THD *thd); 353 void print(THD *thd, String *str); /* To self-print */ 354 }; 355 356 /* For SET PASSWORD */ 357 358 class set_var_password: public set_var_base 359 { 360 st_lex_user *user; 361 char *password; 362 public: set_var_password(st_lex_user * user_arg,char * password_arg)363 set_var_password(st_lex_user *user_arg,char *password_arg) 364 :user(user_arg), password(password_arg) 365 {} 366 int check(THD *thd); 367 int update(THD *thd); 368 void print(THD *thd, String *str); /* To self-print */ 369 }; 370 371 372 /* For SET NAMES and SET CHARACTER SET */ 373 374 class set_var_collation_client: public set_var_base 375 { 376 int set_cs_flags; 377 const CHARSET_INFO *character_set_client; 378 const CHARSET_INFO *character_set_results; 379 const CHARSET_INFO *collation_connection; 380 public: 381 enum set_cs_flags_enum { SET_CS_NAMES=1, SET_CS_DEFAULT=2, SET_CS_COLLATE=4 }; set_var_collation_client(int set_cs_flags_arg,const CHARSET_INFO * client_coll_arg,const CHARSET_INFO * connection_coll_arg,const CHARSET_INFO * result_coll_arg)382 set_var_collation_client(int set_cs_flags_arg, 383 const CHARSET_INFO *client_coll_arg, 384 const CHARSET_INFO *connection_coll_arg, 385 const CHARSET_INFO *result_coll_arg) 386 :set_cs_flags(set_cs_flags_arg), 387 character_set_client(client_coll_arg), 388 character_set_results(result_coll_arg), 389 collation_connection(connection_coll_arg) 390 {} 391 int check(THD *thd); 392 int update(THD *thd); 393 void print(THD *thd, String *str); /* To self-print */ 394 }; 395 396 397 /* optional things, have_* variables */ 398 extern SHOW_COMP_OPTION have_ndbcluster, have_partitioning; 399 extern SHOW_COMP_OPTION have_profiling; 400 401 extern SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen; 402 extern SHOW_COMP_OPTION have_query_cache; 403 extern SHOW_COMP_OPTION have_geometry, have_rtree_keys; 404 extern SHOW_COMP_OPTION have_crypt; 405 extern SHOW_COMP_OPTION have_compress; 406 extern SHOW_COMP_OPTION have_statement_timeout; 407 extern SHOW_COMP_OPTION have_backup_locks; 408 extern SHOW_COMP_OPTION have_backup_safe_binlog_info; 409 extern SHOW_COMP_OPTION have_snapshot_cloning; 410 411 /* 412 Helper functions 413 */ 414 ulong get_system_variable_hash_records(void); 415 ulonglong get_system_variable_hash_version(void); 416 417 bool enumerate_sys_vars(THD *thd, Show_var_array *show_var_array, 418 bool sort, enum enum_var_type type, bool strict); 419 void lock_plugin_mutex(); 420 void unlock_plugin_mutex(); 421 sys_var *find_sys_var(THD *thd, const char *str, size_t length=0); 422 sys_var *find_sys_var_ex(THD *thd, const char *str, size_t length=0, 423 bool throw_error= false, bool locked= false); 424 425 MY_ATTRIBUTE((warn_unused_result)) 426 int sql_set_variables(THD *thd, List<set_var_base> *var_list, 427 bool free_joins = true); 428 429 bool fix_delay_key_write(sys_var *self, THD *thd, enum_var_type type); 430 bool keyring_access_test(); 431 sql_mode_t expand_sql_mode(sql_mode_t sql_mode, THD *thd); 432 bool sql_mode_string_representation(THD *thd, sql_mode_t sql_mode, LEX_STRING *ls); 433 void update_parser_max_mem_size(); 434 435 extern sys_var *Sys_autocommit_ptr; 436 extern sys_var *Sys_gtid_next_ptr; 437 extern sys_var *Sys_gtid_next_list_ptr; 438 extern sys_var *Sys_gtid_purged_ptr; 439 440 const CHARSET_INFO *get_old_charset_by_name(const char *old_name); 441 442 int sys_var_init(); 443 int sys_var_add_options(std::vector<my_option> *long_options, int parse_flags); 444 void sys_var_end(void); 445 446 extern void init_log_slow_verbosity(); 447 extern void init_slow_query_log_use_global_control(); 448 extern void init_log_slow_sp_statements(); 449 450 #endif 451 452