MySQL 9.7.2
Source Code Documentation
jit_executor_value.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024, 2026, Oracle and/or its affiliates.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2.0,
6 * as published by the Free Software Foundation.
7 *
8 * This program is designed to work with certain software (including
9 * but not limited to OpenSSL) that is licensed under separate terms,
10 * as designated in a particular file or component or in included license
11 * documentation. The authors of MySQL hereby grant you an additional
12 * permission to link the program and your derivative works with the
13 * separately licensed software that they have either included with
14 * the program or referenced in the documentation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
19 * the GNU General Public License, version 2.0, for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#ifndef ROUTER_SRC_INCLUDE_MYSQLROUTER_JIT_EXECUTOR_VALUE_H_
27#define ROUTER_SRC_INCLUDE_MYSQLROUTER_JIT_EXECUTOR_VALUE_H_
28
29#include <cstdint>
30#include <map>
31#include <memory>
32#include <stdexcept>
33#include <string>
34#include <variant>
35#include <vector>
36
37#include "mysqlrouter/jit_executor_plugin_export.h"
38
39namespace shcore {
40
41namespace polyglot {
42class Polyglot_object;
43class Object_bridge;
44} // namespace polyglot
45
46class Parser_error : public std::runtime_error {
47 using std::runtime_error::runtime_error;
48};
49
50/** Basic types that can be passed around code in different languages.
51
52 With the exception of Native and Function, all types can be serialized to JSON.
53 */
55 Undefined, //! Undefined
56 Null, //! Null/None value
57 Bool, //! true or false
58 String, //! String values, UTF-8 encoding
59 Integer, //! 64bit integer numbers
60 UInteger, //! unsigned 64bit integer numbers
61 Float, //! double numbers
62
63 // Object, //! Native/bridged C++ object refs, may or may not be
64 // serializable
65 Object, //! Polyglot object of any type
66 ObjectBridge, //! C++ Object
67
68 Array, //! Array/List container
69 Map, //! Dictionary/Map/Object container
70
71 // Function, //! A function reference, not serializable.
72 Binary //! Binary data
73};
74
75bool is_compatible_type(Value_type source_type, Value_type target_type);
76
77// std::string type_description(Value_type type);
78// std::string type_name(Value_type type);
79
80// class Object_bridge;
81// typedef std::shared_ptr<Object_bridge> Object_bridge_ref;
82
83/** Pointer to a function that may be implemented in any language.
84 */
85// class Function_base;
86// using Function_base_ref = std::shared_ptr<Function_base>;
87
88/** A generic value that can be used from any language we support.
89
90 Anything that can be represented using this can be passed as a parameter to
91 scripting functions or stored in the internal registry or anywhere. If
92 serializable types are used, then they may also be stored as a JSON document.
93
94 Values are exposed to scripting languages according to the following rules:
95
96 - Simple types (Null, Bool, String, Integer, Float, UInteger) are converted
97 directly to the target type, both ways
98
99 - Arrays and Maps are converted directly to the target type, both ways
100
101 - Functions are wrapped into callable objects from C++ to scripting language
102 - Scripting language functions are wrapped into an instance of a language
103 specific subclass of Function_base
104
105 - C++ Objects are generically wrapped into a scripting language object, except
106 when there's a specific native counterpart
107
108 - Scripting language objects are either generically wrapped to a language
109 specific generic object wrapper or converted to a specific C++ Object subclass
110
111 Example: JS Date object is converted to a C++ Date object and vice-versa, but
112 Mysql_connection is wrapped generically
113
114 @section Implicit type conversions
115
116 Null Bool String Integer UInteger Float Object Array Map
117 Null OK - - - - - OK OK OK
118 Bool - OK - OK OK OK - - -
119 String - OK OK OK OK OK - - -
120 Integer - OK - OK OK OK - - -
121 UInteger - OK - OK OK OK - - -
122 Float - OK - OK OK OK - - -
123 Object - - - - - - OK - -
124 Array - - - - - - - OK -
125 Map - - - - - - - - OK
126
127 * Integer <-> UInteger conversions are only possible if the range allows it
128 * Null can be cast to Object/Array/Map, but a valid Object/Array/Map pointer
129 is not NULL, so it can't be cast to it.
130 */
131struct JIT_EXECUTOR_PLUGIN_EXPORT Value final {
132 typedef std::vector<Value> Array_type;
133 typedef std::shared_ptr<Array_type> Array_type_ref;
134
135 class Map_type final {
136 public:
137 typedef std::map<std::string, Value> container_type;
138 typedef container_type::const_iterator const_iterator;
139 typedef container_type::iterator iterator;
141 using reverse_iterator = container_type::reverse_iterator;
142 using const_reverse_iterator = container_type::const_reverse_iterator;
143
144 inline bool has_key(const std::string &k) const { return find(k) != end(); }
145
146 Value_type get_type(const std::string &k) const;
147
148 bool is_null(const std::string &k) const {
149 return get_type(k) == Value_type::Null;
150 }
151
152 std::string get_string(const std::string &k,
153 const std::string &def = "") const;
154 bool get_bool(const std::string &k, bool def = false) const;
155 int64_t get_int(const std::string &k, int64_t def = 0) const;
156 uint64_t get_uint(const std::string &k, uint64_t def = 0) const;
157 double get_double(const std::string &k, double def = 0.0) const;
158 std::shared_ptr<Value::Map_type> get_map(
159 const std::string &k,
160 std::shared_ptr<Map_type> def = std::shared_ptr<Map_type>()) const;
161 std::shared_ptr<Value::Array_type> get_array(
162 const std::string &k,
163 std::shared_ptr<Array_type> def = std::shared_ptr<Array_type>()) const;
164 void merge_contents(std::shared_ptr<Map_type> source, bool overwrite);
165
166 // template <class C>
167 // std::shared_ptr<C> get_object(
168 // const std::string &k,
169 // std::shared_ptr<C> def = std::shared_ptr<C>()) const {
170 // const_iterator iter = find(k);
171 // if (iter == end()) return def;
172 // iter->second.check_type(Object);
173 // return iter->second.as_object<C>();
174 // }
175
176 const_iterator find(const std::string &k) const { return _map.find(k); }
177 iterator find(const std::string &k) { return _map.find(k); }
178
179 size_t erase(const std::string &k) { return _map.erase(k); }
180 iterator erase(const_iterator it) { return _map.erase(it); }
181 iterator erase(iterator it) { return _map.erase(it); }
182 void clear() { _map.clear(); }
183
184 const_iterator begin() const { return _map.begin(); }
185 iterator begin() { return _map.begin(); }
186
187 const_reverse_iterator rbegin() const { return _map.rbegin(); }
188 reverse_iterator rbegin() { return _map.rbegin(); }
189
190 const_iterator end() const { return _map.end(); }
191 iterator end() { return _map.end(); }
192
193 const_reverse_iterator rend() const { return _map.rend(); }
194 reverse_iterator rend() { return _map.rend(); }
195
196 void set(const std::string &k, Value &&v) { _map[k] = std::move(v); }
197
198 void set(const std::string &k, const Value &v) { _map[k] = v; }
199
200 const container_type::mapped_type &at(const std::string &k) const {
201 return _map.at(k);
202 }
203 container_type::mapped_type &operator[](const std::string &k) {
204 return _map[k];
205 }
206
207 bool operator==(const Map_type &other) const { return _map == other._map; }
208 bool operator!=(const Map_type &other) const { return !(*this == other); }
209
210 // prevent default usage of these
211 bool operator<(const Map_type &) const = delete;
212 bool operator>(const Map_type &) const = delete;
213 bool operator<=(const Map_type &) const = delete;
214 bool operator>=(const Map_type &) const = delete;
215
216 bool empty() const { return _map.empty(); }
217 size_t size() const { return _map.size(); }
218 size_t count(const std::string &k) const { return _map.count(k); }
219
220 template <class T>
221 std::pair<iterator, bool> emplace(const std::string &key, T &&v) {
222 return _map.emplace(key, Value(std::forward<T>(v)));
223 }
224
225 private:
227 };
228 typedef std::shared_ptr<Map_type> Map_type_ref;
229
230 public:
231 Value() = default;
232 Value(const Value &) = default;
233 Value(Value &&) noexcept = default;
234 Value &operator=(const Value &) = default;
235 Value &operator=(Value &&) noexcept = default;
236
237 ~Value() noexcept = default;
238
239 explicit Value(const std::string &s, bool binary = false);
240 explicit Value(std::string &&s, bool binary = false);
241 explicit Value(const char *);
242 explicit Value(const char *, size_t n, bool binary = false);
243 explicit Value(std::string_view s, bool binary = false);
244 explicit Value(std::wstring_view s);
245 explicit Value(std::nullptr_t);
246 explicit Value(int i);
247 explicit Value(unsigned int ui);
248 explicit Value(int64_t i);
249 explicit Value(uint64_t ui);
250 explicit Value(float f);
251 explicit Value(double d);
252 explicit Value(bool b);
253 // explicit Value(const std::shared_ptr<Function_base> &f);
254 // explicit Value(std::shared_ptr<Function_base> &&f);
255 explicit Value(const std::shared_ptr<polyglot::Polyglot_object> &o);
256 explicit Value(const std::shared_ptr<polyglot::Object_bridge> &o);
257 // explicit Value(std::shared_ptr<Object_bridge> &&o);
258 explicit Value(const Map_type_ref &n);
259 explicit Value(Map_type_ref &&n);
260 explicit Value(const Array_type_ref &n);
261 explicit Value(Array_type_ref &&n);
262
263 // static Value wrap(Object_bridge *o) {
264 // return Value(std::shared_ptr<Object_bridge>(o));
265 // }
266
267 // template <class T>
268 // static Value wrap(std::shared_ptr<T> o) {
269 // return Value(std::static_pointer_cast<Object_bridge>(std::move(o)));
270 // }
271
272 static Value new_array() {
273 return Value(std::shared_ptr<Array_type>(new Array_type()));
274 }
275 static Value new_map() {
276 return Value(std::shared_ptr<Map_type>(new Map_type()));
277 }
278
279 static Value Null() {
280 Value v;
281 v.m_value = null_value{};
282 return v;
283 }
284
285 static Value True() { return Value{true}; }
286 static Value False() { return Value{false}; }
287
288 //! parse a string returned by repr() back into a Value
289 static Value parse(std::string_view s);
290
291 bool operator==(const Value &other) const;
292 bool operator!=(const Value &other) const { return !(*this == other); }
293
294 // prevent default usage of these
295 bool operator<(const Value &) const = delete;
296 bool operator>(const Value &) const = delete;
297 bool operator<=(const Value &) const = delete;
298 bool operator>=(const Value &) const = delete;
299
300 explicit operator bool() const noexcept {
301 auto type = get_type();
303 }
304
305 bool is_null() const noexcept { return (get_type() == Value_type::Null); }
306
307 // helper used by gtest
308 friend std::ostream &operator<<(std::ostream &os, const Value &v);
309
310 //! returns a human-readable description text for the value.
311 // if pprint is true, it will try to pretty-print it (like adding newlines)
312 std::string descr(bool pprint = false) const;
313
314 //! returns a string representation of the serialized object, suitable to be
315 //! passed to parse()
316 std::string repr() const;
317
318 //! returns a JSON representation of the object
319 std::string json(bool pprint = false) const;
320
321 //! returns a YAML representation of the Value
322 // std::string yaml() const;
323
324 std::string &append_descr(std::string &s_out, int indent = -1,
325 char quote_strings = '\0') const;
326 std::string &append_repr(std::string &s_out) const;
327
328 void check_type(Value_type t) const;
330
331 bool as_bool() const;
332 int64_t as_int() const;
333 uint64_t as_uint() const;
334 double as_double() const;
335 std::string as_string() const;
336 std::wstring as_wstring() const;
337
338 const std::string &get_string() const {
339 check_type(String);
340
341 if (std::holds_alternative<binary_string>(m_value))
342 return std::get<binary_string>(m_value);
343 return std::get<std::string>(m_value);
344 }
345
346 template <class C>
347 std::shared_ptr<C> as_object_bridge() const {
348 check_type(ObjectBridge);
349
350 if (is_null()) return nullptr;
351 return std::dynamic_pointer_cast<C>(
352 std::get<std::shared_ptr<polyglot::Object_bridge>>(m_value));
353 }
354
355 std::shared_ptr<polyglot::Object_bridge> as_object_bridge() const;
356 std::shared_ptr<polyglot::Polyglot_object> as_object() const;
357
358 std::shared_ptr<Map_type> as_map() const {
359 check_type(Map);
360
361 if (is_null()) return nullptr;
362 return std::get<std::shared_ptr<Map_type>>(m_value);
363 }
364
365 std::shared_ptr<Array_type> as_array() const {
366 check_type(Array);
367
368 if (is_null()) return nullptr;
369 return std::get<std::shared_ptr<Array_type>>(m_value);
370 }
371
372 // std::shared_ptr<Function_base> as_function() const {
373 // check_type(Function);
374
375 // if (is_null()) return nullptr;
376 // return std::get<std::shared_ptr<Function_base>>(m_value);
377 // }
378
379 // template <class C>
380 // C to_string_container() const {
381 // C vec;
382 // auto arr = as_array();
383
384 // if (arr) {
385 // std::transform(arr->begin(), arr->end(), std::inserter<C>(vec,
386 // vec.end()),
387 // [](const Value &v) { return v.get_string(); });
388 // }
389
390 // return vec;
391 // }
392
393 // std::map<std::string, std::string> to_string_map() const {
394 // check_type(Map);
395
396 // std::map<std::string, std::string> map;
397 // for (const auto &v : *as_map()) {
398 // map.emplace(v.first, v.second.get_string());
399 // }
400 // return map;
401 // }
402
403 // template <class C>
404 // std::map<std::string, C> to_container_map() const {
405 // check_type(Map);
406
407 // std::map<std::string, C> map;
408 // for (const auto &v : *as_map()) {
409 // map.emplace(v.first, v.second.to_string_container<C>());
410 // }
411 // return map;
412 // }
413
414 private:
415 // std::string yaml(int indent) const;
416
417 private:
418 struct null_value {};
419 struct binary_string : std::string {};
420
421 std::variant < std::monostate, null_value, bool, std::string, binary_string,
422 int64_t, uint64_t, double, std::shared_ptr<polyglot::Polyglot_object>,
423 std::shared_ptr<polyglot::Object_bridge>,
424 std::shared_ptr<Array_type>,
425 std::shared_ptr<Map_type> /*,
426std::shared_ptr<Function_base>*/>
428};
429
430using Argument_list = std::vector<Value>;
433
434Dictionary_t JIT_EXECUTOR_PLUGIN_EXPORT make_dict();
435
436inline Array_t make_array() { return std::make_shared<Value::Array_type>(); }
437
438template <typename... Arg>
439inline Array_t make_array(Arg &&...args) {
440 auto array = make_array();
441 (void)std::initializer_list<int>{
442 (array->emplace_back(std::forward<Arg>(args)), 0)...};
443 return array;
444}
445
446template <template <typename...> class C, typename T>
447inline Array_t make_array(const C<T> &container) {
448 auto array = make_array();
449 for (const auto &item : container) {
450 array->emplace_back(item);
451 }
452 return array;
453}
454
455template <template <typename...> class C, typename T>
457 auto array = make_array();
458 for (auto &item : container) {
459 array->emplace_back(std::move(item));
460 }
461 return array;
462}
463
464} // namespace shcore
465
466#endif // ROUTER_SRC_INCLUDE_MYSQLROUTER_JIT_EXECUTOR_VALUE_H_
Using this class is fraught with peril, and you need to be very careful when doing so.
Definition: sql_string.h:169
Definition: jit_executor_value.h:46
Definition: jit_executor_value.h:135
iterator find(const std::string &k)
Definition: jit_executor_value.h:177
container_type _map
Definition: jit_executor_value.h:226
container_type::iterator iterator
Definition: jit_executor_value.h:139
bool operator<(const Map_type &) const =delete
iterator end()
Definition: jit_executor_value.h:191
iterator begin()
Definition: jit_executor_value.h:185
reverse_iterator rbegin()
Definition: jit_executor_value.h:188
bool has_key(const std::string &k) const
Definition: jit_executor_value.h:144
size_t count(const std::string &k) const
Definition: jit_executor_value.h:218
bool is_null(const std::string &k) const
Definition: jit_executor_value.h:148
bool empty() const
Definition: jit_executor_value.h:216
const container_type::mapped_type & at(const std::string &k) const
Definition: jit_executor_value.h:200
void clear()
Definition: jit_executor_value.h:182
reverse_iterator rend()
Definition: jit_executor_value.h:194
std::map< std::string, Value > container_type
Definition: jit_executor_value.h:137
const_reverse_iterator rbegin() const
Definition: jit_executor_value.h:187
bool operator>=(const Map_type &) const =delete
std::shared_ptr< Value::Array_type > get_array(const std::string &k, std::shared_ptr< Array_type > def=std::shared_ptr< Array_type >()) const
bool operator==(const Map_type &other) const
Definition: jit_executor_value.h:207
container_type::value_type value_type
Definition: jit_executor_value.h:140
size_t erase(const std::string &k)
Definition: jit_executor_value.h:179
const_iterator find(const std::string &k) const
Definition: jit_executor_value.h:176
const_iterator begin() const
Definition: jit_executor_value.h:184
iterator erase(const_iterator it)
Definition: jit_executor_value.h:180
const_reverse_iterator rend() const
Definition: jit_executor_value.h:193
bool operator<=(const Map_type &) const =delete
container_type::const_iterator const_iterator
Definition: jit_executor_value.h:138
container_type::const_reverse_iterator const_reverse_iterator
Definition: jit_executor_value.h:142
void set(const std::string &k, const Value &v)
Definition: jit_executor_value.h:198
iterator erase(iterator it)
Definition: jit_executor_value.h:181
std::shared_ptr< Value::Map_type > get_map(const std::string &k, std::shared_ptr< Map_type > def=std::shared_ptr< Map_type >()) const
bool operator!=(const Map_type &other) const
Definition: jit_executor_value.h:208
container_type::mapped_type & operator[](const std::string &k)
Definition: jit_executor_value.h:203
size_t size() const
Definition: jit_executor_value.h:217
void set(const std::string &k, Value &&v)
Definition: jit_executor_value.h:196
std::pair< iterator, bool > emplace(const std::string &key, T &&v)
Definition: jit_executor_value.h:221
bool operator>(const Map_type &) const =delete
const_iterator end() const
Definition: jit_executor_value.h:190
container_type::reverse_iterator reverse_iterator
Definition: jit_executor_value.h:141
#define T
Definition: jit_executor_value.cc:373
std::string as_string(const char *input_str)
Return a string representation of the input character string.
Definition: cluster_metadata.cc:68
bool operator==(const my_thread_handle &a, const my_thread_handle &b)
Definition: my_thread.h:151
static char * get_string(char **to_ptr, const char **from_ptr, struct st_command *command)
Definition: mysqltest.cc:6454
uint16_t value_type
Definition: vt100.h:184
constexpr value_type binary
Definition: classic_protocol_constants.h:275
Definition: atomics_array.h:39
noexcept
The return type for any call_and_catch(f, args...) call where f(args...) returns Type.
Definition: call_and_catch.h:76
static mysql_service_status_t get(THD **thd) noexcept
Definition: mysql_current_thread_reader_all_empty.cc:31
Container::const_iterator find(const Container &c, Value &&value)
Definition: generic.h:40
bool parse(MYSQL_THD thd, const string &query, bool is_prepared, Condition_handler *handler)
Definition: services.cc:81
bool is_null(poly_thread thread, poly_value value)
Definition: jit_executor_type_conversion.cc:46
Definition: file_system_exceptions.h:34
Value::Array_type_ref Array_t
Definition: jit_executor_value.h:432
Value_type
Basic types that can be passed around code in different languages.
Definition: jit_executor_value.h:54
@ String
true or false
Definition: jit_executor_value.h:58
@ Bool
Null/None value.
Definition: jit_executor_value.h:57
@ Integer
String values, UTF-8 encoding.
Definition: jit_executor_value.h:59
@ ObjectBridge
Polyglot object of any type.
Definition: jit_executor_value.h:66
@ Array
C++ Object.
Definition: jit_executor_value.h:68
@ Float
unsigned 64bit integer numbers
Definition: jit_executor_value.h:61
@ Binary
Dictionary/Map/Object container.
Definition: jit_executor_value.h:72
@ UInteger
64bit integer numbers
Definition: jit_executor_value.h:60
@ Map
Array/List container.
Definition: jit_executor_value.h:69
@ Undefined
Definition: jit_executor_value.h:55
@ Object
double numbers
Definition: jit_executor_value.h:65
@ Null
Undefined.
Definition: jit_executor_value.h:56
bool is_compatible_type(Value_type source_type, Value_type target_type)
Definition: jit_executor_value.cc:1428
Array_t make_array()
Definition: jit_executor_value.h:436
std::vector< Value > Argument_list
Definition: jit_executor_value.h:430
Dictionary_t JIT_EXECUTOR_PLUGIN_EXPORT make_dict()
Definition: jit_executor_value.cc:1968
Value::Map_type_ref Dictionary_t
Definition: jit_executor_value.h:431
Define std::hash<Gtid>.
Definition: gtid.h:355
required string key
Definition: replication_asynchronous_connection_failover.proto:60
repeated Source source
Definition: replication_asynchronous_connection_failover.proto:42
required string type
Definition: replication_group_member_actions.proto:34
Definition: jit_executor_value.h:419
Definition: jit_executor_value.h:418
Pointer to a function that may be implemented in any language.
Definition: jit_executor_value.h:131
std::shared_ptr< Map_type > Map_type_ref
Definition: jit_executor_value.h:228
std::vector< Value > Array_type
Definition: jit_executor_value.h:132
std::variant< std::monostate, null_value, bool, std::string, binary_string, int64_t, uint64_t, double, std::shared_ptr< polyglot::Polyglot_object >, std::shared_ptr< polyglot::Object_bridge >, std::shared_ptr< Array_type >, std::shared_ptr< Map_type > > m_value
Definition: jit_executor_value.h:427
friend std::ostream & operator<<(std::ostream &os, const Value &v)
bool is_null() const noexcept
Definition: jit_executor_value.h:305
std::shared_ptr< Array_type > as_array() const
Definition: jit_executor_value.h:365
static Value True()
Definition: jit_executor_value.h:285
bool operator>(const Value &) const =delete
static Value new_map()
Definition: jit_executor_value.h:275
std::shared_ptr< C > as_object_bridge() const
Definition: jit_executor_value.h:347
bool operator<(const Value &) const =delete
static Value False()
Definition: jit_executor_value.h:286
bool operator!=(const Value &other) const
Definition: jit_executor_value.h:292
static Value Null()
Definition: jit_executor_value.h:279
std::shared_ptr< Map_type > as_map() const
Definition: jit_executor_value.h:358
bool operator>=(const Value &) const =delete
Value(Value &&) noexcept=default
Value()=default
std::shared_ptr< Array_type > Array_type_ref
Definition: jit_executor_value.h:133
bool operator<=(const Value &) const =delete
Value(const Value &)=default
const char * get_type(TYPELIB *typelib, unsigned int nr)
int n
Definition: xcom_base.cc:509