MySQL 9.0.0
Source Code Documentation
json_dom.cc File Reference
#include "sql-common/json_dom.h"
#include <errno.h>
#include <float.h>
#include <limits.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <algorithm>
#include <array>
#include <cmath>
#include <functional>
#include <new>
#include <numeric>
#include <string_view>
#include <utility>
#include "my_rapidjson_size_t.h"
#include <rapidjson/encodings.h>
#include <rapidjson/error/en.h>
#include <rapidjson/error/error.h>
#include <rapidjson/memorystream.h>
#include <rapidjson/reader.h>
#include <rapidjson/allocators.h>
#include <rapidjson/fwd.h>
#include "base64.h"
#include "decimal.h"
#include "dig_vec.h"
#include "m_string.h"
#include "my_byteorder.h"
#include "my_checksum.h"
#include "my_compare.h"
#include "my_dbug.h"
#include "my_decimal.h"
#include "my_double2ulonglong.h"
#include "my_sys.h"
#include "my_time.h"
#include "mysql/service_mysql_alloc.h"
#include "mysql/strings/dtoa.h"
#include "mysql/strings/m_ctype.h"
#include "mysql/strings/my_strtoll10.h"
#include "mysqld_error.h"
#include "sql-common/json_binary.h"
#include "sql-common/json_error_handler.h"
#include "sql-common/json_path.h"
#include "sql-common/json_syntax_check.h"
#include "sql/malloc_allocator.h"
#include "sql/sql_const.h"
#include "sql_string.h"
#include "string_with_len.h"
#include "template_utils.h"
#include "mysql/strings/int2str.h"
#include "mysql_com.h"
#include "sql/current_thd.h"
#include "sql/derror.h"
#include "sql/field.h"
#include "sql/psi_memory_key.h"
#include "sql/sql_class.h"
#include "sql/sql_error.h"
#include "sql/sql_sort.h"
#include "sql/sql_time.h"
#include "sql/system_variables.h"

Classes

class  anonymous_namespace{json_dom.cc}::Rapid_json_handler
 This class implements rapidjson's Handler concept to make our own handler which will construct our DOM from the parsing of the JSON text. More...
 
struct  anonymous_namespace{json_dom.cc}::Json_child_equal
 Functor which compares a child DOM of a JSON array or JSON object for equality. More...
 
class  anonymous_namespace{json_dom.cc}::Cmp_json
 
class  anonymous_namespace{json_dom.cc}::Eq_json
 
struct  anonymous_namespace{json_dom.cc}::Json_seek_params
 Input and output parameters to seek_no_dup_elimination that remain constant in recursive calls. More...
 
class  anonymous_namespace{json_dom.cc}::Wrapper_sort_key
 Wrapper around a sort key buffer. More...
 
class  anonymous_namespace{json_dom.cc}::Wrapper_hash_key
 Helper class for building a hash key. More...
 

Namespaces

namespace  anonymous_namespace{json_dom.cc}
 

Macros

#define DUMP_CALLBACK(name, state)
 
#define MAX_NUMBER_SORT_PAD    (std::max(DBL_DIG, DECIMAL_MAX_POSSIBLE_PRECISION) + VARLEN_PREFIX + 3)
 

Typedefs

using Sorted_index_array = Prealloced_array< size_t, 16 >
 

Enumerations

enum class  anonymous_namespace{json_dom.cc}::enum_json_opaque_type { anonymous_namespace{json_dom.cc}::J_OPAQUE_BLOB = static_cast<int>(enum_json_type::J_ERROR) + 1 , anonymous_namespace{json_dom.cc}::J_OPAQUE_BIT }
 Extended type ids so that JSON_TYPE() can give useful type names to certain sub-types of J_OPAQUE. More...
 

Functions

static Json_domjson_binary_to_dom_template (const json_binary::Value &v)
 Create a DOM template for the provided json_binary::Value. More...
 
static Json_array_ptr wrap_in_array (Json_dom_ptr dom)
 Auto-wrap a dom in an array if it is not already an array. More...
 
