Description:
According to component_sys_var_service (https://dev.mysql.com/doc/dev/mysql-server/latest/component__sys__var__service_8h_source.h...), it is not possible to define session level variables like in plugins, but only global. I implemented an example component and I can confirm global variables work fine, but I think session variables may also work with a very simple trick.
// example component (simplified)
thread_local static long test_var = 1; // holds per-session value
static long global_test_var = 1; // holds global value
static void update_variable_test(MYSQL_THD thd [[maybe_unused]], SYS_VAR *self [[maybe_unused]], void *var_ptr, const void *save) {
const long new_val = *(static_cast<const long *>(save));
*(static_cast<long *>(var_ptr)) = new_val;
//test_var = new_val;
//global_test_var = new_val;
}
mysql_service_component_sys_variable_register->register_variable(
"httpclient", "test_var",
PLUGIN_VAR_LONG | PLUGIN_VAR_MEMALLOC | PLUGIN_VAR_NOPERSIST | PLUGIN_VAR_THDLOCAL,
"curl request follow redirects",
nullptr,
update_variable_test,
nullptr,
nullptr
)
How to repeat:
You can test with my simple httpclient component (https://github.com/ardabeyazoglu/mysql-http-client/tree/cce8d5333fbe189f8b2f42754d6a99a7ca...) to reproduce it easily.
Suggested fix:
I would suggest adding a 5th argument (lets say "scope") to "mysql_sys_var_update_func" callback in "mysql_service_component_sys_variable_register::register_variable" method, that holds the scope when SET command is executed.
So, when SET SESSION is used it will be SESSION, otherwise GLOBAL etc. This way, developer would know what kind of variable he is dealing with in the update function. In the example "update_variable_test" function, this would make it possible to set thread_local variable for SET SESSION and global variable for SET GLOBAL and to apply all kind of side effects based on scope.
As far as I can see, it can be done by refactoring SYS_VAR::update calls in sql/sql_plugin.cc and sql/sql_plugin_var.cc .