MySQL 9.1.0
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/**
110 @addtogroup group_components_services_sys_var_service_args Variable
111 definitions
112
113 You need to fill one of these in an pass it to the registration function.
114 The values are copied so this doesn't have to survive once the registration
115 call is done.
116 So usually it's done as an automatic variable in the stack.
117
118 Make sure to use the right one for your variable type.
119 See @ref group_components_services_sys_var_service_types for what to use
120 for the individual types.
121
122 @sa mysql_service_component_sys_variable_register service.
123
124 @{
125*/
126
127/**
128 Defines an integral placeholder to fill in with values and
129 pass to the registration function.
130
131 Make sure to fill in def_val, min_val, max_val and blk_sz.
132*/
133#define INTEGRAL_CHECK_ARG(type) \
134 struct type##_check_arg_s { \
135 type def_val; \
136 type min_val; \
137 type max_val; \
138 type blk_sz; \
139 }
140
141/**
142 Defines an @ref TYPE_LIB placeholder to fill in with values and
143 pass to the registration function.
144
145 Make sure to fill in def_val and typelib.
146*/
147#define ENUM_CHECK_ARG(type) \
148 struct type##_check_arg_s { \
149 unsigned long def_val; \
150 TYPE_LIB *typelib; \
151 }
152
153/**
154 Defines a bool placeholder to fill in with values and
155 pass to the registration function.
156
157 Make sure to fill in def_val.
158*/
159#define BOOL_CHECK_ARG(type) \
160 struct type##_check_arg_s { \
161 bool def_val; \
162 }
163
164/**
165 Defines a char * placeholder to fill in with values and
166 pass to the registration function.
167
168 Make sure to fill in def_val.
169*/
170#define STR_CHECK_ARG(type) \
171 struct type##_check_arg_s { \
172 char *def_val; \
173 }
174/** @} */
175
176/**
177 @ingroup group_components_services_inventory
178
179 Service to register variable and get variable value
180
181 @sa mysql_component_sys_variable_imp
182*/
183BEGIN_SERVICE_DEFINITION(component_sys_variable_register)
184
185/**
186 Register a new system variable.
187
188 The variable registered is then accessible in SQL as "SELECT
189 component_name.name" The variable registration needs a global of the relevant
190 type that stores the value.
191
192 To define a new variable you need to:
193 1. Decide on a variable type among one of the
194 @ref group_components_services_sys_var_service_types
195 2. Decide on attributes of the type among one of the
196 @ref group_components_services_sys_var_service_flags
197 3. Declare a local variable placeholder matching the type using one of the
198 @ref group_components_services_sys_var_service_args macros.
199 4. Fill in the placeholder values (min, max, default etc) as appropriate for
200 the selected type.
201 5. Provide storage for the variable value: usually a global variable of the
202 relevant type.
203 6. Call the function with all of the above to register the system variable.
204
205 @warning: Make sure to unregister the system variable when you no longer
206 intend to have it or when your component deinitializes. Failure to do so will
207 lead to resource leaks and crashes.
208
209 Typical use
210 @code
211 static int int_variable_value;
212 static char *str_variable_value;
213 static ulong enum_variable_value;
214
215 static const char *enums[] = {"LOW", "MEDIUM", "STRONG", NullS};
216
217 static TYPE_LIB enums_typelib_t = {array_elements(enums) - 1,
218 "enums_typelib_t",
219 enums, NULL};
220
221 ...
222
223 INTEGRAL_CHECK_ARG(int) int_arg;
224 int_arg.def_val = 8;
225 int_arg.min_val = 0;
226 int_arg.max_val = 1024;
227 int_arg.blk_sz = 0;
228 if (mysql_service_component_sys_variable_register->register_variable(
229 "foo", "int_sys_var", PLUGIN_VAR_INT,
230 "Registering int sys_variable", NULL, NULL, (void *)&int_arg,
231 (void *)&int_variable_value)) {
232 deal_with_error();
233 }
234
235 STR_CHECK_ARG(str) str_arg;
236 str_arg.def_val = NULL;
237 if (mysql_service_component_sys_variable_register->register_variable(
238 "foo", "str_sys_var", PLUGIN_VAR_STR | PLUGIN_VAR_MEMALLOC,
239 "Registering string sys_variable", NULL, NULL, (void *)&str_arg,
240 (void *)&str_variable_value)) {
241 deal_with_error();
242 }
243
244 ENUM_CHECK_ARG(enum) enum_arg;
245 enum_arg.def_val = 1; // medium
246 enum_arg.typelib = &enum_typelib_t;
247 if (mysql_service_component_sys_variable_register->register_variable(
248 "foo", "enum_sys_var", PLUGIN_VAR_ENUM,
249 "Registering enum sys_variable", NULL, NULL, (void *)&enum_arg,
250 (void *)&enum_variable_value)) {
251 deal_with_error();
252 }
253 @endcode
254
255
256 @sa mysql_service_component_sys_variable_unregister_t
257
258 @param component_name The name of the component the system variable belongs
259 to.
260 @param name The name of the variable.
261 @param flags one of @ref group_components_services_sys_var_service_types plus
262 zero or more of group_components_services_sys_var_service_flags
263 @param comment explanation of what the variable is to be shown in metadata
264 tables
265 @param check A function to be called to check for validity of the new value.
266 @param update A function to be called when the variable value is updated
267 @param check_arg The variable declared through one of
268 @ref group_components_services_sys_var_service_args
269 @param variable_value A pointer to a storage location of the relevant type.
270 @retval true operation failed
271 @retval false operation succeeded
272*/
274 (const char *component_name, const char *name, int flags,
275 const char *comment, mysql_sys_var_check_func check,
276 mysql_sys_var_update_func update, void *check_arg,
277 void *variable_value));
278/**
279 Fetches the global value of a system variable
280
281 Call this to get the global value of a variable. You can access both the
282 component variables (SELECT @@global.component_name.variable_name) and the
283 "legacy" system variables (SELECT @@global.variable_name) that are registered
284 by the server component.
285 To access the latter you need to pass "mysql_server" (lowercase) as a
286 component name.
287
288 A pointer to the value is returned into the val input/output argument. And the
289 length of the value (as applicable) is returned into the out_length_of_val
290 argument.
291
292 In case when the user buffer was too small to copy the value, the call fails
293 and needed buffer size is returned by 'out_length_of_val'.
294
295 Typical use (char * variable):
296 @code
297
298 char *value, buffer_for_value[160];
299 size_t value_length;
300
301 value= &buffer_for_value[0];
302 value_length= sizeof(buffer_for_value) - 1;
303 get_variable("foo", "bar", &value, &value_length);
304
305 printf("%.*s", (int) value_length, value);
306 @endcode
307
308 @param component_name Name of the component or "mysql_server" for the legacy
309 ones.
310 @param name name of the variable
311 @param[in,out] val On input: a buffer to hold the value. On output a pointer
312 to the value.
313 @param[in,out] out_length_of_val On input: the buffer size. On output the
314 length of the data copied.
315
316 @retval true failure
317 @retval false success
318*/
319#if defined(__cplusplus) && (__cplusplus >= 201402L)
320[[deprecated("Use mysql_service_mysql_system_variable_reader->get() instead.")]]
321#endif
322DECLARE_BOOL_METHOD(get_variable, (const char *component_name, const char *name,
323 void **val, size_t *out_length_of_val));
324
325END_SERVICE_DEFINITION(component_sys_variable_register)
326
327/**
328 @ingroup group_components_services_inventory
329
330 Service to unregister variable
331
332 Make sure to call this for each variable registered.
333
334 @sa mysql_service_component_sys_variable_unregister_t
335*/
336BEGIN_SERVICE_DEFINITION(component_sys_variable_unregister)
337
339 (const char *component_name, const char *name));
340
341END_SERVICE_DEFINITION(component_sys_variable_unregister)
342
343#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:6009
#define comment
Definition: lexyy.cc:959
static uint update
Definition: myisamlog.cc:94
mysql_service_status_t unregister_variable(SHOW_VAR *) noexcept
Definition: component_status_var_all_empty.cc:34
mysql_service_status_t register_variable(SHOW_VAR *) noexcept
Definition: component_status_var_all_empty.cc:30
#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