MySQL 9.1.0
Source Code Documentation
|
#include "sql/item_json_func.h"
#include <assert.h>
#include <algorithm>
#include <cstring>
#include <limits>
#include <memory>
#include <new>
#include <string>
#include <utility>
#include <vector>
#include "decimal.h"
#include "field_types.h"
#include "lex_string.h"
#include "my_alloc.h"
#include "my_dbug.h"
#include "my_sys.h"
#include "mysql/mysql_lex_string.h"
#include "mysql/strings/m_ctype.h"
#include "mysqld_error.h"
#include "prealloced_array.h"
#include "scope_guard.h"
#include "sql-common/json_diff.h"
#include "sql-common/json_dom.h"
#include "sql-common/json_path.h"
#include "sql-common/json_schema.h"
#include "sql-common/json_syntax_check.h"
#include "sql-common/my_decimal.h"
#include "sql/current_thd.h"
#include "sql/debug_sync.h"
#include "sql/error_handler.h"
#include "sql/field.h"
#include "sql/field_common_properties.h"
#include "sql/item_cmpfunc.h"
#include "sql/item_create.h"
#include "sql/parser_yystype.h"
#include "sql/psi_memory_key.h"
#include "sql/sql_class.h"
#include "sql/sql_const.h"
#include "sql/sql_error.h"
#include "sql/sql_exception_handler.h"
#include "sql/sql_time.h"
#include "sql/system_variables.h"
#include "sql/table.h"
#include "sql/table_function.h"
#include "sql/thd_raii.h"
#include "sql/thr_malloc.h"
#include "sql_string.h"
#include "string_with_len.h"
#include "template_utils.h"
Classes | |
struct | Item_func_json_value::Default_value |
Typedefs | |
typedef Prealloced_array< size_t, 16 > | Sorted_index_array |
typedef Prealloced_array< std::string, 16 > | String_set |
Functions | |
bool | ensure_utf8mb4 (const String &val, String *buf, const char **resptr, size_t *reslength, bool require_string) |
Helper routines. More... | |
bool | parse_json (const String &res, Json_dom_ptr *dom, bool require_str_or_json, const JsonParseErrorHandler &error_handler, const JsonErrorHandler &depth_handler) |
Parse a JSON dom out of an argument to a JSON function. More... | |
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. More... | |
static enum_field_types | get_real_blob_type (const Field *arg) |
Get correct blob type of given Field. More... | |
static enum_field_types | get_real_blob_type (const Item *arg) |
Get correct blob type of given Item. More... | |
static enum_field_types | get_normalized_field_type (const Item *arg) |
Get the field type of an item. More... | |
bool | get_json_object_member_name (const THD *thd, Item *arg_item, String *value, String *utf8_res, const char **safep, size_t *safe_length) |
Gets a JSON object member name from an Item. More... | |
static bool | is_convertible_to_json (const Item *item) |
A helper method that checks whether or not the given argument can be converted to JSON. More... | |
static bool | check_convertible_to_json (const Item *item, int argument_number, const char *function_name) |
Checks if an Item is of a type that is convertible to JSON. More... | |
static bool | json_is_valid (Item **args, uint arg_idx, String *value, const char *func_name, Json_dom_ptr *dom, bool require_str_or_json, bool *valid) |
Helper method for Item_func_json_* methods. More... | |
bool | parse_path (const String &path_value, bool forbid_wildcards, Json_path *json_path) |
A helper function that uses the above one as workhorse. More... | |
static enum_one_or_all_type | parse_one_or_all (const String *candidate, const char *func_name) |
Parse a oneOrAll argument. More... | |
static enum_one_or_all_type | parse_and_cache_ooa (const THD *thd, Item *arg, enum_one_or_all_type *cached_ooa, const char *func_name) |
Parse and cache a (possibly constant) oneOrAll argument. More... | |
static bool | evaluate_constant_json_schema (THD *thd, Item *json_schema, Json_schema_validator *cached_schema_validator, Item **ref) |
static bool | do_json_schema_validation (const THD *thd, Item *json_schema, Item *json_document, const char *func_name, const Json_schema_validator &cached_schema_validator, bool *null_value, bool *validation_result, Json_schema_validation_report *validation_report) |
bool | json_value (Item *arg, Json_wrapper *result, bool *has_value) |
Return the JSON value of the argument in a wrapper. More... | |
bool | get_json_wrapper (Item **args, uint arg_idx, String *str, const char *func_name, Json_wrapper *wrapper) |
Return the JSON value of the argument in a wrapper. More... | |
static String * | val_string_from_json (Item_func *item, String *buffer) |
static bool | get_date_from_json (Item_func *item, MYSQL_TIME *ltime, my_time_flags_t) |
static bool | get_time_from_json (Item_func *item, MYSQL_TIME *ltime) |
longlong | val_int_from_json (Item_func *item) |
static double | val_real_from_json (Item_func *item) |
static my_decimal * | val_decimal_from_json (Item_func *item, my_decimal *decimal_value) |
template<typename T , typename... Args> | |
static bool | create_scalar (Json_scalar_holder *scalar, Json_dom_ptr *dom, Args &&...args) |
Create a new Json_scalar object, either in memory owned by a Json_scalar_holder object or on the heap. More... | |
bool | sql_scalar_to_json (Item *arg, const char *calling_function, String *value, String *tmp, Json_wrapper *wr, Json_scalar_holder *scalar, bool scalar_string) |
Get a JSON value from an SQL scalar value. More... | |
bool | get_json_atom_wrapper (Item **args, uint arg_idx, const char *calling_function, String *value, String *tmp, Json_wrapper *wr, Json_scalar_holder *scalar, bool accept_string) |
Convert Json values or MySQL values to JSON. More... | |
bool | get_atom_null_as_null (Item **args, uint arg_idx, const char *calling_function, String *value, String *tmp, Json_wrapper *wr) |
Convert JSON values or MySQL values to JSON. More... | |
static bool | possible_root_path (const Json_path_iterator &begin, const Json_path_iterator &end) |
Is this a path that could possibly return the root node of a JSON document? More... | |
static void | disable_logical_diffs (const Field_json *field) |
static void | disable_binary_diffs (const Field_json *field) |
static bool | find_matches (const Json_wrapper &wrapper, String *path, Json_dom_vector *matches, String_set *duplicates, bool one_match, Item *like_node, Item_string *source_string) |
Recursive function to find the string values, nested inside a json document, which satisfy the LIKE condition. More... | |
static void | set_data_type_from_cast_type (Item *item, Cast_target cast_type, unsigned length, unsigned decimals, const CHARSET_INFO *charset) |
Sets the data type of an Item_func_array_cast or Item_func_json_value based on the Cast_type. More... | |
static void | print_cast_type (Cast_target cast_type, const Item *item, String *str) |
Prints the target type of a cast operation (either CAST or JSON_VALUE). More... | |
static enum Item_result | json_cast_result_type (Cast_target cast_type) |
static enum_field_types | data_type_to_real_type (enum_field_types data_type) |
Converts the "data type" used by Item to a "real type" used by Field. More... | |
static bool | can_store_json_value_unencoded (const Field *field_to_store_in, const Json_wrapper *json_data) |
Check if a JSON value is a JSON OPAQUE, and if it can be printed in the field as a non base64 value. More... | |
bool | save_json_to_field (THD *thd, Field *field, const Json_wrapper *w, bool no_error) |
Save JSON to a given field. More... | |
static bool | decimal_within_range (const Item *item, const my_decimal *decimal) |
Checks if a decimal value is within the range of the data type of an Item. More... | |
static bool | same_response_type (Json_on_response_type type1, Json_on_response_type type2) |
Checks if two Json_on_response_type values represent the same response. More... | |
static bool | handle_json_value_conversion_error (Json_on_response_type on_error, const char *type, Item_func_json_value *item) |
Handles conversion errors for JSON_VALUE according to the ON ERROR clause. More... | |
typedef Prealloced_array<size_t, 16> Sorted_index_array |
typedef Prealloced_array<std::string, 16> String_set |
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.
field | the column to update |
diffs | the diffs to apply |
|
static |
Check if a JSON value is a JSON OPAQUE, and if it can be printed in the field as a non base64 value.
This is currently used by JSON_TABLE to see if we can print the JSON value in a field without having to encode it in base64.
field_to_store_in | The field we want to store the JSON value in |
json_data | The JSON value we want to store. |
|
static |
Checks if an Item is of a type that is convertible to JSON.
An error is raised if it is not convertible.
|
static |
Create a new Json_scalar object, either in memory owned by a Json_scalar_holder object or on the heap.
[in,out] | scalar | the Json_scalar_holder in which to create the new Json_scalar, or nullptr if it should be created on the heap |
[in,out] | dom | pointer to the Json_scalar if it's created on the heap |
[in] | args | the arguments to pass to T's constructor |
T | the type of object to create; a subclass of Json_scalar |
Args | type of the arguments to pass to T's constructor |
false | if successful |
true | if memory could not be allocated |
|
static |
Converts the "data type" used by Item to a "real type" used by Field.
|
static |
Checks if a decimal value is within the range of the data type of an Item.
It is considered within range if it can be converted to the data type without losing any leading significant digits.
|
static |
|
static |
|
static |
bool ensure_utf8mb4 | ( | const String & | val, |
String * | buf, | ||
const char ** | resptr, | ||
size_t * | reslength, | ||
bool | require_string | ||
) |
Helper routines.
Check a non-empty val for character set.
|
static |
|
static |
Recursive function to find the string values, nested inside a json document, which satisfy the LIKE condition.
As matches are found, their path locations are added to an evolving vector of matches.
[in] | wrapper | A subdocument of the original document. |
[in] | path | The path location of the subdocument |
[in,out] | matches | The evolving vector of matches. |
[in,out] | duplicates | Sorted set of paths found already, which is used to avoid inserting duplicates into matches. |
[in] | one_match | If true, then terminate search after first match. |
[in] | like_node | The LIKE node that's evaluated on the string values. |
[in] | source_string | The input string item of the LIKE node. |
false | on success |
true | on failure |
bool get_atom_null_as_null | ( | Item ** | args, |
uint | arg_idx, | ||
const char * | calling_function, | ||
String * | value, | ||
String * | tmp, | ||
Json_wrapper * | wr | ||
) |
Convert JSON values or MySQL values to JSON.
Converts SQL NULL to the JSON null literal.
[in] | args | arguments to function |
[in] | arg_idx | the index of the argument to process |
[in] | calling_function | name of the calling function |
[in,out] | value | working area (if the returned Json_wrapper points to a binary value rather than a DOM, this string will end up holding the binary representation, and it must stay alive until the wrapper is destroyed or converted from binary to DOM) |
[in,out] | tmp | temporary scratch space for converting strings to the correct charset; only used if accept_string is true and conversion is needed |
[in,out] | wr | the result wrapper |
|
static |
bool get_json_atom_wrapper | ( | Item ** | args, |
uint | arg_idx, | ||
const char * | calling_function, | ||
String * | value, | ||
String * | tmp, | ||
Json_wrapper * | wr, | ||
Json_scalar_holder * | scalar, | ||
bool | accept_string | ||
) |
Convert Json values or MySQL values to JSON.
[in] | args | arguments to function |
[in] | arg_idx | the index of the argument to process |
[in] | calling_function | name of the calling function |
[in,out] | value | working area (if the returned Json_wrapper points to a binary value rather than a DOM, this string will end up holding the binary representation, and it must stay alive until the wrapper is destroyed or converted from binary to DOM) |
[in,out] | tmp | temporary scratch space for converting strings to the correct charset; only used if accept_string is true and conversion is needed |
[in,out] | wr | the result wrapper |
[in,out] | scalar | pointer to pre-allocated memory that can be borrowed by the result wrapper if the result is a scalar. If the pointer is NULL, memory for a scalar result will be allocated on the heap. |
[in] | accept_string | if true, accept MySQL strings as JSON strings by converting them to UTF8, else emit an error |
bool get_json_object_member_name | ( | const THD * | thd, |
Item * | arg_item, | ||
String * | value, | ||
String * | utf8_res, | ||
const char ** | safep, | ||
size_t * | safe_length | ||
) |
Gets a JSON object member name from an Item.
An error is raised if the Item evaluates to NULL, or if it cannot be converted to a utf8mb4 string.
[in] | thd | THD handle |
[in] | arg_item | An argument Item |
[out] | value | Where to materialize the arg_item's string value |
[out] | utf8_res | Buffer for use by ensure_utf8mb4. |
[out] | safep | String pointer after any relevant conversion |
[out] | safe_length | Corresponding string length |
bool get_json_wrapper | ( | Item ** | args, |
uint | arg_idx, | ||
String * | str, | ||
const char * | func_name, | ||
Json_wrapper * | wrapper | ||
) |
Return the JSON value of the argument in a wrapper.
Abstracts whether the value comes from a field or a function or a valid JSON text.
[in] | args | the arguments |
[in] | arg_idx | the argument index |
[out] | str | the string buffer |
[in] | func_name | the name of the function we are executing |
[out] | wrapper | the JSON value wrapper |
|
static |
Get the field type of an item.
This function returns the same value as arg->data_type() in most cases, but in some cases it may return another field type in order to ensure that the item gets handled the same way as items of a different type.
|
static |
Get correct blob type of given Field.
A helper function for get_normalized_field_type().
arg | the field to get blob type of |
|
static |
Get correct blob type of given Item.
A helper function for get_normalized_field_type().
arg | the item to get blob type of |
|
static |
|
static |
Handles conversion errors for JSON_VALUE according to the ON ERROR clause.
Called when the conversion of the extracted JSON value cannot be converted to the target type without truncation or data loss.
If ERROR ON ERROR is specified, an error is raised, and true is returned.
If NULL ON ERROR is specified (explicitly or implicitly), the item's null_value is set to true, and false is returned.
If DEFAULT ... ON ERROR is specified, the item's null_value is set to false, and false is returned. It is up to the caller to return the correct default value.
on_error | the type of response to give to the error | |
type | the data type returned by the JSON_VALUE expression | |
[in,out] | item | the Item representing the JSON_VALUE expression |
true | for ERROR ON ERROR (my_error() is called before returning) |
false | if DEFAULT .. ON ERROR or NULL ON ERROR was given |
|
static |
A helper method that checks whether or not the given argument can be converted to JSON.
The function only checks the type of the given item, and doesn't do any parsing or further checking of the item.
item | The item to be checked |
true | The item is possibly convertible to JSON |
false | The item is not convertible to JSON |
|
static |
|
static |
Helper method for Item_func_json_* methods.
Check if a JSON item or JSON text is valid and, for the latter, optionally construct a DOM tree (i.e. only if valid).
[in] | args | Item_func::args alias |
[in] | arg_idx | Index (0-based) of argument into the args array |
[out] | value | Alias for Item_func_json_*::m_value
|
[in] | func_name | Name of the user-invoked JSON_ function |
[in,out] | dom | If non-null, we want any text parsed DOM returned at the location pointed to |
[in] | require_str_or_json | If true, generate an error if other types used as input |
[out] | valid | true if a valid JSON value was found (or NULL), else false |
bool json_value | ( | Item * | arg, |
Json_wrapper * | result, | ||
bool * | has_value | ||
) |
Return the JSON value of the argument in a wrapper.
Handles arguments with type JSON, including array objects (which do not report type JSON but rather the type of individual elements).
Does not handle literals. See also get_json_wrapper.
[in] | arg | the argument |
[in,out] | result | the JSON value wrapper |
[out] | has_value | true if argument was handled, false otherwise undefined when error |
|
static |
Parse and cache a (possibly constant) oneOrAll argument.
[in] | thd | THD handle. |
[in] | arg | The oneOrAll arg passed to the JSON function. |
[in] | cached_ooa | Previous result of parsing this arg. |
[in] | func_name | The name of the calling JSON function. |
bool parse_json | ( | const String & | res, |
Json_dom_ptr * | dom, | ||
bool | require_str_or_json, | ||
const JsonParseErrorHandler & | error_handler, | ||
const JsonErrorHandler & | depth_handler | ||
) |
Parse a JSON dom out of an argument to a JSON function.
[in] | res | Pointer to string value of arg. |
[in,out] | dom | If non-null, we want any text parsed DOM returned at the location pointed to |
[in] | require_str_or_json | If true, generate an error if other types used as input |
[in] | error_handler | Pointer to a function that should handle reporting of parsing error. |
[in] | depth_handler | Pointer to a function that should handle error occurred when depth is exceeded. |
|
static |
Parse a oneOrAll argument.
[in] | candidate | The string to compare to "one" or "all" |
[in] | func_name | The name of the calling function |
A helper function that uses the above one as workhorse.
Entry point for for JSON_TABLE (Table_function_json class) and Json_path_cache. Raises an error if the path expression is syntactically incorrect. Raises an error if the path expression contains wildcard tokens but is not supposed to. Otherwise updates the supplied Json_path object with the parsed path.
[in] | path_value | A String to be interpreted as a path. |
[in] | forbid_wildcards | True if the path shouldn't contain * or ** |
[out] | json_path | The object that will hold the parsed path |
|
static |
Is this a path that could possibly return the root node of a JSON document?
A path that returns the root node must be on one of the following forms:
last
that any non-array element at the top level could have been autowrapped to, i.e. '$[0]' or '$[0][0]...[0]'.begin | the beginning of the path |
end | the end of the path (exclusive) |
|
static |
Prints the target type of a cast operation (either CAST or JSON_VALUE).
cast_type | the cast type | |
item | the Item in which the cast operation is performed | |
[out] | str | the string to print to |
|
static |
Checks if two Json_on_response_type values represent the same response.
Implicit responses are equal to NULL ON EMPTY/ERROR.
bool save_json_to_field | ( | THD * | thd, |
Field * | field, | ||
const Json_wrapper * | w, | ||
bool | no_error | ||
) |
Save JSON to a given field.
Value is saved in type-aware manner. Into a JSON-typed column any JSON data could be saved. Into an SQL scalar field only a scalar could be saved. If data being saved isn't scalar or can't be coerced to the target type, an error is returned.
thd | Thread handler |
field | Field to save data to |
w | JSON data to save |
no_error | If true, don't raise an error when the value cannot be converted to the target type |
|
static |
Sets the data type of an Item_func_array_cast or Item_func_json_value based on the Cast_type.
item | the Item whose data type to set |
cast_type | the type of cast |
length | the declared length of the target type |
decimals | the declared precision of the target type |
charset | the character set of the target type (nullptr if not specified) |
bool sql_scalar_to_json | ( | Item * | arg, |
const char * | calling_function, | ||
String * | value, | ||
String * | tmp, | ||
Json_wrapper * | wr, | ||
Json_scalar_holder * | scalar, | ||
bool | scalar_string | ||
) |
Get a JSON value from an SQL scalar value.
[in] | arg | the function argument |
[in] | calling_function | the name of the calling function |
[in,out] | value | a scratch area |
[in,out] | tmp | temporary scratch space for converting strings to the correct charset; only used if accept_string is true and conversion is needed |
[out] | wr | the retrieved JSON value |
[in,out] | scalar | pointer to pre-allocated memory that can be borrowed by the result wrapper to hold the scalar result. If the pointer is NULL, memory will be allocated on the heap. |
[in] | scalar_string | if true, interpret SQL strings as scalar JSON strings. if false, interpret SQL strings as JSON objects. If conversion fails, return the string as a scalar JSON string instead. |
Scalar processing is irrelevant. Geometry types are converted to JSON objects.
|
static |
|
static |