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