|
EXPORT_JSON_FUNCTION bool | is_valid () const |
| Does this value, and all of its members, represent a valid JSON value? More...
|
|
EXPORT_JSON_FUNCTION enum_type | type () const |
|
EXPORT_JSON_FUNCTION bool | large_format () const |
| Does this value use the large storage format? More...
|
|
EXPORT_JSON_FUNCTION const char * | get_data () const |
| Get a pointer to the beginning of the STRING or OPAQUE data represented by this instance. More...
|
|
EXPORT_JSON_FUNCTION uint32_t | get_data_length () const |
| Get the length in bytes of the STRING or OPAQUE value represented by this instance. More...
|
|
EXPORT_JSON_FUNCTION uint32_t | get_container_length () const |
| Get the length in bytes of the STRING or OPAQUE value represented by this instance. More...
|
|
EXPORT_JSON_FUNCTION const char * | get_container_data () const |
|
EXPORT_JSON_FUNCTION int64_t | get_int64 () const |
| Get the value of an INT. More...
|
|
EXPORT_JSON_FUNCTION uint64_t | get_uint64 () const |
| Get the value of a UINT. More...
|
|
EXPORT_JSON_FUNCTION double | get_double () const |
| Get the value of a DOUBLE. More...
|
|
EXPORT_JSON_FUNCTION uint32_t | element_count () const |
| Get the number of elements in an array, or the number of members in an object. More...
|
|
EXPORT_JSON_FUNCTION enum_field_types | field_type () const |
| Get the MySQL field type of an opaque value. More...
|
|
EXPORT_JSON_FUNCTION Value | element (size_t pos) const |
| Get the element at the specified position of a JSON array or a JSON object. More...
|
|
EXPORT_JSON_FUNCTION Value | key (size_t pos) const |
| Get the key of the member stored at the specified position in a JSON object. More...
|
|
EXPORT_JSON_FUNCTION Value | lookup (std::string_view key) const |
| Get the value associated with the specified key in a JSON object. More...
|
|
EXPORT_JSON_FUNCTION size_t | lookup_index (std::string_view key) const |
| Get the index of the element with the specified key in a JSON object. More...
|
|
EXPORT_JSON_FUNCTION bool | is_backed_by (const String *str) const |
| Is this binary value pointing to data that is contained in the specified string. More...
|
|
EXPORT_JSON_FUNCTION bool | raw_binary (const JsonSerializationErrorHandler &error_handler, String *buf) const |
| Copy the binary representation of this value into a buffer, replacing the contents of the receiving buffer. More...
|
|
EXPORT_JSON_FUNCTION bool | get_free_space (const JsonSerializationErrorHandler &error_handler, size_t *space) const |
| Get the amount of unused space in the binary representation of this value. More...
|
|
bool | update_in_shadow (const Field_json *field, size_t pos, Json_wrapper *new_value, size_t data_offset, size_t data_length, const char *original, char *destination, bool *changed) const |
| Update a value in an array or object. More...
|
|
bool | remove_in_shadow (const Field_json *field, size_t pos, const char *original, char *destination) const |
| Remove a value from an array or object. More...
|
|
EXPORT_JSON_FUNCTION bool | has_space (size_t pos, size_t needed, size_t *offset) const |
| Does this array or object have enough space to replace the value at the given position with another value of a given size? More...
|
|
EXPORT_JSON_FUNCTION | Value (enum_type t) |
| Constructor for values that represent literals or errors. More...
|
|
EXPORT_JSON_FUNCTION | Value (enum_type t, int64_t val) |
| Constructor for values that represent ints or uints. More...
|
|
EXPORT_JSON_FUNCTION | Value (double val) |
| Constructor for values that represent doubles. More...
|
|
EXPORT_JSON_FUNCTION | Value (const char *data, uint32_t len) |
| Constructor for values that represent strings. More...
|
|
EXPORT_JSON_FUNCTION | Value (enum_type t, const char *data, uint32_t bytes, uint32_t element_count, bool large) |
| Constructor for values that represent arrays or objects. More...
|
|
EXPORT_JSON_FUNCTION | Value (enum_field_types ft, const char *data, uint32_t len) |
| Constructor for values that represent opaque data. More...
|
|
EXPORT_JSON_FUNCTION | Value () |
| Empty constructor. More...
|
|
EXPORT_JSON_FUNCTION bool | is_array () const |
| Is this value an array? More...
|
|
EXPORT_JSON_FUNCTION bool | is_object () const |
| Is this value an object? More...
|
|
EXPORT_JSON_FUNCTION bool | to_std_string (std::string *buffer, const JsonErrorHandler &depth_handler) const |
| Format the JSON value to an external JSON string in buffer in the format of ISO/IEC 10646. More...
|
|
EXPORT_JSON_FUNCTION bool | to_pretty_std_string (std::string *buffer, const JsonErrorHandler &depth_handler) const |
| Format the JSON value to an external JSON string in buffer in the format of ISO/IEC 10646. More...
|
|
int | eq (const Value &val) const |
| Compare two Values. More...
|
|
EXPORT_JSON_FUNCTION size_t | key_entry_offset (size_t pos) const |
| Get the offset of the key entry that describes the key of the member at a given position in this object. More...
|
|
EXPORT_JSON_FUNCTION size_t | value_entry_offset (size_t pos) const |
| Get the offset of the value entry that describes the element at a given position in this array or object. More...
|
|
Class used for reading JSON values that are stored in the binary format.
Values are parsed lazily, so that only the parts of the value that are interesting to the caller, are read. Array elements can be looked up in constant time using the element() function. Object members can be looked up in O(log n) time using the lookup() function.
bool json_binary::Value::remove_in_shadow |
( |
const Field_json * |
field, |
|
|
size_t |
pos, |
|
|
const char * |
original, |
|
|
char * |
destination |
|
) |
| const |
Remove a value from an array or object.
The updated JSON document is written to a shadow copy. The original document is left unchanged, unless the shadow copy is actually a pointer to the array backing this Value object. It is assumed that the shadow copy is at least as big as the original document, and that there is enough space at the given position to hold the new value.
Typically, if a document is modified multiple times in a single update statement, the first invocation of remove_in_shadow() will have a Value object that points into the binary data in the Field, and write to a separate destination buffer. Subsequent updates of the document will have a Value object that points to the partially updated value in the destination buffer, and write the new modifications to the same buffer.
All changes made to the binary value are recorded as binary diffs using TABLE::add_binary_diff().
- Parameters
-
field | the column that is updated |
pos | the element to remove |
original | pointer to the start of the JSON document |
destination | pointer to the shadow copy of the JSON document (it could be the same as original, in which case the original document will be modified) |
- Returns
- false on success, true if an error occurred
- Example of partial update
- Take the JSON document { "a": "x", "b": "y", "c": "z" }, whose serialized representation looks like the following:
0x00 - type: JSONB_TYPE_SMALL_OBJECT
0x03 - number of elements (low byte)
0x00 - number of elements (high byte)
0x22 - number of bytes (low byte)
0x00 - number of bytes (high byte)
0x19 - offset of key "a" (high byte)
0x00 - offset of key "a" (low byte)
0x01 - length of key "a" (high byte)
0x00 - length of key "a" (low byte)
0x1a - offset of key "b" (high byte)
0x00 - offset of key "b" (low byte)
0x01 - length of key "b" (high byte)
0x00 - length of key "b" (low byte)
0x1b - offset of key "c" (high byte)
0x00 - offset of key "c" (low byte)
0x01 - length of key "c" (high byte)
0x00 - length of key "c" (low byte)
0x0c - type of value "a": JSONB_TYPE_STRING
0x1c - offset of value "a" (high byte)
0x00 - offset of value "a" (low byte)
0x0c - type of value "b": JSONB_TYPE_STRING
0x1e - offset of value "b" (high byte)
0x00 - offset of value "b" (low byte)
0x0c - type of value "c": JSONB_TYPE_STRING
0x20 - offset of value "c" (high byte)
0x00 - offset of value "c" (low byte)
0x61 - first key ('a')
0x62 - second key ('b')
0x63 - third key ('c')
0x01 - length of value "a"
0x78 - contents of value "a" ('x')
0x01 - length of value "b"
0x79 - contents of value "b" ('y')
0x01 - length of value "c"
0x7a - contents of value "c" ('z')
We remove the member with name 'b' from the document, using a statement such as: UPDATE t SET j = JSON_REMOVE(j, '$.b')
This function will then remove the element by moving the key entries and value entries that follow the removed member so that they overwrite the existing entries, and the element count is decremented.
The resulting binary document will look like this:
0x00 - type: JSONB_TYPE_SMALL_OBJECT
CHANGED 0x02 - number of elements (low byte)
0x00 - number of elements (high byte)
0x22 - number of bytes (low byte)
0x00 - number of bytes (high byte)
0x19 - offset of key "a" (high byte)
0x00 - offset of key "a" (low byte)
0x01 - length of key "a" (high byte)
0x00 - length of key "a" (low byte)
CHANGED 0x1b - offset of key "c" (high byte)
CHANGED 0x00 - offset of key "c" (low byte)
CHANGED 0x01 - length of key "c" (high byte)
CHANGED 0x00 - length of key "c" (low byte)
CHANGED 0x0c - type of value "a": JSONB_TYPE_STRING
CHANGED 0x1c - offset of value "a" (high byte)
CHANGED 0x00 - offset of value "a" (low byte)
CHANGED 0x0c - type of value "c": JSONB_TYPE_STRING
CHANGED 0x20 - offset of value "c" (high byte)
CHANGED 0x00 - offset of value "c" (low byte)
(free) 0x00
(free) 0x0c
(free) 0x1e
(free) 0x00
(free) 0x0c
(free) 0x20
(free) 0x00
0x61 - first key ('a')
(free) 0x62
0x63 - third key ('c')
0x01 - length of value "a"
0x78 - contents of value "a" ('x')
(free) 0x01
(free) 0x79
0x01 - length of value "c"
0x7a - contents of value "c" ('z')
Two binary diffs will be created. One diff changes the element count, and one diff changes the key and value entries.
bool json_binary::Value::update_in_shadow |
( |
const Field_json * |
field, |
|
|
size_t |
pos, |
|
|
Json_wrapper * |
new_value, |
|
|
size_t |
data_offset, |
|
|
size_t |
data_length, |
|
|
const char * |
original, |
|
|
char * |
destination, |
|
|
bool * |
changed |
|
) |
| const |
Update a value in an array or object.
The updated value is written to a shadow copy. The original array or object is left unchanged, unless the shadow copy is actually a pointer to the array backing this Value object. It is assumed that the shadow copy is at least as big as the original document, and that there is enough space at the given position to hold the new value.
Typically, if a document is modified multiple times in a single update statement, the first invocation of update_in_shadow() will have a Value object that points into the binary data in the Field, and write to a separate destination buffer. Subsequent updates of the document will have a Value object that points to the partially updated value in the destination buffer, and write the new modifications to the same buffer.
All changes made to the binary value are recorded as binary diffs using TABLE::add_binary_diff().
- Parameters
-
| field | the column that is updated |
| pos | the element to update |
| new_value | the new value of the element |
| data_offset | where to write the value (offset relative to the beginning of the array or object, obtained with has_space) or zero if the value can be inlined |
| data_length | the length of the new value in bytes or zero if the value can be inlined |
| original | pointer to the start of the JSON document |
| destination | pointer to the shadow copy of the JSON document (it could be the same as original, in which case the original document will be modified) |
[out] | changed | gets set to true if a change was made to the document, or to false if this operation was a no-op |
- Returns
- false on success, true if an error occurred
- Example of partial update
- Given the JSON document [ "abc", "def" ], which is serialized like this in a JSON column:
0x02 - type: small JSON array
0x02 - number of elements (low byte)
0x00 - number of elements (high byte)
0x12 - number of bytes (low byte)
0x00 - number of bytes (high byte)
0x0C - type of element 0 (string)
0x0A - offset of element 0 (low byte)
0x00 - offset of element 0 (high byte)
0x0C - type of element 1 (string)
0x0E - offset of element 1 (low byte)
0x00 - offset of element 1 (high byte)
0x03 - length of element 0
'a'
'b' - content of element 0
'c'
0x03 - length of element 1
'd'
'e' - content of element 1
'f'
Let's change element 0 from "abc" to "XY" using the following statement: UPDATE t SET j = JSON_SET(j, '$[0]', 'XY')
Since we're replacing one string with a shorter one, we can just overwrite the length byte with the new length, and the beginning of the original string data. Since the original string "abc" is longer than the new string "XY", we'll have a free byte at the end of the string. This byte is left as is ('c'). The resulting binary representation looks like this: 0x02 - type: small JSON array
0x02 - number of elements (low byte)
0x00 - number of elements (high byte)
0x12 - number of bytes (low byte)
0x00 - number of bytes (high byte)
0x0C - type of element 0 (string)
0x0A - offset of element 0 (low byte)
0x00 - offset of element 0 (high byte)
0x0C - type of element 1 (string)
0x0E - offset of element 1 (low byte)
0x00 - offset of element 1 (high byte)
CHANGED 0x02 - length of element 0
CHANGED 'X'
CHANGED 'Y' - content of element 0
(free) 'c'
0x03 - length of element 1
'd'
'e' - content of element 1
'f'
This change will be represented as one binary diff that covers the three changed bytes.
Let's now change element 1 from "def" to "XYZW":
UPDATE t SET j = JSON_SET(j, '$[1]', 'XYZW')
Since the new string is one byte longer than the original string, we cannot simply overwrite the old one. But we can reuse the free byte from the previous update, which is immediately preceding the original value.
To make use of this, we need to change the offset of element 1 to point to the free byte. Then we can overwrite the free byte and the original string data with the new length and string contents. Resulting binary representation:
0x02 - type: small JSON array
0x02 - number of elements (low byte)
0x00 - number of elements (high byte)
0x12 - number of bytes (low byte)
0x00 - number of bytes (high byte)
0x0C - type of element 0 (string)
0x0A - offset of element 0 (low byte)
0x00 - offset of element 0 (high byte)
0x0C - type of element 1 (string)
CHANGED 0x0D - offset of element 1 (low byte)
0x00 - offset of element 1 (high byte)
0x02 - length of element 0
'X' - content of element 0
'Y' - content of element 0
CHANGED 0x04 - length of element 1
CHANGED 'X'
CHANGED 'Y'
CHANGED 'Z' - content of element 1
CHANGED 'W'
This change will be represented as two binary diffs. One diff for changing the offset, and one for changing the contents of the string.
Then let's replace the string in element 1 with a small number:
UPDATE t SET j = JSON_SET(j, '$[1]', 456)
This will change the type of element 1 from string to int16. Such small numbers are inlined in the value entry, where we normally store the offset of the value. The offset section of the value entry is therefore changed to hold the number 456. The length and contents of the original value ("XYZW") are not touched, but they are now unused and free to be reused. Resulting binary representation:
0x02 - type: small JSON array
0x02 - number of elements (low byte)
0x00 - number of elements (high byte)
0x12 - number of bytes (low byte)
0x00 - number of bytes (high byte)
0x0C - type of element 0 (string)
0x0A - offset of element 0 (low byte)
0x00 - offset of element 0 (high byte)
CHANGED 0x05 - type of element 1 (int16)
CHANGED 0xC8 - value of element 1 (low byte)
CHANGED 0x01 - value of element 1 (high byte)
0x02 - length of element 0
'X' - content of element 0
'Y' - content of element 0
(free) 0x04 - length of element 1
(free) 'X'
(free) 'Y'
(free) 'Z' - content of element 1
(free) 'W'
The change is represented as one binary diff that changes the value entry (type and inlined value).