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