Json_dom_ptr merge_doms (Json_dom_ptr left, Json_dom_ptr right)
 Merge two doms. More...
 
static bool add_if_missing (Json_dom *candidate, Json_dom_vector *duplicates, Json_dom_vector *result)
 Add a value to a vector if it isn't already there. More...
 
static bool is_seek_done (const Json_dom_vector *hits, bool only_need_one)
 Check if a seek operation performed by find_child_doms() or Json_dom::seek() is done. More...
 
static bool find_child_doms (Json_dom *dom, const Json_path_iterator &current_leg, const Json_path_iterator &last_leg, bool auto_wrap, bool only_need_one, Json_dom_vector *duplicates, Json_dom_vector *result)
 Find the child Json_dom objects identified by the given path. More...
 
static bool path_gives_duplicates (const Json_path_iterator &begin, const Json_path_iterator &end, bool auto_wrap)
 Does a search on this path, using Json_dom::seek() or Json_wrapper::seek(), need duplicate elimination? More...
 
static enum_json_type bjson2json (const json_binary::Value::enum_type bintype)
 Map the JSON type used by the binary representation to the type used by Json_dom and Json_wrapper. More...
 
static std::string get_string_data (const json_binary::Value &v)
 Get string data as std::string from a json_binary::Value. More...
 
template<typename Key >
static Json_domjson_object_get (const Json_dom *object, const Json_object_map &map, const Key &key)
 
static bool json_key_less (const char *key1, size_t length1, const char *key2, size_t length2)
 Compare two keys from a JSON object and determine whether or not the first key is less than the second key. More...
 
static bool reserve (String *buffer, size_t needed)
 Reserve space in a string buffer. More...
 
static bool escape_character (char c, String *buf)
 Escape a special character in a JSON string, as described in double_quote(), and append it to a buffer. More...
 
bool double_quote (const char *cptr, size_t length, String *buf)
 Perform quoting on a JSON string to make an external representation of it. More...
 
template<typename T >
static Json_wrapperassign_json_wrapper (T &&from, Json_wrapper *to)
 Common implementation of move-assignment and copy-assignment for Json_wrapper. More...
 
static bool single_quote (String *buffer, bool json_quoted)
 Possibly append a single quote to a buffer. More...
 
static int print_string (String *buffer, bool json_quoted, const char *data, size_t length)
 Pretty-print a string to an evolving buffer, double-quoting if requested. More...
 
static bool newline_and_indent (String *buffer, size_t level)
 Helper function for wrapper_to_string() which adds a newline and indentation up to the specified level. More...
 
static bool append_comma (String *buffer, bool pretty)
 Append a comma to separate elements in JSON arrays and objects. More...
 
static bool wrapper_to_string (const Json_wrapper &wr, String *buffer, bool json_quoted, bool pretty, const char *func_name, size_t depth, const JsonErrorHandler &depth_handler)
 Helper function which does all the heavy lifting for Json_wrapper::to_string(). More...
 
static bool seek_no_dup_elimination (const json_binary::Value &value, const Json_path_iterator &current_leg, const Json_seek_params &params)
 Finds all of the JSON sub-documents which match the path expression. More...
 
static std::function< bool(const json_binary::Value &, const Json_path_iterator &, const Json_seek_params &)> get_seek_func (const Json_path_iterator &it, const Json_seek_params &params)
 Get which helper function of seek_no_dup_elimination() should be used for this path leg. More...
 
static bool seek_member (const json_binary::Value &value, const Json_path_iterator &current_leg, const Json_seek_params &params)
 Helper function for seek_no_dup_elimination which handles jpl_member path legs. More...
 
static bool seek_member_wildcard (const json_binary::Value &value, const Json_path_iterator &current_leg, const Json_seek_params &params)
 Helper function for seek_no_dup_elimination which handles jpl_member_wildcard path legs. More...
 
static bool seek_array_cell (const json_binary::Value &value, const Json_path_iterator &current_leg, const Json_seek_params &params)
 Helper function for seek_no_dup_elimination which handles jpl_array_cell path legs. More...
 
