MySQL 8.2.0
Source Code Documentation
json_dom.h
Go to the documentation of this file.
1#ifndef JSON_DOM_INCLUDED
2#define JSON_DOM_INCLUDED
3
4/* Copyright (c) 2015, 2023, Oracle and/or its affiliates.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License, version 2.0,
8 as published by the Free Software Foundation.
9
10 This program is also distributed with certain software (including
11 but not limited to OpenSSL) that is licensed under separate terms,
12 as designated in a particular file or component or in included license
13 documentation. The authors of MySQL hereby grant you an additional
14 permission to link the program and your derivative works with the
15 separately licensed software that they have included with MySQL.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License, version 2.0, for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
25
26#include <assert.h>
27#include <stddef.h>
28#include <functional>
29#include <iterator>
30#include <map>
31#include <memory> // unique_ptr
32#include <new>
33#include <string>
34#include <type_traits> // is_base_of
35#include <utility>
36#include <vector>
37
38#include "field_types.h" // enum_field_types
39#include "my_compiler.h"
40
41#include "my_inttypes.h"
42#include "my_time.h" // my_time_flags_t
44#include "mysql_time.h" // MYSQL_TIME
45#include "prealloced_array.h" // Prealloced_array
46#include "sql-common/json_binary.h" // json_binary::Value
47#include "sql-common/my_decimal.h" // my_decimal
48#include "sql/malloc_allocator.h" // Malloc_allocator
49
50class Field_json;
51class Json_array;
52class Json_container;
53class Json_dom;
54class Json_object;
55class Json_path;
57class Json_wrapper;
58class String;
59class THD;
60
61struct CHARSET_INFO;
62
65
66using Json_dom_ptr = std::unique_ptr<Json_dom>;
67using Json_array_ptr = std::unique_ptr<Json_array>;
68using Json_object_ptr = std::unique_ptr<Json_object>;
69
70/**
71 @file
72 JSON DOM.
73
74 When a JSON value is retrieved from a column, a prior it exists in
75 a binary form, cf. Json_binary::Value class.
76
77 However, when we need to manipulate the JSON values we mostly convert them
78 from binary form to a structured in-memory from called DOM (from domain
79 object model) which uses a recursive tree representation of the JSON value
80 corresponding closely to a parse tree. This form is more suitable for
81 manipulation.
82
83 The JSON type is mostly represented internally as a Json_wrapper which hides
84 if the representation is a binary or DOM one. This makes is possible to avoid
85 building a DOM unless we really need one.
86
87 The file defines two sets of classes: a) The Json_dom hierarchy and
88 b) Json_wrapper and its companion classes Json_wrapper_object_iterator and
89 Json_object_wrapper. For both sets, arrays are traversed using an operator[].
90*/
91
92/**
93 Json values in MySQL comprises the stand set of JSON values plus a
94 MySQL specific set. A Json _number_ type is subdivided into _int_,
95 _uint_, _double_ and _decimal_.
96
97 MySQL also adds four built-in date/time values: _date_, _time_,
98 _datetime_ and _timestamp_. An additional _opaque_ value can
99 store any other MySQL type.
100
101 The enumeration is common to Json_dom and Json_wrapper.
102
103 The enumeration is also used by Json_wrapper::compare() to
104 determine the ordering when comparing values of different types,
105 so the order in which the values are defined in the enumeration,
106 is significant. The expected order is null < number < string <
107 object < array < boolean < date < time < datetime/timestamp <
108 opaque.
109*/
110enum class enum_json_type {
111 J_NULL,
112 J_DECIMAL,
113 J_INT,
114 J_UINT,
115 J_DOUBLE,
116 J_STRING,
117 J_OBJECT,
118 J_ARRAY,
119 J_BOOLEAN,
120 J_DATE,
121 J_TIME,
124 J_OPAQUE,
125 J_ERROR
126};
127
128/**
129 Allocate a new Json_dom object and return a std::unique_ptr which points to
130 it.
131
132 @param args the arguments to pass to the constructor
133
134 @tparam T the type of Json_dom to create
135 @tparam Args the type of the arguments to pass to the constructor
136
137 @return a pointer to the allocated object
138*/
139template <typename T, typename... Args>
140inline std::unique_ptr<T> create_dom_ptr(Args &&... args) {
141 return std::unique_ptr<T>(new (std::nothrow) T(std::forward<Args>(args)...));
142}
143
144/**
145 JSON DOM abstract base class.
146
147 MySQL representation of in-memory JSON objects used by the JSON type
148 Supports access, deep cloning, and updates. See also Json_wrapper and
149 json_binary::Value.
150 Uses heap for space allocation for now. FIXME.
151
152 Class hierarchy:
153 <code><pre>
154 Json_dom (abstract)
155 Json_scalar (abstract)
156 Json_string
157 Json_number (abstract)
158 Json_decimal
159 Json_int
160 Json_uint
161 Json_double
162 Json_boolean
163 Json_null
164 Json_datetime
165 Json_opaque
166 Json_container (abstract)
167 Json_object
168 Json_array
169 </pre></code>
170 At the outset, object and array add/insert/append operations takes
171 a clone unless specified in the method, e.g. add_alias hands the
172 responsibility for the passed in object over to the object.
173*/
174class Json_dom {
175 // so that these classes can call set_parent()
176 friend class Json_object;
177 friend class Json_array;
178
179 private:
180 /**
181 Set the parent dom to which this dom is attached.
182
183 @param[in] parent the parent we're being attached to
184 */
186
187 public:
188 virtual ~Json_dom() = default;
189
190 /**
191 Allocate space on the heap for a Json_dom object.
192
193 @return pointer to the allocated memory, or NULL if memory could
194 not be allocated (in which case my_error() will have been called
195 with the appropriate error message)
196 */
197 void *operator new(size_t size, const std::nothrow_t &) noexcept;
198
199 /**
200 Deallocate the space used by a Json_dom object.
201 */
202 void operator delete(void *ptr) noexcept;
203
204 /**
205 Nothrow delete.
206 */
207 void operator delete(void *ptr, const std::nothrow_t &) noexcept;
208
209 /**
210 Get the parent dom to which this dom is attached.
211
212 @return the parent dom.
213 */
214 Json_container *parent() const { return m_parent; }
215
216 /**
217 @return the type corresponding to the actual Json_dom subclass
218 */
219 virtual enum_json_type json_type() const = 0;
220
221 /**
222 @return true if the object is a subclass of Json_scalar
223 */
224 virtual bool is_scalar() const { return false; }
225
226 /**
227 @return true of the object is a subclass of Json_number
228 */
229 virtual bool is_number() const { return false; }
230
231 /**
232 Compute the depth of a document. This is the value which would be
233 returned by the JSON_DEPTH() system function.
234
235 - for scalar values, empty array and empty object: 1
236 - for non-empty array: 1+ max(depth of array elements)
237 - for non-empty objects: 1+ max(depth of object values)
238
239 For example:
240 "abc", [] and {} have depth 1.
241 ["abc", [3]] and {"a": "abc", "b": [3]} have depth 3.
242
243 @return the depth of the document
244 */
245 virtual uint32 depth() const = 0;
246
247 /**
248 Make a deep clone. The ownership of the returned object is
249 henceforth with the caller.
250
251 @return a cloned Json_dom object.
252 */
253 virtual Json_dom_ptr clone() const = 0;
254
255 /**
256 Parse Json text to DOM (using rapidjson). The text must be valid JSON.
257 The results when supplying an invalid document is undefined.
258 The ownership of the returned object is henceforth with the caller.
259
260 If the parsing fails because of a syntax error, the errmsg and
261 offset arguments will be given values that point to a detailed
262 error message and where the syntax error was located. The caller
263 will have to generate an error message with my_error() in this
264 case.
265
266 If the parsing fails because of some other error (such as out of
267 memory), errmsg will point to a location that holds the value
268 NULL. In this case, parse() will already have called my_error(),
269 and the caller doesn't need to generate an error message.
270
271 @param[in] text the JSON text
272 @param[in] length the length of the text
273 @param[out] errmsg any syntax error message (will be ignored if it is NULL)
274 @param[out] offset the position in the parsed string a syntax error was
275 found (will be ignored if it is NULL)
276 @param[in] error_handler Pointer to a function that should handle
277 reporting of parsing error.
278 @param[in] depth_handler Pointer to a function that should handle error
279 occurred when depth is exceeded.
280
281
282 @result the built DOM if JSON text was parseable, else NULL
283 */
284 static Json_dom_ptr parse(const char *text, size_t length,
285 const JsonParseErrorHandler &error_handler,
286 const JsonErrorHandler &depth_handler);
287
288 /**
289 Construct a DOM object based on a binary JSON value. The ownership
290 of the returned object is henceforth with the caller.
291
292 @param thd current session
293 @param v the binary value to parse
294 @return a DOM representation of the binary value, or NULL on error
295 */
296 static Json_dom_ptr parse(const json_binary::Value &v);
297
298 /**
299 Get the path location of this dom, measured from the outermost
300 document it nests inside.
301 */
302 Json_path get_location() const;
303
304 /**
305 Finds all of the json sub-documents which match the path expression.
306 Adds a vector element for each match.
307
308 See the header comment for Json_wrapper.seek() for a discussion
309 of complexities involving path expression with more than one
310 ellipsis (**) token.
311
312 @param[in] path the (possibly wildcarded) address of the sub-documents
313 @param[in] legs the number of legs to use from @a path
314 @param[out] hits one element per match
315 @param[in] auto_wrap
316 if true, match a tailing [0] to scalar at that position.
317 @param[in] only_need_one True if we can stop after finding one match
318 @return false on success, true on error
319 */
320 bool seek(const Json_seekable_path &path, size_t legs, Json_dom_vector *hits,
321 bool auto_wrap, bool only_need_one);
322
323 private:
324 /** Parent pointer */
326};
327
328/**
329 Abstract base class of all JSON container types (Json_object and Json_array).
330*/
331class Json_container : public Json_dom {
332 public:
333 /**
334 Replace oldv contained inside this container array or object) with newv. If
335 this container does not contain oldv, calling the method is a no-op.
336
337 @param[in] oldv the value to be replaced
338 @param[in] newv the new value to put in the container
339 */
340 virtual void replace_dom_in_container(const Json_dom *oldv,
341 Json_dom_ptr newv) = 0;
342};
343
344/**
345 A comparator that is used for ordering keys in a Json_object. It
346 orders the keys on length, and lexicographically if the keys have
347 the same length. The ordering is ascending. This ordering was chosen
348 for speed of look-up. See usage in Json_object_map.
349*/
351 bool operator()(const std::string &key1, const std::string &key2) const;
352 bool operator()(const MYSQL_LEX_CSTRING &key1, const std::string &key2) const;
353 bool operator()(const std::string &key1, const MYSQL_LEX_CSTRING &key2) const;
354 // is_transparent must be defined in order to make std::map::find() accept
355 // keys that are of a different type than the key_type of the map. In
356 // particular, this is needed to make it possible to call find() with
357 // MYSQL_LEX_CSTRING arguments and not only std::string arguments. It only has
358 // to be defined, it doesn't matter which type it is set to.
359 using is_transparent = void;
360};
361
362/**
363 A type used to hold JSON object elements in a map, see the
364 Json_object class.
365*/
369
370/**
371 Represents a JSON container value of type "object" (ECMA), type
372 J_OBJECT here.
373*/
374class Json_object final : public Json_container {
375 private:
376 /**
377 Map to hold the object elements.
378 */
380
381 public:
382 Json_object();
384
385 /**
386 Insert a clone of the value into the object. If the key already
387 exists in the object, the existing value is replaced ("last value
388 wins").
389
390 @param[in] key the JSON element key of to be added
391 @param[in] value a JSON value: the element key's value
392 @retval false on success
393 @retval true on failure
394 */
395 bool add_clone(const std::string &key, const Json_dom *value) {
396 return value == nullptr || add_alias(key, value->clone());
397 }
398
399 /**
400 Insert the value into the object. If the key already exists in the
401 object, the existing value is replaced ("last value wins").
402
403 Ownership of the value is effectively transferred to the
404 object and the value will be deallocated by the object so only add
405 values that can be deallocated safely (no stack variables please!)
406
407 New code should prefer #add_alias(const std::string&, Json_dom_ptr)
408 to this function, because that makes the transfer of ownership
409 more explicit. This function might be removed in the future.
410
411 @param[in] key the JSON key of to be added
412 @param[in] value a JSON value: the key's value
413 @retval false on success
414 @retval true on failure
415 */
416 bool add_alias(const std::string &key, Json_dom *value) {
417 return add_alias(key, Json_dom_ptr(value));
418 }
419
420 /**
421 Insert the value into the object. If the key already exists in the
422 object, the existing value is replaced ("last value wins").
423
424 The ownership of the value is transferred to the object.
425
426 @param[in] key the key of the value to be added
427 @param[in] value the value to add
428 @return false on success, true on failure
429 */
430 bool add_alias(const std::string &key, Json_dom_ptr value);
431
432 /**
433 Transfer all of the key/value pairs in the other object into this
434 object. The other object is deleted. If this object and the other
435 object share a key, then the two values of the key are merged.
436
437 @param [in] other a pointer to the object which will be consumed
438 @retval false on success
439 @retval true on failure
440 */
441 bool consume(Json_object_ptr other);
442
443 /**
444 Return the value at key. The value is not cloned, so make
445 one if you need it. Do not delete the returned value, please!
446 If the key is not present, return a null pointer.
447
448 @param[in] key the key of the element whose value we want
449 @return the value associated with the key, or NULL if the key is not found
450 */
451 Json_dom *get(const std::string &key) const;
452 Json_dom *get(const MYSQL_LEX_CSTRING &key) const;
453
454 /**
455 Remove the child element addressed by key. The removed child is deleted.
456
457 @param key the key of the element to remove
458 @retval true if an element was removed
459 @retval false if there was no element with that key
460 */
461 bool remove(const std::string &key);
462
463 /**
464 @return The number of elements in the JSON object.
465 */
466 size_t cardinality() const;
467
468 uint32 depth() const override;
469
470 Json_dom_ptr clone() const override;
471
472 void replace_dom_in_container(const Json_dom *oldv,
473 Json_dom_ptr newv) override;
474
475 /**
476 Remove all elements in the object.
477 */
478 void clear() { m_map.clear(); }
479
480 /**
481 Constant iterator over the elements in the JSON object. Each
482 element is represented as a std::pair where first is a std::string
483 that represents the key name, and second is a pointer to a
484 Json_dom that represents the value.
485 */
486 typedef Json_object_map::const_iterator const_iterator;
487
488 /// Returns a const_iterator that refers to the first element.
489 const_iterator begin() const { return m_map.begin(); }
490
491 /// Returns a const_iterator that refers past the last element.
492 const_iterator end() const { return m_map.end(); }
493
494 /**
495 Implementation of the MergePatch function specified in RFC 7396:
496
497 define MergePatch(Target, Patch):
498 if Patch is an Object:
499 if Target is not an Object:
500 Target = {} # Ignore the contents and set it to an empty Object
501 for each Key/Value pair in Patch:
502 if Value is null:
503 if Key exists in Target:
504 remove the Key/Value pair from Target
505 else:
506 Target[Key] = MergePatch(Target[Key], Value)
507 return Target
508 else:
509 return Patch
510
511 @param patch the object that describes the patch
512 @retval false on success
513 @retval true on memory allocation error
514 */
515 bool merge_patch(Json_object_ptr patch);
516};
517
518/**
519 Represents a JSON array container, i.e. type J_ARRAY here.
520*/
521class Json_array final : public Json_container {
522 private:
523 /// Holds the array values.
524 std::vector<Json_dom_ptr, Malloc_allocator<Json_dom_ptr>> m_v;
525
526 public:
527 Json_array();
528
530
531 /**
532 Append a clone of the value to the end of the array.
533 @param[in] value a JSON value to be appended
534 @retval false on success
535 @retval true on failure
536 */
537 bool append_clone(const Json_dom *value) {
538 return insert_clone(size(), value);
539 }
540
541 /**
542 Append the value to the end of the array.
543
544 Ownership of the value is effectively transferred to the array and
545 the value will be deallocated by the array so only append values
546 that can be deallocated safely (no stack variables please!)
547
548 New code should prefer #append_alias(Json_dom_ptr) to this
549 function, because that makes the transfer of ownership more
550 explicit. This function might be removed in the future.
551
552 @param[in] value a JSON value to be appended
553 @retval false on success
554 @retval true on failure
555 */
556 bool append_alias(Json_dom *value) {
557 return append_alias(Json_dom_ptr(value));
558 }
559
560 /**
561 Append the value to the end of the array and take over the
562 ownership of the value.
563
564 @param value the JSON value to be appended
565 @return false on success, true on failure
566 */
568 return insert_alias(size(), std::move(value));
569 }
570
571 /**
572 Moves all of the elements in the other array to the end of
573 this array. The other array is deleted.
574
575 @param [in] other a pointer to the array which will be consumed
576 @retval false on success
577 @retval true on failure
578 */
579 bool consume(Json_array_ptr other);
580
581 /**
582 Insert a clone of the value at position index of the array. If beyond the
583 end, insert at the end.
584
585 @param[in] index the position at which to insert
586 @param[in] value a JSON value to be inserted
587 @retval false on success
588 @retval true on failure
589 */
590 bool insert_clone(size_t index, const Json_dom *value) {
591 return value == nullptr || insert_alias(index, value->clone());
592 }
593
594 /**
595 Insert the value at position index of the array.
596 If beyond the end, insert at the end.
597
598 Ownership of the value is effectively transferred to the array and
599 the value will be deallocated by the array so only append values
600 that can be deallocated safely (no stack variables please!)
601
602 @param[in] index the position at which to insert
603 @param[in] value a JSON value to be inserted
604 @retval false on success
605 @retval true on failure
606 */
607 bool insert_alias(size_t index, Json_dom_ptr value);
608
609 /**
610 Remove the value at this index. A no-op if index is larger than
611 size. Deletes the value.
612 @param[in] index the index of the value to remove
613 @return true if a value was removed, false otherwise.
614 */
615 bool remove(size_t index);
616
617 /**
618 The cardinality of the array (number of values).
619 @return the size
620 */
621 size_t size() const { return m_v.size(); }
622
623 uint32 depth() const override;
624
625 Json_dom_ptr clone() const override;
626
627 /**
628 Get the value at position index. The value has not been cloned so
629 it is the responsibility of the user to make a copy if needed. Do
630 not try to deallocate the returned value - it is owned by the array
631 and will be deallocated by it in time. It is admissible to modify
632 its contents (in place; without a clone being taken) if it is a
633 compound.
634
635 @param[in] index the array index
636 @return the value at index
637 */
638 Json_dom *operator[](size_t index) const {
639 assert(m_v[index]->parent() == this);
640 return m_v[index].get();
641 }
642
643 /**
644 Remove the values in the array.
645 */
646 void clear() { m_v.clear(); }
647
648 /// Constant iterator over the elements in the JSON array.
650
651 /// Returns a const_iterator that refers to the first element.
652 const_iterator begin() const { return m_v.begin(); }
653
654 /// Returns a const_iterator that refers past the last element.
655 const_iterator end() const { return m_v.end(); }
656
657 void replace_dom_in_container(const Json_dom *oldv,
658 Json_dom_ptr newv) override;
659
660 /// Sort the array
661 void sort(const CHARSET_INFO *cs = nullptr);
662 /// Sort the array using a user-defined comparator.
663 template <class T>
664 void sort(const T &comparator) {
665 std::sort(m_v.begin(), m_v.end(), comparator);
666 }
667
668 /**
669 Check if the given value appears in the array
670
671 @param val value to look for
672
673 @returns
674 true value is found
675 false otherwise
676 */
677 bool binary_search(Json_dom *val);
678
679 /**
680 Sort array and remove duplicate elements.
681 Used by multi-value index implementation.
682 */
683 void remove_duplicates(const CHARSET_INFO *cs);
684
685 friend Json_dom;
686};
687
688/**
689 Abstract base class for all Json scalars.
690*/
691class Json_scalar : public Json_dom {
692 public:
693 uint32 depth() const final { return 1; }
694
695 bool is_scalar() const final { return true; }
696};
697
698/**
699 Represents a JSON string value (ECMA), of type J_STRING here.
700*/
701class Json_string final : public Json_scalar {
702 private:
703 std::string m_str; //!< holds the string
704 public:
705 /*
706 Construct a Json_string object.
707 @param args any arguments accepted by std::string's constructors
708 */
709 template <typename... Args>
710 explicit Json_string(Args &&... args)
711 : Json_scalar(), m_str(std::forward<Args>(args)...) {}
712
714
715 Json_dom_ptr clone() const override {
716 return create_dom_ptr<Json_string>(m_str);
717 }
718
719 /**
720 Get the reference to the value of the JSON string.
721 @return the string reference
722 */
723 const std::string &value() const { return m_str; }
724
725 /**
726 Get the number of characters in the string.
727 @return the number of characters
728 */
729 size_t size() const { return m_str.size(); }
730};
731
732/**
733 Abstract base class of all JSON number (ECMA) types (subclasses
734 represent MySQL extensions).
735*/
736class Json_number : public Json_scalar {
737 public:
738 bool is_number() const final { return true; }
739};
740
741/**
742 Represents a MySQL decimal number, type J_DECIMAL.
743*/
744class Json_decimal final : public Json_number {
745 private:
746 my_decimal m_dec; //!< holds the decimal number
747
748 public:
750
751 explicit Json_decimal(const my_decimal &value);
752
753 /**
754 Get the number of bytes needed to store this decimal in a Json_opaque.
755 @return the number of bytes.
756 */
757 int binary_size() const;
758
759 /**
760 Get the binary representation of the wrapped my_decimal, so that this
761 value can be stored inside of a Json_opaque.
762
763 @param dest the destination buffer to which the binary representation
764 is written
765 @return false on success, true on error
766 */
767 bool get_binary(char *dest) const;
768
769 enum_json_type json_type() const override {
771 }
772
773 /**
774 Get a pointer to the MySQL decimal held by this object. Ownership
775 is _not_ transferred.
776 @return the decimal
777 */
778 const my_decimal *value() const { return &m_dec; }
779
780 Json_dom_ptr clone() const override {
781 return create_dom_ptr<Json_decimal>(m_dec);
782 }
783
784 /**
785 Convert a binary value produced by get_binary() back to a my_decimal.
786
787 @details
788 This and two next functions help storage engine to deal with
789 decimal value in a serialized JSON document. This function converts
790 serialized value to my_decimal. The later two functions extract the
791 decimal value from serialized JSON, so SE can index it in multi-valued
792 index.
793
794 @param[in] bin decimal value in binary format
795 @param[in] len length of the binary value
796 @param[out] dec my_decimal object to store the value to
797 @return false on success, true on failure
798 */
799 static bool convert_from_binary(const char *bin, size_t len, my_decimal *dec);
800 /**
801 Returns stored DECIMAL binary
802
803 @param bin serialized Json_decimal object
804
805 @returns
806 pointer to the binary decimal value
807
808 @see #convert_from_binary
809 */
810 static const char *get_encoded_binary(const char *bin) {
811 // Skip stored precision and scale
812 return bin + 2;
813 }
814 /**
815 Returns length of stored DECIMAL binary
816
817 @param length length of serialized Json_decimal object
818
819 @returns
820 length of the binary decimal value
821
822 @see #convert_from_binary
823 */
824 static size_t get_encoded_binary_len(size_t length) {
825 // Skip stored precision and scale
826 return length - 2;
827 }
828};
829
830/**
831 Represents a MySQL double JSON scalar (an extension of the ECMA
832 number value), type J_DOUBLE.
833*/
834class Json_double final : public Json_number {
835 private:
836 double m_f; //!< holds the double value
837 public:
838 explicit Json_double(double value) : Json_number(), m_f(value) {}
839
841
842 Json_dom_ptr clone() const override {
843 return create_dom_ptr<Json_double>(m_f);
844 }
845
846 /**
847 Return the double value held by this object.
848 @return the value
849 */
850 double value() const { return m_f; }
851};
852
853/**
854 Represents a MySQL integer (64 bits signed) JSON scalar (an extension
855 of the ECMA number value), type J_INT.
856*/
857class Json_int final : public Json_number {
858 private:
859 longlong m_i; //!< holds the value
860 public:
862
863 enum_json_type json_type() const override { return enum_json_type::J_INT; }
864
865 /**
866 Return the signed int held by this object.
867 @return the value
868 */
869 longlong value() const { return m_i; }
870
871 /**
872 @return true if the number can be held by a 16 bit signed integer
873 */
874 bool is_16bit() const { return INT_MIN16 <= m_i && m_i <= INT_MAX16; }
875
876 /**
877 @return true if the number can be held by a 32 bit signed integer
878 */
879 bool is_32bit() const { return INT_MIN32 <= m_i && m_i <= INT_MAX32; }
880
881 Json_dom_ptr clone() const override { return create_dom_ptr<Json_int>(m_i); }
882};
883
884/**
885 Represents a MySQL integer (64 bits unsigned) JSON scalar (an extension
886 of the ECMA number value), type J_UINT.
887*/
888
889class Json_uint final : public Json_number {
890 private:
891 ulonglong m_i; //!< holds the value
892 public:
894
896
897 /**
898 Return the unsigned int held by this object.
899 @return the value
900 */
901 ulonglong value() const { return m_i; }
902
903 /**
904 @return true if the number can be held by a 16 bit unsigned
905 integer.
906 */
907 bool is_16bit() const { return m_i <= UINT_MAX16; }
908
909 /**
910 @return true if the number can be held by a 32 bit unsigned
911 integer.
912 */
913 bool is_32bit() const { return m_i <= UINT_MAX32; }
914
915 Json_dom_ptr clone() const override { return create_dom_ptr<Json_uint>(m_i); }
916};
917
918/**
919 Represents a JSON null type (ECMA), type J_NULL here.
920*/
921class Json_null final : public Json_scalar {
922 public:
924 Json_dom_ptr clone() const override { return create_dom_ptr<Json_null>(); }
925};
926
927/**
928 Represents a MySQL date/time value (DATE, TIME, DATETIME or
929 TIMESTAMP) - an extension to the ECMA set of JSON scalar types, types
930 J_DATE, J_TIME, J_DATETIME and J_TIMESTAMP respectively. The method
931 field_type identifies which of the four it is.
932*/
933class Json_datetime final : public Json_scalar {
934 private:
935 MYSQL_TIME m_t; //!< holds the date/time value
936 enum_field_types m_field_type; //!< identifies which type of date/time
937
938 public:
939 /**
940 Constructs a object to hold a MySQL date/time value.
941
942 @param[in] t the time/value
943 @param[in] ft the field type: must be one of MYSQL_TYPE_TIME,
944 MYSQL_TYPE_DATE, MYSQL_TYPE_DATETIME or
945 MYSQL_TYPE_TIMESTAMP.
946 */
948 : Json_scalar(), m_t(t), m_field_type(ft) {}
949
950 enum_json_type json_type() const override;
951
952 Json_dom_ptr clone() const override;
953
954 /**
955 Return a pointer the date/time value. Ownership is _not_ transferred.
956 To identify which time time the value represents, use @c field_type.
957 @return the pointer
958 */
959 const MYSQL_TIME *value() const { return &m_t; }
960
961 /**
962 Return what kind of date/time value this object holds.
963 @return One of MYSQL_TYPE_TIME, MYSQL_TYPE_DATE, MYSQL_TYPE_DATETIME
964 or MYSQL_TYPE_TIMESTAMP.
965 */
967
968 /**
969 Convert the datetime to the packed format used when storing
970 datetime values.
971 @param dest the destination buffer to write the packed datetime to
972 (must at least have size PACKED_SIZE)
973 */
974 void to_packed(char *dest) const;
975
976 /**
977 Convert a packed datetime back to a MYSQL_TIME.
978 @param from the buffer to read from (must have at least PACKED_SIZE bytes)
979 @param ft the field type of the value
980 @param to the MYSQL_TIME to write the value to
981 */
982 static void from_packed(const char *from, enum_field_types ft,
983 MYSQL_TIME *to);
984
985#ifdef MYSQL_SERVER
986 /**
987 Convert a packed datetime to key string for indexing by SE
988 @param from the buffer to read from
989 @param ft the field type of the value
990 @param to the destination buffer
991 @param dec value's decimals
992 */
993 static void from_packed_to_key(const char *from, enum_field_types ft,
994 uchar *to, uint8 dec);
995#endif
996
997 /** Datetimes are packed in eight bytes. */
998 static const size_t PACKED_SIZE = 8;
999};
1000
1001/**
1002 Represents a MySQL value opaquely, i.e. the Json DOM can not
1003 serialize or deserialize these values. This should be used to store
1004 values that don't map to the other Json_scalar classes. Using the
1005 "to_string" method on such values (via Json_wrapper) will yield a base
1006 64 encoded string tagged with the MySQL type with this syntax:
1007
1008 "base64:typeXX:<base 64 encoded value>"
1009*/
1010class Json_opaque final : public Json_scalar {
1011 private:
1013 std::string m_val;
1014
1015 public:
1016 /**
1017 An opaque MySQL value.
1018
1019 @param[in] mytype the MySQL type of the value
1020 @param[in] args arguments to construct the binary value to be stored
1021 in the DOM (anything accepted by the std::string
1022 constructors)
1023 @see #enum_field_types
1024 @see Class documentation
1025 */
1026 template <typename... Args>
1027 explicit Json_opaque(enum_field_types mytype, Args &&... args)
1028 : Json_scalar(), m_mytype(mytype), m_val(std::forward<Args>(args)...) {}
1029
1031
1032 /**
1033 @return a pointer to the opaque value. Use #size() to get its size.
1034 */
1035 const char *value() const { return m_val.data(); }
1036
1037 /**
1038 @return the MySQL type of the value
1039 */
1040 enum_field_types type() const { return m_mytype; }
1041 /**
1042 @return the size in bytes of the value
1043 */
1044 size_t size() const { return m_val.size(); }
1045
1046 Json_dom_ptr clone() const override;
1047};
1048
1049/**
1050 Represents a JSON true or false value, type J_BOOLEAN here.
1051*/
1052class Json_boolean final : public Json_scalar {
1053 private:
1054 bool m_v; //!< false or true: represents the eponymous JSON literal
1055 public:
1056 explicit Json_boolean(bool value) : Json_scalar(), m_v(value) {}
1057
1058 enum_json_type json_type() const override {
1060 }
1061
1062 /**
1063 @return false for JSON false, true for JSON true
1064 */
1065 bool value() const { return m_v; }
1066
1067 Json_dom_ptr clone() const override {
1068 return create_dom_ptr<Json_boolean>(m_v);
1069 }
1070};
1071
1072/**
1073 Perform quoting on a JSON string to make an external representation
1074 of it. It wraps double quotes (text quotes) around the string (cptr)
1075 and also performs escaping according to the following table:
1076 <pre>
1077 @verbatim
1078 Common name C-style Original unescaped Transformed to
1079 escape UTF-8 bytes escape sequence
1080 notation in UTF-8 bytes
1081 ---------------------------------------------------------------
1082 quote \" %x22 %x5C %x22
1083 backslash \\ %x5C %x5C %x5C
1084 backspace \b %x08 %x5C %x62
1085 formfeed \f %x0C %x5C %x66
1086 linefeed \n %x0A %x5C %x6E
1087 carriage-return \r %x0D %x5C %x72
1088 tab \t %x09 %x5C %x74
1089 unicode \uXXXX A hex number in the %x5C %x75
1090 range of 00-1F, followed by
1091 except for the ones 4 hex digits
1092 handled above (backspace,
1093 formfeed, linefeed,
1094 carriage-return,
1095 and tab).
1096 ---------------------------------------------------------------
1097 @endverbatim
1098 </pre>
1099
1100 @param[in] cptr pointer to string data
1101 @param[in] length the length of the string
1102 @param[in,out] buf the destination buffer
1103 @retval true on error
1104*/
1105bool double_quote(const char *cptr, size_t length, String *buf);
1106
1107/**
1108 Merge two doms. The right dom is either subsumed into the left dom
1109 or the contents of the right dom are transferred to the left dom
1110 and the right dom is deleted. After calling this function, the
1111 caller should not reference the right dom again. It has been
1112 deleted.
1113
1114 Returns NULL if there is a memory allocation failure. In this case
1115 both doms are deleted.
1116
1117 scalars - If any of the documents that are being merged is a scalar,
1118 each scalar document is autowrapped as a single value array before merging.
1119
1120 arrays - When merging a left array with a right array,
1121 then the result is the left array concatenated
1122 with the right array. For instance, [ 1, 2 ] merged with [ 3, 4 ]
1123 is [ 1, 2, 3, 4 ].
1124
1125 array and object - When merging an array with an object,
1126 the object is autowrapped as an array and then the rule above
1127 is applied. So [ 1, 2 ] merged with { "a" : true }
1128 is [ 1, 2, { "a": true } ].
1129
1130 objects - When merging two objects, the two objects are concatenated
1131 into a single, larger object. So { "a" : "foo" } merged with { "b" : 5 }
1132 is { "a" : "foo", "b" : 5 }.
1133
1134 duplicates - When two objects are merged and they share a key,
1135 the values associated with the shared key are merged.
1136
1137 @param [in,out] left The recipient dom.
1138 @param [in,out] right The dom to be consumed
1139
1140 @return A composite dom which subsumes the left and right doms, or NULL
1141 if a failure happened while merging
1142*/
1144
1145/**
1146 How Json_wrapper would handle coercion error
1147*/
1148
1150 CE_WARNING, // Throw a warning, default
1151 CE_ERROR, // Throw an error
1152 CE_IGNORE // Let the caller handle the error
1154
1155/**
1156 Abstraction for accessing JSON values irrespective of whether they
1157 are (started out as) binary JSON values or JSON DOM values. The
1158 purpose of this is to allow uniform access for callers. It allows us
1159 to access binary JSON values without necessarily building a DOM (and
1160 thus having to read the entire value unless necessary, e.g. for
1161 accessing only a single array slot or object field).
1162
1163 Instances of this class are usually created on the stack. In some
1164 cases instances are cached in an Item and reused, in which case they
1165 are allocated from query-duration memory (by allocating them on a
1166 MEM_ROOT).
1167*/
1169 private:
1170 /*
1171 A Json_wrapper wraps either a Json_dom or a json_binary::Value,
1172 never both at the same time.
1173 */
1174 union {
1175 /// The DOM representation, only used if m_is_dom is true.
1176 struct {
1178 /// If true, don't deallocate m_dom_value in destructor.
1181 /// The binary representation, only used if m_is_dom is false.
1183 };
1184 bool m_is_dom; //!< Wraps a DOM iff true
1185 public:
1186 /**
1187 Get the wrapped datetime value in the packed format.
1188
1189 @param[in,out] buffer a char buffer with space for at least
1190 Json_datetime::PACKED_SIZE characters
1191 @return a char buffer that contains the packed representation of the
1192 datetime (may or may not be the same as buffer)
1193 */
1194 const char *get_datetime_packed(char *buffer) const;
1195
1196 /**
1197 Create an empty wrapper. Cf #empty().
1198 */
1199 Json_wrapper() : m_dom{nullptr, true}, m_is_dom(true) {}
1200
1201 /**
1202 Wrap the supplied DOM value (no copy taken). The wrapper takes
1203 ownership, unless alias is true or @c set_alias is called after
1204 construction.
1205 In the latter case the lifetime of the DOM is determined by
1206 the owner of the DOM, so clients need to ensure that that
1207 lifetime is sufficient, lest dead storage is attempted accessed.
1208
1209 @param[in,out] dom_value the DOM value
1210 @param alias Whether the wrapper is an alias to DOM
1211 */
1212 explicit Json_wrapper(Json_dom *dom_value, bool alias = false);
1213
1214 /**
1215 Wrap the supplied DOM value. The wrapper takes over the ownership.
1216 */
1217 explicit Json_wrapper(Json_dom_ptr dom_value)
1218 : Json_wrapper(dom_value.release()) {}
1219
1220 /**
1221 Only meaningful iff the wrapper encapsulates a DOM. Marks the
1222 wrapper as not owning the DOM object, i.e. it will not be
1223 deallocated in the wrapper's destructor. Useful if one wants a wrapper
1224 around a DOM owned by someone else.
1225 */
1226 void set_alias() { m_dom.m_alias = true; }
1227
1228 /**
1229 Wrap a binary value. Does not copy the underlying buffer, so
1230 lifetime is limited the that of the supplied value.
1231
1232 @param[in] value the binary value
1233 */
1234 explicit Json_wrapper(const json_binary::Value &value);
1235
1236 /**
1237 Copy constructor. Does a deep copy of any owned DOM. If a DOM
1238 os not owned (aliased), the copy will also be aliased.
1239 */
1240 Json_wrapper(const Json_wrapper &old);
1241
1242 /**
1243 Move constructor. Take over the ownership of the other wrapper's
1244 DOM, unless it's aliased. If the other wrapper is aliased, this
1245 wrapper becomes an alias too. Any already owned DOM will be
1246 deallocated.
1247
1248 @param old the wrapper whose contents to take over
1249 */
1250 Json_wrapper(Json_wrapper &&old) noexcept;
1251
1252 /**
1253 Assignment operator. Does a deep copy of any owned DOM. If a DOM
1254 os not owned (aliased), the copy will also be aliased. Any owned
1255 DOM in the left side will be deallocated.
1256 */
1257 Json_wrapper &operator=(const Json_wrapper &old);
1258
1259 /**
1260 Move-assignment operator. Take over the ownership of the other
1261 wrapper's DOM, unless it's aliased. If the other wrapper is
1262 aliased, this wrapper becomes an alias too. Any already owned DOM
1263 will be deallocated.
1264
1265 @param old the wrapper whose contents to take over
1266 */
1267 Json_wrapper &operator=(Json_wrapper &&old) noexcept;
1268
1269 ~Json_wrapper();
1270
1271 /**
1272 A Wrapper is defined to be empty if it is passed a NULL value with the
1273 constructor for JSON dom, or if the default constructor is used.
1274
1275 @return true if the wrapper is empty.
1276 */
1277 bool empty() const { return m_is_dom && !m_dom.m_value; }
1278
1279 /**
1280 Does this wrapper contain a DOM?
1281
1282 @retval true if the wrapper contains a DOM representation
1283 @retval false if the wrapper contains a binary representation
1284 */
1285 bool is_dom() const { return m_is_dom; }
1286
1287 /**
1288 Get the wrapped contents in DOM form. The DOM is (still) owned by the
1289 wrapper. If this wrapper originally held a value, it is now converted
1290 to hold (and eventually release) the DOM version.
1291
1292 @return pointer to a DOM object, or NULL if the DOM could not be allocated
1293 */
1294 Json_dom *to_dom();
1295
1296 /**
1297 Gets a pointer to the wrapped Json_dom object, if this wrapper holds a DOM.
1298 If is_dom() returns false, the result of calling this function is undefined.
1299 */
1300 const Json_dom *get_dom() const {
1301 assert(m_is_dom);
1302 return m_dom.m_value;
1303 }
1304
1305 /**
1306 Gets the wrapped json_binary::Value object, if this wrapper holds a binary
1307 JSON value. If is_dom() returns true, the result of calling this function is
1308 undefined.
1309 */
1311 assert(!m_is_dom);
1312 return m_value;
1313 }
1314
1315 /**
1316 Get the wrapped contents in DOM form. Same as to_dom(), except it returns
1317 a clone of the original DOM instead of the actual, internal DOM tree.
1318
1319 @return pointer to a DOM object, or NULL if the DOM could not be allocated
1320 */
1321 Json_dom_ptr clone_dom() const;
1322
1323 /**
1324 Get the wrapped contents in binary value form.
1325
1326 @param[in,out] str a string that will be filled with the binary value
1327 @param json_depth_handler handler which will be called for JSON documents
1328 exceeding the maximum allowed depth
1329 @param json_key_handler handler which will be called for JSON documents
1330 having keys too large
1331 @param json_value_handler handler which will be called for JSON documents
1332 having values too large
1333 @param invalid_json_handler handler which will be called for invalid
1334 JSON documents
1335
1336 @retval false on success
1337 @retval true on error
1338 */
1339 bool to_binary(String *str, const JsonErrorHandler &json_depth_handler,
1340 const JsonErrorHandler &json_key_handler,
1341 const JsonErrorHandler &json_value_handler,
1342 const JsonErrorHandler &invalid_json_handler) const;
1343
1344 /**
1345 Check if the wrapped JSON document is a binary value (a
1346 json_binary::Value), and if that binary is pointing to data stored in the
1347 given string.
1348
1349 This function can be used to check if overwriting the data in the string
1350 might overwrite and corrupt the document contained in this wrapper.
1351
1352 @param str a string which contains JSON binary data
1353 @retval true if the string contains data that the wrapped document
1354 points to from its json_binary::Value representation
1355 @retval false otherwise
1356 */
1357 bool is_binary_backed_by(const String *str) const {
1358 return !m_is_dom && m_value.is_backed_by(str);
1359 }
1360
1361 /**
1362 Format the JSON value to an external JSON string in buffer in
1363 the format of ISO/IEC 10646.
1364
1365 @param[in,out] buffer the formatted string is appended, so make sure
1366 the length is set correctly before calling
1367 @param[in] json_quoted if the JSON value is a string and json_quoted
1368 is false, don't perform quoting on the string.
1369 This is only used by JSON_UNQUOTE.
1370 @param[in] func_name The name of the function that called to_string().
1371
1372 @return false formatting went well, else true
1373 */
1374 bool to_string(String *buffer, bool json_quoted, const char *func_name,
1375 const JsonErrorHandler &depth_handler) const;
1376
1377 /**
1378 Print this JSON document to the debug trace.
1379
1380 @param[in] message If given, the JSON document is prefixed with
1381 this message.
1382 */
1383 void dbug_print(const char *message,
1384 const JsonErrorHandler &depth_handler) const;
1385
1386 /**
1387 Format the JSON value to an external JSON string in buffer in the format of
1388 ISO/IEC 10646. Add newlines and indentation for readability.
1389
1390 @param[in,out] buffer the buffer that receives the formatted string
1391 (the string is appended, so make sure the length
1392 is set correctly before calling)
1393 @param[in] func_name the name of the calling function
1394
1395 @retval false on success
1396 @retval true on error
1397 */
1398 bool to_pretty_string(String *buffer, const char *func_name,
1399 const JsonErrorHandler &depth_handler) const;
1400
1401 // Accessors
1402
1403 /**
1404 Return the type of the wrapped JSON value
1405
1406 @return the type, or Json_dom::J_ERROR if the wrapper does not contain
1407 a JSON value
1408 */
1409 enum_json_type type() const;
1410
1411 /**
1412 Return the MYSQL type of the opaque value, see #type(). Valid for
1413 J_OPAQUE. Calling this method if the type is not J_OPAQUE will give
1414 undefined results.
1415
1416 @return the type
1417 */
1419
1420 /**
1421 If this wrapper holds a JSON array, get an array value by indexing
1422 into the array. Valid for J_ARRAY. Calling this method if the type is
1423 not J_ARRAY will give undefined results.
1424
1425 @return the array value
1426 */
1427 Json_wrapper operator[](size_t index) const;
1428
1429 /**
1430 If this wrapper holds a JSON object, get the value corresponding
1431 to the member key. Valid for J_OBJECT. Calling this method if the type is
1432 not J_OBJECT will give undefined results.
1433
1434 @param[in] key name for identifying member
1435
1436 @return The member value. If there is no member with the specified
1437 name, a value with type Json_dom::J_ERROR is returned.
1438 */
1440
1441 /**
1442 Get a pointer to the data of a JSON string or JSON opaque value.
1443 The data is still owner by the wrapper. The data may not be null
1444 terminated, so use in conjunction with @c get_data_length.
1445 Valid for J_STRING and J_OPAQUE. Calling this method if the type is
1446 not one of those will give undefined results.
1447
1448 @return the pointer
1449 */
1450 const char *get_data() const;
1451
1452 /**
1453 Get the length to the data of a JSON string or JSON opaque value.
1454 Valid for J_STRING and J_OPAQUE. Calling this method if the type is
1455 not one of those will give undefined results.
1456
1457 @return the length
1458 */
1459 size_t get_data_length() const;
1460
1461 /**
1462 Get the MySQL representation of a JSON decimal value.
1463 Valid for J_DECIMAL. Calling this method if the type is
1464 not J_DECIMAL will give undefined results.
1465
1466 @param[out] d the decimal value
1467 @return false on success, true on failure (which would indicate an
1468 internal error)
1469 */
1470 bool get_decimal_data(my_decimal *d) const;
1471
1472 /**
1473 Get the value of a JSON double number.
1474 Valid for J_DOUBLE. Calling this method if the type is
1475 not J_DOUBLE will give undefined results.
1476
1477 @return the value
1478 */
1479 double get_double() const;
1480
1481 /**
1482 Get the value of a JSON signed integer number.
1483 Valid for J_INT. Calling this method if the type is
1484 not J_INT will give undefined results.
1485
1486 @return the value
1487 */
1488 longlong get_int() const;
1489
1490 /**
1491 Get the value of a JSON unsigned integer number.
1492 Valid for J_UINT. Calling this method if the type is
1493 not J_UINT will give undefined results.
1494
1495 @return the value
1496 */
1497 ulonglong get_uint() const;
1498
1499 /**
1500 Get the value of a JSON date/time value. Valid for J_TIME,
1501 J_DATETIME, J_DATE and J_TIMESTAMP. Calling this method if the type
1502 is not one of those will give undefined results.
1503
1504 @param[out] t the date/time value
1505 */
1506 void get_datetime(MYSQL_TIME *t) const;
1507
1508 /**
1509 Get a boolean value (a JSON true or false literal).
1510 Valid for J_BOOLEAN. Calling this method if the type is
1511 not J_BOOLEAN will give undefined results.
1512
1513 @return the value
1514 */
1515 bool get_boolean() const;
1516
1517 /**
1518 Finds all of the json sub-documents which match the path expression.
1519 Puts the matches on an evolving vector of results.
1520 This is a bit inefficient for binary wrappers because you can't
1521 build up a binary array incrementally from its cells. Instead, you
1522 have to turn each cell into a dom and then add the doms to a
1523 dom array.
1524
1525 Calling this if #empty() returns true is an error.
1526
1527 Special care must be taken when the path expression contains more than one
1528 ellipsis (**) token. That is because multiple paths with ellipses may
1529 identify the same value. Consider the following document:
1530
1531 { "a": { "x" : { "b": { "y": { "b": { "z": { "c": 100 } } } } } } }
1532
1533 The innermost value (the number 100) has the following unique,
1534 non-wildcarded address:
1535
1536 $.a.x.b.y.b.z.c
1537
1538 That location is reached by both of the following paths which include
1539 the ellipsis token:
1540
1541 $.a.x.b**.c
1542 $.a.x.b.y.b**.c
1543
1544 And those addresses both satisfy the following path expression which has
1545 two ellipses:
1546
1547 $.a**.b**.c
1548
1549 In this case, we only want to return one instance of $.a.x.b.y.b.z.c
1550
1551 Similarly, special care must be taken if an auto-wrapping array
1552 path leg follows an ellipsis. Consider the following document:
1553
1554 { "a": { "b" : [ 1, 2, 3 ] } }
1555
1556 The first element of the array (the number 1) can be reached with
1557 either of these two non-wildcarded addresses, due to array auto-wrapping:
1558
1559 $.a.b[0]
1560 $.a.b[0][0]
1561
1562 Both of those addresses match the following path expression, which
1563 has an ellipsis followed by an auto-wrapping path leg:
1564
1565 $**[0]
1566
1567 @param[in] path the (possibly wildcarded) address of the sub-documents
1568 @param[in] legs the number of legs to use from @a path
1569 @param[out] hits the result of the search
1570 @param[in] auto_wrap true of we match a final scalar with search for [0]
1571 @param[in] only_need_one True if we can stop after finding one match
1572
1573 @retval false on success
1574 @retval true on error
1575 */
1576 bool seek(const Json_seekable_path &path, size_t legs,
1577 Json_wrapper_vector *hits, bool auto_wrap, bool only_need_one);
1578
1579 /**
1580 Compute the length of a document. This is the value which would be
1581 returned by the JSON_LENGTH() system function. So, this returns
1582
1583 - for scalar values: 1
1584 - for objects: the number of members
1585 - for arrays: the number of cells
1586
1587 @returns 1, the number of members, or the number of cells
1588 */
1589 size_t length() const;
1590
1591 /**
1592 Compare this JSON value to another JSON value.
1593 @param[in] other the other JSON value
1594 @param[in] cs if given, this charset will be used in comparison of
1595 string values
1596 @retval -1 if this JSON value is less than the other JSON value
1597 @retval 0 if the two JSON values are equal
1598 @retval 1 if this JSON value is greater than the other JSON value
1599 */
1600 int compare(const Json_wrapper &other,
1601 const CHARSET_INFO *cs = nullptr) const;
1602
1603 /**
1604 Extract an int (signed or unsigned) from the JSON if possible
1605 coercing if need be.
1606 @param[in] msgnam to use in error message if conversion failed
1607 @param[in] cr_error Whether to raise an error or warning on
1608 data truncation
1609 @param[out] err true <=> error occur during coercion
1610 @param[out] unsigned_flag Whether the value read from JSON data is
1611 unsigned
1612
1613 @returns json value coerced to int
1614 */
1615 longlong coerce_int(const char *msgnam, enum_coercion_error cr_error,
1616 bool *err, bool *unsigned_flag) const;
1617
1618 /// Shorthand for coerce_int(msgnam, CE_WARNING, nullptr, nullptr).
1619 longlong coerce_int(const char *msgnam) const {
1620 return coerce_int(msgnam, CE_WARNING, nullptr, nullptr);
1621 }
1622
1623 /**
1624 Extract a real from the JSON if possible, coercing if need be.
1625
1626 @param[in] msgnam to use in error message if conversion failed
1627 @param[in] cr_error Whether to raise an error or warning on
1628 data truncation
1629 @param[out] err true <=> error occur during coercion
1630 @returns json value coerced to real
1631 */
1632 double coerce_real(const char *msgnam, enum_coercion_error cr_error,
1633 bool *err) const;
1634
1635 /// Shorthand for coerce_real(msgnam, CE_WARNING, nullptr).
1636 double coerce_real(const char *msgnam) const {
1637 return coerce_real(msgnam, CE_WARNING, nullptr);
1638 }
1639
1640 /**
1641 Extract a decimal from the JSON if possible, coercing if need be.
1642
1643 @param[in,out] decimal_value a value buffer
1644 @param[in] msgnam to use in error message if conversion failed
1645 @param[in] cr_error Whether to raise an error or warning on
1646 data truncation
1647 @param[out] err true <=> error occur during coercion
1648 @returns json value coerced to decimal
1649 */
1650 my_decimal *coerce_decimal(my_decimal *decimal_value, const char *msgnam,
1651 enum_coercion_error cr_error, bool *err) const;
1652
1653 /// Shorthand for coerce_decimal(decimal_value, msgnam, CE_WARNING, nullptr).
1654 my_decimal *coerce_decimal(my_decimal *decimal_value, const char *msgnam) {
1655 return coerce_decimal(decimal_value, msgnam, CE_WARNING, nullptr);
1656 }
1657
1658 /**
1659 Extract a date from the JSON if possible, coercing if need be.
1660
1661 @param[in,out] ltime a value buffer
1662 @param msgnam to use in error message if conversion failed
1663 @param[in] cr_error Whether to raise an error or warning on
1664 data truncation
1665 @param[in] date_flags_arg Flags to use for string -> date conversion
1666 @returns json value coerced to date
1667 */
1668 bool coerce_date(MYSQL_TIME *ltime, const char *msgnam,
1670 my_time_flags_t date_flags_arg = 0) const;
1671
1672 /**
1673 Extract a time value from the JSON if possible, coercing if need be.
1674
1675 @param[in,out] ltime a value buffer
1676 @param msgnam to use in error message if conversion failed
1677 @param[in] cr_error Whether to raise an error or warning on
1678 data truncation
1679
1680 @returns json value coerced to time
1681 */
1682 bool coerce_time(MYSQL_TIME *ltime, const char *msgnam,
1683 enum_coercion_error cr_error = CE_WARNING) const;
1684
1685 /**
1686 Make a sort key that can be used by filesort to order JSON values.
1687
1688 @param[out] to a buffer to which the sort key is written
1689 @param[in] length the length of the sort key
1690
1691 @details Key storage format is following:
1692 @verbatim
1693 |<json type>< sort key >|
1694 1 byte / variable length /
1695 @endverbatim
1696
1697 JSON is assumed to be non-sql-null and valid (checked by caller).
1698 Key length contains full length - the len prefix itself, json type and the
1699 sort key.
1700 All numeric types are stored as a number, without distinction to
1701 double/decimal/int/etc. See @c make_json_numeric_sort_key().
1702 Same is done to DATETIME and TIMESTAMP types.
1703 For string and opaque types only the prefix that fits into the output buffer
1704 is stored.
1705 For JSON objects and arrays only their length (number of elements) is
1706 stored, this is a limitation of current implementation.
1707 */
1708 size_t make_sort_key(uchar *to, size_t length) const;
1709
1710 /**
1711 Make a hash key that can be used by sql_executor.cc/unique_hash
1712 in order to support SELECT DISTINCT
1713
1714 @param[in] hash_val An initial hash value.
1715 */
1716 ulonglong make_hash_key(ulonglong hash_val) const;
1717
1718 /**
1719 Calculate the amount of unused space inside a JSON binary value.
1720
1721 @param[out] space the amount of unused space, or zero if this is a DOM
1722 @return false on success
1723 @return true if the JSON binary value was invalid
1724 */
1725 bool get_free_space(size_t *space) const;
1726
1727 /**
1728 Attempt a binary partial update by replacing the value at @a path with @a
1729 new_value. On successful completion, the updated document will be available
1730 in @a result, and this Json_wrapper will point to @a result instead of the
1731 original binary representation. The modifications that have been applied,
1732 will also be collected as binary diffs, which can be retrieved via
1733 TABLE::get_binary_diffs().
1734
1735 @param field the column being updated
1736 @param path the path of the value to update
1737 @param new_value the new value
1738 @param replace true if we use JSON_REPLACE semantics
1739 @param[in,out] result buffer that holds the updated JSON document (is
1740 empty if no partial update has been performed on
1741 this Json_wrapper so far, or contains the binary
1742 representation of the document in this wrapper
1743 otherwise)
1744 @param[out] partially_updated gets set to true if partial update was
1745 successful, also if it was a no-op
1746 @param[out] replaced_path gets set to true if the path was replaced,
1747 will be false if this update is a no-op
1748
1749 @retval false if the update was successful, or if it was determined
1750 that a full update was needed
1751 @retval true if an error occurred
1752 */
1753 bool attempt_binary_update(const Field_json *field,
1754 const Json_seekable_path &path,
1755 Json_wrapper *new_value, bool replace,
1756 String *result, bool *partially_updated,
1757 bool *replaced_path);
1758
1759 /**
1760 Remove a path from a binary JSON document. On successful completion, the
1761 updated document will be available in @a result, and this Json_wrapper will
1762 point to @a result instead of the original binary representation. The
1763 modifications that have been applied, will also be collected as binary
1764 diffs, which can be retrieved via TABLE::get_binary_diffs().
1765
1766 @param field the column being updated
1767 @param path the path to remove from the document
1768 @param[in,out] result buffer that holds the updated JSON document (is
1769 empty if no partial update has been performed on
1770 this Json_wrapper so far, or contains the binary
1771 representation of the document in this wrapper
1772 otherwise)
1773 @param[out] found_path gets set to true if the path is found in the
1774 document, false otherwise
1775
1776 @retval false if the value was successfully updated
1777 @retval true if an error occurred
1778 */
1779 bool binary_remove(const Field_json *field, const Json_seekable_path &path,
1780 String *result, bool *found_path);
1781#ifdef MYSQL_SERVER
1782 /**
1783 Sort contents. Applicable to JSON arrays only.
1784 */
1785 void sort(const CHARSET_INFO *cs = nullptr);
1786 /**
1787 Remove duplicate values. Applicable to JSON arrays only, array will be
1788 sorted.
1789 */
1790 void remove_duplicates(const CHARSET_INFO *cs = nullptr);
1791#endif
1792};
1793
1794/**
1795 Class that iterates over all members of a JSON object that is wrapped in a
1796 Json_wrapper instance.
1797*/
1799 public:
1800 // Type aliases required by ForwardIterator.
1801 using value_type = std::pair<MYSQL_LEX_CSTRING, Json_wrapper>;
1802 using reference = const value_type &;
1803 using pointer = const value_type *;
1804 using difference_type = ptrdiff_t;
1805 using iterator_category = std::forward_iterator_tag;
1806
1807 /**
1808 Creates an iterator that iterates over all members of the given
1809 Json_wrapper, if it wraps a JSON object. If the wrapper does not wrap a JSON
1810 object, the result is undefined.
1811
1812 @param wrapper the Json_wrapper to iterate over
1813 @param begin true to construct an iterator that points to the first member
1814 of the object, false to construct a past-the-end iterator
1815 */
1816 Json_wrapper_object_iterator(const Json_wrapper &wrapper, bool begin);
1817
1818 /// Forward iterators must be default constructible.
1820
1821 /// Advances the iterator to the next element.
1823 if (is_dom())
1824 ++m_iter;
1825 else
1828 return *this;
1829 }
1830
1831 /**
1832 Advances the iterator to the next element and returns an iterator that
1833 points to the current element (post-increment operator).
1834 */
1837 ++(*this);
1838 return copy;
1839 }
1840
1841 /// Checks two iterators for equality.
1842 bool operator==(const Json_wrapper_object_iterator &other) const {
1843 return is_dom() ? m_iter == other.m_iter
1845 }
1846
1847 /// Checks two iterators for inequality.
1848 bool operator!=(const Json_wrapper_object_iterator &other) const {
1849 return !(*this == other);
1850 }
1851
1854 return &m_current_member;
1855 }
1856
1857 reference operator*() { return *this->operator->(); }
1858
1859 private:
1860 /// Pair holding the key and value of the member pointed to by the iterator.
1862 /// True if #m_current_member is initialized.
1864 /// The binary JSON object being iterated over, or nullptr for DOMs.
1866 /// The index of the current member in the binary JSON object.
1868 /// Iterator pointing to the current member in the JSON DOM object.
1870 /// Returns true if iterating over a DOM.
1871 bool is_dom() const { return m_binary_value == nullptr; }
1872 /// Fill #m_current_member with the key and value of the current member.
1874};
1875
1876/**
1877 A wrapper over a JSON object which provides an interface that can be iterated
1878 over with a for-each loop.
1879*/
1881 public:
1883 explicit Json_object_wrapper(const Json_wrapper &wrapper)
1884 : m_wrapper(wrapper) {}
1886 const_iterator cend() const { return const_iterator(m_wrapper, false); }
1887 const_iterator begin() const { return cbegin(); }
1888 const_iterator end() const { return cend(); }
1889
1890 private:
1892};
1893
1894/**
1895 Check if a string contains valid JSON text, without generating a
1896 Json_dom representation of the document.
1897
1898 @param[in] text pointer to the beginning of the string
1899 @param[in] length the length of the string
1900 @return true if the string is valid JSON text, false otherwise
1901*/
1902bool is_valid_json_syntax(const char *text, size_t length);
1903
1904/**
1905 A class that is capable of holding objects of any sub-type of
1906 Json_scalar. Used for pre-allocating space in query-duration memory
1907 for JSON scalars that are to be returned by get_json_atom_wrapper().
1908
1909 This class should be replaced by std::variant when moving to C++17.
1910*/
1912 /// Union of all concrete subclasses of Json_scalar.
1923 /// Constructor which initializes the union to hold a Json_null value.
1925 /// Destructor which delegates to Json_scalar's virtual destructor.
1927 // All members have the same address, and all members are sub-types of
1928 // Json_scalar, so we can take the address of an arbitrary member and
1929 // convert it to Json_scalar.
1930 Json_scalar *scalar = &m_null;
1931 scalar->~Json_scalar();
1932 }
1933 };
1934
1935 /// The buffer in which the Json_scalar value is stored.
1937
1938 /// Pointer to the held scalar, or nullptr if no value is held.
1940
1941 public:
1942 /// Get a pointer to the held object, or nullptr if there is none.
1944
1945 /**
1946 Construct a new Json_scalar value in this Json_scalar_holder.
1947 If a value is already held, the old value is destroyed and replaced.
1948 @tparam T which type of Json_scalar to create
1949 @param args the arguments to T's constructor
1950 */
1951 template <typename T, typename... Args>
1952 void emplace(Args &&... args) {
1953 static_assert(std::is_base_of<Json_scalar, T>::value, "Not a Json_scalar");
1954 static_assert(sizeof(T) <= sizeof(m_buffer), "Buffer is too small");
1956 m_scalar_ptr->~Json_scalar();
1957 ::new (m_scalar_ptr) T(std::forward<Args>(args)...);
1958 }
1959};
1960
1961#endif /* JSON_DOM_INCLUDED */
Kerberos Client Authentication nullptr
Definition: auth_kerberos_client_plugin.cc:250
A field that stores a JSON value.
Definition: field.h:3992
Represents a JSON array container, i.e.
Definition: json_dom.h:521
void sort(const CHARSET_INFO *cs=nullptr)
Sort the array.
Definition: json_dom.cc:1072
Json_dom * operator[](size_t index) const
Get the value at position index.
Definition: json_dom.h:638
Json_array()
Definition: json_dom.cc:970
bool binary_search(Json_dom *val)
Check if the given value appears in the array.
Definition: json_dom.cc:1081
bool remove(size_t index)
Remove the value at this index.
Definition: json_dom.cc:994
const_iterator end() const
Returns a const_iterator that refers past the last element.
Definition: json_dom.h:655
decltype(m_v)::const_iterator const_iterator
Constant iterator over the elements in the JSON array.
Definition: json_dom.h:649
bool append_alias(Json_dom_ptr value)
Append the value to the end of the array and take over the ownership of the value.
Definition: json_dom.h:567
void replace_dom_in_container(const Json_dom *oldv, Json_dom_ptr newv) override
Replace oldv contained inside this container array or object) with newv.
Definition: json_dom.cc:761
bool consume(Json_array_ptr other)
Moves all of the elements in the other array to the end of this array.
Definition: json_dom.cc:972
bool insert_alias(size_t index, Json_dom_ptr value)
Insert the value at position index of the array.
Definition: json_dom.cc:982
Json_dom_ptr clone() const override
Make a deep clone.
Definition: json_dom.cc:1012
void clear()
Remove the values in the array.
Definition: json_dom.h:646
void sort(const T &comparator)
Sort the array using a user-defined comparator.
Definition: json_dom.h:664
size_t size() const
The cardinality of the array (number of values).
Definition: json_dom.h:621
std::vector< Json_dom_ptr, Malloc_allocator< Json_dom_ptr > > m_v
Holds the array values.
Definition: json_dom.h:524
void remove_duplicates(const CHARSET_INFO *cs)
Sort array and remove duplicate elements.
Definition: json_dom.cc:1076
bool append_alias(Json_dom *value)
Append the value to the end of the array.
Definition: json_dom.h:556
friend Json_dom
Definition: json_dom.h:685
bool insert_clone(size_t index, const Json_dom *value)
Insert a clone of the value at position index of the array.
Definition: json_dom.h:590
uint32 depth() const override
Compute the depth of a document.
Definition: json_dom.cc:1003
const_iterator begin() const
Returns a const_iterator that refers to the first element.
Definition: json_dom.h:652
bool append_clone(const Json_dom *value)
Append a clone of the value to the end of the array.
Definition: json_dom.h:537
enum_json_type json_type() const override
Definition: json_dom.h:529
Represents a JSON true or false value, type J_BOOLEAN here.
Definition: json_dom.h:1052
bool value() const
Definition: json_dom.h:1065
enum_json_type json_type() const override
Definition: json_dom.h:1058
Json_boolean(bool value)
Definition: json_dom.h:1056
Json_dom_ptr clone() const override
Make a deep clone.
Definition: json_dom.h:1067
bool m_v
false or true: represents the eponymous JSON literal
Definition: json_dom.h:1054
Abstract base class of all JSON container types (Json_object and Json_array).
Definition: json_dom.h:331
virtual void replace_dom_in_container(const Json_dom *oldv, Json_dom_ptr newv)=0
Replace oldv contained inside this container array or object) with newv.
Represents a MySQL date/time value (DATE, TIME, DATETIME or TIMESTAMP) - an extension to the ECMA set...
Definition: json_dom.h:933
enum_field_types m_field_type
identifies which type of date/time
Definition: json_dom.h:936
MYSQL_TIME m_t
holds the date/time value
Definition: json_dom.h:935
enum_field_types field_type() const
Return what kind of date/time value this object holds.
Definition: json_dom.h:966
enum_json_type json_type() const override
Definition: json_dom.cc:1215
Json_datetime(const MYSQL_TIME &t, enum_field_types ft)
Constructs a object to hold a MySQL date/time value.
Definition: json_dom.h:947
void to_packed(char *dest) const
Convert the datetime to the packed format used when storing datetime values.
Definition: json_dom.cc:1237
static void from_packed(const char *from, enum_field_types ft, MYSQL_TIME *to)
Convert a packed datetime back to a MYSQL_TIME.
Definition: json_dom.cc:1242
static const size_t PACKED_SIZE
Datetimes are packed in eight bytes.
Definition: json_dom.h:998
static void from_packed_to_key(const char *from, enum_field_types ft, uchar *to, uint8 dec)
Convert a packed datetime to key string for indexing by SE.
Definition: json_dom.cc:1248
const MYSQL_TIME * value() const
Return a pointer the date/time value.
Definition: json_dom.h:959
Json_dom_ptr clone() const override
Make a deep clone.
Definition: json_dom.cc:1233
Represents a MySQL decimal number, type J_DECIMAL.
Definition: json_dom.h:744
Json_decimal(const my_decimal &value)
Definition: json_dom.cc:1168
my_decimal m_dec
holds the decimal number
Definition: json_dom.h:746
bool get_binary(char *dest) const
Get the binary representation of the wrapped my_decimal, so that this value can be stored inside of a...
Definition: json_dom.cc:1179
enum_json_type json_type() const override
Definition: json_dom.h:769
const my_decimal * value() const
Get a pointer to the MySQL decimal held by this object.
Definition: json_dom.h:778
static const int MAX_BINARY_SIZE
Definition: json_dom.h:749
static const char * get_encoded_binary(const char *bin)
Returns stored DECIMAL binary.
Definition: json_dom.h:810
Json_dom_ptr clone() const override
Make a deep clone.
Definition: json_dom.h:780
static bool convert_from_binary(const char *bin, size_t len, my_decimal *dec)
Convert a binary value produced by get_binary() back to a my_decimal.
Definition: json_dom.cc:1192
int binary_size() const
Get the number of bytes needed to store this decimal in a Json_opaque.
Definition: json_dom.cc:1171
static size_t get_encoded_binary_len(size_t length)
Returns length of stored DECIMAL binary.
Definition: json_dom.h:824
JSON DOM abstract base class.
Definition: json_dom.h:174
virtual bool is_scalar() const
Definition: json_dom.h:224
Json_container * parent() const
Get the parent dom to which this dom is attached.
Definition: json_dom.h:214
bool seek(const Json_seekable_path &path, size_t legs, Json_dom_vector *hits, bool auto_wrap, bool only_need_one)
Finds all of the json sub-documents which match the path expression.
Definition: json_dom.cc:1909
virtual ~Json_dom()=default
virtual uint32 depth() const =0
Compute the depth of a document.
Json_path get_location() const
Get the path location of this dom, measured from the outermost document it nests inside.
Definition: json_dom.cc:1881
static Json_dom_ptr parse(const char *text, size_t length, const JsonParseErrorHandler &error_handler, const JsonErrorHandler &depth_handler)
Parse Json text to DOM (using rapidjson).
Definition: json_dom.cc:567
void set_parent(Json_container *parent)
Set the parent dom to which this dom is attached.
Definition: json_dom.h:185
virtual bool is_number() const
Definition: json_dom.h:229
Json_container * m_parent
Parent pointer.
Definition: json_dom.h:325
virtual enum_json_type json_type() const =0
virtual Json_dom_ptr clone() const =0
Make a deep clone.
Represents a MySQL double JSON scalar (an extension of the ECMA number value), type J_DOUBLE.
Definition: json_dom.h:834
double m_f
holds the double value
Definition: json_dom.h:836
Json_dom_ptr clone() const override
Make a deep clone.
Definition: json_dom.h:842
enum_json_type json_type() const override
Definition: json_dom.h:840
double value() const
Return the double value held by this object.
Definition: json_dom.h:850
Json_double(double value)
Definition: json_dom.h:838
Represents a MySQL integer (64 bits signed) JSON scalar (an extension of the ECMA number value),...
Definition: json_dom.h:857
enum_json_type json_type() const override
Definition: json_dom.h:863
bool is_16bit() const
Definition: json_dom.h:874
Json_int(longlong value)
Definition: json_dom.h:861
Json_dom_ptr clone() const override
Make a deep clone.
Definition: json_dom.h:881
longlong m_i
holds the value
Definition: json_dom.h:859
bool is_32bit() const
Definition: json_dom.h:879
longlong value() const
Return the signed int held by this object.
Definition: json_dom.h:869
Represents a JSON null type (ECMA), type J_NULL here.
Definition: json_dom.h:921
Json_dom_ptr clone() const override
Make a deep clone.
Definition: json_dom.h:924
enum_json_type json_type() const override
Definition: json_dom.h:923
Abstract base class of all JSON number (ECMA) types (subclasses represent MySQL extensions).
Definition: json_dom.h:736
bool is_number() const final
Definition: json_dom.h:738
A wrapper over a JSON object which provides an interface that can be iterated over with a for-each lo...
Definition: json_dom.h:1880
Json_wrapper_object_iterator const_iterator
Definition: json_dom.h:1882
const_iterator end() const
Definition: json_dom.h:1888
Json_object_wrapper(const Json_wrapper &wrapper)
Definition: json_dom.h:1883
const_iterator begin() const
Definition: json_dom.h:1887
const_iterator cbegin() const
Definition: json_dom.h:1885
const_iterator cend() const
Definition: json_dom.h:1886
const Json_wrapper & m_wrapper
Definition: json_dom.h:1891
Represents a JSON container value of type "object" (ECMA), type J_OBJECT here.
Definition: json_dom.h:374
Json_dom_ptr clone() const override
Make a deep clone.
Definition: json_dom.cc:878
bool remove(const std::string &key)
Remove the child element addressed by key.
Definition: json_dom.cc:858
Json_object_map m_map
Map to hold the object elements.
Definition: json_dom.h:379
Json_object_map::const_iterator const_iterator
Constant iterator over the elements in the JSON object.
Definition: json_dom.h:486
enum_json_type json_type() const override
Definition: json_dom.h:383
bool consume(Json_object_ptr other)
Transfer all of the key/value pairs in the other object into this object.
Definition: json_dom.cc:812
Json_object()
Definition: json_dom.cc:354
const_iterator end() const
Returns a const_iterator that refers past the last element.
Definition: json_dom.h:492
size_t cardinality() const
Definition: json_dom.cc:866
uint32 depth() const override
Compute the depth of a document.
Definition: json_dom.cc:868
bool add_clone(const std::string &key, const Json_dom *value)
Insert a clone of the value into the object.
Definition: json_dom.h:395
Json_dom * get(const std::string &key) const
Return the value at key.
Definition: json_dom.cc:850
bool merge_patch(Json_object_ptr patch)
Implementation of the MergePatch function specified in RFC 7396:
Definition: json_dom.cc:890
void clear()
Remove all elements in the object.
Definition: json_dom.h:478
const_iterator begin() const
Returns a const_iterator that refers to the first element.
Definition: json_dom.h:489
bool add_alias(const std::string &key, Json_dom *value)
Insert the value into the object.
Definition: json_dom.h:416
void replace_dom_in_container(const Json_dom *oldv, Json_dom_ptr newv) override
Replace oldv contained inside this container array or object) with newv.
Definition: json_dom.cc:770
Represents a MySQL value opaquely, i.e.
Definition: json_dom.h:1010
enum_field_types type() const
Definition: json_dom.h:1040
size_t size() const
Definition: json_dom.h:1044
enum_json_type json_type() const override
Definition: json_dom.h:1030
Json_dom_ptr clone() const override
Make a deep clone.
Definition: json_dom.cc:1281
std::string m_val
Definition: json_dom.h:1013
const char * value() const
Definition: json_dom.h:1035
Json_opaque(enum_field_types mytype, Args &&... args)
An opaque MySQL value.
Definition: json_dom.h:1027
enum_field_types m_mytype
Definition: json_dom.h:1012
A JSON path expression.
Definition: json_path.h:356
A class that is capable of holding objects of any sub-type of Json_scalar.
Definition: json_dom.h:1911
Json_scalar * m_scalar_ptr
Pointer to the held scalar, or nullptr if no value is held.
Definition: json_dom.h:1939
Json_scalar * get()
Get a pointer to the held object, or nullptr if there is none.
Definition: json_dom.h:1943
Any_json_scalar m_buffer
The buffer in which the Json_scalar value is stored.
Definition: json_dom.h:1936
void emplace(Args &&... args)
Construct a new Json_scalar value in this Json_scalar_holder.
Definition: json_dom.h:1952
Abstract base class for all Json scalars.
Definition: json_dom.h:691
uint32 depth() const final
Compute the depth of a document.
Definition: json_dom.h:693
bool is_scalar() const final
Definition: json_dom.h:695
A path expression which can be used to seek to a position inside a JSON value.
Definition: json_path.h:301
Represents a JSON string value (ECMA), of type J_STRING here.
Definition: json_dom.h:701
std::string m_str
holds the string
Definition: json_dom.h:703
Json_string(Args &&... args)
Definition: json_dom.h:710
enum_json_type json_type() const override
Definition: json_dom.h:713
Json_dom_ptr clone() const override
Make a deep clone.
Definition: json_dom.h:715
size_t size() const
Get the number of characters in the string.
Definition: json_dom.h:729
const std::string & value() const
Get the reference to the value of the JSON string.
Definition: json_dom.h:723
Represents a MySQL integer (64 bits unsigned) JSON scalar (an extension of the ECMA number value),...
Definition: json_dom.h:889
enum_json_type json_type() const override
Definition: json_dom.h:895
Json_uint(ulonglong value)
Definition: json_dom.h:893
Json_dom_ptr clone() const override
Make a deep clone.
Definition: json_dom.h:915
ulonglong value() const
Return the unsigned int held by this object.
Definition: json_dom.h:901
ulonglong m_i
holds the value
Definition: json_dom.h:891
bool is_16bit() const
Definition: json_dom.h:907
bool is_32bit() const
Definition: json_dom.h:913
Class that iterates over all members of a JSON object that is wrapped in a Json_wrapper instance.
Definition: json_dom.h:1798
bool operator==(const Json_wrapper_object_iterator &other) const
Checks two iterators for equality.
Definition: json_dom.h:1842
const json_binary::Value * m_binary_value
The binary JSON object being iterated over, or nullptr for DOMs.
Definition: json_dom.h:1865
const value_type * pointer
Definition: json_dom.h:1803
size_t m_current_element_index
The index of the current member in the binary JSON object.
Definition: json_dom.h:1867
std::pair< MYSQL_LEX_CSTRING, Json_wrapper > value_type
Definition: json_dom.h:1801
std::forward_iterator_tag iterator_category
Definition: json_dom.h:1805
const Json_wrapper_object_iterator operator++(int)
Advances the iterator to the next element and returns an iterator that points to the current element ...
Definition: json_dom.h:1835
bool is_dom() const
Returns true if iterating over a DOM.
Definition: json_dom.h:1871
void initialize_current_member()
Fill m_current_member with the key and value of the current member.
Definition: json_dom.cc:1298
const value_type & reference
Definition: json_dom.h:1802
bool m_current_member_initialized
True if m_current_member is initialized.
Definition: json_dom.h:1863
bool operator!=(const Json_wrapper_object_iterator &other) const
Checks two iterators for inequality.
Definition: json_dom.h:1848
Json_object::const_iterator m_iter
Iterator pointing to the current member in the JSON DOM object.
Definition: json_dom.h:1869
pointer operator->()
Definition: json_dom.h:1852
Json_wrapper_object_iterator & operator++()
Advances the iterator to the next element.
Definition: json_dom.h:1822
ptrdiff_t difference_type
Definition: json_dom.h:1804
value_type m_current_member
Pair holding the key and value of the member pointed to by the iterator.
Definition: json_dom.h:1861
Json_wrapper_object_iterator()=default
Forward iterators must be default constructible.
reference operator*()
Definition: json_dom.h:1857
Abstraction for accessing JSON values irrespective of whether they are (started out as) binary JSON v...
Definition: json_dom.h:1168
const char * get_data() const
Get a pointer to the data of a JSON string or JSON opaque value.
Definition: json_dom.cc:1798
const Json_dom * get_dom() const
Gets a pointer to the wrapped Json_dom object, if this wrapper holds a DOM.
Definition: json_dom.h:1300
bool to_pretty_string(String *buffer, const char *func_name, const JsonErrorHandler &depth_handler) const
Format the JSON value to an external JSON string in buffer in the format of ISO/IEC 10646.
Definition: json_dom.cc:1708
void set_alias()
Only meaningful iff the wrapper encapsulates a DOM.
Definition: json_dom.h:1226
size_t get_data_length() const
Get the length to the data of a JSON string or JSON opaque value.
Definition: json_dom.cc:1808
bool get_decimal_data(my_decimal *d) const
Get the MySQL representation of a JSON decimal value.
Definition: json_dom.cc:1818
ulonglong get_uint() const
Get the value of a JSON unsigned integer number.
Definition: json_dom.cc:1844
bool get_boolean() const
Get a boolean value (a JSON true or false literal).
Definition: json_dom.cc:1872
enum_field_types field_type() const
Return the MYSQL type of the opaque value, see type().
Definition: json_dom.cc:1762
bool to_string(String *buffer, bool json_quoted, const char *func_name, const JsonErrorHandler &depth_handler) const
Format the JSON value to an external JSON string in buffer in the format of ISO/IEC 10646.
Definition: json_dom.cc:1700
void remove_duplicates(const CHARSET_INFO *cs=nullptr)
Remove duplicate values.
Definition: json_dom.cc:3670
bool m_alias
If true, don't deallocate m_dom_value in destructor.
Definition: json_dom.h:1179
bool get_free_space(size_t *space) const
Calculate the amount of unused space inside a JSON binary value.
Definition: json_dom.cc:3433
Json_dom * to_dom()
Get the wrapped contents in DOM form.
Definition: json_dom.cc:1385
longlong get_int() const
Get the value of a JSON signed integer number.
Definition: json_dom.cc:1836
const char * get_datetime_packed(char *buffer) const
Get the wrapped datetime value in the packed format.
Definition: json_dom.cc:1861
my_decimal * coerce_decimal(my_decimal *decimal_value, const char *msgnam)
Shorthand for coerce_decimal(decimal_value, msgnam, CE_WARNING, nullptr).
Definition: json_dom.h:1654
Json_wrapper operator[](size_t index) const
If this wrapper holds a JSON array, get an array value by indexing into the array.
Definition: json_dom.cc:1784
bool m_is_dom
Wraps a DOM iff true.
Definition: json_dom.h:1184
const json_binary::Value & get_binary_value() const
Gets the wrapped json_binary::Value object, if this wrapper holds a binary JSON value.
Definition: json_dom.h:1310
longlong coerce_int(const char *msgnam, enum_coercion_error cr_error, bool *err, bool *unsigned_flag) const
Extract an int (signed or unsigned) from the JSON if possible coercing if need be.
Definition: json_dom.cc:2710
void get_datetime(MYSQL_TIME *t) const
Get the value of a JSON date/time value.
Definition: json_dom.cc:1852
bool attempt_binary_update(const Field_json *field, const Json_seekable_path &path, Json_wrapper *new_value, bool replace, String *result, bool *partially_updated, bool *replaced_path)
Attempt a binary partial update by replacing the value at path with new_value.
Definition: json_dom.cc:3442
bool coerce_date(MYSQL_TIME *ltime, const char *msgnam, enum_coercion_error cr_error=CE_WARNING, my_time_flags_t date_flags_arg=0) const
Extract a date from the JSON if possible, coercing if need be.
Definition: json_dom.cc:2900
Json_wrapper lookup(const MYSQL_LEX_CSTRING &key) const
If this wrapper holds a JSON object, get the value corresponding to the member key.
Definition: json_dom.cc:1771
enum_json_type type() const
Return the type of the wrapped JSON value.
Definition: json_dom.cc:1729
void dbug_print(const char *message, const JsonErrorHandler &depth_handler) const
Print this JSON document to the debug trace.
Definition: json_dom.cc:1716
Json_wrapper()
Create an empty wrapper.
Definition: json_dom.h:1199
longlong coerce_int(const char *msgnam) const
Shorthand for coerce_int(msgnam, CE_WARNING, nullptr, nullptr).
Definition: json_dom.h:1619
struct Json_wrapper::@35::@37 m_dom
The DOM representation, only used if m_is_dom is true.
double coerce_real(const char *msgnam) const
Shorthand for coerce_real(msgnam, CE_WARNING, nullptr).
Definition: json_dom.h:1636
int compare(const Json_wrapper &other, const CHARSET_INFO *cs=nullptr) const
Compare this JSON value to another JSON value.
Definition: json_dom.cc:2439
void sort(const CHARSET_INFO *cs=nullptr)
Sort contents.
Definition: json_dom.cc:3665
ulonglong make_hash_key(ulonglong hash_val) const
Make a hash key that can be used by sql_executor.cc/unique_hash in order to support SELECT DISTINCT.
Definition: json_dom.cc:3367
bool seek(const Json_seekable_path &path, size_t legs, Json_wrapper_vector *hits, bool auto_wrap, bool only_need_one)
Finds all of the json sub-documents which match the path expression.
Definition: json_dom.cc:2138
Json_wrapper & operator=(const Json_wrapper &old)
Assignment operator.
Definition: json_dom.cc:1377
bool is_binary_backed_by(const String *str) const
Check if the wrapped JSON document is a binary value (a json_binary::Value), and if that binary is po...
Definition: json_dom.h:1357
double get_double() const
Get the value of a JSON double number.
Definition: json_dom.cc:1828
size_t make_sort_key(uchar *to, size_t length) const
Make a sort key that can be used by filesort to order JSON values.
Definition: json_dom.cc:3261
bool binary_remove(const Field_json *field, const Json_seekable_path &path, String *result, bool *found_path)
Remove a path from a binary JSON document.
Definition: json_dom.cc:3588
size_t length() const
Compute the length of a document.
Definition: json_dom.cc:2174
bool empty() const
A Wrapper is defined to be empty if it is passed a NULL value with the constructor for JSON dom,...
Definition: json_dom.h:1277
Json_wrapper(Json_dom_ptr dom_value)
Wrap the supplied DOM value.
Definition: json_dom.h:1217
my_decimal * coerce_decimal(my_decimal *decimal_value, const char *msgnam, enum_coercion_error cr_error, bool *err) const
Extract a decimal from the JSON if possible, coercing if need be.
Definition: json_dom.cc:2837
double coerce_real(const char *msgnam, enum_coercion_error cr_error, bool *err) const
Extract a real from the JSON if possible, coercing if need be.
Definition: json_dom.cc:2787
bool to_binary(String *str, const JsonErrorHandler &json_depth_handler, const JsonErrorHandler &json_key_handler, const JsonErrorHandler &json_value_handler, const JsonErrorHandler &invalid_json_handler) const
Get the wrapped contents in binary value form.
Definition: json_dom.cc:1405
bool coerce_time(MYSQL_TIME *ltime, const char *msgnam, enum_coercion_error cr_error=CE_WARNING) const
Extract a time value from the JSON if possible, coercing if need be.
Definition: json_dom.cc:2940
~Json_wrapper()
Definition: json_dom.cc:1350
Json_dom * m_value
Definition: json_dom.h:1177
bool is_dom() const
Does this wrapper contain a DOM?
Definition: json_dom.h:1285
Json_dom_ptr clone_dom() const
Get the wrapped contents in DOM form.
Definition: json_dom.cc:1397
json_binary::Value m_value
The binary representation, only used if m_is_dom is false.
Definition: json_dom.h:1182
Malloc_allocator is a C++ STL memory allocator based on my_malloc/my_free.
Definition: malloc_allocator.h:62
Using this class is fraught with peril, and you need to be very careful when doing so.
Definition: sql_string.h:166
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:35
Class used for reading JSON values that are stored in the binary format.
Definition: json_binary.h:203
my_decimal class limits 'decimal_t' type to what we need in MySQL.
Definition: my_decimal.h:94
This file contains the field type.
enum_field_types
Column types for MySQL Note: Keep include/mysql/components/services/bits/stored_program_bits....
Definition: field_types.h:54
static const std::string dec("DECRYPTION")
static uint16 key1[1001]
Definition: hp_test2.cc:49
This file specifies the interface for serializing JSON values into binary representation,...
std::unique_ptr< Json_dom > Json_dom_ptr
Definition: json_dom.h:66
Prealloced_array< Json_dom *, 16 > Json_dom_vector
Definition: json_dom.h:64
std::unique_ptr< T > create_dom_ptr(Args &&... args)
Allocate a new Json_dom object and return a std::unique_ptr which points to it.
Definition: json_dom.h:140
std::map< std::string, Json_dom_ptr, Json_key_comparator, Malloc_allocator< std::pair< const std::string, Json_dom_ptr > > > Json_object_map
A type used to hold JSON object elements in a map, see the Json_object class.
Definition: json_dom.h:368
bool is_valid_json_syntax(const char *text, size_t length)
Check if a string contains valid JSON text, without generating a Json_dom representation of the docum...
std::unique_ptr< Json_object > Json_object_ptr
Definition: json_dom.h:68
enum_json_type
Json values in MySQL comprises the stand set of JSON values plus a MySQL specific set.
Definition: json_dom.h:110
std::unique_ptr< Json_array > Json_array_ptr
Definition: json_dom.h:67
bool double_quote(const char *cptr, size_t length, String *buf)
Perform quoting on a JSON string to make an external representation of it.
Definition: json_dom.cc:1136
enum_coercion_error
How Json_wrapper would handle coercion error.
Definition: json_dom.h:1149
@ CE_WARNING
Definition: json_dom.h:1150
@ CE_ERROR
Definition: json_dom.h:1151
@ CE_IGNORE
Definition: json_dom.h:1152
Prealloced_array< Json_wrapper, 16 > Json_wrapper_vector
Definition: json_dom.h:61
Json_dom_ptr merge_doms(Json_dom_ptr left, Json_dom_ptr right)
Merge two doms.
Definition: json_dom.cc:107
std::function< void()> JsonErrorHandler
Definition: json_error_handler.h:31
std::function< void(const char *parse_err, size_t err_offset)> JsonParseErrorHandler
Definition: json_error_handler.h:30
Header for compiler-dependent features.
It is interface module to fixed precision decimals library.
static constexpr int DECIMAL_MAX_FIELD_SIZE
maximum size of packet length.
Definition: my_decimal.h:80
Some integer typedefs for easier portability.
#define UINT_MAX16
Definition: my_inttypes.h:84
unsigned long long int ulonglong
Definition: my_inttypes.h:55
uint8_t uint8
Definition: my_inttypes.h:62
unsigned char uchar
Definition: my_inttypes.h:51
#define INT_MAX16
Definition: my_inttypes.h:83
#define INT_MIN32
Definition: my_inttypes.h:76
long long int longlong
Definition: my_inttypes.h:54
#define INT_MAX32
Definition: my_inttypes.h:77
#define INT_MIN16
Definition: my_inttypes.h:82
uint32_t uint32
Definition: my_inttypes.h:66
#define UINT_MAX32
Definition: my_inttypes.h:78
Interface for low level time utilities.
unsigned int my_time_flags_t
Flags to str_to_datetime and number_to_datetime.
Definition: my_time.h:93
Time declarations shared between the server and client API: you should not add anything to this heade...
static char * path
Definition: mysqldump.cc:148
static bool replace
Definition: mysqlimport.cc:69
void * begin(THD *thd, const TABLE *table, size_t data_size, size_t memory, size_t num_threads) noexcept
Definition: bulk_data_service.cc:1533
void copy(Shards< COUNT > &dst, const Shards< COUNT > &src) noexcept
Copy the counters, overwrite destination.
Definition: ut0counter.h:353
std::string str(const mysqlrouter::ConfigGenerator::Options::Endpoint &ep)
Definition: config_generator.cc:1085
Definition: buf0block_hint.cc:29
Definition: commit_order_queue.h:33
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:75
static Value err()
Create a Value object that represents an error condition.
Definition: json_binary.cc:921
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:417
Definition: varlen_sort.h:183
std::map< Key, Value, Compare, ut::allocator< std::pair< const Key, Value > > > map
Specialization of map which uses ut_allocator.
Definition: ut0new.h:2891
required string key
Definition: replication_asynchronous_connection_failover.proto:59
Definition: m_ctype.h:422
A comparator that is used for ordering keys in a Json_object.
Definition: json_dom.h:350
bool operator()(const std::string &key1, const std::string &key2) const
Definition: json_dom.cc:955
void is_transparent
Definition: json_dom.h:359
Definition: mysql_lex_string.h:39
Definition: mysql_time.h:81
Definition: result.h:29
Union of all concrete subclasses of Json_scalar.
Definition: json_dom.h:1913
Json_null m_null
Definition: json_dom.h:1920
Json_boolean m_boolean
Definition: json_dom.h:1919
Json_decimal m_decimal
Definition: json_dom.h:1915
Json_datetime m_datetime
Definition: json_dom.h:1921
Json_double m_double
Definition: json_dom.h:1918
Json_opaque m_opaque
Definition: json_dom.h:1922
~Any_json_scalar()
Destructor which delegates to Json_scalar's virtual destructor.
Definition: json_dom.h:1926
Json_int m_int
Definition: json_dom.h:1916
Any_json_scalar()
Constructor which initializes the union to hold a Json_null value.
Definition: json_dom.h:1924
Json_uint m_uint
Definition: json_dom.h:1917
Json_string m_string
Definition: json_dom.h:1914