diff --git a/TOC-tidb-cloud.md b/TOC-tidb-cloud.md index 0257bcb95ac52..4f5e21cfc99a3 100644 --- a/TOC-tidb-cloud.md +++ b/TOC-tidb-cloud.md @@ -526,7 +526,15 @@ - [Encryption and Compression Functions](/functions-and-operators/encryption-and-compression-functions.md) - [Locking Functions](/functions-and-operators/locking-functions.md) - [Information Functions](/functions-and-operators/information-functions.md) - - [JSON Functions](/functions-and-operators/json-functions.md) + - JSON Functions + - [Overview](/functions-and-operators/json-functions.md) + - [Functions That Create JSON](/functions-and-operators/json-functions/json-functions-create.md) + - [Functions That Search JSON](/functions-and-operators/json-functions/json-functions-search.md) + - [Functions That Modify JSON](/functions-and-operators/json-functions/json-functions-modify.md) + - [Functions That Return JSON](/functions-and-operators/json-functions/json-functions-return.md) + - [JSON Utility Functions](/functions-and-operators/json-functions/json-functions-utility.md) + - [Functions That Aggregate JSON](/functions-and-operators/json-functions/json-functions-aggregate.md) + - [Functions That Validate JSON](/functions-and-operators/json-functions/json-functions-validate.md) - [Aggregate (GROUP BY) Functions](/functions-and-operators/aggregate-group-by-functions.md) - [GROUP BY Modifiers](/functions-and-operators/group-by-modifier.md) - [Window Functions](/functions-and-operators/window-functions.md) diff --git a/TOC.md b/TOC.md index b44cb680727e4..6b4a29a435436 100644 --- a/TOC.md +++ b/TOC.md @@ -907,7 +907,15 @@ - [Encryption and Compression Functions](/functions-and-operators/encryption-and-compression-functions.md) - [Locking Functions](/functions-and-operators/locking-functions.md) - [Information Functions](/functions-and-operators/information-functions.md) - - [JSON Functions](/functions-and-operators/json-functions.md) + - JSON Functions + - [Overview](/functions-and-operators/json-functions.md) + - [Functions That Create JSON](/functions-and-operators/json-functions/json-functions-create.md) + - [Functions That Search JSON](/functions-and-operators/json-functions/json-functions-search.md) + - [Functions That Modify JSON](/functions-and-operators/json-functions/json-functions-modify.md) + - [Functions That Return JSON](/functions-and-operators/json-functions/json-functions-return.md) + - [JSON Utility Functions](/functions-and-operators/json-functions/json-functions-utility.md) + - [Functions That Aggregate JSON](/functions-and-operators/json-functions/json-functions-aggregate.md) + - [Functions That Validate JSON](/functions-and-operators/json-functions/json-functions-validate.md) - [Aggregate (GROUP BY) Functions](/functions-and-operators/aggregate-group-by-functions.md) - [GROUP BY Modifiers](/functions-and-operators/group-by-modifier.md) - [Window Functions](/functions-and-operators/window-functions.md) diff --git a/data-type-default-values.md b/data-type-default-values.md index 7dbdaf2b35a09..e4be4820b59c7 100644 --- a/data-type-default-values.md +++ b/data-type-default-values.md @@ -14,7 +14,7 @@ You can set default values for all data types. Typically, default values must be - For integer types, you can use the `NEXT VALUE FOR` function to set the next value of a sequence as the default value for a column, and use the [`RAND()`](/functions-and-operators/numeric-functions-and-operators.md) function to generate a random floating-point value as the default value for a column. - For string types, you can use the [`UUID()`](/functions-and-operators/miscellaneous-functions.md) function to generate a [universally unique identifier (UUID)](/best-practices/uuid.md) as the default value for a column. - For binary types, you can use the [`UUID_TO_BIN()`](/functions-and-operators/miscellaneous-functions.md) function to convert a UUID to the binary format and set the converted value as the default value for a column. -- Starting from v8.0.0, TiDB additionally supports [specifying the default values](#specify-expressions-as-default-values) for [`BLOB`](/data-type-string.md#blob-type), [`TEXT`](/data-type-string.md#text-type), and [`JSON`](/data-type-json.md#json-type) data types, but you can only use expressions to set the [default values](#default-values) for them. +- Starting from v8.0.0, TiDB additionally supports [specifying the default values](#specify-expressions-as-default-values) for [`BLOB`](/data-type-string.md#blob-type), [`TEXT`](/data-type-string.md#text-type), and [`JSON`](/data-type-json.md#json-data-type) data types, but you can only use expressions to set the [default values](#default-values) for them. If a column definition includes no explicit `DEFAULT` value, TiDB determines the default value as follows: diff --git a/data-type-json.md b/data-type-json.md index fa043bc000a8c..fd19239772005 100644 --- a/data-type-json.md +++ b/data-type-json.md @@ -4,7 +4,7 @@ summary: Learn about the JSON data type in TiDB. aliases: ['/docs/dev/data-type-json/','/docs/dev/reference/sql/data-types/json/'] --- -# JSON Type +# JSON Data Type TiDB supports the `JSON` (JavaScript Object Notation) data type, which is useful for storing semi-structured data. The `JSON` data type provides the following advantages over storing `JSON`-format strings in a string column: @@ -26,6 +26,27 @@ SELECT id FROM city WHERE population >= 100; For more information, see [JSON Functions](/functions-and-operators/json-functions.md) and [Generated Columns](/generated-columns.md). +## JSON value types + +The values inside a JSON document have types. This is visible in the output of [`JSON_TYPE`()](/functions-and-operators/json-functions/json-functions-return.md#json_type). + +| Type | Example | +|------------------|--------------------------------| +| ARRAY | `[]` | +| BIT | | +| BLOB | `0x616263` | +| BOOLEAN | `true` | +| DATE | `"2025-06-14"` | +| DATETIME | `"2025-06-14 09:05:10.000000"` | +| DOUBLE | `1.14` | +| INTEGER | `5` | +| NULL | `null` | +| OBJECT | `{}` | +| OPAQUE | | +| STRING | `"foobar"` | +| TIME | `"09:10:00.000000"` | +| UNSIGNED INTEGER | `9223372036854776000` | + ## Restrictions - Currently, TiDB only supports pushing down limited `JSON` functions to TiFlash. For more information, see [Push-down expressions](/tiflash/tiflash-supported-pushdown-calculations.md#push-down-expressions). @@ -102,4 +123,4 @@ For more information, see [JSON Functions](/functions-and-operators/json-functio INSERT INTO t VALUES (3); ``` -For more information about the `JSON` data type, see [JSON functions](/functions-and-operators/json-functions.md) and [Generated Columns](/generated-columns.md). \ No newline at end of file +For more information about the `JSON` data type, see [JSON functions](/functions-and-operators/json-functions.md) and [Generated Columns](/generated-columns.md). diff --git a/functions-and-operators/aggregate-group-by-functions.md b/functions-and-operators/aggregate-group-by-functions.md index 2693c910f6ee9..73736c832c3d1 100644 --- a/functions-and-operators/aggregate-group-by-functions.md +++ b/functions-and-operators/aggregate-group-by-functions.md @@ -12,20 +12,21 @@ This document describes details about the supported aggregate functions in TiDB. This section describes the supported MySQL `GROUP BY` aggregate functions in TiDB. -| Name | Description | -|:--------------------------------------------------------------------------------------------------------------|:--------------------------------------------------| +| Name | Description | +|:---------------------------------------------------------------------------------------------------------------|:--------------------------------------------------| | [`COUNT()`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_count) | Return a count of the number of rows returned | | [`COUNT(DISTINCT)`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_count-distinct) | Return the count of a number of different values | | [`SUM()`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_sum) | Return the sum | | [`AVG()`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_avg) | Return the average value of the argument | | [`MAX()`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_max) | Return the maximum value | | [`MIN()`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_min) | Return the minimum value | -| [`GROUP_CONCAT()`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_group-concat) | Return a concatenated string | -| [`VARIANCE()`, `VAR_POP()`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_var-pop) | Return the population standard variance| -| [`STD()`, `STDDEV()`, `STDDEV_POP`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_std) | Return the population standard deviation | -| [`VAR_SAMP()`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_var-samp) | Return the sample variance | -| [`STDDEV_SAMP()`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_stddev-samp) | Return the sample standard deviation | -| [`JSON_OBJECTAGG(key, value)`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_json-objectagg) | Return the result set as a single JSON object containing key-value pairs | +| [`GROUP_CONCAT()`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_group-concat) | Return a concatenated string | +| [`VARIANCE()`, `VAR_POP()`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_var-pop) | Return the population standard variance | +| [`STD()`, `STDDEV()`, `STDDEV_POP`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_std) | Return the population standard deviation | +| [`VAR_SAMP()`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_var-samp) | Return the sample variance | +| [`STDDEV_SAMP()`](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_stddev-samp) | Return the sample standard deviation | +| [`JSON_ARRAYAGG()`](/functions-and-operators/json-functions/json-functions-aggregate.md#json_arrayagg) | Return the result set as a single JSON array | +| [`JSON_OBJECTAGG()`](/functions-and-operators/json-functions/json-functions-aggregate.md#json_objectagg) | Return the result set as a single JSON object containing key-value pairs | - Unless otherwise stated, group functions ignore `NULL` values. - If you use a group function in a statement containing no `GROUP BY` clause, it is equivalent to grouping on all rows. @@ -40,23 +41,19 @@ In addition, TiDB also provides the following aggregate functions: The following example shows how to calculate the fiftieth percentile of a `INT` column: - {{< copyable "sql" >}} - ```sql - drop table if exists t; - create table t(a int); - insert into t values(1), (2), (3); + DROP TABLE IF EXISTS t; + CREATE TABLE t(a INT); + INSERT INTO t VALUES(1), (2), (3); ``` - {{< copyable "sql" >}} - ```sql - select approx_percentile(a, 50) from t; + SELECT APPROX_PERCENTILE(a, 50) FROM t; ``` ```sql +--------------------------+ - | approx_percentile(a, 50) | + | APPROX_PERCENTILE(a, 50) | +--------------------------+ | 2 | +--------------------------+ @@ -153,4 +150,4 @@ group by id, val; ## Related system variables -The `group_concat_max_len` variable sets the maximum number of items for the `GROUP_CONCAT()` function. \ No newline at end of file +The [`group_concat_max_len`](/system-variables.md#group_concat_max_len) variable sets the maximum number of items for the `GROUP_CONCAT()` function. \ No newline at end of file diff --git a/functions-and-operators/json-functions.md b/functions-and-operators/json-functions.md index 747bed4786346..f574c063e6511 100644 --- a/functions-and-operators/json-functions.md +++ b/functions-and-operators/json-functions.md @@ -6,79 +6,144 @@ aliases: ['/docs/dev/functions-and-operators/json-functions/','/docs/dev/referen # JSON Functions -TiDB supports most of the [JSON functions](https://dev.mysql.com/doc/refman/8.0/en/json-functions.html) available in MySQL 8.0. +You can use JSON functions to work with data in the [JSON data type](/data-type-json.md). ## Functions that create JSON values | Function Name | Description | | --------------------------------- | ----------- | -| [JSON_ARRAY([val[, val] ...])](https://dev.mysql.com/doc/refman/8.0/en/json-creation-functions.html#function_json-array) | Evaluates a (possibly empty) list of values and returns a JSON array containing those values | -| [JSON_OBJECT(key, val[, key, val] ...)](https://dev.mysql.com/doc/refman/8.0/en/json-creation-functions.html#function_json-object) | Evaluates a (possibly empty) list of key-value pairs and returns a JSON object containing those pairs | -| [JSON_QUOTE(string)](https://dev.mysql.com/doc/refman/8.0/en/json-creation-functions.html#function_json-quote) | Returns a string as a JSON value with quotes | +| [JSON_ARRAY()](/functions-and-operators/json-functions/json-functions-create.md#json_array) | Evaluates a (possibly empty) list of values and returns a JSON array containing those values | +| [JSON_OBJECT()](/functions-and-operators/json-functions/json-functions-create.md#json_object) | Evaluates a (possibly empty) list of key-value pairs and returns a JSON object containing those pairs | +| [JSON_QUOTE()](/functions-and-operators/json-functions/json-functions-create.md#json_quote) | Returns a string as a JSON value with quotes | ## Functions that search JSON values | Function Name | Description | | --------------------------------- | ----------- | -| [JSON_CONTAINS(target, candidate[, path])](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-contains) | Indicates by returning 1 or 0 whether a given candidate JSON document is contained within a target JSON document | -| [JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] ...)](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-contains-path) | Returns 0 or 1 to indicate whether a JSON document contains data at a given path or paths | -| [JSON_EXTRACT(json_doc, path[, path] ...)](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-extract)| Returns data from a JSON document, selected from the parts of the document matched by the `path` arguments | -| [->](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_json-column-path) | Returns the value from a JSON column after the evaluating path; an alias for `JSON_EXTRACT(doc, path_literal)` | -| [->>](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_json-inline-path) | Returns the value from a JSON column after the evaluating path and unquoting the result; an alias for `JSON_UNQUOTE(JSON_EXTRACT(doc, path_literal))` | -| [JSON_KEYS(json_doc[, path])](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-keys) | Returns the keys from the top-level value of a JSON object as a JSON array, or, if a path argument is given, the top-level keys from the selected path | -| [JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] ...])](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-search) | Search a JSON document for one or all matches of a string | -| [value MEMBER OF(json_array)](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of) | If the passed value is an element of the JSON array, returns 1. Otherwise, returns 0. | -| [JSON_OVERLAPS(json_doc1, json_doc2)](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-overlaps) | Indicates whether two JSON documents have overlapping part. If yes, returns 1. If not, returns 0. | +| [JSON_CONTAINS()](/functions-and-operators/json-functions/json-functions-search.md#json_contains) | Indicates by returning 1 or 0 whether a given candidate JSON document is contained within a target JSON document | +| [JSON_CONTAINS_PATH()](/functions-and-operators/json-functions/json-functions-search.md#json_contains_path) | Returns 0 or 1 to indicate whether a JSON document contains data at a given path or paths | +| [JSON_EXTRACT()](/functions-and-operators/json-functions/json-functions-search.md#json_extract) | Returns data from a JSON document, selected from the parts of the document matched by the `path` arguments | +| [->](/functions-and-operators/json-functions/json-functions-search.md#-) | Returns the value from a JSON column after the evaluating path; an alias for `JSON_EXTRACT(doc, path_literal)` | +| [->>](/functions-and-operators/json-functions/json-functions-search.md#--1) | Returns the value from a JSON column after the evaluating path and unquoting the result; an alias for `JSON_UNQUOTE(JSON_EXTRACT(doc, path_literal))` | +| [JSON_KEYS()](/functions-and-operators/json-functions/json-functions-search.md#json_keys) | Returns the keys from the top-level value of a JSON object as a JSON array, or, if a path argument is given, the top-level keys from the selected path | +| [JSON_SEARCH()](/functions-and-operators/json-functions/json-functions-search.md#json_search) | Search a JSON document for one or all matches of a string | +| [MEMBER OF()](/functions-and-operators/json-functions/json-functions-search.md#member-of) | If the passed value is an element of the JSON array, returns 1. Otherwise, returns 0. | +| [JSON_OVERLAPS()](/functions-and-operators/json-functions/json-functions-search.md#json_overlaps) | Indicates whether two JSON documents have overlapping part. If yes, returns 1. If not, returns 0. | ## Functions that modify JSON values | Function Name | Description | | --------------------------------- | ----------- | -| [JSON_APPEND(json_doc, path, value)](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-append) | An alias to `JSON_ARRAY_APPEND` | -| [JSON_ARRAY_APPEND(json_doc, path, val[, path, val] ...)](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-array-append) | Appends values to the end of the indicated arrays within a JSON document and returns the result | -| [JSON_ARRAY_INSERT(json_doc, path, val[, path, val] ...)](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-array-insert) | Insert values into the specified locations of a JSON document and returns the result | -| [JSON_INSERT(json_doc, path, val[, path, val] ...)](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-insert) | Inserts data into a JSON document and returns the result | -| [JSON_MERGE_PATCH(json_doc, json_doc[, json_doc] ...)](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-merge-patch) | Merge JSON documents | -| [JSON_MERGE_PRESERVE(json_doc, json_doc[, json_doc] ...)](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-merge-preserve) | Merges two or more JSON documents and returns the merged result | -| [JSON_MERGE(json_doc, json_doc[, json_doc] ...)](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-merge) | A deprecated alias for `JSON_MERGE_PRESERVE` | -| [JSON_REMOVE(json_doc, path[, path] ...)](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-remove) | Removes data from a JSON document and returns the result | -| [JSON_REPLACE(json_doc, path, val[, path, val] ...)](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-replace) | Replaces existing values in a JSON document and returns the result | -| [JSON_SET(json_doc, path, val[, path, val] ...)](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-set) | Inserts or updates data in a JSON document and returns the result | -| [JSON_UNQUOTE(json_val)](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-unquote) | Unquotes a JSON value and returns the result as a string | +| [JSON_APPEND()](/functions-and-operators/json-functions/json-functions-modify.md#json_append) | An alias to `JSON_ARRAY_APPEND()` | +| [JSON_ARRAY_APPEND()](/functions-and-operators/json-functions/json-functions-modify.md#json_array_append) | Appends values to the end of the indicated arrays within a JSON document and returns the result | +| [JSON_ARRAY_INSERT()](/functions-and-operators/json-functions/json-functions-modify.md#json_array_insert) | Insert values into the specified locations of a JSON document and returns the result | +| [JSON_INSERT()](/functions-and-operators/json-functions/json-functions-modify.md#json_insert) | Inserts data into a JSON document and returns the result | +| [JSON_MERGE_PATCH()](/functions-and-operators/json-functions/json-functions-modify.md#json_merge_patch) | Merges two or more JSON documents, without preserving values of duplicate keys | +| [JSON_MERGE_PRESERVE()](/functions-and-operators/json-functions/json-functions-modify.md#json_merge_preserve) | Merges two or more JSON documents by preserving all values | +| [JSON_MERGE()](/functions-and-operators/json-functions/json-functions-modify.md#json_merge) | A deprecated alias for `JSON_MERGE_PRESERVE()` | +| [JSON_REMOVE()](/functions-and-operators/json-functions/json-functions-modify.md#json_remove) | Removes data from a JSON document and returns the result | +| [JSON_REPLACE()](/functions-and-operators/json-functions/json-functions-modify.md#json_replace) | Replaces existing values in a JSON document and returns the result | +| [JSON_SET()](/functions-and-operators/json-functions/json-functions-modify.md#json_set) | Inserts or updates data in a JSON document and returns the result | +| [JSON_UNQUOTE()](/functions-and-operators/json-functions/json-functions-modify.md#json_unquote) | Unquotes a JSON value and returns the result as a string | ## Functions that return JSON value attributes | Function Name | Description | | --------------------------------- | ----------- | -| [JSON_DEPTH(json_doc)](https://dev.mysql.com/doc/refman/8.0/en/json-attribute-functions.html#function_json-depth) | Returns the maximum depth of a JSON document | -| [JSON_LENGTH(json_doc[, path])](https://dev.mysql.com/doc/refman/8.0/en/json-attribute-functions.html#function_json-length) | Returns the length of a JSON document, or, if a path argument is given, the length of the value within the path | -| [JSON_TYPE(json_val)](https://dev.mysql.com/doc/refman/8.0/en/json-attribute-functions.html#function_json-type) | Returns a string indicating the type of a JSON value | -| [JSON_VALID(json_doc)](https://dev.mysql.com/doc/refman/8.0/en/json-attribute-functions.html#function_json-valid) | Checks if a json\_doc is valid JSON. Useful for checking a column before converting it to the json type. | +| [JSON_DEPTH()](/functions-and-operators/json-functions/json-functions-return.md#json_depth) | Returns the maximum depth of a JSON document | +| [JSON_LENGTH()](/functions-and-operators/json-functions/json-functions-return.md#json_length) | Returns the length of a JSON document, or, if a path argument is given, the length of the value within the path | +| [JSON_TYPE()](/functions-and-operators/json-functions/json-functions-return.md#json_type) | Returns a string indicating the type of a JSON value | +| [JSON_VALID()](/functions-and-operators/json-functions/json-functions-return.md#json_valid) | Checks if a json\_doc is valid JSON. | ## Utility functions | Function Name | Description | | --------------------------------- | ----------- | -| [JSON_PRETTY(json_doc)](https://dev.mysql.com/doc/refman/8.0/en/json-utility-functions.html#function_json-pretty) | Pretty formatting of a JSON document | -| [JSON_STORAGE_FREE(json_doc)](https://dev.mysql.com/doc/refman/8.0/en/json-utility-functions.html#function_json-storage-free) | Returns how much storage space was freed in the binary representation of the JSON value after it was updated in place. As TiDB has different storage architecture from MySQL, this function always returns 0 for a valid JSON value, and it is implemented for compatibility with MySQL 8.0. | -| [JSON_STORAGE_SIZE(json_doc)](https://dev.mysql.com/doc/refman/8.0/en/json-utility-functions.html#function_json-storage-size) | Returns an approximate size of bytes required to store the json value. As the size does not account for TiKV using compression, the output of this function is not strictly compatible with MySQL. | +| [JSON_PRETTY()](/functions-and-operators/json-functions/json-functions-utility.md#json_pretty) | Pretty formatting of a JSON document | +| [JSON_STORAGE_FREE()](/functions-and-operators/json-functions/json-functions-utility.md#json_storage_free) | Returns how much storage space was freed in the binary representation of the JSON value after it was updated in place. | +| [JSON_STORAGE_SIZE()](/functions-and-operators/json-functions/json-functions-utility.md#json_storage_size) | Returns an approximate size of bytes required to store the json value. As the size does not account for TiKV using compression, the output of this function is not strictly compatible with MySQL. | ## Aggregate functions | Function Name | Description | | --------------------------------- | ----------- | -| [JSON_ARRAYAGG(key)](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_json-arrayagg) | Provides an aggregation of keys. | -| [JSON_OBJECTAGG(key, value)](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_json-objectagg) | Provides an aggregation of values for a given key. | +| [JSON_ARRAYAGG()](/functions-and-operators/json-functions/json-functions-aggregate.md#json_arrayagg) | Provides an aggregation of keys. | +| [JSON_OBJECTAGG()](/functions-and-operators/json-functions/json-functions-aggregate.md#json_objectagg) | Provides an aggregation of values for a given key. | ## Validation functions - + | Function Name | Description | | --------------------------------- | ----------- | -| [JSON_SCHEMA_VALID(schema,json_doc)](https://dev.mysql.com/doc/refman/8.0/en/json-validation-functions.html#function_json-schema-valid) | Validates a JSON document against a schema to ensure data integrity and consistency. | +| [JSON_SCHEMA_VALID()](/functions-and-operators/json-functions/json-functions-validate.md#json_schema_valid) | Validates a JSON document against a schema to ensure data integrity and consistency. | + +## JSONPath + +Many of JSON functions use [JSONPath](https://www.rfc-editor.org/rfc/rfc9535.html) to select parts of a JSON document. + +| Symbol | Description | +| -------------- | ---------------------------- | +| `$` | Document root | +| `.` | Member selection | +| `[]` | Array selection | +| `*` | Wildcard | +| `**` | Path wildcard | +| `[ to ]` | Array range selection | + +The subsequent content takes the following JSON document as an example to demonstrate how to use JSONPath: + +```json +{ + "database": { + "name": "TiDB", + "features": [ + "distributed", + "scalable", + "relational", + "cloud native" + ], + "license": "Apache-2.0 license", + "versions": [ + { + "version": "v8.1.0", + "type": "lts", + "release_date": "2024-05-24" + }, + { + "version": "v8.0.0", + "type": "dmr", + "release_date": "2024-03-29" + } + ] + }, + "migration_tool": { + "name": "TiDB Data Migration", + "features": [ + "MySQL compatible", + "Shard merging" + ], + "license": "Apache-2.0 license" + } +} +``` + +| JSONPath | Description | Example with [`JSON_EXTRACT()`](/functions-and-operators/json-functions/json-functions-search.md#json_extract) | +|-------------------------------------- |-----------------------------------------|-------------------------------| +| `$` | The root of the document | Returns the full document | +| `$.database` | The `database` object | Returns the full structure starting with `"database"`. It does not include `"migration_tool"` and the structure below that. | +| `$.database.name` | The name of the database. | `"TiDB"` | +| `$.database.features` | All database features | `["distributed", "scalable", "relational", "cloud native"]` | +| `$.database.features[0]` | The first database feature. | `"distributed"` | +| `$.database.features[2]` | The third database feature. | `"relational"` | +| `$.database.versions[0].type` | The type of the first database version. | `"lts"` | +| `$.database.versions[*].release_date` | The release date for all versions. | `["2024-05-24","2024-03-29"]` | +| `$.*.features` | Two array's of features | `[["distributed", "scalable", "relational", "cloud native"], ["MySQL compatible", "Shard merging"]]` | +| `$**.version` | All versions, with path wildcard | `["v8.1.0","v8.0.0"]` | +| `$.database.features[0 to 2]` | Range of database features from the first to the third. | `["scalable","relational"]` | + +For more information, see [the IETF draft for JSONPath](https://www.ietf.org/archive/id/draft-goessner-dispatch-jsonpath-00.html). ## See also -* [JSON Function Reference](https://dev.mysql.com/doc/refman/8.0/en/json-function-reference.html) * [JSON Data Type](/data-type-json.md) ## Unsupported functions @@ -87,4 +152,8 @@ TiDB supports most of the [JSON functions](https://dev.mysql.com/doc/refman/8.0/ - `JSON_TABLE()` - `JSON_VALUE()` -For more information, see [#14486](https://github.com/pingcap/tidb/issues/14486). \ No newline at end of file +For more information, see [#14486](https://github.com/pingcap/tidb/issues/14486). + +## MySQL compatibility + +- TiDB supports most of the [JSON functions](https://dev.mysql.com/doc/refman/8.0/en/json-functions.html) available in MySQL 8.0. diff --git a/functions-and-operators/json-functions/json-functions-aggregate.md b/functions-and-operators/json-functions/json-functions-aggregate.md new file mode 100644 index 0000000000000..e564119bc4feb --- /dev/null +++ b/functions-and-operators/json-functions/json-functions-aggregate.md @@ -0,0 +1,132 @@ +--- +title: JSON Functions That Aggregate JSON Values +summary: Learn about JSON functions that aggregate JSON values. +--- + +# JSON Functions That Aggregate JSON Values + +The functions listed on this page are part of the [aggregate functions](/functions-and-operators/aggregate-group-by-functions.md) that TiDB supports, but are specific to working with JSON. + +## [JSON_ARRAYAGG()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_json-arrayagg) + +The `JSON_ARRAYAGG(key)` function aggregates values of keys into a JSON array according to the given `key`. `key` is typically an expression or a column name. + +Example: + +Here the two rows in one column of a table get aggregated into a JSON array. + +```sql +SELECT JSON_ARRAYAGG(v) FROM (SELECT 1 'v' UNION SELECT 2); +``` + +``` ++------------------+ +| JSON_ARRAYAGG(v) | ++------------------+ +| [2, 1] | ++------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_OBJECTAGG()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_json-objectagg) + +The `JSON_OBJECTAGG(key,value)` function aggregates keys and values of keys into a JSON object according to the given `key` and `value`. Both `key` or `value` are typically an expression or a column name. + +Example: + +First, create two tables and add a few rows to them. + +```sql +CREATE TABLE plants ( + id INT PRIMARY KEY, + name VARCHAR(255) +); + +CREATE TABLE plant_attributes ( + id INT PRIMARY KEY AUTO_INCREMENT, + plant_id INT, attribute VARCHAR(255), + value VARCHAR(255), + FOREIGN KEY (plant_id) REFERENCES plants(id) +); + +INSERT INTO plants +VALUES +(1,"rose"), +(2,"tulip"), +(3,"orchid"); + +INSERT INTO plant_attributes(plant_id,attribute,value) +VALUES +(1,"color","red"), +(1,"thorns","yes"), +(2,"color","orange"), +(2,"thorns","no"), +(2,"grows_from","bulb"), +(3,"color","white"), +(3, "thorns","no"); +``` + +Now you can check what the created tables look like. + +```sql +TABLE plants; +``` + +``` ++----+--------+ +| id | name | ++----+--------+ +| 1 | rose | +| 2 | tulip | +| 3 | orchid | ++----+--------+ +3 rows in set (0.00 sec) +``` + +```sql +TABLE plant_attributes; +``` + +``` ++----+----------+------------+--------+ +| id | plant_id | attribute | value | ++----+----------+------------+--------+ +| 1 | 1 | color | red | +| 2 | 1 | thorns | yes | +| 3 | 2 | color | orange | +| 4 | 2 | thorns | no | +| 5 | 2 | grows_from | bulb | +| 6 | 3 | color | white | +| 7 | 3 | thorns | no | ++----+----------+------------+--------+ +7 rows in set (0.00 sec) +``` + +You can use the `JSON_OBJECTAGG()` function with this data. Here you can see that for every group multiple key/value pairs are aggregated into a JSON object. + +```sql +SELECT + p.name, + JSON_OBJECTAGG(attribute,value) +FROM + plant_attributes pa + LEFT JOIN plants p ON pa.plant_id=p.id +GROUP BY + plant_id; +``` + +``` ++--------+-----------------------------------------------------------+ +| name | JSON_OBJECTAGG(attribute,value) | ++--------+-----------------------------------------------------------+ +| rose | {"color": "red", "thorns": "yes"} | +| orchid | {"color": "white", "thorns": "no"} | +| tulip | {"color": "orange", "grows_from": "bulb", "thorns": "no"} | ++--------+-----------------------------------------------------------+ +3 rows in set (0.00 sec) +``` + +## See also + +- [JSON Functions Overview](/functions-and-operators/json-functions.md) +- [JSON Data Type](/data-type-json.md) \ No newline at end of file diff --git a/functions-and-operators/json-functions/json-functions-create.md b/functions-and-operators/json-functions/json-functions-create.md new file mode 100644 index 0000000000000..cbe0eb79761ea --- /dev/null +++ b/functions-and-operators/json-functions/json-functions-create.md @@ -0,0 +1,64 @@ +--- +title: JSON Functions That Create JSON Values +summary: Learn about JSON functions that create JSON values. +--- + +# JSON Functions That Create JSON Values + +This document describes JSON functions that create JSON values. + +## [JSON_ARRAY()](https://dev.mysql.com/doc/refman/8.0/en/json-creation-functions.html#function_json-array) + +The `JSON_ARRAY([val[, val] ...])` function evaluates a (possibly empty) list of values and returns a JSON array containing those values. + +```sql +SELECT JSON_ARRAY(1,2,3,4,5), JSON_ARRAY("foo", "bar"); +``` + +``` ++-----------------------+--------------------------+ +| JSON_ARRAY(1,2,3,4,5) | JSON_ARRAY("foo", "bar") | ++-----------------------+--------------------------+ +| [1, 2, 3, 4, 5] | ["foo", "bar"] | ++-----------------------+--------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_OBJECT()](https://dev.mysql.com/doc/refman/8.0/en/json-creation-functions.html#function_json-object) + +The `JSON_OBJECT([key, val[, key, val] ...])` function evaluates a (possibly empty) list of key-value pairs and returns a JSON object containing those pairs. + +```sql +SELECT JSON_OBJECT("database", "TiDB", "distributed", TRUE); +``` + +``` ++------------------------------------------------------+ +| JSON_OBJECT("database", "TiDB", "distributed", TRUE) | ++------------------------------------------------------+ +| {"database": "TiDB", "distributed": true} | ++------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_QUOTE()](https://dev.mysql.com/doc/refman/8.0/en/json-creation-functions.html#function_json-quote) + +The `JSON_QUOTE(str)` function returns a string as a JSON value with quotes. + +```sql +SELECT JSON_QUOTE('The name is "O\'Neil"'); +``` + +``` ++-------------------------------------+ +| JSON_QUOTE('The name is "O\'Neil"') | ++-------------------------------------+ +| "The name is \"O'Neil\"" | ++-------------------------------------+ +1 row in set (0.00 sec) +``` + +## See also + +- [JSON Functions Overview](/functions-and-operators/json-functions.md) +- [JSON Data Type](/data-type-json.md) \ No newline at end of file diff --git a/functions-and-operators/json-functions/json-functions-modify.md b/functions-and-operators/json-functions/json-functions-modify.md new file mode 100644 index 0000000000000..4d839a5efc7d3 --- /dev/null +++ b/functions-and-operators/json-functions/json-functions-modify.md @@ -0,0 +1,346 @@ +--- +title: JSON Functions That Modify JSON Values +summary: Learn about JSON functions that modify JSON values. +--- + +# JSON Functions That Modify JSON Values + +This document describes JSON functions that modify JSON values. + +## [JSON_APPEND()](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-append) + +An alias to [`JSON_ARRAY_APPEND()`](#json_array_append). + +## [JSON_ARRAY_APPEND()](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-array-append) + +The `JSON_ARRAY_APPEND(json_array, path, value [,path, value] ...)` function appends values to the end of the indicated arrays within a JSON document at the specified `path` and returns the result. + +This function takes arguments in pairs, where each pair is a `path` and a `value`. + +Examples: + +The following example adds an item to an array, which is the root of the JSON document. + +```sql +SELECT JSON_ARRAY_APPEND('["Car", "Boat", "Train"]', '$', "Airplane") AS "Transport options"; +``` + +``` ++--------------------------------------+ +| Transport options | ++--------------------------------------+ +| ["Car", "Boat", "Train", "Airplane"] | ++--------------------------------------+ +1 row in set (0.00 sec) +``` + +The following example adds an item to an array at the specified path. + +```sql +SELECT JSON_ARRAY_APPEND('{"transport_options": ["Car", "Boat", "Train"]}', '$.transport_options', "Airplane") AS "Transport options"; +``` + +``` ++-------------------------------------------------------------+ +| Transport options | ++-------------------------------------------------------------+ +| {"transport_options": ["Car", "Boat", "Train", "Airplane"]} | ++-------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_ARRAY_INSERT()](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-array-insert) + +The `JSON_ARRAY_INSERT(json_array, path, value [,path, value] ...)` function inserts a `value` into the specified position of the `json_array` in the `path` and returns the result. + +This function takes arguments in pairs, where each pair is a `path` and a `value`. + +Examples: + +The following example inserts a value at the position of index 0 in the array. + +```sql +SELECT JSON_ARRAY_INSERT('["Car", "Boat", "Train"]', '$[0]', "Airplane") AS "Transport options"; +``` + +``` ++--------------------------------------+ +| Transport options | ++--------------------------------------+ +| ["Airplane", "Car", "Boat", "Train"] | ++--------------------------------------+ +1 row in set (0.01 sec) +``` + +The following example inserts a value at the position of index 1 in the array. + +```sql +SELECT JSON_ARRAY_INSERT('["Car", "Boat", "Train"]', '$[1]', "Airplane") AS "Transport options"; +``` + +``` ++--------------------------------------+ +| Transport options | ++--------------------------------------+ +| ["Car", "Airplane", "Boat", "Train"] | ++--------------------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_INSERT()](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-insert) + +The `JSON_INSERT(json_doc, path, value [,path, value] ...)` function inserts one or more values into a JSON document and returns the result. + +This function takes arguments in pairs, where each pair is a `path` and a `value`. + +```sql +SELECT JSON_INSERT( + '{"language": ["Go", "Rust", "C++"]}', + '$.architecture', 'riscv', + '$.os', JSON_ARRAY("linux","freebsd") +) AS "Demo"; +``` + +``` ++------------------------------------------------------------------------------------------+ +| Demo | ++------------------------------------------------------------------------------------------+ +| {"architecture": "riscv", "language": ["Go", "Rust", "C++"], "os": ["linux", "freebsd"]} | ++------------------------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +Note that this function does not overwrite values of existing attributes. For example, the following statement appears to overwrite the `"a"` attribute, but it does not actually do so. + +```sql +SELECT JSON_INSERT('{"a": 61, "b": 62}', '$.a', 41, '$.c', 63); +``` + +``` ++---------------------------------------------------------+ +| JSON_INSERT('{"a": 61, "b": 62}', '$.a', 41, '$.c', 63) | ++---------------------------------------------------------+ +| {"a": 61, "b": 62, "c": 63} | ++---------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_MERGE_PATCH()](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-merge-patch) + +The `JSON_MERGE_PATCH(json_doc, json_doc [,json_doc] ...)` function merges two or more JSON documents into a single JSON document, without preserving values of duplicate keys. For `json_doc` arguments with duplicated keys, only the values from the later specified `json_doc` argument are preserved in the merged result. + +Examples: + +In the following example, you can see that the value of `a` gets overwritten by argument 2 and that `c` is added as a new attribute in the merged result. + +```sql +SELECT JSON_MERGE_PATCH( + '{"a": 1, "b": 2}', + '{"a": 100}', + '{"c": 300}' +); +``` + +``` ++-----------------------------------------------------------------+ +| JSON_MERGE_PATCH('{"a": 1, "b": 2}','{"a": 100}', '{"c": 300}') | ++-----------------------------------------------------------------+ +| {"a": 100, "b": 2, "c": 300} | ++-----------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_MERGE_PRESERVE()](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-merge-preserve) + +The `JSON_MERGE_PRESERVE(json_doc, json_doc [,json_doc] ...)` function merges two or more JSON documents while preserving all values associated with each key and returns the merged result. + +Examples: + +In the following example, you can see that the value of argument 2 is appended to `a` and that `c` is added as a new attribute. + +```sql +SELECT JSON_MERGE_PRESERVE('{"a": 1, "b": 2}','{"a": 100}', '{"c": 300}'); +``` + +``` ++--------------------------------------------------------------------+ +| JSON_MERGE_PRESERVE('{"a": 1, "b": 2}','{"a": 100}', '{"c": 300}') | ++--------------------------------------------------------------------+ +| {"a": [1, 100], "b": 2, "c": 300} | ++--------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_MERGE()](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-merge) + +> **Warning:** +> +> This function is deprecated. + +A deprecated alias for [`JSON_MERGE_PRESERVE()`](#json_merge_preserve). + +## [JSON_REMOVE()](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-remove) + +The `JSON_REMOVE(json_doc, path [,path] ...)` function removes data of the specified `path` from a JSON document and returns the result. + +Examples: + +This example removes the `b` attribute from the JSON document. + +```sql +SELECT JSON_REMOVE('{"a": 61, "b": 62, "c": 63}','$.b'); +``` + +``` ++--------------------------------------------------+ +| JSON_REMOVE('{"a": 61, "b": 62, "c": 63}','$.b') | ++--------------------------------------------------+ +| {"a": 61, "c": 63} | ++--------------------------------------------------+ +1 row in set (0.00 sec) +``` + +This example removes the `b` and `c` attributes from the JSON document. + +```sql +SELECT JSON_REMOVE('{"a": 61, "b": 62, "c": 63}','$.b','$.c'); +``` + +``` ++--------------------------------------------------------+ +| JSON_REMOVE('{"a": 61, "b": 62, "c": 63}','$.b','$.c') | ++--------------------------------------------------------+ +| {"a": 61} | ++--------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_REPLACE()](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-replace) + +The `JSON_REPLACE(json_doc, path, value [, path, value] ...)` function replaces values in specified paths of a JSON document and returns the result. If a specified path does not exist, the value corresponding to the path is not added to the result. + +This function takes arguments in pairs, where each pair is a `path` and a `value`. + +Examples: + +In the following example, you change the value at `$.b` from `62` to `42`. + +```sql +SELECT JSON_REPLACE('{"a": 41, "b": 62}','$.b',42); +``` + +``` ++---------------------------------------------+ +| JSON_REPLACE('{"a": 41, "b": 62}','$.b',42) | ++---------------------------------------------+ +| {"a": 41, "b": 42} | ++---------------------------------------------+ +1 row in set (0.00 sec) +``` + +In the following example, you can change the value at `$.b` from `62` to `42`. In addition, this statement tries to replace the value at `$.c` with `43`, but it does not work because the `$.c` path does not exist in `{"a": 41, "b": 62}`. + +```sql +SELECT JSON_REPLACE('{"a": 41, "b": 62}','$.b',42,'$.c',43); +``` + +``` ++------------------------------------------------------+ +| JSON_REPLACE('{"a": 41, "b": 62}','$.b',42,'$.c',43) | ++------------------------------------------------------+ +| {"a": 41, "b": 42} | ++------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_SET()](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-set) + +The `JSON_SET(json_doc, path, value [,path, value] ...)` function inserts or updates data in a JSON document and returns the result. + +This function takes arguments in pairs, where each pair is a `path` and a `value`. + +Examples: + +In the following example, you can update the `$.version` from `1.1` to `1.2`. + +```sql +SELECT JSON_SET('{"version": 1.1, "name": "example"}','$.version',1.2); +``` + +``` ++-----------------------------------------------------------------+ +| JSON_SET('{"version": 1.1, "name": "example"}','$.version',1.2) | ++-----------------------------------------------------------------+ +| {"name": "example", "version": 1.2} | ++-----------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +In the following example, you can update the `$.version` from `1.1` to `1.2`. And you can update `$.branch`, which does not exist before, to `main`. + +```sql +SELECT JSON_SET('{"version": 1.1, "name": "example"}','$.version',1.2,'$.branch', "main"); +``` + +``` ++------------------------------------------------------------------------------------+ +| JSON_SET('{"version": 1.1, "name": "example"}','$.version',1.2,'$.branch', "main") | ++------------------------------------------------------------------------------------+ +| {"branch": "main", "name": "example", "version": 1.2} | ++------------------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_UNQUOTE()](https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-unquote) + +The `JSON_UNQUOTE(json)` function unquotes a JSON value and returns the result as a string. This is the opposite of the [`JSON_QUOTE()`](/functions-and-operators/json-functions/json-functions-create.md#json_quote) function. + +Examples: + +In the example, `"foo"` is unquoted to `foo`. + +```sql +SELECT JSON_UNQUOTE('"foo"'); +``` + +``` ++-----------------------+ +| JSON_UNQUOTE('"foo"') | ++-----------------------+ +| foo | ++-----------------------+ +1 row in set (0.00 sec) +``` + +This function is often used together with [`JSON_EXTRACT()`](/functions-and-operators/json-functions/json-functions-search.md#json_extract). For the following examples, you can extract a JSON value with quotes in the first example and then use the two functions together to unquote the value in the second example. Note that instead of `JSON_UNQUOTE(JSON_EXTRACT(...))`, you can use the [`->>`](/functions-and-operators/json-functions/json-functions-search.md#--1) operator. + +```sql +SELECT JSON_EXTRACT('{"database": "TiDB"}', '$.database'); +``` + +``` ++----------------------------------------------------+ +| JSON_EXTRACT('{"database": "TiDB"}', '$.database') | ++----------------------------------------------------+ +| "TiDB" | ++----------------------------------------------------+ +1 row in set (0.00 sec) +``` + +```sql +SELECT JSON_UNQUOTE(JSON_EXTRACT('{"database": "TiDB"}', '$.database')); +``` + +``` ++------------------------------------------------------------------+ +| JSON_UNQUOTE(JSON_EXTRACT('{"database": "TiDB"}', '$.database')) | ++------------------------------------------------------------------+ +| TiDB | ++------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## See also + +- [JSON Functions Overview](/functions-and-operators/json-functions.md) +- [JSON Data Type](/data-type-json.md) \ No newline at end of file diff --git a/functions-and-operators/json-functions/json-functions-return.md b/functions-and-operators/json-functions/json-functions-return.md new file mode 100644 index 0000000000000..cc4afd41a04fe --- /dev/null +++ b/functions-and-operators/json-functions/json-functions-return.md @@ -0,0 +1,168 @@ +--- +title: JSON Functions That Return JSON Values +summary: Learn about JSON functions that return JSON values. +--- + +# JSON Functions That Return JSON Values + +This document describes JSON functions that return JSON values. + +## [JSON_DEPTH()](https://dev.mysql.com/doc/refman/8.0/en/json-attribute-functions.html#function_json-depth) + +The `JSON_DEPTH(json_doc)` function returns the maximum depth of a JSON document. + +Examples: + +In the following example, `JSON_DEPTH()` returns `3` because there are three levels: + +- root (`$`) +- weather (`$.weather`) +- weather current (`$.weather.sunny`) + +```sql +SELECT JSON_DEPTH('{"weather": {"current": "sunny"}}'); +``` + +``` ++-------------------------------------------------+ +| JSON_DEPTH('{"weather": {"current": "sunny"}}') | ++-------------------------------------------------+ +| 3 | ++-------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_LENGTH()](https://dev.mysql.com/doc/refman/8.0/en/json-attribute-functions.html#function_json-length) + +The `JSON_LENGTH(json_doc [,path])` function returns the length of a JSON document. If a `path` argument is given, it returns the length of the value within the path. + +Examples: + +In the following example, the returned value is `1` because the only item at the root of the document is `weather`. + +```sql +SELECT JSON_LENGTH('{"weather": {"current": "sunny", "tomorrow": "cloudy"}}','$'); +``` + +``` ++----------------------------------------------------------------------------+ +| JSON_LENGTH('{"weather": {"current": "sunny", "tomorrow": "cloudy"}}','$') | ++----------------------------------------------------------------------------+ +| 1 | ++----------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +In the following example, the returned value is `2` because there are two items at `$.weather`: `current` and `tomorrow`. + +```sql +SELECT JSON_LENGTH('{"weather": {"current": "sunny", "tomorrow": "cloudy"}}','$.weather'); +``` + +``` ++------------------------------------------------------------------------------------+ +| JSON_LENGTH('{"weather": {"current": "sunny", "tomorrow": "cloudy"}}','$.weather') | ++------------------------------------------------------------------------------------+ +| 2 | ++------------------------------------------------------------------------------------+ +1 row in set (0.01 sec) +``` + +## [JSON_TYPE()](https://dev.mysql.com/doc/refman/8.0/en/json-attribute-functions.html#function_json-type) + +The `JSON_TYPE(json_val)` function returns a string indicating [the type of a JSON value](/data-type-json.md#json-value-types). + +Example: + +```sql +WITH demo AS ( + SELECT 'null' AS 'v' + UNION SELECT '"foobar"' + UNION SELECT 'true' + UNION SELECT '5' + UNION SELECT '1.14' + UNION SELECT '[]' + UNION SELECT '{}' + UNION SELECT POW(2,63) +) +SELECT v, JSON_TYPE(v) FROM demo ORDER BY 2; +``` + +``` ++----------------------+--------------+ +| v | JSON_TYPE(v) | ++----------------------+--------------+ +| [] | ARRAY | +| true | BOOLEAN | +| 1.14 | DOUBLE | +| 9.223372036854776e18 | DOUBLE | +| 5 | INTEGER | +| null | NULL | +| {} | OBJECT | +| "foobar" | STRING | ++----------------------+--------------+ +8 rows in set (0.00 sec) +``` + +Note that values that look the same might not have the same type, as demonstrated in the following example. + +```sql +SELECT '"2025-06-14"',CAST(CAST('2025-06-14' AS date) AS json); +``` + +``` ++--------------+------------------------------------------+ +| "2025-06-14" | CAST(CAST('2025-06-14' AS date) AS json) | ++--------------+------------------------------------------+ +| "2025-06-14" | "2025-06-14" | ++--------------+------------------------------------------+ +1 row in set (0.00 sec) +``` + +```sql +SELECT JSON_TYPE('"2025-06-14"'),JSON_TYPE(CAST(CAST('2025-06-14' AS date) AS json)); +``` + +``` ++---------------------------+-----------------------------------------------------+ +| JSON_TYPE('"2025-06-14"') | JSON_TYPE(CAST(CAST('2025-06-14' AS date) AS json)) | ++---------------------------+-----------------------------------------------------+ +| STRING | DATE | ++---------------------------+-----------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_VALID()](https://dev.mysql.com/doc/refman/8.0/en/json-attribute-functions.html#function_json-valid) + +The `JSON_VALID(str)` function checks if the argument is valid JSON. This can be useful for checking a column before converting it to the `JSON` type. + +```sql +SELECT JSON_VALID('{"foo"="bar"}'); +``` + +``` ++-----------------------------+ +| JSON_VALID('{"foo"="bar"}') | ++-----------------------------+ +| 0 | ++-----------------------------+ +1 row in set (0.01 sec) +``` + +```sql +SELECT JSON_VALID('{"foo": "bar"}'); +``` + +``` ++------------------------------+ +| JSON_VALID('{"foo": "bar"}') | ++------------------------------+ +| 1 | ++------------------------------+ +1 row in set (0.01 sec) +``` + +## See also + +- [JSON Functions Overview](/functions-and-operators/json-functions.md) +- [JSON Data Type](/data-type-json.md) diff --git a/functions-and-operators/json-functions/json-functions-search.md b/functions-and-operators/json-functions/json-functions-search.md new file mode 100644 index 0000000000000..89e0d13877dfe --- /dev/null +++ b/functions-and-operators/json-functions/json-functions-search.md @@ -0,0 +1,360 @@ +--- +title: JSON Functions That Search JSON Values +summary: Learn about JSON functions that search JSON values. +--- + +# JSON Functions That Search JSON Values + +This document describes JSON functions that search JSON values. + +## [JSON_CONTAINS()](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-contains) + +By returning `1` or `0`, the `JSON_CONTAINS(json_doc, candidate [,path])` function indicates whether a given `candidate` JSON document is contained within a target JSON document. + +Examples: + +Here `a` is contained in the target document. + +```sql +SELECT JSON_CONTAINS('["a","b","c"]','"a"'); +``` + +``` ++--------------------------------------+ +| JSON_CONTAINS('["a","b","c"]','"a"') | ++--------------------------------------+ +| 1 | ++--------------------------------------+ +1 row in set (0.00 sec) +``` + +Here `e` is not contained in the target document. + +```sql +SELECT JSON_CONTAINS('["a","b","c"]','"e"'); +``` + +``` ++--------------------------------------+ +| JSON_CONTAINS('["a","b","c"]','"e"') | ++--------------------------------------+ +| 0 | ++--------------------------------------+ +1 row in set (0.00 sec) +``` + +Here `{"foo": "bar"}` is contained in the target document. + +```sql +SELECT JSON_CONTAINS('{"foo": "bar", "aaa": 5}','{"foo": "bar"}'); +``` + +``` ++------------------------------------------------------------+ +| JSON_CONTAINS('{"foo": "bar", "aaa": 5}','{"foo": "bar"}') | ++------------------------------------------------------------+ +| 1 | ++------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +Here `"bar"` is not contained in the root of the target document. + +```sql +SELECT JSON_CONTAINS('{"foo": "bar", "aaa": 5}','"bar"'); +``` + +``` ++---------------------------------------------------+ +| JSON_CONTAINS('{"foo": "bar", "aaa": 5}','"bar"') | ++---------------------------------------------------+ +| 0 | ++---------------------------------------------------+ +1 row in set (0.00 sec) +``` + +Here `"bar"` is contained in the `$.foo` attribute of the target document. + +```sql +SELECT JSON_CONTAINS('{"foo": "bar", "aaa": 5}','"bar"', '$.foo'); +``` + +``` ++------------------------------------------------------------+ +| JSON_CONTAINS('{"foo": "bar", "aaa": 5}','"bar"', '$.foo') | ++------------------------------------------------------------+ +| 1 | ++------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_CONTAINS_PATH()](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-contains-path) + +The `JSON_CONTAINS_PATH(json_doc, all_or_one, path [,path, ...])` function returns `0` or `1` to indicate whether a JSON document contains data at a given path or paths. + +Examples: + +Here the document contains `$.foo`. + +```sql +SELECT JSON_CONTAINS_PATH('{"foo": "bar", "aaa": 5}','all','$.foo'); +``` + +``` ++--------------------------------------------------------------+ +| JSON_CONTAINS_PATH('{"foo": "bar", "aaa": 5}','all','$.foo') | ++--------------------------------------------------------------+ +| 1 | ++--------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +Here the document does not contain `$.bar`. + +```sql +SELECT JSON_CONTAINS_PATH('{"foo": "bar", "aaa": 5}','all','$.bar'); +``` + +``` ++--------------------------------------------------------------+ +| JSON_CONTAINS_PATH('{"foo": "bar", "aaa": 5}','all','$.bar') | ++--------------------------------------------------------------+ +| 0 | ++--------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +Here the document contains both `$.foo` and `$.aaa`. + +```sql +SELECT JSON_CONTAINS_PATH('{"foo": "bar", "aaa": 5}','all','$.foo', '$.aaa'); +``` + +``` ++-----------------------------------------------------------------------+ +| JSON_CONTAINS_PATH('{"foo": "bar", "aaa": 5}','all','$.foo', '$.aaa') | ++-----------------------------------------------------------------------+ +| 1 | ++-----------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_EXTRACT()](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-extract) + +The `JSON_EXTRACT(json_doc, path[, path] ...)` function extracts data from a JSON document, selected from the parts of the document matched by the `path` arguments. + +```sql +SELECT JSON_EXTRACT('{"foo": "bar", "aaa": 5}', '$.foo'); +``` + +``` ++---------------------------------------------------+ +| JSON_EXTRACT('{"foo": "bar", "aaa": 5}', '$.foo') | ++---------------------------------------------------+ +| "bar" | ++---------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## [->](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_json-column-path) + +The `column->path` function returns the data in `column` that matches the `path` argument. It is an alias for [`JSON_EXTRACT()`](#json_extract). + +```sql +SELECT + j->'$.foo', + JSON_EXTRACT(j, '$.foo') +FROM ( + SELECT + '{"foo": "bar", "aaa": 5}' AS j + ) AS tbl; +``` + +``` ++------------+--------------------------+ +| j->'$.foo' | JSON_EXTRACT(j, '$.foo') | ++------------+--------------------------+ +| "bar" | "bar" | ++------------+--------------------------+ +1 row in set (0.00 sec) +``` + +## [->>](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_json-inline-path) + +The `column->>path` function unquotes data in `column` that matches the `path` argument. It is an alias for `JSON_UNQUOTE(JSON_EXTRACT(doc, path_literal))`. + +```sql +SELECT + j->'$.foo', + JSON_EXTRACT(j, '$.foo') + j->>'$.foo', + JSON_UNQUOTE(JSON_EXTRACT(j, '$.foo')) +FROM ( + SELECT + '{"foo": "bar", "aaa": 5}' AS j + ) AS tbl; +``` + +``` ++------------+--------------------------+-------------+----------------------------------------+ +| j->'$.foo' | JSON_EXTRACT(j, '$.foo') | j->>'$.foo' | JSON_UNQUOTE(JSON_EXTRACT(j, '$.foo')) | ++------------+--------------------------+-------------+----------------------------------------+ +| "bar" | "bar" | bar | bar | ++------------+--------------------------+-------------+----------------------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_KEYS()](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-keys) + +The `JSON_KEYS(json_doc [,path])` function returns the top-level keys of a JSON object as a JSON array. If a `path` argument is given, it returns the top-level keys from the selected path. + +Examples: + +The following example returns the two top-level keys in the JSON document. + +```sql +SELECT JSON_KEYS('{"name": {"first": "John", "last": "Doe"}, "type": "Person"}'); +``` + +``` ++---------------------------------------------------------------------------+ +| JSON_KEYS('{"name": {"first": "John", "last": "Doe"}, "type": "Person"}') | ++---------------------------------------------------------------------------+ +| ["name", "type"] | ++---------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +The following example returns the top-level keys that are in the `$.name` path of the JSON document. + +```sql +SELECT JSON_KEYS('{"name": {"first": "John", "last": "Doe"}, "type": "Person"}', '$.name'); +``` + +``` ++-------------------------------------------------------------------------------------+ +| JSON_KEYS('{"name": {"first": "John", "last": "Doe"}, "type": "Person"}', '$.name') | ++-------------------------------------------------------------------------------------+ +| ["first", "last"] | ++-------------------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_SEARCH()](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-search) + +The `JSON_SEARCH(json_doc, one_or_all, str)` function searches a JSON document for one or all matches of a string. + +Examples: + +In the following example, you can search for the first result for `cc`, which is at the position of index 2 in the `a` array. + +```sql +SELECT JSON_SEARCH('{"a": ["aa", "bb", "cc"], "b": ["cc", "dd"]}','one','cc'); +``` + +``` ++------------------------------------------------------------------------+ +| JSON_SEARCH('{"a": ["aa", "bb", "cc"], "b": ["cc", "dd"]}','one','cc') | ++------------------------------------------------------------------------+ +| "$.a[2]" | ++------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +Now you do the same, but set `one_or_all` to `all` to get not just the first result, but all results. + +```sql +SELECT JSON_SEARCH('{"a": ["aa", "bb", "cc"], "b": ["cc", "dd"]}','all','cc'); +``` + +``` ++------------------------------------------------------------------------+ +| JSON_SEARCH('{"a": ["aa", "bb", "cc"], "b": ["cc", "dd"]}','all','cc') | ++------------------------------------------------------------------------+ +| ["$.a[2]", "$.b[0]"] | ++------------------------------------------------------------------------+ +1 row in set (0.01 sec) +``` + +## [MEMBER OF()](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of) + +The `str MEMBER OF (json_array)` function tests if the passed value `str` is an element of the `json_array`, it returns `1`. Otherwise, it returns `0`. It returns `NULL` if any of the arguments is `NULL`. + +``` +SELECT '🍍' MEMBER OF ('["🍍","🥥","🥭"]') AS 'Contains pineapple'; +``` + +``` ++--------------------+ +| Contains pineapple | ++--------------------+ +| 1 | ++--------------------+ +1 row in set (0.00 sec) + +``` + +## [JSON_OVERLAPS()](https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-overlaps) + +The `JSON_OVERLAPS(json_doc, json_doc)` function indicates whether two JSON documents have overlapping part. If yes, it returns `1`. If not, it returns `0`. It returns `NULL` if any of the arguments is `NULL`. + +Examples: + +The following example shows that there is no overlap because the array value does not have the same number of elements. + +```sql +SELECT JSON_OVERLAPS( + '{"languages": ["Go","Rust","C#"]}', + '{"languages": ["Go","Rust"]}' +) AS 'Overlaps'; +``` + +``` ++----------+ +| Overlaps | ++----------+ +| 0 | ++----------+ +1 row in set (0.00 sec) +``` + +The following example shows that both JSON documents overlap as they are identical. + +```sql +SELECT JSON_OVERLAPS( + '{"languages": ["Go","Rust","C#"]}', + '{"languages": ["Go","Rust","C#"]}' +) AS 'Overlaps'; +``` + +``` ++----------+ +| Overlaps | ++----------+ +| 1 | ++----------+ +1 row in set (0.00 sec) +``` + +The following example shows that there is an overlap, while the second document has an extra attribute. + +```sql +SELECT JSON_OVERLAPS( + '{"languages": ["Go","Rust","C#"]}', + '{"languages": ["Go","Rust","C#"], "arch": ["arm64"]}' +) AS 'Overlaps'; +``` + +``` ++----------+ +| Overlaps | ++----------+ +| 1 | ++----------+ +1 row in set (0.00 sec) +``` + +## See also + +- [JSON Functions Overview](/functions-and-operators/json-functions.md) +- [JSON Data Type](/data-type-json.md) \ No newline at end of file diff --git a/functions-and-operators/json-functions/json-functions-utility.md b/functions-and-operators/json-functions/json-functions-utility.md new file mode 100644 index 0000000000000..4f0c0c27eb04e --- /dev/null +++ b/functions-and-operators/json-functions/json-functions-utility.md @@ -0,0 +1,73 @@ +--- +title: JSON Utility Functions +summary: Learn about JSON utility functions. +--- + +# JSON Utility Functions + +This document describes JSON utility functions. + +## [JSON_PRETTY()](https://dev.mysql.com/doc/refman/8.0/en/json-utility-functions.html#function_json-pretty) + +The `JSON_PRETTY(json_doc)` function does pretty formatting of a JSON document. + +```sql +SELECT JSON_PRETTY('{"person":{"name":{"first":"John","last":"Doe"},"age":23}}')\G +``` + +``` +*************************** 1. row *************************** +JSON_PRETTY('{"person":{"name":{"first":"John","last":"Doe"},"age":23}}'): { + "person": { + "age": 23, + "name": { + "first": "John", + "last": "Doe" + } + } +} +1 row in set (0.00 sec) +``` + +## [JSON_STORAGE_FREE()](https://dev.mysql.com/doc/refman/8.0/en/json-utility-functions.html#function_json-storage-free) + +The `JSON_STORAGE_FREE(json_doc)` function returns how much storage space is freed in the binary representation of the JSON value after it is updated in place. + +> **Note:** +> +> Because TiDB has a different storage architecture from MySQL, this function always returns `0` for a valid JSON value, and it is implemented for [compatibility with MySQL 8.0](/mysql-compatibility.md). Note that TiDB does not do in-place updates. For more information, see [RocksDB space usage](/storage-engine/rocksdb-overview.md#rocksdb-space-usage). + +```sql +SELECT JSON_STORAGE_FREE('{}'); +``` + +``` ++-------------------------+ +| JSON_STORAGE_FREE('{}') | ++-------------------------+ +| 0 | ++-------------------------+ +1 row in set (0.00 sec) +``` + +## [JSON_STORAGE_SIZE()](https://dev.mysql.com/doc/refman/8.0/en/json-utility-functions.html#function_json-storage-size) + +The `JSON_STORAGE_SIZE(json_doc)` function returns an approximate size of bytes required to store the JSON value. Because the size does not account for TiKV using compression, the output of this function is not strictly compatible with MySQL. + +```sql +SELECT JSON_STORAGE_SIZE('{}'); +``` + +``` ++-------------------------+ +| JSON_STORAGE_SIZE('{}') | ++-------------------------+ +| 9 | ++-------------------------+ +1 row in set (0.00 sec) +``` + +## See also + +- [JSON Functions Overview](/functions-and-operators/json-functions.md) +- [JSON Data Type](/data-type-json.md) \ No newline at end of file diff --git a/functions-and-operators/json-functions/json-functions-validate.md b/functions-and-operators/json-functions/json-functions-validate.md new file mode 100644 index 0000000000000..a01a47c362c4d --- /dev/null +++ b/functions-and-operators/json-functions/json-functions-validate.md @@ -0,0 +1,386 @@ +--- +title: JSON Functions That Validate JSON Documents +summary: Learn about JSON functions that validate JSON documents. +--- + +# JSON Functions That Validate JSON Documents + +This document describes JSON functions that validate JSON documents. + +## [JSON_SCHEMA_VALID()](https://dev.mysql.com/doc/refman/8.0/en/json-validation-functions.html#function_json-schema-valid) + +The `JSON_SCHEMA_VALID(schema, json_doc)` function validate a JSON document against a schema to ensure data integrity and consistency. + +This can be used together with a [CHECK](/constraints.md#check) constraint to do automatic schema validation when a table is modified. + +This function follows the [JSON Schema specification](https://json-schema.org/specification). + +The supported validation keywords are as follows: + +| Validation keyword | Applied type | Description | +|---|---|---| +| `type` | Any | Tests the type (such as `array` and `string`) | +| `enum` | Any | Tests if a value is in the specified array of values | +| `const` | Any | Similar to `enum`, but for a single value | +| `allOf` | Any | Matches all of the specified schemas | +| `anyOf` | Any | Matches any of the specified schemas | +| `multipleOf` | `number`/`integer` | Tests if the value is a multiple of the specified value | +| `maximum` | `number`/`integer` | Tests if the value is below the maximum (inclusive) | +| `exclusiveMaximum` | `number`/`integer` | Tests if the value is below the maximum (exclusive) | +| `minimum` | `number`/`integer` | Tests if the value is above the minimum (inclusive) | +| `exclusiveMinimum` | `number`/`integer` | Tests if the value is above the minimum (exclusive) | +| `maxlength` | `string` | Tests if the length of the value is not exceeding the specified value | +| `minLength` | `string` | Tests if the length of the value is at least the specified value | +| `format` | `string` | Tests if a string matches a named format | +| `pattern` | `string` | Tests if a string matches a pattern | +| `items` | `array` | Schema to apply to the items of an array | +| `prefixItems` | `array` | Schema to apply to positional items of an array | +| `maxItems` | `array` | Tests if the number of items in the array is not exceeding the specified value | +| `minItems` | `array` | Tests if the number of items in the array is at least the specified value | +| `uniqueItems` | `array` | Tests if the items in the array are unique, `true`/`false`| +| `contains` | `array` | Sets schema for items contained in the array | +| `maxContains` | `array` | Used together with `contains` to test the maximum times an item can be present | +| `minContains` | `array` | Used together with `contains` to test the minimum times an item can be present | +| `properties` | `object` | Schema to apply to the properties of an object | +| `patternProperties` | `object` | Schema to apply to certain properties based on pattern matching of the property name | +| `additionalProperties` | `object` | Whether additional properties are allowed or not, `true`/`false` | +| `minProperties` | `object` | Tests the minimum number of properties that an object can have | +| `maxProperties` | `object` | Tests the maximum number of properties that an object can have | +| `required` | `object` | Tests if the specified property names exist in an object | + +Examples: + +For some of the examples, use this JSON document: + +```json +{ + "fruits": [ + "orange", + "apple", + "pear" + ], + "vegetables": [ + "carrot", + "pepper", + "kale"] +} +``` + +Use a [user defined variable](/user-defined-variables.md) to hold the JSON document. + +```sql +SET @j := '{"fruits": ["orange", "apple", "pear"], "vegetables": ["carrot", "pepper", "kale"]}'; +``` + +Start by testing the type: + +```sql +SELECT JSON_SCHEMA_VALID('{"type": "object"}',@j); +``` + +``` ++--------------------------------------------+ +| JSON_SCHEMA_VALID('{"type": "object"}',@j) | ++--------------------------------------------+ +| 1 | ++--------------------------------------------+ +1 row in set (0.00 sec) +``` + +```sql +SELECT JSON_SCHEMA_VALID('{"type": "array"}',@j); +``` + +``` ++-------------------------------------------+ +| JSON_SCHEMA_VALID('{"type": "array"}',@j) | ++-------------------------------------------+ +| 0 | ++-------------------------------------------+ +1 row in set (0.00 sec) +``` + +```sql +mysql> SELECT JSON_TYPE(@j); +``` + +``` ++---------------+ +| JSON_TYPE(@j) | ++---------------+ +| OBJECT | ++---------------+ +1 row in set (0.00 sec) +``` + +As you can see in the preceding output, the type of `@j` is `object`. This matches with the output of [`JSON_TYPE()`](/functions-and-operators/json-functions/json-functions-return.md#json_type). + +Now validate the presence of certain attributes. + +```sql +SELECT JSON_SCHEMA_VALID('{"required": ["fruits","vegetables"]}',@j); +``` + +``` ++---------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"required": ["fruits","vegetables"]}',@j) | ++---------------------------------------------------------------+ +| 1 | ++---------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +In the preceding output, you can see that see that validation of the presence of the `fruits` and `vegetables` attributes succeeds. + +```sql +SELECT JSON_SCHEMA_VALID('{"required": ["fruits","vegetables","grains"]}',@j); +``` + +``` ++------------------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"required": ["fruits","vegetables","grains"]}',@j) | ++------------------------------------------------------------------------+ +| 0 | ++------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +In the preceding output, you can see that see that validation of the presence of the `fruits`, `vegetables` and `grains` attributes fails because `grains` is not present. + +Now validate that `fruits` is an array. + +```sql +SELECT JSON_SCHEMA_VALID('{"properties": {"fruits": {"type": "array"}}}',@j); +``` + +``` ++-----------------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"properties": {"fruits": {"type": "array"}}}',@j) | ++-----------------------------------------------------------------------+ +| 1 | ++-----------------------------------------------------------------------+ +1 row in set (0.01 sec) +``` + +The preceding output confirms that `fruits` is an array. + +```sql +SELECT JSON_SCHEMA_VALID('{"properties": {"fruits": {"type": "string"}}}',@j); +``` + +``` ++------------------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"properties": {"fruits": {"type": "string"}}}',@j) | ++------------------------------------------------------------------------+ +| 0 | ++------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +The preceding output shows that `fruits` is **not** a string. + +Now verify the number of items in the array. + +```sql +SELECT JSON_SCHEMA_VALID('{"properties": {"fruits": {"type": "array", "minItems": 3}}}',@j); +``` + +``` ++--------------------------------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"properties": {"fruits": {"type": "array", "minItems": 3}}}',@j) | ++--------------------------------------------------------------------------------------+ +| 1 | ++--------------------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +The preceding output shows that `fruits` is an array with at least 3 items. + +```sql +SELECT JSON_SCHEMA_VALID('{"properties": {"fruits": {"type": "array", "minItems": 4}}}',@j); +``` + +``` ++--------------------------------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"properties": {"fruits": {"type": "array", "minItems": 4}}}',@j) | ++--------------------------------------------------------------------------------------+ +| 0 | ++--------------------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +The preceding output shows that `fruits` is **not** an array with at least 4 items. This is because it does not meet the minimum number of items. + +For integers values, you can check if they are in a certain range. + +```sql +SELECT JSON_SCHEMA_VALID('{"type": "integer", "minimum": 40, "maximum": 45}', '42'); ++------------------------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"type": "integer", "minimum": 40, "maximum": 45}', '42') | ++------------------------------------------------------------------------------+ +| 1 | ++------------------------------------------------------------------------------+ +1 row in set (0.01 sec) +``` + +```sql +SELECT JSON_SCHEMA_VALID('{"type": "integer", "minimum": 40, "maximum": 45}', '123'); +``` + +``` ++-------------------------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"type": "integer", "minimum": 40, "maximum": 45}', '123') | ++-------------------------------------------------------------------------------+ +| 0 | ++-------------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +For a string, you can validate whether it matches a certain pattern. + +```sql +SELECT JSON_SCHEMA_VALID('{"type": "string", "pattern": "^Ti"}', '"TiDB"'); +``` + +``` ++---------------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"type": "string", "pattern": "^Ti"}', '"TiDB"') | ++---------------------------------------------------------------------+ +| 1 | ++---------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +```sql +SELECT JSON_SCHEMA_VALID('{"type": "string", "pattern": "^Ti"}', '"PingCAP"'); +``` + +``` ++------------------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"type": "string", "pattern": "^Ti"}', '"PingCAP"') | ++------------------------------------------------------------------------+ +| 0 | ++------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +You can check whether a value matches a certain named format. The formats that can be validated include `ipv4`, `ipv6`, `time`, `date`, `duration`, `email`, `hostname`, `uuid`, and `uri`. + +```sql +SELECT JSON_SCHEMA_VALID('{"format": "ipv4"}', '"127.0.0.1"'); +``` + +``` ++--------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"format": "ipv4"}', '"127.0.0.1"') | ++--------------------------------------------------------+ +| 1 | ++--------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +```sql +SELECT JSON_SCHEMA_VALID('{"format": "ipv4"}', '"327.0.0.1"'); +``` + +``` ++--------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"format": "ipv4"}', '"327.0.0.1"') | ++--------------------------------------------------------+ +| 0 | ++--------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +You can also use `enum` to check if a string is in an array. + +```sql +SELECT JSON_SCHEMA_VALID('{"enum": ["TiDB", "MySQL"]}', '"TiDB"'); +``` + +``` ++------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"enum": ["TiDB", "MySQL"]}', '"TiDB"') | ++------------------------------------------------------------+ +| 1 | ++------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +```sql +SELECT JSON_SCHEMA_VALID('{"enum": ["TiDB", "MySQL"]}', '"MySQL"'); +``` + +``` ++-------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"enum": ["TiDB", "MySQL"]}', '"MySQL"') | ++-------------------------------------------------------------+ +| 1 | ++-------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +```sql +SELECT JSON_SCHEMA_VALID('{"enum": ["TiDB", "MySQL"]}', '"SQLite"'); +``` + +``` ++--------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"enum": ["TiDB", "MySQL"]}', '"SQLite"') | ++--------------------------------------------------------------+ +| 0 | ++--------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +With `anyOf`, you can combine certain requirements and validate whether any of the requirements is met. + +```sql +SELECT JSON_SCHEMA_VALID('{"anyOf": [{"type": "string"},{"type": "integer"}]}', '"TiDB"'); +``` + +``` ++------------------------------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"anyOf": [{"type": "string"},{"type": "integer"}]}', '"TiDB"') | ++------------------------------------------------------------------------------------+ +| 1 | ++------------------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +```sql +SELECT JSON_SCHEMA_VALID('{"anyOf": [{"type": "string"},{"type": "integer"}]}', '["TiDB", "MySQL"]'); +``` + +``` ++-----------------------------------------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"anyOf": [{"type": "string"},{"type": "integer"}]}', '["TiDB", "MySQL"]') | ++-----------------------------------------------------------------------------------------------+ +| 0 | ++-----------------------------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +```sql +SELECT JSON_SCHEMA_VALID('{"anyOf": [{"type": "string"},{"type": "integer"}]}', '5'); +``` + +``` ++-------------------------------------------------------------------------------+ +| JSON_SCHEMA_VALID('{"anyOf": [{"type": "string"},{"type": "integer"}]}', '5') | ++-------------------------------------------------------------------------------+ +| 1 | ++-------------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + +## MySQL compatibility + +- If the schema to be validated in `JSON_SCHEMA_VALID()` is invalid (such as `{"type": "sting"}`), MySQL might accept it, but TiDB returns an error. Note that there is a spelling mistake in `"sting"`, which should be `"string"`. +- MySQL uses an older draft version of the JSON Schema standard. + +## See also + +- [JSON Schema Reference](https://json-schema.org/understanding-json-schema/reference) +- [JSON Functions Overview](/functions-and-operators/json-functions.md) +- [JSON Data Type](/data-type-json.md) \ No newline at end of file