static bool seek_array_range (const json_binary::Value &value, const Json_path_iterator &current_leg, const Json_seek_params &params)
 Helper function for seek_no_dup_elimination which handles jpl_array_cell_wildcard and jpl_array_range path legs. More...
 
static bool seek_ellipsis (const json_binary::Value &value, const Json_path_iterator &current_leg, const Json_seek_params &params)
 Helper function for seek_no_dup_elimination which handles jpl_ellipsis path legs. More...
 
static bool seek_end (const json_binary::Value &value, const Json_path_iterator &current_leg, const Json_seek_params &params)
 Helper function for seek_no_dup_elimination which handles the end of the path. More...
 
static int compare_json_decimal_double (const my_decimal &a, double b)
 Compare a decimal value to a double by converting the double to a decimal. More...
 
static int compare_json_decimal_int (const my_decimal &a, longlong b)
 Compare a decimal value to a signed integer by converting the integer to a decimal. More...
 
static int compare_json_decimal_uint (const my_decimal &a, ulonglong b)
 Compare a decimal value to an unsigned integer by converting the integer to a decimal. More...
 
static int compare_json_double_int (double a, longlong b)
 Compare a JSON double to a JSON signed integer. More...
 
static int compare_json_double_uint (double a, ulonglong b)
 Compare a JSON double to a JSON unsigned integer. More...
 
static int compare_json_int_uint (longlong a, ulonglong b)
 Compare a JSON signed integer to a JSON unsigned integer. More...
 
static int compare_json_strings (const char *str1, size_t str1_len, const char *str2, size_t str2_len, const CHARSET_INFO *cs=nullptr)
 Compare the contents of two strings in a JSON value. More...
 
static void make_json_numeric_sort_key (const char *from, size_t len, bool negative, Wrapper_sort_key *to)
 Make a sort key for a JSON numeric value from its string representation. More...
 
static bool sort_and_remove_dups (const Json_wrapper &orig, Sorted_index_array *v)
 Sort the elements of a JSON array and remove duplicates. More...
 
bool json_wrapper_contains (const Json_wrapper &doc_wrapper, const Json_wrapper &containee_wr, bool *result)
 Check if one Json_wrapper contains all the elements of another Json_wrapper. More...
 
size_t anonymous_namespace{json_dom.cc}::opaque_index (enum_field_types field_type)
 Compute an index into json_type_string_map to be applied to certain sub-types of J_OPAQUE. More...
 
string_view json_type_name (const Json_wrapper &doc)
 Returns the name of the type of the JSON document contained in "doc". More...
 

Variables

static constexpr int num_json_types
 The number of enumerators in the enum_json_type enum. More...
 
static constexpr int type_comparison [num_json_types][num_json_types]
 The following matrix tells how two JSON values should be compared based on their types. More...
 
constexpr uchar anonymous_namespace{json_dom.cc}::JSON_KEY_NULL = '\x00'
 
constexpr uchar anonymous_namespace{json_dom.cc}::JSON_KEY_NUMBER_NEG = '\x01'
 
constexpr uchar anonymous_namespace{json_dom.cc}::JSON_KEY_NUMBER_ZERO = '\x02'
 
constexpr uchar anonymous_namespace{json_dom.cc}::JSON_KEY_NUMBER_POS = '\x03'
 
constexpr uchar anonymous_namespace{json_dom.cc}::JSON_KEY_STRING = '\x04'
 
constexpr uchar anonymous_namespace{json_dom.cc}::JSON_KEY_OBJECT = '\x05'
 
constexpr uchar anonymous_namespace{json_dom.cc}::JSON_KEY_ARRAY = '\x06'
 
constexpr uchar anonymous_namespace{json_dom.cc}::JSON_KEY_FALSE = '\x07'
 
constexpr uchar anonymous_namespace{json_dom.cc}::JSON_KEY_TRUE = '\x08'
 
constexpr uchar anonymous_namespace{json_dom.cc}::JSON_KEY_DATE = '\x09'
 
