MySQL  8.0.16
Source Code Documentation
json_binary.h File Reference

This file specifies the interface for serializing JSON values into binary representation, and for reading values back from the binary representation. More...

#include <stddef.h>
#include <string>
#include "field_types.h"
#include "my_dbug.h"
#include "my_inttypes.h"

Go to the source code of this file.

Classes

class  json_binary::Value
 Class used for reading JSON values that are stored in the binary format. More...
 

Namespaces

 json_binary
 

Functions

bool json_binary::serialize (const THD *thd, const Json_dom *dom, String *dest)
 Serialize the JSON document represented by dom to binary format in the destination string, replacing any content already in the destination string. More...
 
Value json_binary::parse_binary (const char *data, size_t len)
 Parse a JSON binary document. More...
 
bool json_binary::space_needed (const THD *thd, const Json_wrapper *value, bool large, size_t *needed)
 How much space is needed for a JSON value when it is stored in the binary format. More...
 
template<typename Func >
bool json_binary::for_each_node (const Value &value, const Func &func)
 Apply a function to every value in a JSON document. More...
 

Detailed Description

This file specifies the interface for serializing JSON values into binary representation, and for reading values back from the binary representation.

The binary format is as follows:

Each JSON value (scalar, object or array) has a one byte type identifier followed by the actual value.

If the value is a JSON object, its binary representation will have a header that contains:

  • the member count
  • the size of the binary value in bytes
  • a list of pointers to each key
  • a list of pointers to each value

The actual keys and values will come after the header, in the same order as in the header.

Similarly, if the value is a JSON array, the binary representation will have a header with

  • the element count
  • the size of the binary value in bytes
  • a list of pointers to each value

followed by the actual values, in the same order as in the header.

doc ::= type value

type ::=
    0x00 |       // small JSON object
    0x01 |       // large JSON object
    0x02 |       // small JSON array
    0x03 |       // large JSON array
    0x04 |       // literal (true/false/null)
    0x05 |       // int16
    0x06 |       // uint16
    0x07 |       // int32
    0x08 |       // uint32
    0x09 |       // int64
    0x0a |       // uint64
    0x0b |       // double
    0x0c |       // utf8mb4 string
    0x0f         // custom data (any MySQL data type)

value ::=
    object  |
    array   |
    literal |
    number  |
    string  |
    custom-data

object ::= element-count size key-entry* value-entry* key* value*

array ::= element-count size value-entry* value*

// number of members in object or number of elements in array
element-count ::=
    uint16 |  // if used in small JSON object/array
    uint32    // if used in large JSON object/array

// number of bytes in the binary representation of the object or array
size ::=
    uint16 |  // if used in small JSON object/array
    uint32    // if used in large JSON object/array

key-entry ::= key-offset key-length

key-offset ::=
    uint16 |  // if used in small JSON object
    uint32    // if used in large JSON object

key-length ::= uint16    // key length must be less than 64KB

value-entry ::= type offset-or-inlined-value

// This field holds either the offset to where the value is stored,
// or the value itself if it is small enough to be inlined (that is,
// if it is a JSON literal or a small enough [u]int).
offset-or-inlined-value ::=
    uint16 |   // if used in small JSON object/array
    uint32     // if used in large JSON object/array

key ::= utf8mb4-data

literal ::=
    0x00 |   // JSON null literal
    0x01 |   // JSON true literal
    0x02 |   // JSON false literal

number ::=  ....  // little-endian format for [u]int(16|32|64), whereas
                  // double is stored in a platform-independent, eight-byte
                  // format using float8store()

string ::= data-length utf8mb4-data

custom-data ::= custom-type data-length binary-data

custom-type ::= uint8   // type identifier that matches the
                        // internal enum_field_types enum

data-length ::= uint8*  // If the high bit of a byte is 1, the length
                        // field is continued in the next byte,
                        // otherwise it is the last byte of the length
                        // field. So we need 1 byte to represent
                        // lengths up to 127, 2 bytes to represent
                        // lengths up to 16383, and so on...