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