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