MySQL 8.0.33
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, 2023, 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
44#include "sql/psi_memory_key.h" // key_memory_JSON
45
46class Field_json;
47class Json_dom;
48class Json_wrapper;
49class String;
50
51/// Enum that describes what kind of operation a Json_diff object represents.
53 /**
54 The JSON value in the given path is replaced with a new value.
55 It has the same effect as `JSON_REPLACE(col, path, value)`.
56 */
57 REPLACE,
58
59 /**
60 Add a new element at the given path.
61
62 If the path specifies an array element, it has the same effect as
63 `JSON_ARRAY_INSERT(col, path, value)`.
64
65 If the path specifies an object member, it has the same effect as
66 `JSON_INSERT(col, path, value)`.
67 */
68 INSERT,
69
70 /**
71 The JSON value at the given path is removed from an array or object.
72 It has the same effect as `JSON_REMOVE(col, path)`.
73 */
74 REMOVE,
75};
76/// The number of elements of the enumeration above.
77static const int JSON_DIFF_OPERATION_COUNT = 3;
78
79/**
80 A class that represents a logical change to a JSON document. It is used by
81 row-based replication to send information about changes in JSON documents
82 without sending the whole updated document.
83*/
84class Json_diff final {
85 /// The path that is changed.
87 /// The operation to perform on the changed path.
89 /// The new value to add to the changed path.
90 std::unique_ptr<Json_dom> m_value;
91
92 /// The length of the operation when encoded in binary format.
93 static const size_t ENCODED_OPERATION_BYTES = 1;
94
95 public:
96 /**
97 Construct a Json_diff object.
98
99 @param path the path that is changed
100 @param operation the operation to perform on the path
101 @param value the new value in the path (the Json_diff object
102 takes over the ownership of the value)
103 */
105 std::unique_ptr<Json_dom> value)
108 m_value(std::move(value)) {
109 for (const Json_path_leg *leg : path) m_path.append(*leg);
110 }
111
112 /// Get the path that is changed by this diff.
113 const Json_path &path() const { return m_path; }
114
115 /// Get the operation that is performed on the path.
117
118 /**
119 Get a Json_wrapper representing the new value to add to the path. The
120 wrapper is an alias, so the ownership of the contained Json_dom is retained
121 by the Json_diff object.
122 @see Json_wrapper::set_alias()
123 */
124 Json_wrapper value() const;
125
126 size_t binary_length() const;
127 /**
128 Serialize this Json_diff object and append to the given string
129
130 @param to The String to append to
131 @retval false Success
132 @retval true Failure, meaning out of memory
133 */
134 bool write_binary(String *to) const;
135};
136
137/**
138 Vector of logical diffs describing changes to a JSON column.
139*/
141 public:
142 /// Type of the allocator for the underlying invector.
144 /// Type of the underlying vector
145 typedef std::vector<Json_diff, allocator_type> vector;
146 /// Type of iterator over the underlying vector
147 typedef vector::iterator iterator;
148 /// Type of iterator over the underlying vector
149 typedef vector::const_iterator const_iterator;
150 /**
151 Constructor
152 @param arg Mem_root_allocator to use for the vector
153 */
154 explicit Json_diff_vector(allocator_type arg);
155 /**
156 Append a new diff at the end of this vector.
157 @param path Path to update
158 @param operation Operation
159 @param dom New value to insert
160 */
161 void add_diff(const Json_seekable_path &path,
162 enum_json_diff_operation operation,
163 std::unique_ptr<Json_dom> dom);
164 /**
165 Append a new diff at the end of this vector when operation == REMOVE.
166 @param path Path to update
167 @param operation Operation
168 */
169 void add_diff(const Json_seekable_path &path,
170 enum_json_diff_operation operation);
171 /// Clear the vector.
172 void clear();
173 /// Return the number of elements in the vector.
174 inline size_t size() const { return m_vector.size(); }
175
176 /**
177 Return the element at the given position
178 @param pos Position
179 @return the pos'th element
180 */
181 inline Json_diff &at(size_t pos) { return m_vector.at(pos); }
182
183 // Return forward iterator to the beginning
184 inline const_iterator begin() const { return m_vector.begin(); }
185
186 // Return forward iterator to the end
187 const_iterator end() const { return m_vector.end(); }
188
189 /**
190 Return the length of the binary representation of this
191 Json_diff_vector.
192
193 The binary format has this form:
194
195 +--------+--------+--------+ +--------+
196 | length | diff_1 | diff_2 | ... | diff_N |
197 +--------+--------+--------+ +--------+
198
199 This function returns the length of only the diffs, if
200 include_metadata==false. It returns the length of the 'length'
201 field plus the length of the diffs, if include_metadata=true. The
202 value of the 'length' field is exactly the return value from this
203 function when include_metadata=false.
204
205 @param include_metadata if true, include the length of the length
206 field in the computation, otherwise don't.
207
208 @return The computed length
209 */
210 size_t binary_length(bool include_metadata = true) const;
211
212 /**
213 Serialize this Json_diff_vector into the given String.
214
215 @param to String to which the vector will be appended
216
217 @retval false Success
218 @retval true Failure (out of memory)
219 */
220 bool write_binary(String *to) const;
221
222 /**
223 De-serialize Json_diff objects from the given String into this
224 Json_diff_vector.
225
226 @param[in,out] from Pointer to buffer to read from. The function
227 will move this to point to the next byte to read after those that
228 were read.
229
230 @param[in] table Table structure (used for error messages).
231
232 @param[in] field_name Field name (used for error messages).
233
234 @retval false Success
235 @retval true Failure (bad format or out of memory)
236 */
237 bool read_binary(const char **from, const struct TABLE *table,
238 const char *field_name);
239
240 /// An empty diff vector (having no diffs).
242
243 private:
244 // The underlying vector
246
247 /// Length in bytes of the binary representation, not counting the 4 bytes
248 /// length
250
251 /// The length of the field where the total length is encoded.
252 static const size_t ENCODED_LENGTH_BYTES = 4;
253};
254
255/**
256 The result of applying JSON diffs on a JSON value using apply_json_diffs().
257*/
259 /**
260 The JSON diffs were applied and the JSON value in the column was updated
261 successfully.
262 */
263 SUCCESS,
264
265 /**
266 An error was raised while applying one of the diffs. The value in the
267 column was not updated.
268 */
269 ERROR,
270
271 /**
272 One of the diffs was rejected. This could happen if the path specified in
273 the diff does not exist in the JSON value, or if the diff is supposed to
274 add a new value at a given path, but there already is a value at the path.
275
276 This return code would usually indicate that the replication slave where
277 the diff is applied, is out of sync with the replication master where the
278 diff was created.
279
280 The value in the column was not updated, but no error was raised.
281 */
282 REJECTED,
283};
284
285/**
286 Apply a sequence of JSON diffs to the value stored in a JSON column.
287
288 @param field the column to update
289 @param diffs the diffs to apply
290 @return an enum_json_diff_status value that tells if the diffs were
291 applied successfully
292*/
294 const Json_diff_vector *diffs);
295
296#endif /* JSON_DIFF_INCLUDED */
A field that stores a JSON value.
Definition: field.h:3930
Vector of logical diffs describing changes to a JSON column.
Definition: json_diff.h:140
std::vector< Json_diff, allocator_type > vector
Type of the underlying vector.
Definition: json_diff.h:145
size_t m_binary_length
Length in bytes of the binary representation, not counting the 4 bytes length.
Definition: json_diff.h:249
vector::iterator iterator
Type of iterator over the underlying vector.
Definition: json_diff.h:147
const_iterator end() const
Definition: json_diff.h:187
static const size_t ENCODED_LENGTH_BYTES
The length of the field where the total length is encoded.
Definition: json_diff.h:252
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:255
Mem_root_allocator< Json_diff > allocator_type
Type of the allocator for the underlying invector.
Definition: json_diff.h:143
size_t size() const
Return the number of elements in the vector.
Definition: json_diff.h:174
vector::const_iterator const_iterator
Type of iterator over the underlying vector.
Definition: json_diff.h:149
Json_diff_vector(allocator_type arg)
Constructor.
Definition: json_diff.cc:229
const_iterator begin() const
Definition: json_diff.h:184
Json_diff & at(size_t pos)
Return the element at the given position.
Definition: json_diff.h:181
vector m_vector
Definition: json_diff.h:245
bool write_binary(String *to) const
Serialize this Json_diff_vector into the given String.
Definition: json_diff.cc:259
static const Json_diff_vector EMPTY_JSON_DIFF_VECTOR
An empty diff vector (having no diffs).
Definition: json_diff.h:241
void clear()
Clear the vector.
Definition: json_diff.cc:250
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:281
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:237
A class that represents a logical change to a JSON document.
Definition: json_diff.h:84
size_t binary_length() const
Definition: json_diff.cc:108
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:93
const Json_path & path() const
Get the path that is changed by this diff.
Definition: json_diff.h:113
std::unique_ptr< Json_dom > m_value
The new value to add to the changed path.
Definition: json_diff.h:90
Json_path m_path
The path that is changed.
Definition: json_diff.h:86
bool write_binary(String *to) const
Serialize this Json_diff object and append to the given string.
Definition: json_diff.cc:147
enum_json_diff_operation m_operation
The operation to perform on the changed path.
Definition: json_diff.h:88
enum_json_diff_operation operation() const
Get the operation that is performed on the path.
Definition: json_diff.h:116
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:104
JSON DOM abstract base class.
Definition: json_dom.h:172
One path leg in a JSON path expression.
Definition: json_path.h:149
A JSON path expression.
Definition: json_path.h:356
bool append(const Json_path_leg &leg)
Add a path leg to the end of this path.
Definition: json_path.h:414
A path expression which can be used to seek to a position inside a JSON value.
Definition: json_path.h:301
Abstraction for accessing JSON values irrespective of whether they are (started out as) binary JSON v...
Definition: json_dom.h:1160
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:166
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:402
enum_json_diff_status
The result of applying JSON diffs on a JSON value using apply_json_diffs().
Definition: json_diff.h:258
@ 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:52
@ 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:77
This file contains interface support for the JSON path abstraction.
static char * path
Definition: mysqldump.cc:133
Definition: varlen_sort.h:183
PSI_memory_key key_memory_JSON
Definition: psi_memory_key.cc:52
Definition: table.h:1395