constexpr uchar anonymous_namespace{json_dom.cc}::JSON_KEY_TIME = '\x0A'
 
constexpr uchar anonymous_namespace{json_dom.cc}::JSON_KEY_DATETIME = '\x0B'
 
constexpr uchar anonymous_namespace{json_dom.cc}::JSON_KEY_OPAQUE = '\x0C'
 
constexpr std::array anonymous_namespace{json_dom.cc}::json_type_string_map
 Maps the enumeration value of type enum_json_type into a string. More...
 
const size_t kMaxJsonTypeNameLength
 The maximum length of the type name returned from JSON_TYPE. More...
 

Macro Definition Documentation

◆ DUMP_CALLBACK

#define DUMP_CALLBACK (   name,
  state 
)

◆ MAX_NUMBER_SORT_PAD

#define MAX_NUMBER_SORT_PAD    (std::max(DBL_DIG, DECIMAL_MAX_POSSIBLE_PRECISION) + VARLEN_PREFIX + 3)

Typedef Documentation

◆ Sorted_index_array

using Sorted_index_array = Prealloced_array<size_t, 16>

Function Documentation

◆ add_if_missing()

static bool add_if_missing ( Json_dom candidate,
Json_dom_vector duplicates,
Json_dom_vector result 
)
static

Add a value to a vector if it isn't already there.

This is used for removing duplicate matches for daisy-chained ellipsis tokens in find_child_doms(). The problem with daisy-chained ellipses is that the candidate set may contain the same Json_dom object multiple times at different nesting levels after matching the first ellipsis. That is, the candidate set may contain a Json_dom and its parent, grandparent and so on. When matching the next ellipsis in the path, each value in the candidate set and all its children will be inspected, so the nested Json_dom will be seen multiple times, as its grandparent, parent and finally itself are inspected. We want it to appear only once in the result.

The same problem occurs if a possibly auto-wrapping array path leg comes after an ellipsis. If the candidate set contains both an array element and its parent array due to the ellipsis, the auto-wrapping path leg may match the array element twice, and we only want it once in the result.

Parameters
[in]candidatevalue to add
[in,out]duplicatesset of values added, or nullptr if duplicate checking is not needed
[in,out]resultvector
Returns
false on success, true on error

◆ append_comma()

static bool append_comma ( String buffer,
bool  pretty 
)
static

Append a comma to separate elements in JSON arrays and objects.

Parameters
bufferthe string buffer
prettytrue if pretty printing is enabled
Returns
true on error, false on success

◆ assign_json_wrapper()

template<typename T >
static Json_wrapper & assign_json_wrapper ( T &&  from,
Json_wrapper to 
)
static

Common implementation of move-assignment and copy-assignment for Json_wrapper.

If from is an rvalue, its contents are moved into to, otherwise the contents are copied over.

◆ bjson2json()

static enum_json_type bjson2json ( const json_binary::Value::enum_type  bintype)
static

Map the JSON type used by the binary representation to the type used by Json_dom and Json_wrapper.

Note: Does not look into opaque values to determine if they represent decimal or date/time values. For that, look into the Value and retrieve field_type.

Parameters
[in]bintypetype of json_binary
Returns
the JSON_dom JSON type.

◆ compare_json_decimal_double()

static int compare_json_decimal_double ( const my_decimal a,
double  b 
)
static

Compare a decimal value to a double by converting the double to a decimal.

Parameters
athe decimal value
bthe double value
Returns
-1 if a is less than b, 0 if a is equal to b, 1 if a is greater than b

◆ compare_json_decimal_int()

static int compare_json_decimal_int ( const my_decimal a,
longlong  b 
)
static

Compare a decimal value to a signed integer by converting the integer to a decimal.

Parameters
athe decimal value
bthe signed integer value
Returns
-1 if a is less than b, 0 if a is equal to b, 1 if a is greater than b

◆ compare_json_decimal_uint()

static int compare_json_decimal_uint ( const my_decimal a,
ulonglong  b 
)
static

Compare a decimal value to an unsigned integer by converting the integer to a decimal.

Parameters
athe decimal value
bthe unsigned integer value
Returns
-1 if a is less than b, 0 if a is equal to b, 1 if a is greater than b

◆ compare_json_double_int()

static int compare_json_double_int ( double  a,
longlong  b 
)
static

Compare a JSON double to a JSON signed integer.

Parameters
athe double value
bthe integer value
Returns
-1 if a is less than b, 0 if a is equal to b, 1 if a is greater than b

◆ compare_json_double_uint()

static int compare_json_double_uint ( double  a,
ulonglong  b 
)
static

Compare a JSON double to a JSON unsigned integer.

Parameters
athe double value
bthe unsigned integer value
Returns
-1 if a is less than b, 0 if a is equal to b, 1 if a is greater than b

◆ compare_json_int_uint()

static int compare_json_int_uint ( longlong  a,
ulonglong  b 
)
static

Compare a JSON signed integer to a JSON unsigned integer.

Parameters
athe signed integer
bthe unsigned integer
Returns
-1 if a is less than b, 0 if a is equal to b, 1 if a is greater than b

◆ compare_json_strings()

static int compare_json_strings ( const char *  str1,
size_t  str1_len,
const char *  str2,
size_t  str2_len,
const CHARSET_INFO cs = nullptr 
)
static

Compare the contents of two strings in a JSON value.

The strings could be either JSON string scalars encoded in utf8mb4, or binary strings from JSON opaque scalars. In either case they are compared byte by byte.

Parameters
str1the first string
str1_lenthe length of str1
str2the second string
str2_lenthe length of str2
csIf given, this charset will be used for comparison
Return values
-1if str1 is less than str2,
0if str1 is equal to str2,
1if str1 is greater than str2

◆ double_quote()

bool double_quote ( const char *  cptr,
size_t  length,
String buf 
)

Perform quoting on a JSON string to make an external representation of it.

It wraps double quotes (text quotes) around the string (cptr) and also performs escaping according to the following table:

Common name     C-style  Original unescaped     Transformed to
                escape   UTF-8 bytes            escape sequence
                notation                        in UTF-8 bytes
---------------------------------------------------------------
quote           \"       %x22                    %x5C %x22
backslash       \\       %x5C                    %x5C %x5C
backspace       \b       %x08                    %x5C %x62
formfeed        \f       %x0C                    %x5C %x66
linefeed        \n       %x0A                    %x5C %x6E
carriage-return \r       %x0D                    %x5C %x72
tab             \t       %x09                    %x5C %x74
unicode         \uXXXX  A hex number in the      %x5C %x75
                        range of 00-1F,          followed by
                        except for the ones      4 hex digits
                        handled above (backspace,
                        formfeed, linefeed,
                        carriage-return,
                        and tab).
---------------------------------------------------------------
Parameters
[in]cptrpointer to string data
[in]lengththe length of the string
[in,out]bufthe destination buffer
Return values
trueon error

◆ escape_character()

static bool escape_character ( char  c,
String buf 
)
static

Escape a special character in a JSON string, as described in double_quote(), and append it to a buffer.

Parameters
cthe special character to escape
bufthe destination buffer
Return values
falseon success
trueon memory allocation failure

◆ find_child_doms()

static bool find_child_doms ( Json_dom dom,
const Json_path_iterator current_leg,
const Json_path_iterator last_leg,
bool  auto_wrap,
bool  only_need_one,
Json_dom_vector duplicates,
Json_dom_vector result 
)
static

Find the child Json_dom objects identified by the given path.

The child doms are added to a vector.

See the header comment for Json_wrapper::seek() for a discussion of complexities involving path expressions with more than one ellipsis (**) token, or a combination of ellipsis and auto-wrapping path legs.

Parameters
[in]domthe DOM to search
[in]current_legiterator to the path leg to look at
[in]last_legiterator to the last path leg (exclusive)
[in]auto_wrapif true, auto-wrap non-arrays when matching against array path legs
[in]only_need_onetrue if we can stop after finding one match
[in,out]duplicatesset of values collected, which helps to identify duplicate arrays and objects introduced by daisy-chained tokens or auto-wrapping, or nullptr if duplicate elimination is not needed for this path leg
[in,out]resultthe vector of qualifying children
Returns
false on success, true on error

