MySQL  8.0.21
Source Code Documentation
component_sys_var_service.h
Go to the documentation of this file.
1 /* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
2 
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6 
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22 
23 #ifndef COMPONENT_SYS_VAR_SERVICE_H
24 #define COMPONENT_SYS_VAR_SERVICE_H
25 
26 #include <stddef.h>
27 
29 
30 /**
31  A utility class for the ENUM variables
32 */
33 
34 struct TYPE_LIB {
35  size_t count{0}; /* How many types */
36  const char *name{nullptr}; /* Name of typelib */
37  const char **type_names{nullptr};
38  unsigned int *type_lengths{nullptr};
39 };
40 
41 /**
42  @addtogroup group_components_services_sys_var_service_types Variable types
43 
44  Possible system variable types. Use at most one of these.
45 
46  @sa mysql_service_component_sys_variable_register service.
47 
48  @{
49 */
50 
51 /** bool variable. Use @ref BOOL_CHECK_ARG */
52 #define PLUGIN_VAR_BOOL 0x0001
53 /** int variable. Use @ref INTEGRAL_CHECK_ARG */
54 #define PLUGIN_VAR_INT 0x0002
55 /** long variable Use @ref INTEGRAL_CHECK_ARG */
56 #define PLUGIN_VAR_LONG 0x0003
57 /** longlong variable. Use @ref INTEGRAL_CHECK_ARG */
58 #define PLUGIN_VAR_LONGLONG 0x0004
59 /** char * variable. Use @ref STR_CHECK_ARG */
60 #define PLUGIN_VAR_STR 0x0005
61 /** Enum variable. Use @ref ENUM_CHECK_ARG */
62 #define PLUGIN_VAR_ENUM 0x0006
63 /** A set variable. Use @ref ENUM_CHECK_ARG */
64 #define PLUGIN_VAR_SET 0x0007
65 /** double variable. Use @ref INTEGRAL_CHECK_ARG */
66 #define PLUGIN_VAR_DOUBLE 0x0008
67 /** @} */
68 /**
69  @addtogroup group_components_services_sys_var_service_flags Variable flags
70 
71  Flags to specify the behavior of system variables. Use multiple as needed.
72 
73  @sa mysql_service_component_sys_variable_register service.
74 
75  @{
76 */
77 #define PLUGIN_VAR_UNSIGNED 0x0080 /**< The variable is unsigned */
78 #define PLUGIN_VAR_THDLOCAL 0x0100 /**< Variable is per-connection */
79 #define PLUGIN_VAR_READONLY 0x0200 /**< Server variable is read only */
80 #define PLUGIN_VAR_NOSYSVAR 0x0400 /**< Not a server variable */
81 #define PLUGIN_VAR_NOCMDOPT 0x0800 /**< Not a command line option */
82 #define PLUGIN_VAR_NOCMDARG 0x1000 /**< No argument for cmd line */
83 #define PLUGIN_VAR_RQCMDARG 0x0000 /**< Argument required for cmd line */
84 #define PLUGIN_VAR_OPCMDARG 0x2000 /**< Argument optional for cmd line */
85 #define PLUGIN_VAR_NODEFAULT 0x4000 /**< SET DEFAULT is prohibited */
86 #define PLUGIN_VAR_MEMALLOC 0x8000 /**< String needs memory allocated */
87 #define PLUGIN_VAR_NOPERSIST \
88  0x10000 /**< SET PERSIST_ONLY is prohibited for read only variables */
89 /** @} */
90 
91 class THD;
92 struct SYS_VAR;
93 #define MYSQL_THD THD *
94 
95 /**
96  Signature for the check function
97 
98  This is called to check if the value supplied is valid and can be set
99  as a new variable value at that time.
100  It needs to extract the value supplied from the value API pointer.
101  Note that extracting this value can be expensive (e.g. a scalar subquery)
102  hence it should be done only once. This is why the result of this should
103  be stored into the save output parameter so that it can be futher reused by
104  update() etc.
105  For a multi-variable SET statement the server will first call all of the
106  check functions and only if they all return success it will start calling the
107  update functions.
108  So the idea is that the update function should succeed no matter what.
109  And all the necessary checks should be done in the check function.
110  If you do not supply a check or update function the server will use the basic
111  ones to check e.g. min and max values for the integer types etc.
112 
113  @param thd The thread handle to the current thread
114  @param var handle to the system variable definition
115  @param[out] save placeholder for the value. This should be cast according to
116  the type
117  @param value Interface to extract the actual parameter value.
118  @return status
119  @retval 0 success
120  @retval 1 failure
121 
122  @sa mysql_sys_var_update_func, mysql_service_component_sys_variable_register_t
123 */
124 typedef int (*mysql_sys_var_check_func)(MYSQL_THD thd, SYS_VAR *var, void *save,
125  struct st_mysql_value *value);
126 
127 /**
128  Signature for the update function
129 
130  This is called to set the updated value into the var_ptr placeholder and
131  invoke any side effects that may stem from setting this system variable.
132 
133  It receives the pre-calculated value (usually from
134  @ref mysql_sys_var_check_func) in the save pointer.
135  It needs to set it into the var_ptr pointer and invoke any side effects.
136 
137  For a multi-variable SET statement the server will first call all of the
138  check functions and only if they all return success it will start calling the
139  update functions.
140  So the idea is that the update function should succeed no matter what.
141  And all the necessary checks should be done in the check function.
142  If you do not supply an update function the server will use the basic
143  one to set the value according to the variable's type.
144 
145  @param thd The thread handle to the current thread
146  @param var handle to the system variable definition
147  @param[out] val_ptr placeholder for the value. Store save in here.
148  @param save The pre-calculated value from check.
149 
150  @sa mysql_sys_var_check_func, mysql_service_component_sys_variable_register_t
151 */
152 typedef void (*mysql_sys_var_update_func)(MYSQL_THD thd, SYS_VAR *var,
153  void *val_ptr, const void *save);
154 
155 #define COPY_MYSQL_PLUGIN_VAR_HEADER(sys_var_type, type, sys_var_check, \
156  sys_var_update) \
157  sys_var_type->flags = flags; \
158  sys_var_type->name = var_name; \
159  sys_var_type->comment = comment; \
160  sys_var_type->check = check_func ? check_func : sys_var_check; \
161  sys_var_type->update = update_func ? update_func : sys_var_update; \
162  sys_var_type->value = (type *)variable_value;
163 
164 #define COPY_MYSQL_PLUGIN_VAR_REMAINING(sys_var_type, check_arg_type) \
165  sys_var_type->def_val = check_arg_type->def_val; \
166  sys_var_type->min_val = check_arg_type->min_val; \
167  sys_var_type->max_val = check_arg_type->max_val; \
168  sys_var_type->blk_sz = check_arg_type->blk_sz;
169 
170 #define SYSVAR_INTEGRAL_TYPE(type) \
171  struct sysvar_##type##_type { \
172  MYSQL_PLUGIN_VAR_HEADER; \
173  type *value; \
174  type def_val; \
175  type min_val; \
176  type max_val; \
177  type blk_sz; \
178  }
179 
180 #define SYSVAR_ENUM_TYPE(type) \
181  struct sysvar_##type##_type { \
182  MYSQL_PLUGIN_VAR_HEADER; \
183  unsigned long *value; \
184  unsigned long def_val; \
185  TYPE_LIB *typelib; \
186  }
187 
188 #define SYSVAR_BOOL_TYPE(type) \
189  struct sysvar_##type##_type { \
190  MYSQL_PLUGIN_VAR_HEADER; \
191  bool *value; \
192  bool def_val; \
193  }
194 
195 #define SYSVAR_STR_TYPE(type) \
196  struct sysvar_##type##_type { \
197  MYSQL_PLUGIN_VAR_HEADER; \
198  char **value; \
199  char *def_val; \
200  }
201 
202 /**
203  @addtogroup group_components_services_sys_var_service_args Variable
204  definitions
205 
206  You need to fill one of these in an pass it to the registration function.
207  The values are copied so this doesn't have to survive once the registration
208  call is done.
209  So usually it's done as an automatic variable in the stack.
210 
211  Make sure to use the right one for your variable type.
212  See @ref group_components_services_sys_var_service_types for what to use
213  for the individual types.
214 
215  @sa mysql_service_component_sys_variable_register service.
216 
217  @{
218 */
219 
220 /**
221  Defines an integral placeholder to fill in with values and
222  pass to the registration function.
223 
224  Make sure to fill in def_val, min_val, max_val and blk_sz.
225 */
226 #define INTEGRAL_CHECK_ARG(type) \
227  struct type##_check_arg_s { \
228  type def_val; \
229  type min_val; \
230  type max_val; \
231  type blk_sz; \
232  }
233 
234 /**
235  Defines an @ref TYPE_LIB placeholder to fill in with values and
236  pass to the registration function.
237 
238  Make sure to fill in def_val and typelib.
239 */
240 #define ENUM_CHECK_ARG(type) \
241  struct type##_check_arg_s { \
242  unsigned long def_val; \
243  TYPE_LIB *typelib; \
244  }
245 
246 /**
247  Defines a bool placeholder to fill in with values and
248  pass to the registration function.
249 
250  Make sure to fill in def_val.
251 */
252 #define BOOL_CHECK_ARG(type) \
253  struct type##_check_arg_s { \
254  bool def_val; \
255  }
256 
257 /**
258  Defines a char * placeholder to fill in with values and
259  pass to the registration function.
260 
261  Make sure to fill in def_val.
262 */
263 #define STR_CHECK_ARG(type) \
264  struct type##_check_arg_s { \
265  char *def_val; \
266  }
267 /** @} */
268 
269 /**
270  @ingroup group_components_services_inventory
271 
272  Service to register variable and get variable value
273 
274  @sa mysql_component_sys_variable_imp
275 */
276 BEGIN_SERVICE_DEFINITION(component_sys_variable_register)
277 
278 /**
279  Register a new system variable.
280 
281  The variable registered is then accessible in SQL as "SELECT
282  component_name.name" The variable registration needs a global of the relevant
283  type that stores the value.
284 
285  To define a new variable you need to:
286  1. Decide on a variable type among one of the
287  @ref group_components_services_sys_var_service_types
288  2. Decide on attributes of the type among one of the
289  @ref group_components_services_sys_var_service_flags
290  3. Declare a local variable placeholder matching the type using one of the
291  @ref group_components_services_sys_var_service_args macros.
292  4. Fill in the placeholder values (min, max, default etc) as appropriate for
293  the selected type.
294  5. Provide storage for the variable value: usually a global variable of the
295  relevant type.
296  6. Call the function with all of the above to register the system variable.
297 
298  @warning: Make sure to unregister the system variable when you no longer
299  intend to have it or when your component deinitializes. Failure to do so will
300  lead to resource leaks and crashes.
301 
302  Typical use
303  @code
304  static int int_variable_value;
305  static char *str_variable_value;
306  static ulong enum_variable_value;
307 
308  static const char *enums[] = {"LOW", "MEDIUM", "STRONG", NullS};
309 
310  static TYPE_LIB enums_typelib_t = {array_elements(enums) - 1,
311  "enums_typelib_t",
312  enums, NULL};
313 
314  ...
315 
316  INTEGRAL_CHECK_ARG(int) int_arg;
317  int_arg.def_val = 8;
318  int_arg.min_val = 0;
319  int_arg.max_val = 1024;
320  int_arg.blk_sz = 0;
321  if (mysql_service_component_sys_variable_register->register_variable(
322  "foo", "int_sys_var", PLUGIN_VAR_INT,
323  "Registering int sys_variable", NULL, NULL, (void *)&int_arg,
324  (void *)&int_variable_value)) {
325  deal_with_error();
326  }
327 
328  STR_CHECK_ARG(str) str_arg;
329  str_arg.def_val = NULL;
330  if (mysql_service_component_sys_variable_register->register_variable(
331  "foo", "str_sys_var", PLUGIN_VAR_STR | PLUGIN_VAR_MEMALLOC,
332  "Registering string sys_variable", NULL, NULL, (void *)&str_arg,
333  (void *)&str_variable_value)) {
334  deal_with_error();
335  }
336 
337  ENUM_CHECK_ARG(enum) enum_arg;
338  enum_arg.def_val = 1; // medium
339  enum_arg.typelib = &enum_typelib_t;
340  if (mysql_service_component_sys_variable_register->register_variable(
341  "foo", "enum_sys_var", PLUGIN_VAR_ENUM,
342  "Registering enum sys_variable", NULL, NULL, (void *)&enum_arg,
343  (void *)&enum_variable_value)) {
344  deal_with_error();
345  }
346  @endcode
347 
348 
349  @sa mysql_service_component_sys_variable_unregister_t
350 
351  @param component_name The name of the component the system variable belongs
352  to.
353  @param name The name of the variable.
354  @param flags one of @ref group_components_services_sys_var_service_types plus
355  zero or more of group_components_services_sys_var_service_flags
356  @param comment explanation of what the variable is to be shown in metadata
357  tables
358  @param check A function to be called to check for validity of the new value.
359  @param update A function to be called when the variable value is updated
360  @param check_arg The variable declared through one of
361  @ref group_components_services_sys_var_service_args
362  @param variable_value A pointer to a storage location of the relevant type.
363  @retval true operation failed
364  @retval false operation succeeded
365 */
366 DECLARE_BOOL_METHOD(register_variable,
367  (const char *component_name, const char *name, int flags,
368  const char *comment, mysql_sys_var_check_func check,
369  mysql_sys_var_update_func update, void *check_arg,
370  void *variable_value));
371 /**
372  Fetches the global value of a system variable
373 
374  Call this to get the global value of a variable. You can access both the
375  component variables (SELECT @@global.component_name.variable_name) and the
376  "legacy" system variables (SELECT @@global.variable_name) that are registered
377  by the server component.
378  To access the latter you need to pass "mysql_server" (lowercase) as a
379  component name.
380 
381  A pointer to the value is returned into the val input/output argument. And the
382  length of the value (as applicable) is returned into the out_length_of_val
383  argument.
384 
385  In case when the user buffer was too small to copy the value, the call fails
386  and needed buffer size is returned by 'out_length_of_val'.
387 
388  Typical use (char * variable):
389  @code
390 
391  char *value, buffer_for_value[160];
392  size_t value_length;
393 
394  value= &buffer_for_value[0];
395  value_length= sizeof(buffer_for_value) - 1;
396  get_variable("foo", "bar", &value, &value_length);
397 
398  printf("%.*s", (int) value_length, value);
399  @endcode
400 
401  @param component_name Name of the component or "mysql_server" for the legacy
402  ones.
403  @param name name of the variable
404  @param[in,out] val On input: a buffer to hold the value. On output a pointer
405  to the value.
406  @param[in,out] out_length_of_val On input: the buffer size. On output the
407  length of the data copied.
408 
409  @retval true failure
410  @retval false success
411 */
412 DECLARE_BOOL_METHOD(get_variable, (const char *component_name, const char *name,
413  void **val, size_t *out_length_of_val));
414 
415 END_SERVICE_DEFINITION(component_sys_variable_register)
416 
417 /**
418  @ingroup group_components_services_inventory
419 
420  Service to unregister variable
421 
422  Make sure to call this for each variable registered.
423 
424  @sa mysql_service_component_sys_variable_unregister_t
425 */
426 BEGIN_SERVICE_DEFINITION(component_sys_variable_unregister)
427 
428 DECLARE_BOOL_METHOD(unregister_variable,
429  (const char *component_name, const char *name));
430 
431 END_SERVICE_DEFINITION(component_sys_variable_unregister)
432 
433 #endif /* COMPONENT_SYS_VAR_SERVICE_H */
const char * name
Definition: component_sys_var_service.h:36
Definition: plugin.h:62
#define MYSQL_THD
Definition: component_sys_var_service.h:93
Definition: plugin.h:770
void(* mysql_sys_var_update_func)(MYSQL_THD thd, SYS_VAR *var, void *val_ptr, const void *save)
Signature for the update function.
Definition: component_sys_var_service.h:152
int(* mysql_sys_var_check_func)(MYSQL_THD thd, SYS_VAR *var, void *save, struct st_mysql_value *value)
Signature for the check function.
Definition: component_sys_var_service.h:124
static user_var_entry * get_variable(THD *thd, const Name_string &name, const CHARSET_INFO *cs)
Definition: item_func.cc:5514
#define END_SERVICE_DEFINITION(name)
static uint update
Definition: myisamlog.cc:90
const char ** type_names
Definition: component_sys_var_service.h:37
unsigned int * type_lengths
Definition: component_sys_var_service.h:38
const string value("\alue\)
#define BEGIN_SERVICE_DEFINITION(name)
#define DECLARE_BOOL_METHOD(name, args)
static int flags[50]
Definition: hp_test1.cc:39
size_t count
Definition: component_sys_var_service.h:35
#define comment
Definition: lexyy.cc:959
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_class.h:799
A utility class for the ENUM variables.
Definition: component_sys_var_service.h:34