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