◆ get_seek_func()

static std::function< bool(const json_binary::Value &, const Json_path_iterator &, const Json_seek_params &)> get_seek_func ( const Json_path_iterator it,
const Json_seek_params &  params 
)
static

Get which helper function of seek_no_dup_elimination() should be used for this path leg.

◆ get_string_data()

static std::string get_string_data ( const json_binary::Value v)
static

Get string data as std::string from a json_binary::Value.

◆ is_seek_done()

static bool is_seek_done ( const Json_dom_vector hits,
bool  only_need_one 
)
inlinestatic

Check if a seek operation performed by find_child_doms() or Json_dom::seek() is done.

Returns
true if only one result is needed and a result has been found

◆ json_binary_to_dom_template()

static Json_dom * json_binary_to_dom_template ( const json_binary::Value v)
static

Create a DOM template for the provided json_binary::Value.

If the binary value represents a scalar, create a Json_dom object that represents the scalar and return a pointer to it.

If the binary value represents an object or an array, create an empty Json_object or Json_array object and return a pointer to it.

Parameters
vthe binary value to convert to DOM
Returns
a DOM template for the top-level the binary value, or NULL if an error is detected.

◆ json_key_less()

static bool json_key_less ( const char *  key1,
size_t  length1,
const char *  key2,
size_t  length2 
)
static

Compare two keys from a JSON object and determine whether or not the first key is less than the second key.

key1 is considered less than key2 if

a) key1 is shorter than key2, or if

b) key1 and key2 have the same length, but different contents, and the first byte that differs has a smaller value in key1 than in key2

Otherwise, key1 is not less than key2.

Parameters
key1the first key to compare
length1the length of the first key
key2the second key to compare
length2the length of the second key
Returns
true if key1 is considered less than key2, false otherwise

◆ json_object_get()

template<typename Key >
static Json_dom * json_object_get ( const Json_dom object,
const Json_object_map map,
const Key &  key 
)
static

◆ json_type_name()

string_view json_type_name ( const Json_wrapper doc)

Returns the name of the type of the JSON document contained in "doc".

◆ json_wrapper_contains()

bool json_wrapper_contains ( const Json_wrapper doc_wrapper,
const Json_wrapper containee_wr,
bool *  result 
)

Check if one Json_wrapper contains all the elements of another Json_wrapper.

Parameters
[in]doc_wrapperthe containing document
[in]containee_wrthe possibly contained document
[out]resulttrue if doc_wrapper contains containee_wr, false otherwise
Return values
falseon success
trueon failure

◆ make_json_numeric_sort_key()

static void make_json_numeric_sort_key ( const char *  from,
size_t  len,
bool  negative,
Wrapper_sort_key *  to 
)
static

Make a sort key for a JSON numeric value from its string representation.

The input string could be either on scientific format (such as 1.234e2) or on plain format (such as 12.34).

The sort key will have the following parts:

1) One byte that is JSON_KEY_NUMBER_NEG, JSON_KEY_NUMBER_ZERO or JSON_KEY_NUMBER_POS if the number is positive, zero or negative, respectively.

2) Two bytes that represent the decimal exponent of the number (log10 of the number, truncated to an integer).

3) All the digits of the number, without leading zeros.

4) Padding to ensure that equal numbers sort equal even if they have a different number of trailing zeros.

If the number is zero, parts 2, 3 and 4 are skipped.

For negative numbers, the values in parts 2, 3 and 4 need to be inverted so that bigger negative numbers sort before smaller negative numbers.

Parameters
[in]fromthe string representation of the number
[in]lenthe length of the input string
[in]negativetrue if the number is negative, false otherwise
[in,out]tothe target sort key

◆ merge_doms()

Json_dom_ptr merge_doms ( Json_dom_ptr  left,
Json_dom_ptr  right 
)

