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