1#ifndef SET_VAR_INCLUDED
2#define SET_VAR_INCLUDED
3/* Copyright (c) 2002, 2013, Oracle and/or its affiliates.
4 Copyright (c) 2009, 2014, SkySQL Ab.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; version 2 of the License.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
18
19/**
20 @file
21 "public" interface to sys_var - server configuration variables.
22*/
23
24#ifdef USE_PRAGMA_INTERFACE
25#pragma interface /* gcc class implementation */
26#endif
27
28#include <my_getopt.h>
29
30class sys_var;
31class set_var;
32class sys_var_pluginvar;
33class PolyLock;
34class Item_func_set_user_var;
35
36// This include needs to be here since item.h requires enum_var_type :-P
37#include "item.h" /* Item */
38#include "sql_class.h" /* THD */
39
40extern TYPELIB bool_typelib;
41
42struct sys_var_chain
43{
44 sys_var *first;
45 sys_var *last;
46};
47
48int mysql_add_sys_var_chain(sys_var *chain);
49int mysql_del_sys_var_chain(sys_var *chain);
50
51
52/**
53 A class representing one system variable - that is something
54 that can be accessed as @@global.variable_name or @@session.variable_name,
55 visible in SHOW xxx VARIABLES and in INFORMATION_SCHEMA.xxx_VARIABLES,
56 optionally it can be assigned to, optionally it can have a command-line
57 counterpart with the same name.
58*/
59class sys_var: protected Value_source // for double_from_string_with_check
60{
61public:
62 sys_var *next;
63 LEX_CSTRING name;
64 bool *test_load;
65 enum flag_enum { GLOBAL, SESSION, ONLY_SESSION, SCOPE_MASK=1023,
66 READONLY=1024, ALLOCATED=2048, PARSE_EARLY=4096,
67 NO_SET_STATEMENT=8192, AUTO_SET=16384};
68 enum { NO_GETOPT=-1, GETOPT_ONLY_HELP=-2 };
69 enum where { CONFIG, AUTO, SQL, COMPILE_TIME, ENV };
70
71 /**
72 Enumeration type to indicate for a system variable whether
73 it will be written to the binlog or not.
74 */
75 enum binlog_status_enum { VARIABLE_NOT_IN_BINLOG,
76 SESSION_VARIABLE_IN_BINLOG } binlog_status;
77
78 my_option option; ///< min, max, default values are stored here
79 enum where value_origin;
80
81protected:
82 typedef bool (*on_check_function)(sys_var *self, THD *thd, set_var *var);
83 typedef bool (*on_update_function)(sys_var *self, THD *thd, enum_var_type type);
84
85 int flags; ///< or'ed flag_enum values
86 const SHOW_TYPE show_val_type; ///< what value_ptr() returns for sql_show.cc
87 PolyLock *guard; ///< *second* lock that protects the variable
88 ptrdiff_t offset; ///< offset to the value from global_system_variables
89 on_check_function on_check;
90 on_update_function on_update;
91 const char *const deprecation_substitute;
92 bool is_os_charset; ///< true if the value is in character_set_filesystem
93
94public:
95 sys_var(sys_var_chain *chain, const char *name_arg, const char *comment,
96 int flag_args, ptrdiff_t off, int getopt_id,
97 enum get_opt_arg_type getopt_arg_type, SHOW_TYPE show_val_type_arg,
98 longlong def_val, PolyLock *lock, enum binlog_status_enum binlog_status_arg,
99 on_check_function on_check_func, on_update_function on_update_func,
100 const char *substitute);
101
102 virtual ~sys_var() {}
103
104 /**
105 All the cleanup procedures should be performed here
106 */
107 virtual void cleanup() {}
108 /**
109 downcast for sys_var_pluginvar. Returns this if it's an instance
110 of sys_var_pluginvar, and 0 otherwise.
111 */
112 virtual sys_var_pluginvar *cast_pluginvar() { return 0; }
113
114 bool check(THD *thd, set_var *var);
115 uchar *value_ptr(THD *thd, enum_var_type type, const LEX_CSTRING *base);
116
117 /**
118 Update the system variable with the default value from either
119 session or global scope. The default value is stored in the
120 'var' argument. Return false when successful.
121 */
122 bool set_default(THD *thd, set_var *var);
123 bool update(THD *thd, set_var *var);
124
125 String *val_str_nolock(String *str, THD *thd, const uchar *value);
126 longlong val_int(bool *is_null, THD *thd, enum_var_type type, const LEX_CSTRING *base);
127 String *val_str(String *str, THD *thd, enum_var_type type, const LEX_CSTRING *base);
128 double val_real(bool *is_null, THD *thd, enum_var_type type, const LEX_CSTRING *base);
129
130 SHOW_TYPE show_type() { return show_val_type; }
131 int scope() const { return flags & SCOPE_MASK; }
132 CHARSET_INFO *charset(THD *thd);
133 bool is_readonly() const { return flags & READONLY; }
134 /**
135 the following is only true for keycache variables,
136 that support the syntax @@keycache_name.variable_name
137 */
138 bool is_struct() { return option.var_type & GET_ASK_ADDR; }
139 bool is_set_stmt_ok() const { return !(flags & NO_SET_STATEMENT); }
140 bool is_written_to_binlog(enum_var_type type)
141 { return type != OPT_GLOBAL && binlog_status == SESSION_VARIABLE_IN_BINLOG; }
142 bool check_update_type(const Item *item)
143 {
144 Item_result type= item->result_type();
145 switch (option.var_type & GET_TYPE_MASK) {
146 case GET_INT:
147 case GET_UINT:
148 case GET_LONG:
149 case GET_ULONG:
150 case GET_LL:
151 case GET_ULL:
152 return type != INT_RESULT &&
153 (type != DECIMAL_RESULT || item->decimals != 0);
154 case GET_STR:
155 case GET_STR_ALLOC:
156 return type != STRING_RESULT;
157 case GET_ENUM:
158 case GET_BOOL:
159 case GET_SET:
160 case GET_FLAGSET:
161 case GET_BIT:
162 return type != STRING_RESULT && type != INT_RESULT;
163 case GET_DOUBLE:
164 return type != INT_RESULT && type != REAL_RESULT && type != DECIMAL_RESULT;
165 default:
166 return true;
167 }
168 }
169
170 bool check_type(enum_var_type type)
171 {
172 switch (scope())
173 {
174 case GLOBAL: return type != OPT_GLOBAL;
175 case SESSION: return false; // always ok
176 case ONLY_SESSION: return type == OPT_GLOBAL;
177 }
178 return true; // keep gcc happy
179 }
180 bool register_option(DYNAMIC_ARRAY *array, int parse_flags)
181 {
182 DBUG_ASSERT(parse_flags == GETOPT_ONLY_HELP ||
183 parse_flags == PARSE_EARLY || parse_flags == 0);
184 if (option.id == NO_GETOPT)
185 return 0;
186 if (parse_flags == GETOPT_ONLY_HELP)
187 {
188 if (option.id != GETOPT_ONLY_HELP)
189 return 0;
190 }
191 else
192 {
193 if (option.id == GETOPT_ONLY_HELP)
194 return 0;
195 if ((flags & PARSE_EARLY) != parse_flags)
196 return 0;
197 }
198 return insert_dynamic(array, (uchar*)&option);
199 }
200 void do_deprecated_warning(THD *thd);
201 /**
202 whether session value of a sysvar is a default one.
203
204 in this simple implementation we don't distinguish between default
205 and non-default values. for most variables it's ok, they don't treat
206 default values specially. this method is overwritten in descendant
207 classes as necessary.
208 */
209 virtual bool session_is_default(THD *thd) { return false; }
210
211 virtual uchar *default_value_ptr(THD *thd)
212 { return (uchar*)&option.def_value; }
213
214private:
215 virtual bool do_check(THD *thd, set_var *var) = 0;
216 /**
217 save the session default value of the variable in var
218 */
219 virtual void session_save_default(THD *thd, set_var *var) = 0;
220 /**
221 save the global default value of the variable in var
222 */
223 virtual void global_save_default(THD *thd, set_var *var) = 0;
224 virtual bool session_update(THD *thd, set_var *var) = 0;
225 virtual bool global_update(THD *thd, set_var *var) = 0;
226
227protected:
228 /**
229 A pointer to a value of the variable for SHOW.
230 It must be of show_val_type type (my_bool for SHOW_MY_BOOL,
231 int for SHOW_INT, longlong for SHOW_LONGLONG, etc).
232 */
233 virtual uchar *session_value_ptr(THD *thd, const LEX_CSTRING *base);
234 virtual uchar *global_value_ptr(THD *thd, const LEX_CSTRING *base);
235
236 /**
237 A pointer to a storage area of the variable, to the raw data.
238 Typically it's the same as session_value_ptr(), but it's different,
239 for example, for ENUM, that is printed as a string, but stored as a number.
240 */
241 uchar *session_var_ptr(THD *thd)
242 { return ((uchar*)&(thd->variables)) + offset; }
243
244 uchar *global_var_ptr()
245 { return ((uchar*)&global_system_variables) + offset; }
246
247 friend class Session_sysvars_tracker;
248 friend class Session_tracker;
249};
250
251#include "sql_plugin.h" /* SHOW_HA_ROWS, SHOW_MY_BOOL */
252
253
254/****************************************************************************
255 Classes for parsing of the SET command
256****************************************************************************/
257
258/**
259 A base class for everything that can be set with SET command.
260 It's similar to Items, an instance of this is created by the parser
261 for every assigmnent in SET (or elsewhere, e.g. in SELECT).
262*/
263class set_var_base :public Sql_alloc
264{
265public:
266 set_var_base() {}
267 virtual ~set_var_base() {}
268 virtual int check(THD *thd)=0; /* To check privileges etc. */
269 virtual int update(THD *thd)=0; /* To set the value */
270 virtual int light_check(THD *thd) { return check(thd); } /* for PS */
271 virtual bool is_system() { return FALSE; }
272};
273
274
275/**
276 set_var_base descendant for assignments to the system variables.
277*/
278class set_var :public set_var_base
279{
280public:
281 sys_var *var; ///< system variable to be updated
282 Item *value; ///< the expression that provides the new value of the variable
283 enum_var_type type;
284 union ///< temp storage to hold a value between sys_var::check and ::update
285 {
286 ulonglong ulonglong_value; ///< for unsigned integer, set, enum sysvars
287 longlong longlong_value; ///< for signed integer
288 double double_value; ///< for Sys_var_double
289 plugin_ref plugin; ///< for Sys_var_plugin
290 plugin_ref *plugins; ///< for Sys_var_pluginlist
291 Time_zone *time_zone; ///< for Sys_var_tz
292 LEX_STRING string_value; ///< for Sys_var_charptr and others
293 const void *ptr; ///< for Sys_var_struct
294 } save_result;
295 LEX_CSTRING base; /**< for structured variables, like keycache_name.variable_name */
296
297 set_var(THD *thd, enum_var_type type_arg, sys_var *var_arg,
298 const LEX_CSTRING *base_name_arg, Item *value_arg);
299 virtual bool is_system() { return 1; }
300 int check(THD *thd);
301 int update(THD *thd);
302 int light_check(THD *thd);
303};
304
305
306/* User variables like @my_own_variable */
307class set_var_user: public set_var_base
308{
309 Item_func_set_user_var *user_var_item;
310public:
311 set_var_user(Item_func_set_user_var *item)
312 :user_var_item(item)
313 {}
314 int check(THD *thd);
315 int update(THD *thd);
316 int light_check(THD *thd);
317};
318
319/* For SET PASSWORD */
320
321class set_var_password: public set_var_base
322{
323 LEX_USER *user;
324public:
325 set_var_password(LEX_USER *user_arg) :user(user_arg)
326 {}
327 int check(THD *thd);
328 int update(THD *thd);
329};
330
331/* For SET ROLE */
332
333class set_var_role: public set_var_base
334{
335 LEX_CSTRING role;
336 ulonglong access;
337public:
338 set_var_role(LEX_CSTRING role_arg) : role(role_arg) {}
339 int check(THD *thd);
340 int update(THD *thd);
341};
342
343/* For SET DEFAULT ROLE */
344
345class set_var_default_role: public set_var_base
346{
347 LEX_USER *user, *real_user;
348 LEX_CSTRING role;
349public:
350 set_var_default_role(LEX_USER *user_arg, LEX_CSTRING role_arg) :
351 user(user_arg), role(role_arg) {}
352 int check(THD *thd);
353 int update(THD *thd);
354};
355
356/* For SET NAMES and SET CHARACTER SET */
357
358class set_var_collation_client: public set_var_base
359{
360 CHARSET_INFO *character_set_client;
361 CHARSET_INFO *character_set_results;
362 CHARSET_INFO *collation_connection;
363public:
364 set_var_collation_client(CHARSET_INFO *client_coll_arg,
365 CHARSET_INFO *connection_coll_arg,
366 CHARSET_INFO *result_coll_arg)
367 :character_set_client(client_coll_arg),
368 character_set_results(result_coll_arg),
369 collation_connection(connection_coll_arg)
370 {}
371 int check(THD *thd);
372 int update(THD *thd);
373};
374
375
376/* optional things, have_* variables */
377extern SHOW_COMP_OPTION have_csv, have_innodb;
378extern SHOW_COMP_OPTION have_ndbcluster, have_partitioning;
379extern SHOW_COMP_OPTION have_profiling;
380
381extern SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen;
382extern SHOW_COMP_OPTION have_query_cache;
383extern SHOW_COMP_OPTION have_geometry, have_rtree_keys;
384extern SHOW_COMP_OPTION have_crypt;
385extern SHOW_COMP_OPTION have_compress;
386extern SHOW_COMP_OPTION have_openssl;
387
388/*
389 Prototypes for helper functions
390*/
391
392SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted, enum enum_var_type type);
393int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond);
394
395sys_var *find_sys_var(THD *thd, const char *str, size_t length=0);
396int sql_set_variables(THD *thd, List<set_var_base> *var_list, bool free);
397
398#define SYSVAR_AUTOSIZE(VAR,VAL) \
399 do { \
400 VAR= (VAL); \
401 set_sys_var_value_origin(&VAR, sys_var::AUTO); \
402 } while(0)
403
404#define SYSVAR_AUTOSIZE_IF_CHANGED(VAR,VAL,TYPE) \
405 do { \
406 TYPE tmp= (VAL); \
407 if (VAR != tmp) \
408 { \
409 VAR= (VAL); \
410 set_sys_var_value_origin(&VAR, sys_var::AUTO); \
411 } \
412 } while(0)
413
414void set_sys_var_value_origin(void *ptr, enum sys_var::where here);
415
416enum sys_var::where get_sys_var_value_origin(void *ptr);
417inline bool IS_SYSVAR_AUTOSIZE(void *ptr)
418{
419 enum sys_var::where res= get_sys_var_value_origin(ptr);
420 return (res == sys_var::AUTO || res == sys_var::COMPILE_TIME);
421}
422
423bool fix_delay_key_write(sys_var *self, THD *thd, enum_var_type type);
424
425sql_mode_t expand_sql_mode(sql_mode_t sql_mode);
426bool sql_mode_string_representation(THD *thd, sql_mode_t sql_mode,
427 LEX_CSTRING *ls);
428int default_regex_flags_pcre(const THD *thd);
429
430extern sys_var *Sys_autocommit_ptr;
431
432CHARSET_INFO *get_old_charset_by_name(const char *old_name);
433
434int sys_var_init();
435uint sys_var_elements();
436int sys_var_add_options(DYNAMIC_ARRAY *long_options, int parse_flags);
437void sys_var_end(void);
438plugin_ref *resolve_engine_list(THD *thd, const char *str_arg, size_t str_arg_len,
439 bool error_on_unknown_engine, bool temp_copy);
440void free_engine_list(plugin_ref *list);
441plugin_ref *copy_engine_list(plugin_ref *list);
442plugin_ref *temp_copy_engine_list(THD *thd, plugin_ref *list);
443char *pretty_print_engine_list(THD *thd, plugin_ref *list);
444
445#endif
446
447