Merge two doms.

The right dom is either subsumed into the left dom or the contents of the right dom are transferred to the left dom and the right dom is deleted. After calling this function, the caller should not reference the right dom again. It has been deleted.

Returns NULL if there is a memory allocation failure. In this case both doms are deleted.

scalars - If any of the documents that are being merged is a scalar, each scalar document is autowrapped as a single value array before merging.

arrays - When merging a left array with a right array, then the result is the left array concatenated with the right array. For instance, [ 1, 2 ] merged with [ 3, 4 ] is [ 1, 2, 3, 4 ].

array and object - When merging an array with an object, the object is autowrapped as an array and then the rule above is applied. So [ 1, 2 ] merged with { "a" : true } is [ 1, 2, { "a": true } ].

objects - When merging two objects, the two objects are concatenated into a single, larger object. So { "a" : "foo" } merged with { "b" : 5 } is { "a" : "foo", "b" : 5 }.

duplicates - When two objects are merged and they share a key, the values associated with the shared key are merged.

Parameters
[in,out]leftThe recipient dom.
[in,out]rightThe dom to be consumed
Returns
A composite dom which subsumes the left and right doms, or NULL if a failure happened while merging

◆ newline_and_indent()

static bool newline_and_indent ( String buffer,
size_t  level 
)
static

Helper function for wrapper_to_string() which adds a newline and indentation up to the specified level.

Parameters
[in,out]bufferthe buffer to write to
[in]levelhow many nesting levels to add indentation for
Return values
falseon success
trueon error

◆ path_gives_duplicates()

static bool path_gives_duplicates ( const Json_path_iterator begin,
const Json_path_iterator end,
bool  auto_wrap 
)
static

Does a search on this path, using Json_dom::seek() or Json_wrapper::seek(), need duplicate elimination?

Duplicate elimination is needed if the path contains multiple ellipses, or if it contains an auto-wrapping array path leg after an ellipses. See Json_wrapper::seek() for more details.

Parameters
beginthe beginning of the path
endthe end of the path (exclusive)
auto_wraptrue if array auto-wrapping is used
Return values
trueif duplicate elimination is needed
falseif the path won't produce duplicates

◆ print_string()

static int print_string ( String buffer,
bool  json_quoted,
const char *  data,
size_t  length 
)
static

Pretty-print a string to an evolving buffer, double-quoting if requested.

Parameters
[in]bufferthe buffer to print to
[in]json_quotedtrue if we should double-quote
[in]datathe string to print
[in]lengththe string's length
Returns
false on success, true on failure

◆ reserve()

static bool reserve ( String buffer,
size_t  needed 
)
static

Reserve space in a string buffer.

If reallocation is needed, increase the size of the buffer exponentially.

Parameters
bufferthe string buffer
neededthe number of bytes needed
Returns
true on error, false on success

◆ seek_array_cell()

static bool seek_array_cell ( const json_binary::Value value,
const Json_path_iterator current_leg,
const Json_seek_params &  params 
)
static

Helper function for seek_no_dup_elimination which handles jpl_array_cell path legs.

◆ seek_array_range()

static bool seek_array_range ( const json_binary::Value value,
const Json_path_iterator current_leg,
const Json_seek_params &  params 
)
static

Helper function for seek_no_dup_elimination which handles jpl_array_cell_wildcard and jpl_array_range path legs.

◆ seek_ellipsis()

static bool seek_ellipsis ( const json_binary::Value value,
const Json_path_iterator current_leg,
const Json_seek_params &  params 
)
static

Helper function for seek_no_dup_elimination which handles jpl_ellipsis path legs.

◆ seek_end()

static bool seek_end ( const json_binary::Value value,
const Json_path_iterator current_leg,
const Json_seek_params &  params 
)
static

Helper function for seek_no_dup_elimination which handles the end of the path.

◆ seek_member()

static bool seek_member ( const json_binary::Value value,
const Json_path_iterator current_leg,
const Json_seek_params &  params 
)
static

Helper function for seek_no_dup_elimination which handles jpl_member path legs.

