JSON type, it is not used or
produced by the following functions.
Trino supports three functions for querying JSON data:
json_exists, json_query, and json_value. Each of them
is based on the same mechanism of exploring and processing JSON input using
JSON path.
Trino also supports two functions for generating JSON data:
json-array, and json_object.
JSON path language
The JSON path language is a special language, used exclusively by certain SQL operators to specify the query to perform on the JSON input. Although JSON path expressions are embedded in SQL queries, their syntax significantly differs from SQL. The semantics of predicates, operators, etc. in JSON path expressions generally follow the semantics of SQL. The JSON path language is case-sensitive for keywords and identifiers.JSON path syntax and semantics
JSON path expressions are recursive structures. Although the name “path” suggests a linear sequence of operations going step by step deeper into the JSON structure, a JSON path expression is in fact a tree. It can access the input JSON item multiple times, in multiple ways, and combine the results. Moreover, the result of a JSON path expression is not a single item, but an ordered sequence of items. Each of the sub-expressions takes one or more input sequences, and returns a sequence as the result.In the lax mode, most path operations first unnest all JSON arrays in the
input sequence. Any divergence from this rule is mentioned in the following
listing. Path modes are explained in JSON path modes.
literals
- numeric literals They include exact and approximate numbers, and are interpreted as if they were SQL values.
- string literals They are enclosed in double quotes.
- boolean literals
- null literal It has the semantics of the JSON null, not of SQL null. See comparison rules.
variables
- context variable It refers to the currently processed input of the JSON function.
- named variable It refers to a named parameter by its name.
- current item variable It is used inside the filter expression to refer to the currently processed item from the input sequence.
- last subscript variable It refers to the last index of the innermost enclosing array. Array indexes in JSON path expressions are zero-based.
arithmetic binary expressions
The JSON path language supports five arithmetic binary operators:<path1> and <path2>, are evaluated to sequences of
items. For arithmetic binary operators, each input sequence must contain a
single numeric item. The arithmetic operation is performed according to SQL
semantics, and it returns a sequence containing a single element with the
result.
The operators follow the same precedence rules as in SQL arithmetic operations,
and parentheses can be used for grouping.
arithmetic unary expressions
<path> is evaluated to a sequence of items. Every item must be
a numeric value. The unary plus or minus is applied to every item in the
sequence, following SQL semantics, and the results form the returned sequence.
member accessor
The member accessor returns the value of the member with the specified key for each JSON object in the input sequence.<path> return a sequence of three JSON objects:
<path>.customer succeeds in the first and the third object,
but the second object lacks the required member. In strict mode, path
evaluation fails. In lax mode, the second object is silently skipped, and the
resulting sequence is 100, 300.
All items in the input sequence must be JSON objects.
Trino does not support JSON objects with duplicate keys.
wildcard member accessor
Returns values from all key-value pairs for each JSON object in the input sequence. All the partial results are concatenated into the returned sequence.<path> return a sequence of three JSON objects:
descendant member accessor
Returns the values associated with the specified key in all JSON objects on all levels of nesting in the input sequence.<path> be a sequence containing a JSON object:
array accessor
Returns the elements at the specified indexes for each JSON array in the input sequence. Indexes are zero-based.<subscripts> list contains one or more subscripts. Each subscript
specifies a single index or a range (ends inclusive):
- The variable
lastis set to the last index of the array. - All subscript indexes are computed in order of declaration. For a
singleton subscript
<path1>, the result must be a singleton numeric item. For a range subscript<path2> to <path3>, two numeric items are expected. - The specified array elements are added in order to the output sequence.
<path> return a sequence of three JSON arrays:
5 to 3.
Note that the subscripts may overlap, and they do not need to follow the
element order. The order in the returned sequence follows the subscripts:
wildcard array accessor
Returns all elements of each JSON array in the input sequence.<path> return a sequence of three JSON arrays:
filter
Retrieves the items from the input sequence which satisfy the predicate.- They operate on sequences of items.
- They have their own error handling (they never fail).
- They behave different depending on the lax or strict mode.
true, false, or unknown. Note that some
predicate expressions involve nested JSON path expression. When evaluating the
nested path, the variable @ refers to the currently examined item from the
input sequence.
The following predicate expressions are supported:
- Conjunction
- Disjunction
- Negation
existspredicate
true if the nested path evaluates to a non-empty sequence, and
false when the nested path evaluates to an empty sequence. If the path
evaluation throws an error, returns unknown.
starts withpredicate
<path> must evaluate to a sequence of textual items, and the
other operand must evaluate to a single textual item. If evaluating of either
operand throws an error, the result is unknown. All items from the sequence
are checked for starting with the right operand. The result is true if a
match is found, otherwise false. However, if any of the comparisons throws
an error, the result in the strict mode is unknown. The result in the lax
mode depends on whether the match or the error was found first.
is unknownpredicate
true if the nested predicate evaluates to unknown, and
false otherwise.
- Comparisons
unknown. Items from the left and
right sequence are then compared pairwise. Similarly to the starts with
predicate, the result is true if any of the comparisons returns true,
otherwise false. However, if any of the comparisons throws an error, for
example because the compared types are not compatible, the result in the strict
mode is unknown. The result in the lax mode depends on whether the true
comparison or the error was found first.
Comparison rules
Null values in the context of comparison behave different than SQL null:- null == null —>
true - null != null, null < null, … —>
false - null compared to a scalar value —>
false - null compared to a JSON array or a JSON object —>
false
true or false is returned if the
comparison is successfully performed. The semantics of the comparison is the
same as in SQL. In case of an error, e.g. comparing text and number,
unknown is returned.
Comparing a scalar value with a JSON array or a JSON object, and comparing JSON
arrays/objects is an error, so unknown is returned.
Examples of filter
Let<path> return a sequence of three JSON objects:
double()
Converts numeric or text values into double values.<path> return a sequence -1, 23e4, "5.6":
ceiling(), floor(), and abs()
Gets the ceiling, the floor or the absolute value for every numeric item in the sequence. The semantics of the operations is the same as in SQL. Let<path> return a sequence -1.5, -1, 1.3:
keyvalue()
Returns a collection of JSON objects including one object per every member of the original object for every JSON object in the sequence.- “name”, which is the original key,
- “value”, which is the original bound value,
- “id”, which is the unique number, specific to an input object.
<path> be a sequence of three JSON objects:
type()
Returns a textual value containing the type name for every item in the sequence."null"for JSON null,"number"for a numeric item,"string"for a textual item,"boolean"for a boolean item,"date"for an item of type date,"time without time zone"for an item of type time,"time with time zone"for an item of type time with time zone,"timestamp without time zone"for an item of type timestamp,"timestamp with time zone"for an item of type timestamp with time zone,"array"for JSON array,"object"for JSON object,
size()
Returns a numeric value containing the size for every JSON array in the sequence.1.
It is required that all items in the input sequence are JSON arrays.
Let <path> return a sequence of three JSON arrays:
Limitations
The SQL standard describes thedatetime() JSON path item method and the
like_regex() JSON path predicate. Trino does not support them.
JSON path modes
The JSON path expression can be evaluated in two modes: strict and lax. In the strict mode, it is required that the input JSON data strictly fits the schema required by the path expression. In the lax mode, the input JSON data can diverge from the expected schema. The following table shows the differences between the two modes.Examples of the lax mode behavior
Let<path> return a sequence of three items, a JSON array, a JSON object,
and a scalar numeric value:
size() method, the JSON object and the number are also
wrapped in singleton arrays:
floor()
method, the item "a" causes type mismatch.
json_exists
Thejson_exists function determines whether a JSON value satisfies a JSON
path specification.
json_path is evaluated using the json_input as the context variable
($), and the passed arguments as the named variables ($variable_name).
The returned value is true if the path returns a non-empty sequence, and
false if the path returns an empty sequence. If an error occurs, the
returned value depends on the ON ERROR clause. The default value returned
ON ERROR is FALSE. The ON ERROR clause is applied for the following
kinds of errors:
- Input conversion errors, such as malformed JSON
- JSON path evaluation errors, e.g. division by zero
json_input is a character string or a binary string. It should contain
a single JSON item. For a binary string, you can specify encoding.
json_path is a string literal, containing the path mode specification, and
the path expression, following the syntax rules described in
JSON path syntax and semantics.
PASSING clause you can pass arbitrary expressions to be used by the
path expression.
$.
PASSING clause:
Examples
Letcustomers be a table containing two columns: id:bigint,
description:varchar.
The following query checks which customers have children above the age of 10:
In the following query, the path mode is strict. We check the third child for
each customer. This should cause a structural error for the customers who do
not have three or more children. This error is handled according to the
ON ERROR clause.
json_query
Thejson_query function extracts a JSON value from a JSON value.
json_path is evaluated using the json_input as the
context variable ($), and the passed arguments as the named variables
($variable_name).
The returned value is a JSON item returned by the path. By default, it is
represented as a character string (varchar). In the RETURNING clause,
you can specify other character string type or varbinary. With
varbinary, you can also specify the desired encoding.
json_input is a character string or a binary string. It should contain
a single JSON item. For a binary string, you can specify encoding.
json_path is a string literal, containing the path mode specification, and
the path expression, following the syntax rules described in
JSON path syntax and semantics.
PASSING clause you can pass arbitrary expressions to be used by the
path expression.
$.
PASSING clause:
ARRAY WRAPPER clause lets you modify the output by wrapping the results
in a JSON array. WITHOUT ARRAY WRAPPER is the default option. WITH CONDITIONAL ARRAY WRAPPER wraps every result which is not a singleton JSON
array or JSON object. WITH UNCONDITIONAL ARRAY WRAPPER wraps every result.
The QUOTES clause lets you modify the result for a scalar string by
removing the double quotes being part of the JSON string representation.
Examples
Letcustomers be a table containing two columns: id:bigint,
description:varchar.
children array for each customer:
The following query gets the collection of children for each customer.
Note that the
json_query function can only output a single JSON item. If
you don’t use array wrapper, you get an error for every customer with multiple
children. The error is handled according to the ON ERROR clause.
The following query gets the last child for each customer, wrapped in a JSON
array:
The following query gets all children above the age of 12 for each customer,
wrapped in a JSON array. The second and the third customer don’t have children
of this age. Such case is handled according to the
ON EMPTY clause. The
default value returned ON EMPTY is NULL. In the following example,
EMPTY ARRAY ON EMPTY is specified.
The following query shows the result of the
QUOTES clause. Note that KEEP QUOTES is the default.
If an error occurs, the returned value depends on the
ON ERROR clause. The
default value returned ON ERROR is NULL. One example of error is
multiple items returned by the path. Other errors caught and handled according
to the ON ERROR clause are:
- Input conversion errors, such as malformed JSON
- JSON path evaluation errors, e.g. division by zero
- Output conversion errors
json_value
Thejson_value function extracts a scalar SQL value from a JSON value.
json_path is evaluated using the json_input as the context variable
($), and the passed arguments as the named variables ($variable_name).
The returned value is the SQL scalar returned by the path. By default, it is
converted to string (varchar). In the RETURNING clause, you can specify
other desired type: a character string type, numeric, boolean or datetime type.
json_input is a character string or a binary string. It should contain
a single JSON item. For a binary string, you can specify encoding.
json_path is a string literal, containing the path mode specification, and
the path expression, following the syntax rules described in
JSON path syntax and semantics.
PASSING clause you can pass arbitrary expressions to be used by the
path expression.
$.
PASSING clause:
ON EMPTY clause is applied. The
default value returned ON EMPTY is NULL. You can also specify the
default value:
ON ERROR clause. The
default value returned ON ERROR is NULL. One example of error is
multiple items returned by the path. Other errors caught and handled according
to the ON ERROR clause are:
- Input conversion errors, such as malformed JSON
- JSON path evaluation errors, e.g. division by zero
- Returned scalar not convertible to the desired type
Examples
Letcustomers be a table containing two columns: id:bigint,
description:varchar.
comment for each customer as char(12):
The following query gets the first child’s age for each customer as
tinyint:
The following query gets the third child’s age for each customer. In the strict
mode, this should cause a structural error for the customers who do not have
the third child. This error is handled according to the
ON ERROR clause.
After changing the mode to lax, the structural error is suppressed, and the
customers without a third child produce empty sequence. This case is handled
according to the
ON EMPTY clause.
json_array
Thejson_array function creates a JSON array containing given elements.
Argument types
The array elements can be arbitrary expressions. Each passed value is converted into a JSON item according to its type, and optionalFORMAT and
ENCODING specification.
You can pass SQL values of types boolean, numeric, and character string. They
are converted to corresponding JSON literals:
FORMAT
option is implicit:
Null handling
If a value passed for an array element isnull, it is treated according to
the specified null treatment option. If ABSENT ON NULL is specified, the
null element is omitted in the result. If NULL ON NULL is specified, JSON
null is added to the result. ABSENT ON NULL is the default
configuration:
Returned type
The SQL standard imposes that there is no dedicated data type to represent JSON data in SQL. Instead, JSON data is represented as character or binary strings. By default, thejson_array function returns varchar containing the textual
representation of the JSON array. With the RETURNING clause, you can
specify other character string type:
json_object
Thejson_object function creates a JSON object containing given key-value pairs.
Argument passing conventions
There are two conventions for passing keys and values:KEY keyword:
Argument types
The keys can be arbitrary expressions. They must be of character string type. Each key is converted into a JSON text item, and it becomes a key in the created JSON object. Keys must not be null. The values can be arbitrary expressions. Each passed value is converted into a JSON item according to its type, and optionalFORMAT and
ENCODING specification.
You can pass SQL values of types boolean, numeric, and character string. They
are converted to corresponding JSON literals:
FORMAT
option is implicit:
Null handling
The values passed for JSON object keys must not be null. It is allowed to passnull for JSON object values. A null value is treated according to the
specified null treatment option. If NULL ON NULL is specified, a JSON
object entry with null value is added to the result. If ABSENT ON NULL
is specified, the entry is omitted in the result. NULL ON NULL is the
default configuration.:
Key uniqueness
If a duplicate key is encountered, it is handled according to the specified key uniqueness constraint. IfWITH UNIQUE KEYS is specified, a duplicate key results in a query
failure:
FORMAT specification.
If WITHOUT UNIQUE KEYS is specified, duplicate keys are not supported due
to implementation limitation. WITHOUT UNIQUE KEYS is the default
configuration.
Returned type
The SQL standard imposes that there is no dedicated data type to represent JSON data in SQL. Instead, JSON data is represented as character or binary strings. By default, thejson_object function returns varchar containing the textual
representation of the JSON object. With the RETURNING clause, you can
specify other character string type:
Cast to JSON
The following types can be cast to JSON:BOOLEANTINYINTSMALLINTINTEGERBIGINTREALDOUBLEVARCHAR
ARRAY, MAP, and ROW types can be cast to JSON when
the following requirements are met:
ARRAYtypes can be cast when the element type of the array is one of the supported types.MAPtypes can be cast when the key type of the map isVARCHARand the value type of the map is a supported type,ROWtypes can be cast when every field type of the row is a supported type.
Cast operations with supported character string types treat the input as a string, not validated as JSON.
This means that a cast operation with a string-type input of invalid JSON
results in a succesful cast to invalid JSON.Instead, consider using the
json_parse function to create validated JSON from a string.JSON is not straightforward. Casting
from a standalone NULL will produce SQL NULL instead of
JSON 'null'. However, when casting from arrays or map containing
NULLs, the produced JSON will have nulls in it.
Cast from JSON
Casting toBOOLEAN, TINYINT, SMALLINT, INTEGER,
BIGINT, REAL, DOUBLE or VARCHAR is supported.
Casting to ARRAY and MAP is supported when the element type of
the array is one of the supported types, or when the key type of the map
is VARCHAR and value type of the map is one of the supported types.
Behaviors of the casts are shown with the examples below:
JSON to ROW, both JSON array and JSON object are supported.
Other JSON functions
In addition to the functions explained in more details in the preceding sections, the following functions are available:is_json_scalar
json is a scalar (i.e. a JSON number, a JSON string, true, false or null):
json_array_contains
value exists in json (a string containing a JSON array):
json_array_get
json_array.
The index is zero-based:
json_array_length
json (a string containing a JSON array):
json_extract
json_path on json
(a string containing JSON) and returns the result as a JSON string:
json_extract_scalar
json_path must be a
scalar (boolean, number or string).
json_format
json_parse.
json_format function and
CAST(json AS VARCHAR) have completely
different semantics.json_format function serializes the input JSON value to JSON text conforming to
RFC 7159. The JSON value can be a JSON object, a JSON array, a JSON string,
a JSON number, true, false or null.CAST(json AS VARCHAR) casts the JSON value to the corresponding SQL VARCHAR value.
For JSON string, JSON number, true, false or null, the cast
behavior is same as the corresponding SQL type. JSON object and JSON array
cannot be cast to VARCHAR.json_parse
json_parse and CAST(string AS JSON) have completely
different semantics.json_parse expects a JSON text conforming to RFC 7159, and returns
the JSON value deserialized from the JSON text.
The JSON value can be a JSON object, a JSON array, a JSON string, a JSON number,
true, false or null.CAST(string AS JSON) takes any VARCHAR value as input, and returns
a JSON string with its value set to input string.