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