summaryrefslogtreecommitdiff
path: root/doc/src
diff options
context:
space:
mode:
authorAndrew Dunstan <andrew@dunslane.net>2022-09-01 17:07:14 -0400
committerAndrew Dunstan <andrew@dunslane.net>2022-09-01 17:07:14 -0400
commit2f2b18bd3f554e96a8cc885b177211be12288e4a (patch)
tree344a5d33738de735f68b98361a54eb5944726f8f /doc/src
parent90247e742f849794d061a0444071647728054b45 (diff)
downloadpostgresql-2f2b18bd3f554e96a8cc885b177211be12288e4a.tar.gz
Revert SQL/JSON features
The reverts the following and makes some associated cleanups: commit f79b803dc: Common SQL/JSON clauses commit f4fb45d15: SQL/JSON constructors commit 5f0adec25: Make STRING an unreserved_keyword. commit 33a377608: IS JSON predicate commit 1a36bc9db: SQL/JSON query functions commit 606948b05: SQL JSON functions commit 49082c2cc: RETURNING clause for JSON() and JSON_SCALAR() commit 4e34747c8: JSON_TABLE commit fadb48b00: PLAN clauses for JSON_TABLE commit 2ef6f11b0: Reduce running time of jsonb_sqljson test commit 14d3f24fa: Further improve jsonb_sqljson parallel test commit a6baa4bad: Documentation for SQL/JSON features commit b46bcf7a4: Improve readability of SQL/JSON documentation. commit 112fdb352: Fix finalization for json_objectagg and friends commit fcdb35c32: Fix transformJsonBehavior commit 4cd8717af: Improve a couple of sql/json error messages commit f7a605f63: Small cleanups in SQL/JSON code commit 9c3d25e17: Fix JSON_OBJECTAGG uniquefying bug commit a79153b7a: Claim SQL standard compliance for SQL/JSON features commit a1e7616d6: Rework SQL/JSON documentation commit 8d9f9634e: Fix errors in copyfuncs/equalfuncs support for JSON node types. commit 3c633f32b: Only allow returning string types or bytea from json_serialize commit 67b26703b: expression eval: Fix EEOP_JSON_CONSTRUCTOR and EEOP_JSONEXPR size. The release notes are also adjusted. Backpatch to release 15. Discussion: https://postgr.es/m/40d2c882-bcac-19a9-754d-4299e1d87ac7@postgresql.org
Diffstat (limited to 'doc/src')
-rw-r--r--doc/src/sgml/func.sgml1065
-rw-r--r--doc/src/sgml/keywords/sql2016-02-reserved.txt1
2 files changed, 6 insertions, 1060 deletions
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index f87afefeae..ee515cec8f 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -16294,7 +16294,7 @@ table2-mapping
</para>
<para>
<literal>jsonb_set_lax('[{"f1":1,"f2":null},2,null,3]', '{0,f1}', null)</literal>
- <returnvalue>[{"f1": null, "f2": null}, 2, null, 3]</returnvalue>
+ <returnvalue>[{"f1":null,"f2":null},2,null,3]</returnvalue>
</para>
<para>
<literal>jsonb_set_lax('[{"f1":99,"f2":null},2]', '{0,f3}', null, true, 'return_target')</literal>
@@ -16533,7 +16533,7 @@ table2-mapping
comparisons.
</para>
<para>
- <literal>jsonb_path_exists_tz('["2015-08-01 12:00:00-05"]', '$[*] ? (@.datetime() &lt; "2015-08-02".datetime())')</literal>
+ <literal>jsonb_path_exists_tz('["2015-08-01 12:00:00 -05"]', '$[*] ? (@.datetime() &lt; "2015-08-02".datetime())')</literal>
<returnvalue>t</returnvalue>
</para></entry>
</row>
@@ -17571,937 +17571,7 @@ $.* ? (@ like_regex "^\\d+$")
</programlisting>
</para>
</sect3>
- </sect2>
-
- <sect2 id="functions-sqljson">
- <title>SQL/JSON Functions and Expressions</title>
- <indexterm zone="functions-json">
- <primary>SQL/JSON</primary>
- <secondary>functions and expressions</secondary>
- </indexterm>
-
- <para>
- To provide native support for JSON data types within the SQL environment,
- <productname>PostgreSQL</productname> implements the
- <firstterm>SQL/JSON data model</firstterm>.
- This model comprises sequences of items. Each item can hold SQL scalar
- values, with an additional SQL/JSON null value, and composite data structures
- that use JSON arrays and objects. The model is a formalization of the implied
- data model in the JSON specification
- <ulink url="https://tools.ietf.org/html/rfc7159">RFC 7159</ulink>.
- </para>
-
- <para>
- SQL/JSON allows you to handle JSON data alongside regular SQL data,
- with transaction support, including:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- Uploading JSON data into the database and storing it in
- regular SQL columns as character or binary strings.
- </para>
- </listitem>
- <listitem>
- <para>
- Generating JSON objects and arrays from relational data.
- </para>
- </listitem>
- <listitem>
- <para>
- Querying JSON data using SQL/JSON query functions and
- SQL/JSON path language expressions.
- </para>
- </listitem>
- </itemizedlist>
-
- <para>
- There are two groups of SQL/JSON functions.
- <link linkend="functions-sqljson-producing">Constructor functions</link>
- generate JSON data from values of SQL types.
- <link linkend="functions-sqljson-querying">Query functions</link>
- evaluate SQL/JSON path language expressions against JSON values
- and produce values of SQL/JSON types, which are converted to SQL types.
- </para>
-
- <para>
- Many SQL/JSON functions have an optional <literal>FORMAT</literal>
- clause. This is provided to conform with the SQL standard, but has no
- effect except where noted otherwise.
- </para>
-
- <para>
- <xref linkend="functions-sqljson-producing" /> lists the SQL/JSON
- Constructor functions. Each function has a <literal>RETURNING</literal>
- clause specifying the data type returned. For the <function>json</function> and
- <function>json_scalar</function> functions, this needs to be either <type>json</type> or
- <type>jsonb</type>. For the other constructor functions it must be one of <type>json</type>,
- <type>jsonb</type>, <type>bytea</type>, a character string type (<type>text</type>, <type>char</type>,
- <type>varchar</type>, or <type>nchar</type>), or a type for which there is a cast
- from <type>json</type> to that type.
- By default, the <type>json</type> type is returned.
- </para>
-
- <note>
- <para>
- Many of the results that can be obtained from the SQL/JSON Constructor
- functions can also be obtained by calling
- <productname>PostgreSQL</productname>-specific functions detailed in
- <xref linkend="functions-json-creation-table" /> and
- <xref linkend="functions-aggregate-table"/>.
- </para>
- </note>
-
- <table id="functions-sqljson-producing">
- <title>SQL/JSON Constructor Functions</title>
- <tgroup cols="1">
- <thead>
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- Function signature
- </para>
- <para>
- Description
- </para>
- <para>
- Example(s)
- </para></entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- <indexterm><primary>json constructor</primary></indexterm>
- <function>json</function> (
- <parameter>expression</parameter>
- <optional> <literal>FORMAT JSON</literal> <optional> <literal>ENCODING UTF8</literal> </optional></optional>
- <optional> { <literal>WITH</literal> | <literal>WITHOUT</literal> } <literal>UNIQUE</literal> <optional> <literal>KEYS</literal> </optional></optional>
- <optional> <literal>RETURNING</literal> <replaceable>json_data_type</replaceable> </optional>)
- </para>
- <para>
- The <parameter>expression</parameter> can be any text type or a
- <type>bytea</type> in UTF8 encoding. If the
- <parameter>expression</parameter> is NULL, an
- <acronym>SQL</acronym> null value is returned.
- If <literal>WITH UNIQUE</literal> is specified, the
- <parameter>expression</parameter> must not contain any duplicate
- object keys.
- </para>
- <para>
- <literal>json('{"a":123, "b":[true,"foo"], "a":"bar"}')</literal>
- <returnvalue>{"a":123, "b":[true,"foo"], "a":"bar"}</returnvalue>
- </para>
- <para>
- <literal>json('{"a":123,"b":[true,"foo"],"a":"bar"}' returning jsonb)</literal>
- <returnvalue>{"a": "bar", "b": [true, "foo"]}</returnvalue>
- </para></entry>
- </row>
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- <indexterm><primary>json_scalar</primary></indexterm>
- <function>json_scalar</function> (<parameter>expression</parameter>
- <optional> <literal>RETURNING</literal> <replaceable>json_data_type</replaceable> </optional>)
- </para>
- <para>
- Returns a JSON scalar value representing
- <parameter>expression</parameter>.
- If the input is NULL, an SQL NULL is returned. If the input is a number
- or a boolean value, a corresponding JSON number or boolean value is
- returned. For any other value a JSON string is returned.
- </para>
- <para>
- <literal>json_scalar(123.45)</literal>
- <returnvalue>123.45</returnvalue>
- </para>
- <para>
- <literal>json_scalar(CURRENT_TIMESTAMP)</literal>
- <returnvalue>"2022-05-10T10:51:04.62128-04:00"</returnvalue>
- </para></entry>
- </row>
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- <indexterm><primary>json_object</primary></indexterm>
- <function>json_object</function> (
- <optional> { <parameter>key_expression</parameter> { <literal>VALUE</literal> | ':' }
- <parameter>value_expression</parameter> <optional> <literal>FORMAT JSON</literal> <optional> <literal>ENCODING UTF8</literal> </optional> </optional> }<optional>, ...</optional> </optional>
- <optional> { <literal>NULL</literal> | <literal>ABSENT</literal> } <literal>ON NULL</literal> </optional>
- <optional> { <literal>WITH</literal> | <literal>WITHOUT</literal> } <literal>UNIQUE</literal> <optional> <literal>KEYS</literal> </optional> </optional>
- <optional> <literal>RETURNING</literal> <replaceable>data_type</replaceable> <optional> <literal>FORMAT JSON</literal> <optional> <literal>ENCODING UTF8</literal> </optional> </optional> </optional>)
- </para>
- <para>
- Constructs a JSON object of all the key value pairs given,
- or an empty object if none are given.
- <parameter>key_expression</parameter> is a scalar expression
- defining the <acronym>JSON</acronym> key, which is
- converted to the <type>text</type> type.
- It cannot be <literal>NULL</literal> nor can it
- belong to a type that has a cast to the <type>json</type>.
- If <literal>WITH UNIQUE</literal> is specified, there must not
- be any duplicate <parameter>key_expression</parameter>.
- If <literal>ABSENT ON NULL</literal> is specified, the entire
- pair is omitted if the <parameter>value_expression</parameter>
- is <literal>NULL</literal>.
- </para>
- <para>
- <literal>json_object('code' VALUE 'P123', 'title': 'Jaws')</literal>
- <returnvalue>{"code" : "P123", "title" : "Jaws"}</returnvalue>
- </para></entry>
- </row>
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- <indexterm><primary>json_objectagg</primary></indexterm>
- <function>json_objectagg</function> (
- <optional> { <parameter>key_expression</parameter> { <literal>VALUE</literal> | ':' } <parameter>value_expression</parameter> } </optional>
- <optional> { <literal>NULL</literal> | <literal>ABSENT</literal> } <literal>ON NULL</literal> </optional>
- <optional> { <literal>WITH</literal> | <literal>WITHOUT</literal> } <literal>UNIQUE</literal> <optional> <literal>KEYS</literal> </optional> </optional>
- <optional> <literal>RETURNING</literal> <replaceable>data_type</replaceable> <optional> <literal>FORMAT JSON</literal> <optional> <literal>ENCODING UTF8</literal> </optional> </optional> </optional>)
- </para>
- <para>
- Behaves like <function>json_object</function> above, but as an
- aggregate function, so it only takes one
- <parameter>key_expression</parameter> and one
- <parameter>value_expression</parameter> parameter.
- </para>
- <para>
- <literal>SELECT json_objectagg(k:v) FROM (VALUES ('a'::text,current_date),('b',current_date + 1)) AS t(k,v)</literal>
- <returnvalue>{ "a" : "2022-05-10", "b" : "2022-05-11" }</returnvalue>
- </para></entry>
- </row>
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- <indexterm><primary>json_array</primary></indexterm>
- <function>json_array</function> (
- <optional> { <parameter>value_expression</parameter> <optional> <literal>FORMAT JSON</literal> </optional> } <optional>, ...</optional> </optional>
- <optional> { <literal>NULL</literal> | <literal>ABSENT</literal> } <literal>ON NULL</literal> </optional>
- <optional> <literal>RETURNING</literal> <replaceable>data_type</replaceable> <optional> <literal>FORMAT JSON</literal> <optional> <literal>ENCODING UTF8</literal> </optional> </optional> </optional>)
- </para>
- <para role="func_signature">
- <function>json_array</function> (
- <optional> <replaceable>query_expression</replaceable> </optional>
- <optional> <literal>RETURNING</literal> <replaceable>data_type</replaceable> <optional> <literal>FORMAT JSON</literal> <optional> <literal>ENCODING UTF8</literal> </optional> </optional> </optional>)
- </para>
- <para>
- Constructs a JSON array from either a series of
- <parameter>value_expression</parameter> parameters or from the results
- of <replaceable>query_expression</replaceable>,
- which must be a SELECT query returning a single column. If
- <literal>ABSENT ON NULL</literal> is specified, NULL values are ignored.
- This is always the case if a
- <replaceable>query_expression</replaceable> is used.
- </para>
- <para>
- <literal>json_array(1,true,json '{"a":null}')</literal>
- <returnvalue>[1, true, {"a":null}]</returnvalue>
- </para>
- <para>
- <literal>json_array(SELECT * FROM (VALUES(1),(2)) t)</literal>
- <returnvalue>[1, 2]</returnvalue>
- </para></entry>
- </row>
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- <indexterm><primary>json_arrayagg</primary></indexterm>
- <function>json_arrayagg</function> (
- <optional> <parameter>value_expression</parameter> </optional>
- <optional> <literal>ORDER BY</literal> <replaceable>sort_expression</replaceable> </optional>
- <optional> { <literal>NULL</literal> | <literal>ABSENT</literal> } <literal>ON NULL</literal> </optional>
- <optional> <literal>RETURNING</literal> <replaceable>data_type</replaceable> <optional> <literal>FORMAT JSON</literal> <optional> <literal>ENCODING UTF8</literal> </optional> </optional> </optional>)
- </para>
- <para>
- Behaves in the same way as <function>json_array</function>
- but as an aggregate function so it only takes one
- <parameter>value_expression</parameter> parameter.
- If <literal>ABSENT ON NULL</literal> is specified, any NULL
- values are omitted.
- If <literal>ORDER BY</literal> is specified, the elements will
- appear in the array in that order rather than in the input order.
- </para>
- <para>
- <literal>SELECT json_arrayagg(v) FROM (VALUES(2),(1)) t(v)</literal>
- <returnvalue>[2, 1]</returnvalue>
- </para></entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>
- <xref linkend="functions-sqljson-misc" /> details SQL/JSON
- facilities for testing and serializing JSON.
- </para>
-
- <table id="functions-sqljson-misc">
- <title>SQL/JSON Testing and Serializing Functions</title>
- <tgroup cols="1">
- <thead>
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- Function signature
- </para>
- <para>
- Description
- </para>
- <para>
- Example(s)
- </para></entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- <indexterm><primary>IS JSON</primary></indexterm>
- <parameter>expression</parameter> <literal>IS</literal> <optional> <literal>NOT</literal> </optional> <literal>JSON</literal>
- <optional> { <literal>VALUE</literal> | <literal>SCALAR</literal> | <literal>ARRAY</literal> | <literal>OBJECT</literal> } </optional>
- <optional> { <literal>WITH</literal> | <literal>WITHOUT</literal> } <literal>UNIQUE</literal> <optional> <literal>KEYS</literal> </optional> </optional>
- </para>
- <para>
- This predicate tests whether <parameter>expression</parameter> can be
- parsed as JSON, possibly of a specified type.
- If <literal>SCALAR</literal> or <literal>ARRAY</literal> or
- <literal>OBJECT</literal> is specified, the
- test is whether or not the JSON is of that particular type. If
- <literal>WITH UNIQUE</literal> is specified, then an any object in the
- <parameter>expression</parameter> is also tested to see if it
- has duplicate keys.
- </para>
- <para>
-<screen>
-SELECT js,
- js IS JSON "json?",
- js IS JSON SCALAR "scalar?",
- js IS JSON OBJECT "object?",
- js IS JSON ARRAY "array?"
-FROM
-(VALUES ('123'), ('"abc"'), ('{"a": "b"}'),
-('[1,2]'),('abc')) foo(js);
- js | json? | scalar? | object? | array?
-------------+-------+---------+---------+--------
- 123 | t | t | f | f
- "abc" | t | t | f | f
- {"a": "b"} | t | f | t | f
- [1,2] | t | f | f | t
- abc | f | f | f | f
-</screen>
- </para></entry>
- </row>
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- <function>json_serialize</function> (
- <parameter>expression</parameter> <optional> <literal>FORMAT JSON</literal> <optional> <literal>ENCODING UTF8</literal> </optional> </optional>
- <optional> <literal>RETURNING</literal> <parameter>data_type</parameter> <optional> <literal>FORMAT JSON</literal> <optional> <literal>ENCODING UTF8</literal> </optional> </optional> </optional>)
- </para>
- <para>
- Transforms an SQL/JSON value into a character or binary string. The
- <parameter>expression</parameter> can be of any JSON type, any
- character string type, or <type>bytea</type> in UTF8 encoding.
- The returned type can be any character string type or
- <type>bytea</type>. The default is <type>text</type>.
- </para>
- <para>
- <literal>json_serialize('{ "a" : 1 } ' RETURNING bytea)</literal>
- <returnvalue>\x7b20226122203a2031207d20</returnvalue>
- </para></entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>
- <xref linkend="functions-sqljson-querying"/> details the SQL/JSON
- functions that can be used to query JSON data, except
- for <function>json_table</function>.
- </para>
-
- <note>
- <para>
- SQL/JSON paths can only be applied to the <type>jsonb</type> type, so it
- might be necessary to cast the <parameter>context_item</parameter>
- argument of these functions to <type>jsonb</type>.
- </para>
- </note>
-
- <table id="functions-sqljson-querying">
- <title>SQL/JSON Query Functions</title>
- <tgroup cols="1">
- <thead>
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- Function signature
- </para>
- <para>
- Description
- </para>
- <para>
- Example(s)
- </para></entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- <indexterm><primary>json_exists</primary></indexterm>
- <function>json_exists</function> (
- <parameter>context_item</parameter>, <parameter>path_expression</parameter> <optional> <literal>PASSING</literal> { <parameter>value</parameter> <literal>AS</literal> <replaceable>varname</replaceable> } <optional>, ...</optional></optional>
- <optional> <literal>RETURNING</literal> <replaceable>data_type</replaceable> </optional>
- <optional> { <literal>TRUE</literal> | <literal>FALSE</literal> |<literal> UNKNOWN</literal> | <literal>ERROR</literal> } <literal>ON ERROR</literal> </optional>)
- </para>
- <para>
- Returns true if the SQL/JSON <parameter>path_expression</parameter>
- applied to the <parameter>context_item</parameter> using the
- <parameter>value</parameter>s yields any items.
- The <literal>ON ERROR</literal> clause specifies what is returned if
- an error occurs. Note that if the <parameter>path_expression</parameter>
- is <literal>strict</literal>, an error is generated if it yields no items.
- The default value is <literal>UNKNOWN</literal> which causes a NULL
- result.
- </para>
- <para>
- <literal>json_exists(jsonb '{"key1": [1,2,3]}', 'strict $.key1[*] ? (@ > 2)')</literal>
- <returnvalue>t</returnvalue>
- </para>
- <para>
- <literal>json_exists(jsonb '{"a": [1,2,3]}', 'lax $.a[5]' ERROR ON ERROR)</literal>
- <returnvalue>f</returnvalue>
- </para>
- <para>
- <literal>json_exists(jsonb '{"a": [1,2,3]}', 'strict $.a[5]' ERROR ON ERROR)</literal>
- <returnvalue>ERROR: jsonpath array subscript is out of bounds</returnvalue>
- </para></entry>
- </row>
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- <indexterm><primary>json_value</primary></indexterm>
- <function>json_value</function> (
- <parameter>context_item</parameter>, <parameter>path_expression</parameter>
- <optional> <literal>PASSING</literal> { <parameter>value</parameter> <literal>AS</literal> <parameter>varname</parameter> } <optional>, ...</optional></optional>
- <optional> <literal>RETURNING</literal> <parameter>data_type</parameter> </optional>
- <optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>DEFAULT</literal> <parameter>expression</parameter> } <literal>ON EMPTY</literal> </optional>
- <optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>DEFAULT</literal> <parameter>expression</parameter> } <literal>ON ERROR</literal> </optional>)
- </para>
- <para>
- Returns the result of applying the
- <parameter>path_expression</parameter> to the
- <parameter>context_item</parameter> using the
- <parameter>value</parameter>s. The extracted value must be
- a single <acronym>SQL/JSON</acronym> scalar item. For results that
- are objects or arrays, use the <function>json_query</function>
- instead.
- The returned <parameter>data_type</parameter> has the same semantics
- as for constructor functions like <function>json_objectagg</function>.
- The default returned type is <type>text</type>.
- The <literal>ON EMPTY</literal> clause specifies the behavior if the
- <parameter>path_expression</parameter> yields no value at all.
- The <literal>ON ERROR</literal> clause specifies the behavior if an
- error occurs, as a result of either the evaluation or the application
- of the <literal>ON EMPTY</literal> clause.
- </para>
- <para>
- <literal>json_value(jsonb '"123.45"', '$' RETURNING float)</literal>
- <returnvalue>123.45</returnvalue>
- </para>
- <para>
- <literal>json_value(jsonb '"03:04 2015-02-01"', '$.datetime("HH24:MI&nbsp;YYYY-MM-DD")' RETURNING date)</literal>
- <returnvalue>2015-02-01</returnvalue>
- </para>
- <para>
- <literal>json_value(jsonb '[1,2]', 'strict $[*]' DEFAULT 9 ON ERROR)</literal>
- <returnvalue>9</returnvalue>
- </para></entry>
- </row>
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- <indexterm><primary>json_query</primary></indexterm>
- <function>json_query</function> (
- <parameter>context_item</parameter>, <parameter>path_expression</parameter> <optional> <literal>PASSING</literal> { <parameter>value</parameter> <literal>AS</literal> <parameter>varname</parameter> } <optional>, ...</optional></optional>
- <optional> <literal>RETURNING</literal> <parameter>data_type</parameter> <optional> <literal>FORMAT JSON</literal> <optional> <literal>ENCODING UTF8</literal> </optional> </optional> </optional>
- <optional> { <literal>WITHOUT</literal> | <literal>WITH</literal> { <literal>CONDITIONAL</literal> | <optional><literal>UNCONDITIONAL</literal></optional> } } <optional> <literal>ARRAY</literal> </optional> <literal>WRAPPER</literal> </optional>
- <optional> { <literal>KEEP</literal> | <literal>OMIT</literal> } <literal>QUOTES</literal> <optional> <literal>ON SCALAR STRING</literal> </optional> </optional>
- <optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>EMPTY</literal> { <optional> <literal>ARRAY</literal> </optional> | <literal>OBJECT</literal> } | <literal>DEFAULT</literal> <parameter>expression</parameter> } <literal>ON EMPTY</literal> </optional>
- <optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>EMPTY</literal> { <optional> <literal>ARRAY</literal> </optional> | <literal>OBJECT</literal> } | <literal>DEFAULT</literal> <parameter>expression</parameter> } <literal>ON ERROR</literal> </optional>)
- </para>
- <para>
- Returns the result of applying the
- <parameter>path_expression</parameter> to the
- <parameter>context_item</parameter> using the
- <parameter>value</parameter>s.
- This function must return a JSON string, so if the path expression
- returns multiple SQL/JSON items, you must wrap the result using the
- <literal>WITH WRAPPER</literal> clause. If the wrapper is
- <literal>UNCONDITIONAL</literal>, an array wrapper will always
- be applied, even if the returned value is already a single JSON object
- or array, but if it is <literal>CONDITIONAL</literal> it will not be
- applied to a single array or object. <literal>UNCONDITIONAL</literal>
- is the default.
- If the result is a scalar string, by default the value returned will have
- surrounding quotes making it a valid JSON value. However, this behavior
- is reversed if <literal>OMIT QUOTES</literal> is specified.
- The <literal>ON ERROR</literal> and <literal>ON EMPTY</literal>
- clauses have similar semantics to those clauses for
- <function>json_value</function>.
- The returned <parameter>data_type</parameter> has the same semantics
- as for constructor functions like <function>json_objectagg</function>.
- The default returned type is <type>text</type>.
- </para>
- <para>
- <literal>json_query(jsonb '[1,[2,3],null]', 'lax $[*][1]' WITH CONDITIONAL WRAPPER)</literal>
- <returnvalue>[3]</returnvalue>
- </para></entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- </sect2>
-
- <sect2 id="functions-sqljson-table">
- <title>JSON_TABLE</title>
- <indexterm>
- <primary>json_table</primary>
- </indexterm>
-
- <para>
- <function>json_table</function> is an SQL/JSON function which
- queries <acronym>JSON</acronym> data
- and presents the results as a relational view, which can be accessed as a
- regular SQL table. You can only use <function>json_table</function> inside the
- <literal>FROM</literal> clause of a <literal>SELECT</literal> statement.
- </para>
-
- <para>
- Taking JSON data as input, <function>json_table</function> uses
- a path expression to extract a part of the provided data that
- will be used as a <firstterm>row pattern</firstterm> for the
- constructed view. Each SQL/JSON item at the top level of the row pattern serves
- as the source for a separate row in the constructed relational view.
- </para>
-
- <para>
- To split the row pattern into columns, <function>json_table</function>
- provides the <literal>COLUMNS</literal> clause that defines the
- schema of the created view. For each column to be constructed,
- this clause provides a separate path expression that evaluates
- the row pattern, extracts a JSON item, and returns it as a
- separate SQL value for the specified column. If the required value
- is stored in a nested level of the row pattern, it can be extracted
- using the <literal>NESTED PATH</literal> subclause. Joining the
- columns returned by <literal>NESTED PATH</literal> can add multiple
- new rows to the constructed view. Such rows are called
- <firstterm>child rows</firstterm>, as opposed to the <firstterm>parent row</firstterm>
- that generates them.
- </para>
-
- <para>
- The rows produced by <function>JSON_TABLE</function> are laterally
- joined to the row that generated them, so you do not have to explicitly join
- the constructed view with the original table holding <acronym>JSON</acronym>
- data. Optionally, you can specify how to join the columns returned
- by <literal>NESTED PATH</literal> using the <literal>PLAN</literal> clause.
- </para>
-
- <para>
- Each <literal>NESTED PATH</literal> clause can generate one or more
- columns. Columns produced by <literal>NESTED PATH</literal>s at the
- same level are considered to be <firstterm>siblings</firstterm>,
- while a column produced by a <literal>NESTED PATH</literal> is
- considered to be a child of the column produced by and
- <literal>NESTED PATH</literal> or row expression at a higher level.
- Sibling columns are always joined first. Once they are processed,
- the resulting rows are joined to the parent row.
- </para>
-
- <variablelist>
- <varlistentry>
- <term>
- <literal><parameter>context_item</parameter>, <parameter>path_expression</parameter> <optional> <literal>AS</literal> <parameter>json_path_name</parameter> </optional> <optional> <literal>PASSING</literal> { <parameter>value</parameter> <literal>AS</literal> <parameter>varname</parameter> } <optional>, ...</optional></optional></literal>
- </term>
- <listitem>
- <para>
- The input data to query, the JSON path expression defining the query,
- and an optional <literal>PASSING</literal> clause, which can provide data
- values to the <parameter>path_expression</parameter>.
- The result of the input data
- evaluation is called the <firstterm>row pattern</firstterm>. The row
- pattern is used as the source for row values in the constructed view.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <literal>COLUMNS</literal>( <parameter>json_table_column</parameter> <optional>, ...</optional> )
- </term>
- <listitem>
-
- <para>
- The <literal>COLUMNS</literal> clause defining the schema of the
- constructed view. In this clause, you must specify all the columns
- to be filled with SQL/JSON items.
- The <parameter>json_table_column</parameter>
- expression has the following syntax variants:
- </para>
-
- <variablelist>
- <varlistentry>
- <term>
- <literal><parameter>name</parameter> <parameter>type</parameter>
- <optional> <literal>PATH</literal> <parameter>json_path_specification</parameter> </optional></literal>
- </term>
- <listitem>
-
- <para>
- Inserts a single SQL/JSON item into each row of
- the specified column.
- </para>
- <para>
- The provided <literal>PATH</literal> expression parses the
- row pattern defined by <parameter>json_api_common_syntax</parameter>
- and fills the column with produced SQL/JSON items, one for each row.
- If the <literal>PATH</literal> expression is omitted,
- <function>JSON_TABLE</function> uses the
- <literal>$.<replaceable>name</replaceable></literal> path expression,
- where <replaceable>name</replaceable> is the provided column name.
- In this case, the column name must correspond to one of the
- keys within the SQL/JSON item produced by the row pattern.
- </para>
- <para>
- Optionally, you can add <literal>ON EMPTY</literal> and
- <literal>ON ERROR</literal> clauses to define how to handle missing values
- or structural errors.
- <literal>WRAPPER</literal> and <literal>QUOTES</literal> clauses can only
- be used with JSON, array, and composite types.
- These clauses have the same syntax and semantics as for
- <function>json_value</function> and <function>json_query</function>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <parameter>name</parameter> <parameter>type</parameter> <literal>FORMAT</literal> <parameter>json_representation</parameter>
- <optional> <literal>PATH</literal> <parameter>json_path_specification</parameter> </optional>
- </term>
- <listitem>
-
- <para>
- Generates a column and inserts a composite SQL/JSON
- item into each row of this column.
- </para>
- <para>
- The provided <literal>PATH</literal> expression parses the
- row pattern defined by <parameter>json_api_common_syntax</parameter>
- and fills the column with produced SQL/JSON items, one for each row.
- If the <literal>PATH</literal> expression is omitted,
- <function>JSON_TABLE</function> uses the
- <literal>$.<parameter>name</parameter></literal> path expression,
- where <parameter>name</parameter> is the provided column name.
- In this case, the column name must correspond to one of the
- keys within the SQL/JSON item produced by the row pattern.
- </para>
- <para>
- Optionally, you can add <literal>WRAPPER</literal>, <literal>QUOTES</literal>,
- <literal>ON EMPTY</literal> and <literal>ON ERROR</literal> clauses
- to define additional settings for the returned SQL/JSON items.
- These clauses have the same syntax and semantics as
- for <function>json_query</function>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <parameter>name</parameter> <parameter>type</parameter>
- <literal>EXISTS</literal> <optional> <literal>PATH</literal> <parameter>json_path_specification</parameter> </optional>
- </term>
- <listitem>
-
- <para>
- Generates a column and inserts a boolean item into each row of this column.
- </para>
- <para>
- The provided <literal>PATH</literal> expression parses the
- row pattern defined by <parameter>json_api_common_syntax</parameter>,
- checks whether any SQL/JSON items were returned, and fills the column with
- resulting boolean value, one for each row.
- The specified <parameter>type</parameter> should have cast from
- <type>boolean</type>.
- If the <literal>PATH</literal> expression is omitted,
- <function>JSON_TABLE</function> uses the
- <literal>$.<replaceable>name</replaceable></literal> path expression,
- where <replaceable>name</replaceable> is the provided column name.
- </para>
- <para>
- Optionally, you can add <literal>ON ERROR</literal> clause to define
- error behavior. This clause has the same syntax and semantics as
- for <function>json_exists</function>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <literal>NESTED PATH</literal> <parameter>json_path_specification</parameter> <optional> <literal>AS</literal> <parameter>json_path_name</parameter> </optional>
- <literal>COLUMNS</literal> ( <parameter>json_table_column</parameter> <optional>, ...</optional> )
- </term>
- <listitem>
-
- <para>
- Extracts SQL/JSON items from nested levels of the row pattern,
- generates one or more columns as defined by the <literal>COLUMNS</literal>
- subclause, and inserts the extracted SQL/JSON items into each row of these columns.
- The <parameter>json_table_column</parameter> expression in the
- <literal>COLUMNS</literal> subclause uses the same syntax as in the
- parent <literal>COLUMNS</literal> clause.
- </para>
-
- <para>
- The <literal>NESTED PATH</literal> syntax is recursive,
- so you can go down multiple nested levels by specifying several
- <literal>NESTED PATH</literal> subclauses within each other.
- It allows to unnest the hierarchy of JSON objects and arrays
- in a single function invocation rather than chaining several
- <function>JSON_TABLE</function> expressions in an SQL statement.
- </para>
-
- <para>
- You can use the <literal>PLAN</literal> clause to define how
- to join the columns returned by <parameter>NESTED PATH</parameter> clauses.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <parameter>name</parameter> <literal>FOR ORDINALITY</literal>
- </term>
- <listitem>
-
- <para>
- Adds an ordinality column that provides sequential row numbering.
- You can have only one ordinality column per table. Row numbering
- is 1-based. For child rows that result from the <literal>NESTED PATH</literal>
- clauses, the parent row number is repeated.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
-
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <literal>AS</literal> <parameter>json_path_name</parameter>
- </term>
- <listitem>
-
- <para>
- The optional <parameter>json_path_name</parameter> serves as an
- identifier of the provided <parameter>json_path_specification</parameter>.
- The path name must be unique and distinct from the column names.
- When using the <literal>PLAN</literal> clause, you must specify the names
- for all the paths, including the row pattern. Each path name can appear in
- the <literal>PLAN</literal> clause only once.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <literal>PLAN</literal> ( <parameter>json_table_plan</parameter> )
- </term>
- <listitem>
-
- <para>
- Defines how to join the data returned by <literal>NESTED PATH</literal>
- clauses to the constructed view.
- </para>
- <para>
- To join columns with parent/child relationship, you can use:
- </para>
- <variablelist>
- <varlistentry>
- <term>
- <literal>INNER</literal>
- </term>
- <listitem>
-
- <para>
- Use <literal>INNER JOIN</literal>, so that the parent row
- is omitted from the output if it does not have any child rows
- after joining the data returned by <literal>NESTED PATH</literal>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <literal>OUTER</literal>
- </term>
- <listitem>
-
- <para>
- Use <literal>LEFT OUTER JOIN</literal>, so that the parent row
- is always included into the output even if it does not have any child rows
- after joining the data returned by <literal>NESTED PATH</literal>, with NULL values
- inserted into the child columns if the corresponding
- values are missing.
- </para>
- <para>
- This is the default option for joining columns with parent/child relationship.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
-
- <para>
- To join sibling columns, you can use:
- </para>
-
- <variablelist>
- <varlistentry>
- <term>
- <literal>UNION</literal>
- </term>
- <listitem>
-
- <para>
- Generate one row for each value produced by each of the sibling
- columns. The columns from the other siblings are set to null.
- </para>
- <para>
- This is the default option for joining sibling columns.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <literal>CROSS</literal>
- </term>
- <listitem>
-
- <para>
- Generate one row for each combination of values from the sibling columns.
- </para>
- </listitem>
- </varlistentry>
-
- </variablelist>
-
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
- <literal>PLAN DEFAULT</literal> ( <replaceable>OUTER | INNER</replaceable> <optional>, <replaceable>UNION | CROSS</replaceable> </optional> )
- </term>
- <listitem>
- <para>
- The terms can also be specified in reverse order. The
- <literal>INNER</literal> or <literal>OUTER</literal> option defines the
- joining plan for parent/child columns, while <literal>UNION</literal> or
- <literal>CROSS</literal> affects joins of sibling columns. This form
- of <literal>PLAN</literal> overrides the default plan for
- all columns at once. Even though the path names are not included in the
- <literal>PLAN DEFAULT</literal> form, to conform to the SQL/JSON standard
- they must be provided for all the paths if the <literal>PLAN</literal>
- clause is used.
- </para>
- <para>
- <literal>PLAN DEFAULT</literal> is simpler than specifying a complete
- <literal>PLAN</literal>, and is often all that is required to get the desired
- output.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
-
- <para>Examples</para>
-
- <para>
- In these examples the following small table storing some JSON data will be used:
-<programlisting>
-CREATE TABLE my_films ( js jsonb );
-
-INSERT INTO my_films VALUES (
-'{ "favorites" : [
- { "kind" : "comedy", "films" : [
- { "title" : "Bananas",
- "director" : "Woody Allen"},
- { "title" : "The Dinner Game",
- "director" : "Francis Veber" } ] },
- { "kind" : "horror", "films" : [
- { "title" : "Psycho",
- "director" : "Alfred Hitchcock" } ] },
- { "kind" : "thriller", "films" : [
- { "title" : "Vertigo",
- "director" : "Alfred Hitchcock" } ] },
- { "kind" : "drama", "films" : [
- { "title" : "Yojimbo",
- "director" : "Akira Kurosawa" } ] }
- ] }');
-</programlisting>
- </para>
- <para>
- Query the <structname>my_films</structname> table holding
- some JSON data about the films and create a view that
- distributes the film genre, title, and director between separate columns:
-<screen>
-SELECT jt.* FROM
- my_films,
- JSON_TABLE ( js, '$.favorites[*]' COLUMNS (
- id FOR ORDINALITY,
- kind text PATH '$.kind',
- NESTED PATH '$.films[*]' COLUMNS (
- title text PATH '$.title',
- director text PATH '$.director'))) AS jt;
-----+----------+------------------+-------------------
- id | kind | title | director
-----+----------+------------------+-------------------
- 1 | comedy | Bananas | Woody Allen
- 1 | comedy | The Dinner Game | Francis Veber
- 2 | horror | Psycho | Alfred Hitchcock
- 3 | thriller | Vertigo | Alfred Hitchcock
- 4 | drama | Yojimbo | Akira Kurosawa
- (5 rows)
-</screen>
- </para>
-
- <para>
- Find a director that has done films in two different genres:
-<screen>
-SELECT
- director1 AS director, title1, kind1, title2, kind2
-FROM
- my_films,
- JSON_TABLE ( js, '$.favorites' AS favs COLUMNS (
- NESTED PATH '$[*]' AS films1 COLUMNS (
- kind1 text PATH '$.kind',
- NESTED PATH '$.films[*]' AS film1 COLUMNS (
- title1 text PATH '$.title',
- director1 text PATH '$.director')
- ),
- NESTED PATH '$[*]' AS films2 COLUMNS (
- kind2 text PATH '$.kind',
- NESTED PATH '$.films[*]' AS film2 COLUMNS (
- title2 text PATH '$.title',
- director2 text PATH '$.director'
- )
- )
- )
- PLAN (favs OUTER ((films1 INNER film1) CROSS (films2 INNER film2)))
- ) AS jt
- WHERE kind1 > kind2 AND director1 = director2;
-
- director | title1 | kind1 | title2 | kind2
-------------------+---------+----------+--------+--------
- Alfred Hitchcock | Vertigo | thriller | Psycho | horror
-(1 row)
-</screen>
- </para>
- </sect2>
-
+ </sect2>
</sect1>
<sect1 id="functions-sequence">
@@ -20882,29 +19952,6 @@ SELECT NULLIF(value, '(none)') ...
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
- <primary>json_agg_strict</primary>
- </indexterm>
- <function>json_agg_strict</function> ( <type>anyelement</type> )
- <returnvalue>json</returnvalue>
- </para>
- <para role="func_signature">
- <indexterm>
- <primary>jsonb_agg_strict</primary>
- </indexterm>
- <function>jsonb_agg_strict</function> ( <type>anyelement</type> )
- <returnvalue>jsonb</returnvalue>
- </para>
- <para>
- Collects all the input values, skipping nulls, into a JSON array.
- Values are converted to JSON as per <function>to_json</function>
- or <function>to_jsonb</function>.
- </para></entry>
- <entry>No</entry>
- </row>
-
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- <indexterm>
<primary>json_object_agg</primary>
</indexterm>
<function>json_object_agg</function> ( <parameter>key</parameter>
@@ -20923,97 +19970,9 @@ SELECT NULLIF(value, '(none)') ...
</para>
<para>
Collects all the key/value pairs into a JSON object. Key arguments
- are coerced to text; value arguments are converted as per
- <function>to_json</function> or <function>to_jsonb</function>
- Values can be null, but keys cannot.
- </para></entry>
- <entry>No</entry>
- </row>
-
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- <indexterm>
- <primary>json_object_agg_strict</primary>
- </indexterm>
- <function>json_object_agg_strict</function> (
- <parameter>key</parameter> <type>"any"</type>,
- <parameter>value</parameter> <type>"any"</type> )
- <returnvalue>json</returnvalue>
- </para>
- <para role="func_signature">
- <indexterm>
- <primary>jsonb_object_agg_strict</primary>
- </indexterm>
- <function>jsonb_object_agg_strict</function> (
- <parameter>key</parameter> <type>"any"</type>,
- <parameter>value</parameter> <type>"any"</type> )
- <returnvalue>jsonb</returnvalue>
- </para>
- <para>
- Collects all the key/value pairs into a JSON object. Key arguments
- are coerced to text; value arguments are converted as per
- <function>to_json</function> or <function>to_jsonb</function>.
- The <parameter>key</parameter> can not be null. If the
- <parameter>value</parameter> is null then the entry is skipped,
- </para></entry>
- <entry>No</entry>
- </row>
-
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- <indexterm>
- <primary>json_object_agg_unique</primary>
- </indexterm>
- <function>json_object_agg_unique</function> (
- <parameter>key</parameter> <type>"any"</type>,
- <parameter>value</parameter> <type>"any"</type> )
- <returnvalue>json</returnvalue>
- </para>
- <para role="func_signature">
- <indexterm>
- <primary>jsonb_object_agg_unique</primary>
- </indexterm>
- <function>jsonb_object_agg_unique</function> (
- <parameter>key</parameter> <type>"any"</type>,
- <parameter>value</parameter> <type>"any"</type> )
- <returnvalue>jsonb</returnvalue>
- </para>
- <para>
- Collects all the key/value pairs into a JSON object. Key arguments
- are coerced to text; value arguments are converted as per
- <function>to_json</function> or <function>to_jsonb</function>.
- Values can be null, but keys cannot.
- If there is a duplicate key an error is thrown.
- </para></entry>
- <entry>No</entry>
- </row>
-
- <row>
- <entry role="func_table_entry"><para role="func_signature">
- <indexterm>
- <primary>json_object_agg_unique_strict</primary>
- </indexterm>
- <function>json_object_agg_unique_strict</function> (
- <parameter>key</parameter> <type>"any"</type>,
- <parameter>value</parameter> <type>"any"</type> )
- <returnvalue>json</returnvalue>
- </para>
- <para role="func_signature">
- <indexterm>
- <primary>jsonb_object_agg_unique_strict</primary>
- </indexterm>
- <function>jsonb_object_agg_unique_strict</function> (
- <parameter>key</parameter> <type>"any"</type>,
- <parameter>value</parameter> <type>"any"</type> )
- <returnvalue>jsonb</returnvalue>
- </para>
- <para>
- Collects all the key/value pairs into a JSON object. Key arguments
- are coerced to text; value arguments are converted as per
- <function>to_json</function> or <function>to_jsonb</function>.
- The <parameter>key</parameter> can not be null. If the
- <parameter>value</parameter> is null then the entry is skipped,
- If there is a duplicate key an error is thrown.
+ are coerced to text; value arguments are converted as
+ per <function>to_json</function> or <function>to_jsonb</function>.
+ Values can be null, but not keys.
</para></entry>
<entry>No</entry>
</row>
@@ -21191,12 +20150,7 @@ SELECT NULLIF(value, '(none)') ...
<para>
The aggregate functions <function>array_agg</function>,
<function>json_agg</function>, <function>jsonb_agg</function>,
- <function>json_agg_strict</function>, <function>jsonb_agg_strict</function>,
<function>json_object_agg</function>, <function>jsonb_object_agg</function>,
- <function>json_object_agg_strict</function>, <function>jsonb_object_agg_strict</function>,
- <function>json_object_agg_unique</function>, <function>jsonb_object_agg_unique</function>,
- <function>json_object_agg_unique_strict</function>,
- <function>jsonb_object_agg_unique_strict</function>,
<function>string_agg</function>,
and <function>xmlagg</function>, as well as similar user-defined
aggregate functions, produce meaningfully different result values
@@ -21217,13 +20171,6 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
</para>
<note>
- <para>
- In addition to the JSON aggregates shown here, see the <function>json_objectagg</function>
- and <function>json_arrayagg</function> constructors in <xref linkend="functions-sqljson"/>.
- </para>
- </note>
-
- <note>
<indexterm>
<primary>ANY</primary>
</indexterm>
diff --git a/doc/src/sgml/keywords/sql2016-02-reserved.txt b/doc/src/sgml/keywords/sql2016-02-reserved.txt
index 7e1a5e4d89..b1bb0776dc 100644
--- a/doc/src/sgml/keywords/sql2016-02-reserved.txt
+++ b/doc/src/sgml/keywords/sql2016-02-reserved.txt
@@ -157,7 +157,6 @@ INTERVAL
INTO
IS
JOIN
-JSON
JSON_ARRAY
JSON_ARRAYAGG
JSON_EXISTS