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