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