MySQL  8.0.21
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 override { return 1; }
691 #endif
692 
693  bool is_scalar() const final override { 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 override { 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  Function for double-quoting a string and escaping characters
1072  to make up a valid EMCA Json text.
1073 
1074  @param[in] cptr the unquoted character string
1075  @param[in] length its length
1076  @param[in,out] buf the destination buffer
1077 
1078  @return false on success, true on error
1079 */
1080 bool double_quote(const char *cptr, size_t length, String *buf);
1081 
1082 /**
1083  Merge two doms. The right dom is either subsumed into the left dom
1084  or the contents of the right dom are transferred to the left dom
1085  and the right dom is deleted. After calling this function, the
1086  caller should not reference the right dom again. It has been
1087  deleted.
1088 
1089  Returns NULL if there is a memory allocation failure. In this case
1090  both doms are deleted.
1091 
1092  scalars - If any of the documents that are being merged is a scalar,
1093  each scalar document is autowrapped as a single value array before merging.
1094 
1095  arrays - When merging a left array with a right array,
1096  then the result is the left array concatenated
1097  with the right array. For instance, [ 1, 2 ] merged with [ 3, 4 ]
1098  is [ 1, 2, 3, 4 ].
1099 
1100  array and object - When merging an array with an object,
1101  the object is autowrapped as an array and then the rule above
1102  is applied. So [ 1, 2 ] merged with { "a" : true }
1103  is [ 1, 2, { "a": true } ].
1104 
1105  objects - When merging two objects, the two objects are concatenated
1106  into a single, larger object. So { "a" : "foo" } merged with { "b" : 5 }
1107  is { "a" : "foo", "b" : 5 }.
1108 
1109  duplicates - When two objects are merged and they share a key,
1110  the values associated with the shared key are merged.
1111 
1112  @param [in,out] left The recipient dom.
1113  @param [in,out] right The dom to be consumed
1114 
1115  @return A composite dom which subsumes the left and right doms, or NULL
1116  if a failure happened while merging
1117 */
1119 
1120 /**
1121  How Json_wrapper would handle coercion error
1122 */
1123 
1125  CE_WARNING, // Throw a warning, default
1126  CE_ERROR, // Throw an error
1127  CE_IGNORE // Let the caller handle the error
1128 };
1129 
1130 /**
1131  Abstraction for accessing JSON values irrespective of whether they
1132  are (started out as) binary JSON values or JSON DOM values. The
1133  purpose of this is to allow uniform access for callers. It allows us
1134  to access binary JSON values without necessarily building a DOM (and
1135  thus having to read the entire value unless necessary, e.g. for
1136  accessing only a single array slot or object field).
1137 
1138  Instances of this class are usually created on the stack. In some
1139  cases instances are cached in an Item and reused, in which case they
1140  are allocated from query-duration memory (by allocating them on a
1141  MEM_ROOT).
1142 */
1144  private:
1145  /*
1146  A Json_wrapper wraps either a Json_dom or a json_binary::Value,
1147  never both at the same time.
1148  */
1149  union {
1150  /// The DOM representation, only used if m_is_dom is true.
1151  struct {
1153  /// If true, don't deallocate m_dom_value in destructor.
1155  };
1156  /// The binary representation, only used if m_is_dom is false.
1158  };
1159  bool m_is_dom; //!< Wraps a DOM iff true
1160  public:
1161  /**
1162  Get the wrapped datetime value in the packed format.
1163 
1164  @param[in,out] buffer a char buffer with space for at least
1165  Json_datetime::PACKED_SIZE characters
1166  @return a char buffer that contains the packed representation of the
1167  datetime (may or may not be the same as buffer)
1168  */
1169  const char *get_datetime_packed(char *buffer) const;
1170 
1171  /**
1172  Create an empty wrapper. Cf #empty().
1173  */
1174  Json_wrapper() : m_dom_value(nullptr), m_is_dom(true) {
1175  // Workaround for Solaris Studio, initialize in CTOR body.
1176  m_dom_alias = true;
1177  }
1178 
1179  /**
1180  Wrap the supplied DOM value (no copy taken). The wrapper takes
1181  ownership, unless alias is true or @c set_alias is called after
1182  construction.
1183  In the latter case the lifetime of the DOM is determined by
1184  the owner of the DOM, so clients need to ensure that that
1185  lifetime is sufficient, lest dead storage is attempted accessed.
1186 
1187  @param[in,out] dom_value the DOM value
1188  @param alias Whether the wrapper is an alias to DOM
1189  */
1190  explicit Json_wrapper(Json_dom *dom_value, bool alias = false);
1191 
1192  /**
1193  Wrap the supplied DOM value. The wrapper takes over the ownership.
1194  */
1195  explicit Json_wrapper(Json_dom_ptr dom_value)
1196  : Json_wrapper(dom_value.release()) {}
1197 
1198  /**
1199  Only meaningful iff the wrapper encapsulates a DOM. Marks the
1200  wrapper as not owning the DOM object, i.e. it will not be
1201  deallocated in the wrapper's destructor. Useful if one wants a wrapper
1202  around a DOM owned by someone else.
1203  */
1204  void set_alias() { m_dom_alias = true; }
1205 
1206  /**
1207  Wrap a binary value. Does not copy the underlying buffer, so
1208  lifetime is limited the that of the supplied value.
1209 
1210  @param[in] value the binary value
1211  */
1212  explicit Json_wrapper(const json_binary::Value &value);
1213 
1214  /**
1215  Copy constructor. Does a deep copy of any owned DOM. If a DOM
1216  os not owned (aliased), the copy will also be aliased.
1217  */
1218  Json_wrapper(const Json_wrapper &old);
1219 
1220  /**
1221  Move constructor. Take over the ownership of the other wrapper's
1222  DOM, unless it's aliased. If the other wrapper is aliased, this
1223  wrapper becomes an alias too. Any already owned DOM will be
1224  deallocated.
1225 
1226  @param old the wrapper whose contents to take over
1227  */
1228  Json_wrapper(Json_wrapper &&old) noexcept;
1229 
1230  /**
1231  Assignment operator. Does a deep copy of any owned DOM. If a DOM
1232  os not owned (aliased), the copy will also be aliased. Any owned
1233  DOM in the left side will be deallocated.
1234  */
1235  Json_wrapper &operator=(const Json_wrapper &old);
1236 
1237  /**
1238  Move-assignment operator. Take over the ownership of the other
1239  wrapper's DOM, unless it's aliased. If the other wrapper is
1240  aliased, this wrapper becomes an alias too. Any already owned DOM
1241  will be deallocated.
1242 
1243  @param old the wrapper whose contents to take over
1244  */
1245  Json_wrapper &operator=(Json_wrapper &&old) noexcept;
1246 
1247  ~Json_wrapper();
1248 
1249  /**
1250  A Wrapper is defined to be empty if it is passed a NULL value with the
1251  constructor for JSON dom, or if the default constructor is used.
1252 
1253  @return true if the wrapper is empty.
1254  */
1255  bool empty() const { return m_is_dom && !m_dom_value; }
1256 
1257  /**
1258  Does this wrapper contain a DOM?
1259 
1260  @retval true if the wrapper contains a DOM representation
1261  @retval false if the wrapper contains a binary representation
1262  */
1263  bool is_dom() const { return m_is_dom; }
1264 
1265  /**
1266  Get the wrapped contents in DOM form. The DOM is (still) owned by the
1267  wrapper. If this wrapper originally held a value, it is now converted
1268  to hold (and eventually release) the DOM version.
1269 
1270  @param thd current session (can be nullptr if is_dom() returns true)
1271  @return pointer to a DOM object, or NULL if the DOM could not be allocated
1272  */
1273  Json_dom *to_dom(const THD *thd);
1274 
1275  /**
1276  Gets a pointer to the wrapped Json_dom object, if this wrapper holds a DOM.
1277  If is_dom() returns false, the result of calling this function is undefined.
1278  */
1279  const Json_dom *get_dom() const {
1280  DBUG_ASSERT(m_is_dom);
1281  return m_dom_value;
1282  }
1283 
1284  /**
1285  Gets the wrapped json_binary::Value object, if this wrapper holds a binary
1286  JSON value. If is_dom() returns true, the result of calling this function is
1287  undefined.
1288  */
1290  DBUG_ASSERT(!m_is_dom);
1291  return m_value;
1292  }
1293 
1294 #ifdef MYSQL_SERVER
1295  /**
1296  Get the wrapped contents in DOM form. Same as to_dom(), except it returns
1297  a clone of the original DOM instead of the actual, internal DOM tree.
1298 
1299  @param thd current session
1300  @return pointer to a DOM object, or NULL if the DOM could not be allocated
1301  */
1302  Json_dom_ptr clone_dom(const THD *thd) const;
1303 
1304  /**
1305  Get the wrapped contents in binary value form.
1306 
1307  @param[in] thd current session
1308  @param[in,out] str a string that will be filled with the binary value
1309  @retval false on success
1310  @retval true on error
1311  */
1312  bool to_binary(const THD *thd, String *str) const;
1313 #endif
1314 
1315  /**
1316  Check if the wrapped JSON document is a binary value (a
1317  json_binary::Value), and if that binary is pointing to data stored in the
1318  given string.
1319 
1320  This function can be used to check if overwriting the data in the string
1321  might overwrite and corrupt the document contained in this wrapper.
1322 
1323  @param str a string which contains JSON binary data
1324  @retval true if the string contains data that the wrapped document
1325  points to from its json_binary::Value representation
1326  @retval false otherwise
1327  */
1328  bool is_binary_backed_by(const String *str) const {
1329  return !m_is_dom && m_value.is_backed_by(str);
1330  }
1331 
1332  /**
1333  Format the JSON value to an external JSON string in buffer in
1334  the format of ISO/IEC 10646.
1335 
1336  @param[in,out] buffer the formatted string is appended, so make sure
1337  the length is set correctly before calling
1338  @param[in] json_quoted if the JSON value is a string and json_quoted
1339  is false, don't perform quoting on the string.
1340  This is only used by JSON_UNQUOTE.
1341  @param[in] func_name The name of the function that called to_string().
1342 
1343  @return false formatting went well, else true
1344  */
1345  bool to_string(String *buffer, bool json_quoted, const char *func_name) const;
1346 
1347  /**
1348  Print this JSON document to the debug trace.
1349 
1350  @param[in] message If given, the JSON document is prefixed with
1351  this message.
1352  */
1353  void dbug_print(const char *message MY_ATTRIBUTE((unused)) = "") const;
1354 
1355  /**
1356  Format the JSON value to an external JSON string in buffer in the format of
1357  ISO/IEC 10646. Add newlines and indentation for readability.
1358 
1359  @param[in,out] buffer the buffer that receives the formatted string
1360  (the string is appended, so make sure the length
1361  is set correctly before calling)
1362  @param[in] func_name the name of the calling function
1363 
1364  @retval false on success
1365  @retval true on error
1366  */
1367  bool to_pretty_string(String *buffer, const char *func_name) const;
1368 
1369  // Accessors
1370 
1371  /**
1372  Return the type of the wrapped JSON value
1373 
1374  @return the type, or Json_dom::J_ERROR if the wrapper does not contain
1375  a JSON value
1376  */
1377  enum_json_type type() const;
1378 
1379  /**
1380  Return the MYSQL type of the opaque value, see #type(). Valid for
1381  J_OPAQUE. Calling this method if the type is not J_OPAQUE will give
1382  undefined results.
1383 
1384  @return the type
1385  */
1386  enum_field_types field_type() const;
1387 
1388  /**
1389  If this wrapper holds a JSON array, get an array value by indexing
1390  into the array. Valid for J_ARRAY. Calling this method if the type is
1391  not J_ARRAY will give undefined results.
1392 
1393  @return the array value
1394  */
1395  Json_wrapper operator[](size_t index) const;
1396 
1397  /**
1398  If this wrapper holds a JSON object, get the value corresponding
1399  to the member key. Valid for J_OBJECT. Calling this method if the type is
1400  not J_OBJECT will give undefined results.
1401 
1402  @param[in] key name for identifying member
1403 
1404  @return The member value. If there is no member with the specified
1405  name, a value with type Json_dom::J_ERROR is returned.
1406  */
1407  Json_wrapper lookup(const MYSQL_LEX_CSTRING &key) const;
1408 
1409  /**
1410  Get a pointer to the data of a JSON string or JSON opaque value.
1411  The data is still owner by the wrapper. The data may not be null
1412  terminated, so use in conjunction with @c get_data_length.
1413  Valid for J_STRING and J_OPAQUE. Calling this method if the type is
1414  not one of those will give undefined results.
1415 
1416  @return the pointer
1417  */
1418  const char *get_data() const;
1419 
1420  /**
1421  Get the length to the data of a JSON string or JSON opaque value.
1422  Valid for J_STRING and J_OPAQUE. Calling this method if the type is
1423  not one of those will give undefined results.
1424 
1425  @return the length
1426  */
1427  size_t get_data_length() const;
1428 
1429  /**
1430  Get the MySQL representation of a JSON decimal value.
1431  Valid for J_DECIMAL. Calling this method if the type is
1432  not J_DECIMAL will give undefined results.
1433 
1434  @param[out] d the decimal value
1435  @return false on success, true on failure (which would indicate an
1436  internal error)
1437  */
1438  bool get_decimal_data(my_decimal *d) const;
1439 
1440  /**
1441  Get the value of a JSON double number.
1442  Valid for J_DOUBLE. Calling this method if the type is
1443  not J_DOUBLE will give undefined results.
1444 
1445  @return the value
1446  */
1447  double get_double() const;
1448 
1449  /**
1450  Get the value of a JSON signed integer number.
1451  Valid for J_INT. Calling this method if the type is
1452  not J_INT will give undefined results.
1453 
1454  @return the value
1455  */
1456  longlong get_int() const;
1457 
1458  /**
1459  Get the value of a JSON unsigned integer number.
1460  Valid for J_UINT. Calling this method if the type is
1461  not J_UINT will give undefined results.
1462 
1463  @return the value
1464  */
1465  ulonglong get_uint() const;
1466 
1467  /**
1468  Get the value of a JSON date/time value. Valid for J_TIME,
1469  J_DATETIME, J_DATE and J_TIMESTAMP. Calling this method if the type
1470  is not one of those will give undefined results.
1471 
1472  @param[out] t the date/time value
1473  */
1474  void get_datetime(MYSQL_TIME *t) const;
1475 
1476  /**
1477  Get a boolean value (a JSON true or false literal).
1478  Valid for J_BOOLEAN. Calling this method if the type is
1479  not J_BOOLEAN will give undefined results.
1480 
1481  @return the value
1482  */
1483  bool get_boolean() const;
1484 
1485  /**
1486  Finds all of the json sub-documents which match the path expression.
1487  Puts the matches on an evolving vector of results.
1488  This is a bit inefficient for binary wrappers because you can't
1489  build up a binary array incrementally from its cells. Instead, you
1490  have to turn each cell into a dom and then add the doms to a
1491  dom array.
1492 
1493  Calling this if #empty() returns true is an error.
1494 
1495  Special care must be taken when the path expression contains more than one
1496  ellipsis (**) token. That is because multiple paths with ellipses may
1497  identify the same value. Consider the following document:
1498 
1499  { "a": { "x" : { "b": { "y": { "b": { "z": { "c": 100 } } } } } } }
1500 
1501  The innermost value (the number 100) has the following unique,
1502  non-wildcarded address:
1503 
1504  $.a.x.b.y.b.z.c
1505 
1506  That location is reached by both of the following paths which include
1507  the ellipsis token:
1508 
1509  $.a.x.b**.c
1510  $.a.x.b.y.b**.c
1511 
1512  And those addresses both satisfy the following path expression which has
1513  two ellipses:
1514 
1515  $.a**.b**.c
1516 
1517  In this case, we only want to return one instance of $.a.x.b.y.b.z.c
1518 
1519  Similarly, special care must be taken if an auto-wrapping array
1520  path leg follows an ellipsis. Consider the following document:
1521 
1522  { "a": { "b" : [ 1, 2, 3 ] } }
1523 
1524  The first element of the array (the number 1) can be reached with
1525  either of these two non-wildcarded addresses, due to array auto-wrapping:
1526 
1527  $.a.b[0]
1528  $.a.b[0][0]
1529 
1530  Both of those addresses match the following path expression, which
1531  has an ellipsis followed by an auto-wrapping path leg:
1532 
1533  $**[0]
1534 
1535  @param[in] path the (possibly wildcarded) address of the sub-documents
1536  @param[in] legs the number of legs to use from @a path
1537  @param[out] hits the result of the search
1538  @param[in] auto_wrap true of we match a final scalar with search for [0]
1539  @param[in] only_need_one True if we can stop after finding one match
1540 
1541  @retval false on success
1542  @retval true on error
1543  */
1544  bool seek(const Json_seekable_path &path, size_t legs,
1545  Json_wrapper_vector *hits, bool auto_wrap, bool only_need_one);
1546 
1547  /**
1548  Compute the length of a document. This is the value which would be
1549  returned by the JSON_LENGTH() system function. So, this returns
1550 
1551  - for scalar values: 1
1552  - for objects: the number of members
1553  - for arrays: the number of cells
1554 
1555  @returns 1, the number of members, or the number of cells
1556  */
1557  size_t length() const;
1558 
1559  /**
1560  Compare this JSON value to another JSON value.
1561  @param[in] other the other JSON value
1562  @param[in] cs if given, this charset will be used in comparison of
1563  string values
1564  @retval -1 if this JSON value is less than the other JSON value
1565  @retval 0 if the two JSON values are equal
1566  @retval 1 if this JSON value is greater than the other JSON value
1567  */
1568  int compare(const Json_wrapper &other,
1569  const CHARSET_INFO *cs = nullptr) const;
1570 
1571  /**
1572  Extract an int (signed or unsigned) from the JSON if possible
1573  coercing if need be.
1574  @param[in] msgnam to use in error message if conversion failed
1575  @param[in] cr_error Whether to raise an error or warning on
1576  data truncation
1577  @param[out] err true <=> error occur during coercion
1578  @param[out] unsigned_flag Whether the value read from JSON data is
1579  unsigned
1580 
1581  @returns json value coerced to int
1582  */
1583  longlong coerce_int(const char *msgnam, enum_coercion_error cr_error,
1584  bool *err, bool *unsigned_flag) const;
1585 
1586  /// Shorthand for coerce_int(msgnam, CE_WARNING, nullptr, nullptr).
1587  longlong coerce_int(const char *msgnam) const {
1588  return coerce_int(msgnam, CE_WARNING, nullptr, nullptr);
1589  }
1590 
1591  /**
1592  Extract a real from the JSON if possible, coercing if need be.
1593 
1594  @param[in] msgnam to use in error message if conversion failed
1595  @param[in] cr_error Whether to raise an error or warning on
1596  data truncation
1597  @param[out] err true <=> error occur during coercion
1598  @returns json value coerced to real
1599  */
1600  double coerce_real(const char *msgnam, enum_coercion_error cr_error,
1601  bool *err) const;
1602 
1603  /// Shorthand for coerce_real(msgnam, CE_WARNING, nullptr).
1604  double coerce_real(const char *msgnam) const {
1605  return coerce_real(msgnam, CE_WARNING, nullptr);
1606  }
1607 
1608  /**
1609  Extract a decimal from the JSON if possible, coercing if need be.
1610 
1611  @param[in,out] decimal_value a value buffer
1612  @param[in] msgnam to use in error message if conversion failed
1613  @param[in] cr_error Whether to raise an error or warning on
1614  data truncation
1615  @param[out] err true <=> error occur during coercion
1616  @returns json value coerced to decimal
1617  */
1618  my_decimal *coerce_decimal(my_decimal *decimal_value, const char *msgnam,
1619  enum_coercion_error cr_error, bool *err) const;
1620 
1621  /// Shorthand for coerce_decimal(decimal_value, msgnam, CE_WARNING, nullptr).
1622  my_decimal *coerce_decimal(my_decimal *decimal_value, const char *msgnam) {
1623  return coerce_decimal(decimal_value, msgnam, CE_WARNING, nullptr);
1624  }
1625 
1626  /**
1627  Extract a date from the JSON if possible, coercing if need be.
1628 
1629  @param[in,out] ltime a value buffer
1630  @param msgnam to use in error message if conversion failed
1631  @param[in] cr_error Whether to raise an error or warning on
1632  data truncation
1633  @param[in] date_flags_arg Flags to use for string -> date conversion
1634  @returns json value coerced to date
1635  */
1636  bool coerce_date(MYSQL_TIME *ltime, const char *msgnam,
1637  enum_coercion_error cr_error = CE_WARNING,
1638  my_time_flags_t date_flags_arg = 0) const;
1639 
1640  /**
1641  Extract a time value from the JSON if possible, coercing if need be.
1642 
1643  @param[in,out] ltime a value buffer
1644  @param msgnam to use in error message if conversion failed
1645  @param[in] cr_error Whether to raise an error or warning on
1646  data truncation
1647 
1648  @returns json value coerced to time
1649  */
1650  bool coerce_time(MYSQL_TIME *ltime, const char *msgnam,
1651  enum_coercion_error cr_error = CE_WARNING) const;
1652 
1653  /**
1654  Make a sort key that can be used by filesort to order JSON values.
1655 
1656  @param[out] to a buffer to which the sort key is written
1657  @param[in] length the length of the sort key
1658 
1659  @details Key storage format is following:
1660  @verbatim
1661  |<json type>< sort key >|
1662  1 byte / variable length /
1663  @endverbatim
1664 
1665  JSON is assumed to be non-sql-null and valid (checked by caller).
1666  Key length contains full length - the len prefix itself, json type and the
1667  sort key.
1668  All numeric types are stored as a number, without distinction to
1669  double/decimal/int/etc. See @c make_json_numeric_sort_key().
1670  Same is done to DATETIME and TIMESTAMP types.
1671  For string and opaque types only the prefix that fits into the output buffer
1672  is stored.
1673  For JSON objects and arrays only their length (number of elements) is
1674  stored, this is a limitation of current implementation.
1675  */
1676  size_t make_sort_key(uchar *to, size_t length) const;
1677 
1678  /**
1679  Make a hash key that can be used by sql_executor.cc/unique_hash
1680  in order to support SELECT DISTINCT
1681 
1682  @param[in] hash_val An initial hash value.
1683  */
1684  ulonglong make_hash_key(ulonglong hash_val) const;
1685 
1686  /**
1687  Calculate the amount of unused space inside a JSON binary value.
1688 
1689  @param[out] space the amount of unused space, or zero if this is a DOM
1690  @return false on success
1691  @return true if the JSON binary value was invalid
1692  */
1693  bool get_free_space(size_t *space) const;
1694 
1695  /**
1696  Attempt a binary partial update by replacing the value at @a path with @a
1697  new_value. On successful completion, the updated document will be available
1698  in @a result, and this Json_wrapper will point to @a result instead of the
1699  original binary representation. The modifications that have been applied,
1700  will also be collected as binary diffs, which can be retrieved via
1701  TABLE::get_binary_diffs().
1702 
1703  @param field the column being updated
1704  @param path the path of the value to update
1705  @param new_value the new value
1706  @param replace true if we use JSON_REPLACE semantics
1707  @param[in,out] result buffer that holds the updated JSON document (is
1708  empty if no partial update has been performed on
1709  this Json_wrapper so far, or contains the binary
1710  representation of the document in this wrapper
1711  otherwise)
1712  @param[out] partially_updated gets set to true if partial update was
1713  successful, also if it was a no-op
1714  @param[out] replaced_path gets set to true if the path was replaced,
1715  will be false if this update is a no-op
1716 
1717  @retval false if the update was successful, or if it was determined
1718  that a full update was needed
1719  @retval true if an error occurred
1720  */
1721  bool attempt_binary_update(const Field_json *field,
1722  const Json_seekable_path &path,
1723  Json_wrapper *new_value, bool replace,
1724  String *result, bool *partially_updated,
1725  bool *replaced_path);
1726 
1727  /**
1728  Remove a path from a binary JSON document. On successful completion, the
1729  updated document will be available in @a result, and this Json_wrapper will
1730  point to @a result instead of the original binary representation. The
1731  modifications that have been applied, will also be collected as binary
1732  diffs, which can be retrieved via TABLE::get_binary_diffs().
1733 
1734  @param field the column being updated
1735  @param path the path to remove from the document
1736  @param[in,out] result buffer that holds the updated JSON document (is
1737  empty if no partial update has been performed on
1738  this Json_wrapper so far, or contains the binary
1739  representation of the document in this wrapper
1740  otherwise)
1741  @param[out] found_path gets set to true if the path is found in the
1742  document, false otherwise
1743 
1744  @retval false if the value was successfully updated
1745  @retval true if an error occurred
1746  */
1747  bool binary_remove(const Field_json *field, const Json_seekable_path &path,
1748  String *result, bool *found_path);
1749 #ifdef MYSQL_SERVER
1750  /**
1751  Sort contents. Applicable to JSON arrays only.
1752  */
1753  void sort(const CHARSET_INFO *cs = nullptr);
1754  /**
1755  Remove duplicate values. Applicable to JSON arrays only, array will be
1756  sorted.
1757  */
1758  void remove_duplicates(const CHARSET_INFO *cs = nullptr);
1759 #endif
1760 };
1761 
1762 /**
1763  Class that iterates over all members of a JSON object that is wrapped in a
1764  Json_wrapper instance.
1765 */
1767  public:
1768  // Type aliases required by ForwardIterator.
1769  using value_type = std::pair<MYSQL_LEX_CSTRING, Json_wrapper>;
1770  using reference = const value_type &;
1771  using pointer = const value_type *;
1772  using difference_type = ptrdiff_t;
1773  using iterator_category = std::forward_iterator_tag;
1774 
1775  /**
1776  Creates an iterator that iterates over all members of the given
1777  Json_wrapper, if it wraps a JSON object. If the wrapper does not wrap a JSON
1778  object, the result is undefined.
1779 
1780  @param wrapper the Json_wrapper to iterate over
1781  @param begin true to construct an iterator that points to the first member
1782  of the object, false to construct a past-the-end iterator
1783  */
1784  Json_wrapper_object_iterator(const Json_wrapper &wrapper, bool begin);
1785 
1786  /// Forward iterators must be default constructible.
1787  Json_wrapper_object_iterator() = default;
1788 
1789  /// Advances the iterator to the next element.
1791  if (is_dom())
1792  ++m_iter;
1793  else
1794  ++m_current_element_index;
1795  m_current_member_initialized = false;
1796  return *this;
1797  }
1798 
1799  /**
1800  Advances the iterator to the next element and returns an iterator that
1801  points to the current element (post-increment operator).
1802  */
1805  ++(*this);
1806  return copy;
1807  }
1808 
1809  /// Checks two iterators for equality.
1810  bool operator==(const Json_wrapper_object_iterator &other) const {
1811  return is_dom() ? m_iter == other.m_iter
1812  : m_current_element_index == other.m_current_element_index;
1813  }
1814 
1815  /// Checks two iterators for inequality.
1816  bool operator!=(const Json_wrapper_object_iterator &other) const {
1817  return !(*this == other);
1818  }
1819 
1821  if (!m_current_member_initialized) initialize_current_member();
1822  return &m_current_member;
1823  }
1824 
1825  reference operator*() { return *this->operator->(); }
1826 
1827  private:
1828  /// Pair holding the key and value of the member pointed to by the iterator.
1830  /// True if #m_current_member is initialized.
1831  bool m_current_member_initialized{false};
1832  /// The binary JSON object being iterated over, or nullptr for DOMs.
1834  /// The index of the current member in the binary JSON object.
1836  /// Iterator pointing to the current member in the JSON DOM object.
1838  /// Returns true if iterating over a DOM.
1839  bool is_dom() const { return m_binary_value == nullptr; }
1840  /// Fill #m_current_member with the key and value of the current member.
1841  void initialize_current_member();
1842 };
1843 
1844 /**
1845  A wrapper over a JSON object which provides an interface that can be iterated
1846  over with a for-each loop.
1847 */
1849  public:
1851  explicit Json_object_wrapper(const Json_wrapper &wrapper)
1852  : m_wrapper(wrapper) {}
1853  const_iterator cbegin() const { return const_iterator(m_wrapper, true); }
1854  const_iterator cend() const { return const_iterator(m_wrapper, false); }
1855  const_iterator begin() const { return cbegin(); }
1856  const_iterator end() const { return cend(); }
1857 
1858  private:
1860 };
1861 
1862 /**
1863  Check if a string contains valid JSON text, without generating a
1864  Json_dom representation of the document.
1865 
1866  @param[in] text pointer to the beginning of the string
1867  @param[in] length the length of the string
1868  @return true if the string is valid JSON text, false otherwise
1869 */
1870 bool is_valid_json_syntax(const char *text, size_t length);
1871 
1872 /**
1873  A class that is capable of holding objects of any sub-type of
1874  Json_scalar. Used for pre-allocating space in query-duration memory
1875  for JSON scalars that are to be returned by get_json_atom_wrapper().
1876 
1877  This class should be replaced by std::variant when moving to C++17.
1878 */
1880  /// Union of all concrete subclasses of Json_scalar.
1891  /// Constructor which initializes the union to hold a Json_null value.
1892  Any_json_scalar() : m_null() {}
1893  /// Destructor which delegates to Json_scalar's virtual destructor.
1895  // All members have the same address, and all members are sub-types of
1896  // Json_scalar, so we can take the address of an arbitrary member and
1897  // convert it to Json_scalar.
1898  Json_scalar *scalar = &m_null;
1899  scalar->~Json_scalar();
1900  }
1901  };
1902 
1903  /// The buffer in which the Json_scalar value is stored.
1905 
1906  /// Pointer to the held scalar, or nullptr if no value is held.
1907  Json_scalar *m_scalar_ptr{nullptr};
1908 
1909  public:
1910  /// Get a pointer to the held object, or nullptr if there is none.
1911  Json_scalar *get() { return m_scalar_ptr; }
1912 
1913  /**
1914  Construct a new Json_scalar value in this Json_scalar_holder.
1915  If a value is already held, the old value is destroyed and replaced.
1916  @tparam T which type of Json_scalar to create
1917  @param args the arguments to T's constructor
1918  */
1919  template <typename T, typename... Args>
1920  void emplace(Args &&... args) {
1921  static_assert(std::is_base_of<Json_scalar, T>::value, "Not a Json_scalar");
1922  static_assert(sizeof(T) <= sizeof(m_buffer), "Buffer is too small");
1923  m_scalar_ptr = &m_buffer.m_null;
1924  m_scalar_ptr->~Json_scalar();
1925  ::new (m_scalar_ptr) T(std::forward<Args>(args)...);
1926  }
1927 };
1928 
1929 #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:1143
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:1770
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:2025
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:1772
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:1851
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:1856
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:1889
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:1879
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:1810
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:1092
const_iterator begin() const
Definition: json_dom.h:1855
Definition: mysql_lex_string.h:39
Json_int m_int
Definition: json_dom.h:1884
value_type m_current_member
Pair holding the key and value of the member pointed to by the iterator.
Definition: json_dom.h:1829
bool is_number() const final override
Definition: json_dom.h:736
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:1803
const_iterator cbegin() const
Definition: json_dom.h:1853
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
uint32 depth() const final override
Compute the depth of a document.
Definition: json_dom.h:690
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:1833
Represents a MySQL integer (64 bits signed) JSON scalar (an extension of the ECMA number value)...
Definition: json_dom.h:855
Json_object::const_iterator m_iter
Iterator pointing to the current member in the JSON DOM object.
Definition: json_dom.h:1837
Class that iterates over all members of a JSON object that is wrapped in a Json_wrapper instance...
Definition: json_dom.h:1766
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:1328
bool is_dom() const
Returns true if iterating over a DOM.
Definition: json_dom.h:1839
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:1289
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:1894
#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:76
const_iterator end() const
Returns a const_iterator that refers past the last element.
Definition: json_dom.h:490
Definition: json_dom.h:1126
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)
Function for double-quoting a string and escaping characters to make up a valid EMCA Json text...
Definition: json_dom.cc:1261
Json_path get_location()
Get the path location of this dom, measured from the outermost document it nests inside.
Definition: json_dom.cc:1998
Represents a JSON array container, i.e.
Definition: json_dom.h:519
std::forward_iterator_tag iterator_category
Definition: json_dom.h:1773
Json_dom_ptr clone() const override
Make a deep clone.
Definition: json_dom.h:913
Json_decimal m_decimal
Definition: json_dom.h:1883
bool m_is_dom
Wraps a DOM iff true.
Definition: json_dom.h:1159
#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:1892
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:1124
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
bool is_scalar() const final override
Definition: json_dom.h:693
const value_type * pointer
Definition: json_dom.h:1771
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:1255
Json_string m_string
Definition: json_dom.h:1882
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:1279
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:1904
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:1127
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:1195
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:1622
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:1204
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:1587
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:1885
#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:1886
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:1859
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:1174
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:1604
Json_opaque m_opaque
Definition: json_dom.h:1890
bool is_dom() const
Does this wrapper contain a DOM?
Definition: json_dom.h:1263
reference operator*()
Definition: json_dom.h:1825
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:1790
Definition: json_dom.h:1125
std::pair< MYSQL_LEX_CSTRING, Json_wrapper > value_type
Definition: json_dom.h:1769
Json_boolean m_boolean
Definition: json_dom.h:1887
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:1152
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:1881
A field that stores a JSON value.
Definition: field.h:4038
const_iterator cend() const
Definition: json_dom.h:1854
size_t m_current_element_index
The index of the current member in the binary JSON object.
Definition: json_dom.h:1835
Json_null m_null
Definition: json_dom.h:1888
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:1920
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:1154
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:1848
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:1816
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:1820
json_binary::Value m_value
The binary representation, only used if m_is_dom is false.
Definition: json_dom.h:1157
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:103
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:799
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