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