MySQL 8.4.2
Source Code Documentation
srv0dynamic_procedures.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 2020, 2024, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is designed to work with certain software (including
10but not limited to OpenSSL) that is licensed under separate terms,
11as designated in a particular file or component or in included license
12documentation. The authors of MySQL hereby grant you an additional
13permission to link the program and your derivative works with the
14separately licensed software that they have either included with
15the program or referenced in the documentation.
16
17This program is distributed in the hope that it will be useful, but WITHOUT
18ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
20for more details.
21
22You should have received a copy of the GNU General Public License along with
23this program; if not, write to the Free Software Foundation, Inc.,
2451 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
26*****************************************************************************/
27
28/** @file include/srv0dynamic_procedures.h
29 Helper for managing dynamic SQL procedures.
30
31 *******************************************************/
32
33#ifndef srv0dynamic_procedures_h
34#define srv0dynamic_procedures_h
35
36#include <string>
37#include <vector>
38
41#include "mysql/plugin.h"
43#include "sql/auth/auth_acls.h"
44#include "sql/current_thd.h"
45#include "sql/sql_class.h"
46#include "univ.i" /* LogErr */
47
48namespace srv {
49#ifndef UNIV_HOTBACKUP
50/**
51 Type and data for tracking registered UDFs.
52*/
54 const std::string m_name;
59
60 dynamic_procedure_data_t(const std::string &name, const Udf_func_string func,
61 const Udf_func_init init_func,
62 const Udf_func_deinit deinit_func,
63 const Item_result return_type = STRING_RESULT)
64 : m_name(name),
65 m_return_type(return_type),
66 m_func(reinterpret_cast<Udf_func_any>(func)),
67 m_init_func(init_func),
68 m_deinit_func(deinit_func) {}
69
70 dynamic_procedure_data_t(const std::string &name,
71 const Udf_func_longlong func,
72 const Udf_func_init init_func,
73 const Udf_func_deinit deinit_func)
74 : m_name(name),
76 m_func(reinterpret_cast<Udf_func_any>(func)),
77 m_init_func(init_func),
78 m_deinit_func(deinit_func) {}
79
80 dynamic_procedure_data_t(const std::string &name, const Udf_func_double func,
81 const Udf_func_init init_func,
82 const Udf_func_deinit deinit_func)
83 : m_name(name),
85 m_func(reinterpret_cast<Udf_func_any>(func)),
86 m_init_func(init_func),
87 m_deinit_func(deinit_func) {}
88};
89
91 public:
92 virtual ~Dynamic_procedures() = default;
93
94 /** Register dynamic SQL procedure.
95 This does first try to unregister any functions, that might be left over
96 from an earlier use of the component.
97
98 @return status, true on success */
100 /* Try to unregister potentially left over functions from last run. */
101 unregister();
102
103 auto plugin_registry = get_mysql_registry();
104
105 bool success = true;
106 /* Open a new block so that udf_registrar is automatically destroyed
107 before we release the plugin_registry. */
108 {
109 my_service<SERVICE_TYPE(udf_registration)> registrar =
110 get_procedure_registar(plugin_registry);
111 if (registrar.is_valid()) {
112 for (auto &procedure : get_procedures()) {
113 const char *name = procedure.m_name.c_str();
114 if (registrar->udf_register(name, procedure.m_return_type,
115 procedure.m_func, procedure.m_init_func,
116 procedure.m_deinit_func)) {
117 /* purecov: begin inspected */
118 /* Only needed if register fails. */
119 std::string msg = get_module_name() +
120 ": Cannot register dynamic SQL procedure '" +
121 name + "'";
122 LogErr(ERROR_LEVEL, ER_INNODB_ERROR_LOGGER_MSG, msg.c_str());
123 success = false;
124 /* purecov: end */
125 }
126 }
127 }
128 }
129 /* end of udf_registrar block */
130 mysql_plugin_registry_release(plugin_registry);
131 if (!success) {
132 unregister();
133 }
134 return success;
135 }
136
137 /** Unregister dynamic SQL procedure */
138 void unregister() {
139 auto plugin_registry = get_mysql_registry();
140
141 /* Open a new block so that udf_registrar is automatically destroyed
142 before we release the plugin_registry. */
143 {
144 my_service<SERVICE_TYPE(udf_registration)> registrar =
145 get_procedure_registar(plugin_registry);
146 if (registrar.is_valid()) {
147 for (auto &procedure : get_procedures()) {
148 const char *name = procedure.m_name.c_str();
149 int was_present = 0;
150 if (registrar->udf_unregister(name, &was_present) && was_present) {
151 /* purecov: begin inspected */
152 /* Only needed if unregister fails. */
153 std::string msg = get_module_name() +
154 ": Cannot unregister dynamic SQL procedure '" +
155 name + "'";
156 LogErr(WARNING_LEVEL, ER_INNODB_ERROR_LOGGER_MSG, msg.c_str());
157 /* purecov: end */
158 }
159 }
160 }
161 } /* end of udf_registrar block */
162 mysql_plugin_registry_release(plugin_registry);
163 }
164
165 protected:
166 virtual std::vector<dynamic_procedure_data_t> get_procedures() const = 0;
167 virtual std::string get_module_name() const = 0;
168
169 private:
171 SERVICE_TYPE(registry) *plugin_registry = mysql_plugin_registry_acquire();
172 if (plugin_registry == nullptr) {
173 /* purecov: begin inspected */
174 LogErr(
175 WARNING_LEVEL, ER_INNODB_ERROR_LOGGER_MSG,
176 (get_module_name() + ": mysql_plugin_registry_acquire() returns NULL")
177 .c_str());
178 /* purecov: end */
179 }
180 return plugin_registry;
181 }
182
184 SERVICE_TYPE(registry) * plugin_registry) {
185 my_service<SERVICE_TYPE(udf_registration)> registrar("udf_registration",
186 plugin_registry);
187 if (!registrar.is_valid()) {
188 LogErr(WARNING_LEVEL, ER_INNODB_ERROR_LOGGER_MSG,
189 (get_module_name() + ": Cannot get valid udf_registration service")
190 .c_str());
191 }
192 return registrar;
193 }
194};
195
196#endif
197
198} // namespace srv
199
200#endif
Wraps my_h_service struct conforming ABI into RAII C++ object with ability to cast to desired service...
Definition: my_service.h:35
bool is_valid() const
Definition: my_service.h:104
Definition: srv0dynamic_procedures.h:90
const mysql_service_registry_t * get_mysql_registry()
Definition: srv0dynamic_procedures.h:170
virtual std::string get_module_name() const =0
virtual ~Dynamic_procedures()=default
void unregister()
Unregister dynamic SQL procedure.
Definition: srv0dynamic_procedures.h:138
my_service< const mysql_service_udf_registration_t > get_procedure_registar(const mysql_service_registry_t *plugin_registry)
Definition: srv0dynamic_procedures.h:183
bool register_procedures()
Register dynamic SQL procedure.
Definition: srv0dynamic_procedures.h:99
virtual std::vector< dynamic_procedure_data_t > get_procedures() const =0
#define LogErr(severity, ecode,...)
Definition: log_builtins.h:843
@ WARNING_LEVEL
Definition: my_loglevel.h:44
@ ERROR_LEVEL
Definition: my_loglevel.h:43
Definition: srv0dynamic_procedures.h:48
#define SERVICE_TYPE(name)
Generates the standard Service type name.
Definition: service.h:76
Declaration of the registry plugin service.
const mysql_service_registry_t * mysql_plugin_registry_acquire()
Returns a new reference to the "registry" service.
Definition: plugin_registry_service.cc:47
int mysql_plugin_registry_release(const mysql_service_registry_t *)
Releases a registry service reference.
Definition: plugin_registry_service.cc:75
case opt name
Definition: sslopt-case.h:29
Type and data for tracking registered UDFs.
Definition: srv0dynamic_procedures.h:53
const Udf_func_init m_init_func
Definition: srv0dynamic_procedures.h:57
const Item_result m_return_type
Definition: srv0dynamic_procedures.h:55
const Udf_func_deinit m_deinit_func
Definition: srv0dynamic_procedures.h:58
const Udf_func_any m_func
Definition: srv0dynamic_procedures.h:56
dynamic_procedure_data_t(const std::string &name, const Udf_func_double func, const Udf_func_init init_func, const Udf_func_deinit deinit_func)
Definition: srv0dynamic_procedures.h:80
const std::string m_name
Definition: srv0dynamic_procedures.h:54
dynamic_procedure_data_t(const std::string &name, const Udf_func_longlong func, const Udf_func_init init_func, const Udf_func_deinit deinit_func)
Definition: srv0dynamic_procedures.h:70
dynamic_procedure_data_t(const std::string &name, const Udf_func_string func, const Udf_func_init init_func, const Udf_func_deinit deinit_func, const Item_result return_type=STRING_RESULT)
Definition: srv0dynamic_procedures.h:60
long long(* Udf_func_longlong)(UDF_INIT *, UDF_ARGS *, unsigned char *, unsigned char *)
Definition: udf_registration_types.h:85
char *(* Udf_func_string)(UDF_INIT *, UDF_ARGS *, char *, unsigned long *, unsigned char *, unsigned char *)
Definition: udf_registration_types.h:87
void(* Udf_func_deinit)(UDF_INIT *)
Definition: udf_registration_types.h:80
double(* Udf_func_double)(UDF_INIT *, UDF_ARGS *, unsigned char *, unsigned char *)
Definition: udf_registration_types.h:83
Item_result
Type of the user defined function return slot and arguments.
Definition: udf_registration_types.h:39
@ STRING_RESULT
not valid for UDFs
Definition: udf_registration_types.h:41
@ REAL_RESULT
char *
Definition: udf_registration_types.h:42
@ INT_RESULT
double
Definition: udf_registration_types.h:43
bool(* Udf_func_init)(UDF_INIT *, UDF_ARGS *, char *)
Definition: udf_registration_types.h:81
void(* Udf_func_any)(void)
Definition: udf_registration_types.h:82
Version control for database, common definitions, and include files.