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