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