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