◆ seek_member_wildcard()

static bool seek_member_wildcard ( const json_binary::Value value,
const Json_path_iterator current_leg,
const Json_seek_params &  params 
)
static

Helper function for seek_no_dup_elimination which handles jpl_member_wildcard path legs.

◆ seek_no_dup_elimination()

static bool seek_no_dup_elimination ( const json_binary::Value value,
const Json_path_iterator current_leg,
const Json_seek_params &  params 
)
static

Finds all of the JSON sub-documents which match the path expression.

Puts the matches on an evolving vector of results. This is a fast-track method for paths which don't need duplicate elimination due to multiple ellipses or the combination of ellipses and auto-wrapping. Those paths can take advantage of the efficient positioning logic of json_binary::Value.

Parameters
[in]valuethe JSON value to search
[in]current_legiterator to the first path leg to look at. Usually called on the root document with an iterator pointing to the beginning of the path, and then incremented in recursive calls within this function.
[in,out]paramsthe seek parameters
Returns
false if there was no error, otherwise true on error

◆ single_quote()

static bool single_quote ( String buffer,
bool  json_quoted 
)
inlinestatic

Possibly append a single quote to a buffer.

Parameters
[in,out]bufferreceiving buffer
[in]json_quotedwhether or not a quote should be appended
Returns
false if successful, true on error

◆ sort_and_remove_dups()

static bool sort_and_remove_dups ( const Json_wrapper orig,
Sorted_index_array v 
)
static

Sort the elements of a JSON array and remove duplicates.

Parameters
[in]origthe original JSON array
[out]vvector that will be filled with the indexes of the array elements in increasing order
Returns
false on success, true on error

◆ wrap_in_array()

static Json_array_ptr wrap_in_array ( Json_dom_ptr  dom)
static

Auto-wrap a dom in an array if it is not already an array.

Delete the dom if there is a memory allocation failure.

◆ wrapper_to_string()

static bool wrapper_to_string ( const Json_wrapper wr,
String buffer,
bool  json_quoted,
bool  pretty,
const char *  func_name,
size_t  depth,
const JsonErrorHandler depth_handler 
)
static

Helper function which does all the heavy lifting for Json_wrapper::to_string().

It processes the Json_wrapper recursively. The depth parameter keeps track of the current nesting level. When it reaches JSON_DOCUMENT_MAX_DEPTH (see json_syntax_check.cc for definition), it gives up in order to avoid running out of stack space.

Parameters
[in]wrthe value to convert to a string
[in,out]bufferthe buffer to write to
[in]json_quotedquote strings if true
[in]prettyadd newlines and indentation if true
[in]func_namethe name of the calling function
[in]depththe nesting level of wr
[in]depth_handlerPointer to a function that should handle error occurred when depth is exceeded.
Return values
falseon success
trueon error

Variable Documentation

◆ kMaxJsonTypeNameLength

const size_t kMaxJsonTypeNameLength
Initial value:
= std::transform_reduce(
json_type_string_map.begin(), json_type_string_map.end(), size_t{0},
[](size_t length1, size_t length2) { return std::max(length1, length2); },
[](string_view type_name) { return type_name.length(); })
constexpr std::array json_type_string_map
Maps the enumeration value of type enum_json_type into a string.
Definition: json_dom.cc:3815

The maximum length of the type name returned from JSON_TYPE.

◆ num_json_types

constexpr int num_json_types
staticconstexpr
Initial value:
=
static_cast<int>(enum_json_type::J_ERROR) + 1

The number of enumerators in the enum_json_type enum.

◆ type_comparison

constexpr int type_comparison[num_json_types][num_json_types]
staticconstexpr
Initial value:
= {
{0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1},
{1, 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, -1, -1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, -1, -1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, -1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
}

The following matrix tells how two JSON values should be compared based on their types.

If type_comparison[type_of_a][type_of_b] is -1, it means that a is smaller than b. If it is 1, it means that a is greater than b. If it is 0, it means it cannot be determined which value is the greater one just by looking at the types.