JSON Type
The JSON data type provides the capability to store native JSON in a single column and apply JSON-specific functions to it.Create Table
Insert Data
Retrieve Data
To render a JSON value as a single-line string value:JSON Operators
JSON operators can be used to determine whether a givenvalue meets (or does
NOT meet) the criteria for being of a certain JSON type category.
Note that the following syntax differs between SQL and the native APIs (like
Python) and that the category is specified differently between the two.
category code (APIs) or category name (SQL) will check the
given value against the following JSON types:
| Category Code | Category Name | JSON Types |
|---|---|---|
0 | N/A | JSON array or object (API default) |
1 | VALUE | Any JSON type (SQL default) |
2 | ARRAY | JSON array |
3 | OBJECT | JSON object (map) |
4 | SCALAR | * BOOLEAN * LONG * DOUBLE * STRING |
Example
To pretty-print only JSON objects (maps) in a given JSON column:JSON Functions
Scalar Functions
These functions can be applied to individual json column values, as well as array & string columns. However, for some functions to work as expected, the array or string value may need to be cast to JSON first.JSON(expr)
JSON(expr)
expr to JSON data typeExamples:| Function Call | Result |
|---|---|
JSON(‘[1, 2, “C”]’) | [1,2,“C”] |
JSON(’{“A”: “B”, “C”: {“D”: 5, “F”: 7}}’) | {“A”:“B”,“C”:{“D”:5,“F”:7}} |
JSON(null) | null |
JSON_ARRAY (value[,...] <null_hand>)
JSON_ARRAY (value[,...] <null_hand>)
<null_hand> parameter can be added to the end of the list to specify
handling of null values, though, at present, this only exists for compatibility with
other databases’ syntax—the option will be ignored and all null values will be added
to the array as null. Accepted null handling options:NULL ON NULL
| Function Call | Result |
|---|---|
JSON_ARRAY(1, 2, ‘C’) | [1,2,“C”] |
JSON_ARRAY(JSON(’{“A”: “B”}’), JSON(’{“C”: 4}’)) | [{“A”:“B”},{“C”:4}] |
JSON_ARRAY(1, null, ‘C’ NULL ON NULL) | [1,null,“C”] |
JSON_ARRAY_APPEND(arr, value)
JSON_ARRAY_APPEND(arr, value)
value to the given array arr of type string, array, or JSONExamples:| Function Call | Result |
|---|---|
JSON_ARRAY_APPEND(‘[1, 2]’, ‘C’) | [1,2,“C”] |
JSON_ARRAY_APPEND(’{“A”: “B”}’, JSON(’{“C”: 4}’)) | [{“A”:“B”},{“C”:4}] |
JSON_ARRAY_CONTAINS (json, path, val)
JSON_ARRAY_CONTAINS (json, path, val)
json contains the primitive value val at the JSON
query path, pathExamples:| Function Call | Result |
|---|---|
JSON_ARRAY_CONTAINS(‘[1, 2]’, ’$’, 2) | true |
JSON_ARRAY_CONTAINS(‘[1, 2]’, ’$’, ‘C’) | false |
JSON_ARRAY_CONTAINS(’{“A”: [2, 3]}’, ’$.A’, 2) | true |
JSON_ARRAY_CONTAINS(’{“A”: {“B”: [3, 4]}}’, ’$[“A”][“B”]’, 4) | true |
JSON_CARDINALITY(json)
JSON_CARDINALITY(json)
JSON_LENGTHJSON_EXISTS(json, path)
JSON_EXISTS(json, path)
json contains the JSON query path, pathExamples:| Function Call | Result |
|---|---|
JSON_EXISTS(‘[1, 2]’, ’$‘) | true |
JSON_EXISTS(‘[1, 2]’, ’$.A’) | false |
JSON_EXISTS(’{“A”: [2, 3]}’, ’$.A’) | true |
JSON_EXISTS(’{“A”: {“B”: 3, “D”: 5}}’, ’$[“A”][“D”]‘) | true |
JSON_KEYS(json, path)
JSON_KEYS(json, path)
path in json; null, if the
path doesn’t exist or contains a non-object (non-map) valueExamples:| Function Call | Result |
|---|---|
JSON_KEYS(’{}’, ’$’) | [] |
JSON_KEYS(‘[1, 2]’, ’$.A’) | null |
JSON_KEYS(’{“A”: [2, 3]}’, ’$’) | [“A”] |
JSON_KEYS(’{“A”: {“B”: 3, “D”: 5}}’, ’$[“A”]’) | [“B”,“D”] |
JSON_KEYS(’{“A”: {“B”: 3, “D”: 5}}’, ’$[“A”][“D”]‘) | null |
JSON_KEYS(’{“A”: {“B”: 3, “D”: {}}}’, ’$[“A”][“D”]’) | [] |
JSON_LENGTH(json[, path])
JSON_LENGTH(json[, path])
json, or at the
level of the optional JSON pathExamples:| Function Call | Result |
|---|---|
JSON_LENGTH(’{}‘) | 0 |
JSON_LENGTH(’[]‘) | 0 |
JSON_LENGTH(‘[1, 2]‘) | 2 |
JSON_LENGTH(’{“A”: [2, 3]}‘) | 1 |
JSON_LENGTH(’{“A”: {“B”: 3}, “D”: “E”}‘) | 2 |
JSON_LENGTH(’{“A”: [2, 3]}’, ’$.A’) | 2 |
JSON_LENGTH(’{“A”: {“B”: 3}, “D”: “E”}’, ’$.A’) | 1 |
JSON_MAKE_ARRAY(value)
JSON_MAKE_ARRAY(value)
valueExamples:| Function Call | Result |
|---|---|
JSON_MAKE_ARRAY(1) | [1] |
JSON_MAKE_ARRAY(JSON_ARRAY(1,2,3)) | [[1,2,3]] |
JSON_MAKE_ARRAY(JSON(’{“A”: “B”}’)) | [{“A”:“B”}] |
JSON_OBJECT (value[,...] <null_hand>)
JSON_OBJECT (value[,...] <null_hand>)
value setAn optional <null_hand> parameter can be added to the end of the list to specify
handling of null values, though, at present, this only exists for compatibility with
other databases’ syntax—the option will be ignored and all null values will be added
to the array as null. Accepted null handling options:NULL ON NULL
| Function Call | Result |
|---|---|
JSON_OBJECT() | {} |
JSON_OBJECT(‘A’: 2) | {“A”:2} |
JSON_OBJECT(‘A’ VALUE 2) | {“A”:2} |
JSON_OBJECT(KEY ‘A’ VALUE 2) | {“A”:2} |
JSON_OBJECT(‘A’: ‘B’, ‘C’: null NULL ON NULL) | {“A”:“B”,“C”:null} |
JSON_PRETTY(json)
JSON_PRETTY(json)
json objectExamples:| Function Call | JSON_PRETTY(‘[1,2,“C”]‘) |
| Return | |
| Function Call | JSON_PRETTY(’{“A”: “B”, “C”: {“D”: 5, “F”: 7}}‘) |
| Return | |
JSON_QUERY (json, path [<return>])
JSON_QUERY (json, path [<return>])
path in json; null, if the path doesn’t exist
or contains a primitive (non-object) valueAn optional return clause can be added to the end of the path to specify the return type
of the object found, as well as the error handling for the object lookup. The format of the
clause is:| Parameter | Description |
|---|---|
<wrapper> | Whether the returned object(s) should be wrapped in an array before being returned Valid wrapping schemes include:
|
<empty hand> | The scheme to use for handling empty returned objects Valid schemes include:
|
<error hand> | The scheme to use for handling errors in looking up the object Valid schemes include:
|
| Function Call | Result |
|---|---|
JSON_QUERY(‘[1, 2]’, ’$’) | [1,2] |
JSON_QUERY(‘[1, 2]’, ’$.A’) | null |
JSON_QUERY(’{“A”: [2, 3]}’, ’$.A’) | [2,3] |
JSON_QUERY(’{“A”: {“B”: 3, “D”: 5}}’, ’$[“A”]’) | {“B”:3,“D”:5} |
JSON_QUERY(’{“A”: {“B”: 3, “D”: 5}}’, ’$[“A”][“D”]‘) | null |
JSON_QUERY(’{“A”: {“B”: 3, “D”: [5, 6]}}’, ’$[“A”][“D”]’) | [5,6] |
JSON_QUERY(’{“A”: []}’, ’$.B’ EMPTY ARRAY ON EMPTY) | [] |
JSON_QUERY(’{“A”: 0}’, ’$.A’ EMPTY OBJECT ON ERROR) | {} |
JSON_QUERY(’{“A”: 2, “C”: 4}’, ’$.*‘) | null |
JSON_QUERY(’{“A”: 2, “C”: 4}’, ’$.*’ WITH WRAPPER) | [2,4] |
JSON_REPLACE(json, path, repl)
JSON_REPLACE(json, path, repl)
json with the value at the JSON path path replaced with the
replacement value replExamples:| Function Call | Result |
|---|---|
JSON_REPLACE(‘[1, 2]’, ’$’, ‘[3, 4]’) | [3,4] |
JSON_REPLACE(‘[1, 2]’, ’$.A’, ‘“B”’) | [1,2] |
JSON_REPLACE(’{“A”: [2, 3]}’, ’$.A’, ’{“D”: 5}’) | {“A”:{“D”:5}} |
JSON_REPLACE(’{“A”: {“B”: 3}}’, ’$[“A”]’, ‘“D”’) | {“A”:“D”} |
JSON_REPLACE(’{“A”: {“B”: [3, 4]}}’, ’$[“A”][“B”]’, 5) | {“A”:{“B”:5}} |
JSON_TYPE(expr)
JSON_TYPE(expr)
expr| Expression Type | JSON Type |
|---|---|
BOOLEAN | BOOLEAN |
| LONG |
| DOUBLE |
|
|
ARRAY (any) | ARRAY |
JSON_VALUE (json, path [return])
JSON_VALUE (json, path [return])
path in json; null, if the path doesn’t exist
or contains an object (non-primitive) valueAn optional return clause can be added to the end of the path to specify the return type
of the value found, as well as the error handling for the value lookup. The format of the
clause is:| Parameter | Description |
|---|---|
<type> | The JSON type of the value to return; if the value is not already of that type, it will be cast to that type, if possible Valid types include:
|
<empty hand> | The scheme to use for handling empty returned values Valid schemes include:
|
<error hand> | The scheme to use for handling errors in looking up the value Valid schemes include:
|
| Function Call | Result |
|---|---|
JSON_VALUE(‘1’, ’$‘) | 1 |
JSON_VALUE(‘[1, 2]’, ’$.A’) | null |
JSON_VALUE(’[“A”, “B”]’, ‘$.1’) | B |
JSON_VALUE(’{“A”: [2, 3]}’, ’$[“A”][“1”]‘) | 3 |
JSON_VALUE(’{“A”: {“B”: 3, “D”: 5}}’, ’$[“A”][“D”]‘) | 5 |
JSON_VALUE(’{“A”: {“B”: 3, “D”: [5, 6]}}’, ’$.A.D.1’) | 6 |
JSON_VALUE(‘1’, ’$’ RETURNING DOUBLE) | 1.0 |
JSON_VALUE(’{“A”: []}’, ’$.B’ DEFAULT ‘<null>’ ON EMPTY) | <null> |
JSON_VALUE(’{“A”: []}’, ’$.A’ ERROR ON ERROR) | error returned |
Aggregation Functions
JSON_ARRAYAGG(expr)
JSON_ARRAYAGG(expr)
JSON_ARRAYAGG_DISTINCT(expr)
JSON_ARRAYAGG_DISTINCT(expr)
JSON_COLLECT_SET(expr)
JSON_COLLECT_SET(expr)
JSON_ARRAYAGG_DISTINCT.Examples
JSON_ARRAYAGG
JSON_ARRAYAGG_DISTINCT
UNNEST_JSON_ARRAY
TheUNNEST_JSON_ARRAY function transposes array values into columnar data.
The two forms of the UNNEST_JSON_ARRAY function follow, one for cases where
only one column needs to be unnested and one for cases where more than one
column needs to be unnested. See
examples.
<column alias>
<column alias>
* to select the column<table name>
<table name>
<column name>
<column name>
WITH ORDINALITY
WITH ORDINALITY
ordinality<column alias list>
<column alias list>
<table/columns aliases><ordinality alias>
<ordinality alias>
<table/columns aliases>,
if WITH ORDINALITY is specified<table name>
<table name>
<table alias>
<table alias>
<column list>
<column list>
<table/columns aliases>
<table/columns aliases>
uai & uav,
respectively, and the corresponding ordinality index as index, all within the
virtual table unn use:WITH ORDINALITY
WITH ORDINALITY
<table/columns aliases>Examples
The following examples use this data set as a baseline:av JSON column in the
example.js_unn_arr table into a column of values aliased as uav:
ai JSON column in the
example.js_unn_arr table into a column of values aliased as uai and the
corresponding index in the original json for each as a column of indices named
ordinality:
ai & av JSON columns in the
example.js_unn_arr table into two columns of values aliased as uai &
uav in a virtual table with alias t, respectively:
ai & av JSON columns in the
example.js_unn_arr table into two columns of values aliased as uai &
uav in a virtual table with alias t, respectively, and adding the
corresponding index in the original array for each as a column of indices
aliased as index:
ai JSON column in the
example.js_unn_arr table into a column of values aliased as uai,
removing any duplicates across all arrays:
UNNEST_JSON_OBJECT
TheUNNEST_JSON_OBJECT function transposes JSON objects (maps) into columnar
data. Each source object is split out into two columns: a string column
containing the top-level object keys, and a JSON column containing the value
objects for those keys.
The two forms of the UNNEST_JSON_OBJECT function follow, one for cases where
only one column needs to be unnested and one for cases where more than one
column needs to be unnested. See
examples.
<column alias list>
<column alias list>
<table/columns aliases>; if no aliases are specified, use * to select the
columns<table name>
<table name>
<column name>
<column name>
<table/columns aliases>
<table/columns aliases>
j_k & j_v, respectively, with the corresponding ordinality index as
index, all within the virtual table unn, use:KEY_0 &
VALUE_0, respectively.WITH ORDINALITY
WITH ORDINALITY
ordinality unless overridden in
<table/columns aliases><column alias list>
<column alias list>
<table/columns aliases><ordinality alias>
<ordinality alias>
<table/columns aliases>,
if WITH ORDINALITY is specified<table name>
<table name>
<table alias>
<table alias>
<column list>
<column list>
<table/columns aliases>
<table/columns aliases>
j1_k & j1_v and j2_k & j2_v, respectively, with the
corresponding ordinality index as index, all within the virtual table unn,
use:WITH ORDINALITY
WITH ORDINALITY
<table/columns aliases>Examples
The following examples use this data set as a baseline:j1 JSON column in the example.js_unn_obj
table into key/value pair columns of values aliased as j1_k & j1_v,
respectively:
j2 JSON column in the example.js_unn_obj
table into key/value pair columns of values aliased as j2_k & j2_v, and
the corresponding index in the original map for each as a column of indices
aliased as index:
j1 & j2 JSON columns in the
example.js_unn_obj table into two sets of key/value pair columns of values
aliased as j1_k & j1_v and j2_k & j2_v, respectively, in a
virtual table with alias t:
j1 & j2 JSON columns in the
example.js_unn_obj table into two sets of key/value pair columns of values
aliased as j1_k & j1_v and j2_k & j2_v, respectively, in a
virtual table with alias t, and adding the corresponding index in the
original map for each as a column of indices aliased as index: