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