MySQL  8.0.27
Source Code Documentation
json_diff.h
Go to the documentation of this file.
1 #ifndef JSON_DIFF_INCLUDED
2 #define JSON_DIFF_INCLUDED
3 
4 /* Copyright (c) 2017, 2021, Oracle and/or its affiliates.
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License, version 2.0,
8  as published by the Free Software Foundation.
9 
10  This program is also distributed with certain software (including
11  but not limited to OpenSSL) that is licensed under separate terms,
12  as designated in a particular file or component or in included license
13  documentation. The authors of MySQL hereby grant you an additional
14  permission to link the program and your derivative works with the
15  separately licensed software that they have included with MySQL.
16 
17  This program is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  GNU General Public License, version 2.0, for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with this program; if not, write to the Free Software
24  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
25 
26 /**
27  @file
28 
29  Header file for the Json_diff class.
30 
31  The Json_diff class is used to represent a logical change in a JSON column,
32  so that a replication master can send only what has changed, instead of
33  sending the whole new value to the replication slave when a JSON column is
34  updated.
35 */
36 
37 #include <stddef.h>
38 #include <algorithm>
39 #include <memory> // std::unique_ptr
40 #include <vector>
41 
42 #include "sql/json_path.h"
43 #include "sql/mem_root_allocator.h"
44 
45 class Field_json;
46 class Json_dom;
47 class Json_wrapper;
48 class String;
49 
50 /// Enum that describes what kind of operation a Json_diff object represents.
52  /**
53  The JSON value in the given path is replaced with a new value.
54  It has the same effect as `JSON_REPLACE(col, path, value)`.
55  */
56  REPLACE,
57 
58  /**
59  Add a new element at the given path.
60 
61  If the path specifies an array element, it has the same effect as
62  `JSON_ARRAY_INSERT(col, path, value)`.
63 
64  If the path specifies an object member, it has the same effect as
65  `JSON_INSERT(col, path, value)`.
66  */
67  INSERT,
68 
69  /**
70  The JSON value at the given path is removed from an array or object.
71  It has the same effect as `JSON_REMOVE(col, path)`.
72  */
73  REMOVE,
74 };
75 /// The number of elements of the enumeration above.
76 static const int JSON_DIFF_OPERATION_COUNT = 3;
77 
78 /**
79  A class that represents a logical change to a JSON document. It is used by
80  row-based replication to send information about changes in JSON documents
81  without sending the whole updated document.
82 */
83 class Json_diff final {
84  /// The path that is changed.
86  /// The operation to perform on the changed path.
88  /// The new value to add to the changed path.
89  std::unique_ptr<Json_dom> m_value;
90 
91  /// The length of the operation when encoded in binary format.
92  static const size_t ENCODED_OPERATION_BYTES = 1;
93 
94  public:
95  /**
96  Construct a Json_diff object.
97 
98  @param path the path that is changed
99  @param operation the operation to perform on the path
100  @param value the new value in the path (the Json_diff object
101  takes over the ownership of the value)
102  */
104  std::unique_ptr<Json_dom> value)
105  : m_path(), m_operation(operation), m_value(std::move(value)) {
106  for (const Json_path_leg *leg : path) m_path.append(*leg);
107  }
108 
109  /// Get the path that is changed by this diff.
110  const Json_path &path() const { return m_path; }
111 
112  /// Get the operation that is performed on the path.
114 
115  /**
116  Get a Json_wrapper representing the new value to add to the path. The
117  wrapper is an alias, so the ownership of the contained Json_dom is retained
118  by the Json_diff object.
119  @see Json_wrapper::set_alias()
120  */
121  Json_wrapper value() const;
122 
123  size_t binary_length() const;
124  /**
125  Serialize this Json_diff object and append to the given string
126 
127  @param to The String to append to
128  @retval false Success
129  @retval true Failure, meaning out of memory
130  */
131  bool write_binary(String *to) const;
132 };
133 
134 /**
135  Vector of logical diffs describing changes to a JSON column.
136 */
138  public:
139  /// Type of the allocator for the underlying invector.
141  /// Type of the underlying vector
142  typedef std::vector<Json_diff, allocator_type> vector;
143  /// Type of iterator over the underlying vector
144  typedef vector::iterator iterator;
145  /// Type of iterator over the underlying vector
146  typedef vector::const_iterator const_iterator;
147  /**
148  Constructor
149  @param arg Mem_root_allocator to use for the vector
150  */
151  explicit Json_diff_vector(allocator_type arg);
152  /**
153  Append a new diff at the end of this vector.
154  @param path Path to update
155  @param operation Operation
156  @param dom New value to insert
157  */
158  void add_diff(const Json_seekable_path &path,
159  enum_json_diff_operation operation,
160  std::unique_ptr<Json_dom> dom);
161  /**
162  Append a new diff at the end of this vector when operation == REMOVE.
163  @param path Path to update
164  @param operation Operation
165  */
166  void add_diff(const Json_seekable_path &path,
167  enum_json_diff_operation operation);
168  /// Clear the vector.
169  void clear();
170  /// Return the number of elements in the vector.
171  inline size_t size() const { return m_vector.size(); }
172 
173  /**
174  Return the element at the given position
175  @param pos Position
176  @return the pos'th element
177  */
178  inline Json_diff &at(size_t pos) { return m_vector.at(pos); }
179 
180  // Return forward iterator to the beginning
181  inline const_iterator begin() const { return m_vector.begin(); }
182 
183  // Return forward iterator to the end
184  const_iterator end() const { return m_vector.end(); }
185 
186  /**
187  Return the length of the binary representation of this
188  Json_diff_vector.
189 
190  The binary format has this form:
191 
192  +--------+--------+--------+ +--------+
193  | length | diff_1 | diff_2 | ... | diff_N |
194  +--------+--------+--------+ +--------+
195 
196  This function returns the length of only the diffs, if
197  include_metadata==false. It returns the length of the 'length'
198  field plus the length of the diffs, if include_metadata=true. The
199  value of the 'length' field is exactly the return value from this
200  function when include_metadata=false.
201 
202  @param include_metadata if true, include the length of the length
203  field in the computation, otherwise don't.
204 
205  @return The computed length
206  */
207  size_t binary_length(bool include_metadata = true) const;
208 
209  /**
210  Serialize this Json_diff_vector into the given String.
211 
212  @param to String to which the vector will be appended
213 
214  @retval false Success
215  @retval true Failure (out of memory)
216  */
217  bool write_binary(String *to) const;
218 
219  /**
220  De-serialize Json_diff objects from the given String into this
221  Json_diff_vector.
222 
223  @param[in,out] from Pointer to buffer to read from. The function
224  will move this to point to the next byte to read after those that
225  were read.
226 
227  @param[in] table Table structure (used for error messages).
228 
229  @param[in] field_name Field name (used for error messages).
230 
231  @retval false Success
232  @retval true Failure (bad format or out of memory)
233  */
234  bool read_binary(const char **from, const struct TABLE *table,
235  const char *field_name);
236 
237  /// An empty diff vector (having no diffs).
239 
240  private:
241  // The underlying vector
243 
244  /// Length in bytes of the binary representation, not counting the 4 bytes
245  /// length
247 
248  /// The length of the field where the total length is encoded.
249  static const size_t ENCODED_LENGTH_BYTES = 4;
250 };
251 
252 /**
253  The result of applying JSON diffs on a JSON value using apply_json_diffs().
254 */
256  /**
257  The JSON diffs were applied and the JSON value in the column was updated
258  successfully.
259  */
260  SUCCESS,
261 
262  /**
263  An error was raised while applying one of the diffs. The value in the
264  column was not updated.
265  */
266  ERROR,
267 
268  /**
269  One of the diffs was rejected. This could happen if the path specified in
270  the diff does not exist in the JSON value, or if the diff is supposed to
271  add a new value at a given path, but there already is a value at the path.
272 
273  This return code would usually indicate that the replication slave where
274  the diff is applied, is out of sync with the replication master where the
275  diff was created.
276 
277  The value in the column was not updated, but no error was raised.
278  */
279  REJECTED,
280 };
281 
282 /**
283  Apply a sequence of JSON diffs to the value stored in a JSON column.
284 
285  @param field the column to update
286  @param diffs the diffs to apply
287  @return an enum_json_diff_status value that tells if the diffs were
288  applied successfully
289 */
291  const Json_diff_vector *diffs);
292 
293 #endif /* JSON_DIFF_INCLUDED */
A field that stores a JSON value.
Definition: field.h:3941
Vector of logical diffs describing changes to a JSON column.
Definition: json_diff.h:137
std::vector< Json_diff, allocator_type > vector
Type of the underlying vector.
Definition: json_diff.h:142
size_t m_binary_length
Length in bytes of the binary representation, not counting the 4 bytes length.
Definition: json_diff.h:246
vector::iterator iterator
Type of iterator over the underlying vector.
Definition: json_diff.h:144
const_iterator end() const
Definition: json_diff.h:184
static const size_t ENCODED_LENGTH_BYTES
The length of the field where the total length is encoded.
Definition: json_diff.h:249
size_t binary_length(bool include_metadata=true) const
Return the length of the binary representation of this Json_diff_vector.
Definition: json_diff.cc:254
Mem_root_allocator< Json_diff > allocator_type
Type of the allocator for the underlying invector.
Definition: json_diff.h:140
size_t size() const
Return the number of elements in the vector.
Definition: json_diff.h:171
vector::const_iterator const_iterator
Type of iterator over the underlying vector.
Definition: json_diff.h:146
Json_diff_vector(allocator_type arg)
Constructor.
Definition: json_diff.cc:228
const_iterator begin() const
Definition: json_diff.h:181
vector m_vector
Definition: json_diff.h:242
bool write_binary(String *to) const
Serialize this Json_diff_vector into the given String.
Definition: json_diff.cc:258
static const Json_diff_vector EMPTY_JSON_DIFF_VECTOR
An empty diff vector (having no diffs).
Definition: json_diff.h:238
void clear()
Clear the vector.
Definition: json_diff.cc:249
Json_diff & at(size_t pos)
Return the element at the given position.
Definition: json_diff.h:178
bool read_binary(const char **from, const struct TABLE *table, const char *field_name)
De-serialize Json_diff objects from the given String into this Json_diff_vector.
Definition: json_diff.cc:280
void add_diff(const Json_seekable_path &path, enum_json_diff_operation operation, std::unique_ptr< Json_dom > dom)
Append a new diff at the end of this vector.
Definition: json_diff.cc:236
A class that represents a logical change to a JSON document.
Definition: json_diff.h:83
size_t binary_length() const
Definition: json_diff.cc:107
Json_wrapper value() const
Get a Json_wrapper representing the new value to add to the path.
Definition: json_diff.cc:51
static const size_t ENCODED_OPERATION_BYTES
The length of the operation when encoded in binary format.
Definition: json_diff.h:92
const Json_path & path() const
Get the path that is changed by this diff.
Definition: json_diff.h:110
std::unique_ptr< Json_dom > m_value
The new value to add to the changed path.
Definition: json_diff.h:89
Json_path m_path
The path that is changed.
Definition: json_diff.h:85
bool write_binary(String *to) const
Serialize this Json_diff object and append to the given string.
Definition: json_diff.cc:146
enum_json_diff_operation m_operation
The operation to perform on the changed path.
Definition: json_diff.h:87
enum_json_diff_operation operation() const
Get the operation that is performed on the path.
Definition: json_diff.h:113
Json_diff(const Json_seekable_path &path, enum_json_diff_operation operation, std::unique_ptr< Json_dom > value)
Construct a Json_diff object.
Definition: json_diff.h:103
JSON DOM abstract base class.
Definition: json_dom.h:171
One path leg in a JSON path expression.
Definition: json_path.h:147
A JSON path expression.
Definition: json_path.h:354
bool append(const Json_path_leg &leg)
Add a path leg to the end of this path.
Definition: json_path.h:405
A path expression which can be used to seek to a position inside a JSON value.
Definition: json_path.h:299
Abstraction for accessing JSON values irrespective of whether they are (started out as) binary JSON v...
Definition: json_dom.h:1167
Mem_root_allocator is a C++ STL memory allocator based on MEM_ROOT.
Definition: mem_root_allocator.h:67
Using this class is fraught with peril, and you need to be very careful when doing so.
Definition: sql_string.h:165
char * pos
Definition: do_ctype.cc:76
enum_json_diff_status apply_json_diffs(Field_json *field, const Json_diff_vector *diffs)
Apply a sequence of JSON diffs to the value stored in a JSON column.
Definition: json_diff.cc:401
enum_json_diff_status
The result of applying JSON diffs on a JSON value using apply_json_diffs().
Definition: json_diff.h:255
@ REJECTED
One of the diffs was rejected.
@ ERROR
An error was raised while applying one of the diffs.
@ SUCCESS
The JSON diffs were applied and the JSON value in the column was updated successfully.
enum_json_diff_operation
Enum that describes what kind of operation a Json_diff object represents.
Definition: json_diff.h:51
@ REPLACE
The JSON value in the given path is replaced with a new value.
@ INSERT
Add a new element at the given path.
@ REMOVE
The JSON value at the given path is removed from an array or object.
static const int JSON_DIFF_OPERATION_COUNT
The number of elements of the enumeration above.
Definition: json_diff.h:76
This file contains interface support for the JSON path abstraction.
static char * path
Definition: mysqldump.cc:130
Definition: varlen_sort.h:183
Definition: table.h:1394