@@ -17912,6 +17912,11 @@ FROM films AS f;
1791217912 <link linkend="functions-jsonquery"><literal>JSON_QUERY</literal></link>
1791317913 </para>
1791417914 </listitem>
17915+ <listitem>
17916+ <para>
17917+ <xref linkend="functions-jsontable"/>
17918+ </para>
17919+ </listitem>
1791517920 </itemizedlist>
1791617921
1791717922 <para>
@@ -18582,6 +18587,285 @@ FROM
1858218587 </sect5>
1858318588 </sect4>
1858418589
18590+ <refentry id="functions-jsontable">
18591+ <refnamediv>
18592+ <refname>JSON_TABLE</refname>
18593+ <refpurpose>display JSON data as an SQL relation</refpurpose>
18594+ </refnamediv>
18595+
18596+ <refsynopsisdiv>
18597+
18598+ <synopsis>
18599+ JSON_TABLE (
18600+ <replaceable class="parameter">json_api_common_syntax</replaceable>
18601+ COLUMNS ( <replaceable class="parameter">json_table_column</replaceable> [, ...] )
18602+ )
18603+ <phrase>
18604+ where <replaceable class="parameter">json_table_column</replaceable> is:
18605+ </phrase>
18606+ <replaceable>name</replaceable> <replaceable>type</replaceable> [ PATH <replaceable>json_path_specification</replaceable> ]
18607+ [ { ERROR | NULL | DEFAULT expression } ON EMPTY ]
18608+ [ { ERROR | NULL | DEFAULT expression } ON ERROR ]
18609+ | <replaceable>name</replaceable> <replaceable>type</replaceable> FORMAT <replaceable>json_representation</replaceable>
18610+ [ PATH <replaceable>json_path_specification</replaceable> ]
18611+ [ { WITHOUT | WITH { CONDITIONAL | [UNCONDITIONAL] } }
18612+ [ ARRAY ] WRAPPER ]
18613+ [ { KEEP | OMIT } QUOTES [ ON SCALAR STRING ] ]
18614+ [ { ERROR | NULL | EMPTY { ARRAY | OBJECT } } ON EMPTY ]
18615+ [ { ERROR | NULL | EMPTY { ARRAY | OBJECT } } ON ERROR ]
18616+ | NESTED PATH <replaceable>json_path_specification</replaceable> [ AS <replaceable>path_name</replaceable> ]
18617+ COLUMNS ( <replaceable>json_table_column</replaceable> [, ...] )
18618+ | <replaceable>name</replaceable> FOR ORDINALITY
18619+
18620+ </synopsis>
18621+ </refsynopsisdiv>
18622+ <refsect1>
18623+ <title>Description</title>
18624+
18625+ <para>
18626+ <function>JSON_TABLE</function> function queries <acronym>JSON</acronym> data
18627+ and presents the results as a relational view, which can be accessed as a
18628+ regular SQL table. You can only use <function>JSON_TABLE</function> inside the
18629+ <literal>FROM</literal> clause of the <literal>SELECT</literal> statement
18630+ for an SQL table.
18631+ </para>
18632+
18633+ <para>
18634+ Taking JSON data as input, <function>JSON_TABLE</function> uses
18635+ a path expression to extract a part of the provided data that
18636+ will be used as a <firstterm>row pattern</firstterm> for the
18637+ constructed view. Each SQL/JSON item at the top level of the row pattern serves
18638+ as the source for a separate row in the constructed relational view.
18639+ </para>
18640+
18641+ <para>
18642+ To split the row pattern into columns, <function>JSON_TABLE</function>
18643+ provides the <literal>COLUMNS</literal> clause that defines the
18644+ schema of the created view. For each column to be constructed,
18645+ this clause provides a separate path expression that evaluates
18646+ the row pattern, extracts a JSON item, and returns it as a
18647+ separate SQL value for the specified column. If the required value
18648+ is stored in a nested level of the row pattern, it can be extracted
18649+ using the <literal>NESTED PATH</literal> subclause. Joining the
18650+ columns returned by <literal>NESTED PATH</literal> can add multiple
18651+ new rows to the constructed view. Such rows are called
18652+ <firstterm>child rows</firstterm>, as opposed to the <firstterm>parent row</firstterm>
18653+ that generates them.
18654+ </para>
18655+
18656+ <para>
18657+ The rows produced by <function>JSON_TABLE</function> are laterally
18658+ joined to the row that generated them, so you do not have to explicitly join
18659+ the constructed view with the original table holding <acronym>JSON</acronym>
18660+ data.
18661+ </para>
18662+
18663+ <para>
18664+ Each <literal>NESTED PATH</literal> clause can generate one or more
18665+ columns, which are considered to be <firstterm>siblings</firstterm>
18666+ to each other. In relation to the columns returned directly from the row
18667+ expression or by the <literal>NESTED PATH</literal> clause of a
18668+ higher level, these columns are <firstterm>child</firstterm> columns.
18669+ Sibling columns are always joined first. Once they are processed,
18670+ the resulting rows are joined to the parent row.
18671+ </para>
18672+
18673+ <para>
18674+ Columns with parent/child relationship are joined using
18675+ <literal>LEFT OUTER JOIN</literal>, so that the parent row
18676+ is always included into the output even if it does not have any child rows
18677+ after joining the data returned by <literal>NESTED PATH</literal>,
18678+ with NULL values inserted into the child columns if the corresponding
18679+ values are missing.
18680+ </para>
18681+
18682+ <para>
18683+ Sibling columns are joined using
18684+ <literal>FULL OUTER JOIN ON FALSE</literal>, so that both parent and child
18685+ rows are included into the output, with NULL values inserted
18686+ into both child and parrent columns for all missing values.
18687+ </para>
18688+
18689+ </refsect1>
18690+ <refsect1>
18691+ <title>Parameters</title>
18692+
18693+ <variablelist>
18694+ <varlistentry>
18695+ <term>
18696+ <literal><replaceable class="parameter">json_api_common_syntax</replaceable></literal>
18697+ </term>
18698+ <listitem>
18699+
18700+ <para>
18701+ The input data to query, the JSON path expression defining the query,
18702+ and an optional <literal>PASSING</literal> clause, as described in
18703+ <xref linkend="sqljson-input-clause"/>. The result of the input data
18704+ evaluation is called the <firstterm>row pattern</firstterm>. The row
18705+ pattern is used as the source for row values in the constructed view.
18706+ </para>
18707+ </listitem>
18708+ </varlistentry>
18709+
18710+ <varlistentry>
18711+ <term>
18712+ <literal>COLUMNS( { <replaceable class="parameter">json_table_column</replaceable> } [, ...] )</literal>
18713+ </term>
18714+ <listitem>
18715+
18716+ <para>
18717+ The <literal>COLUMNS</literal> clause defining the schema of the
18718+ constructed view. In this clause, you must specify all the columns
18719+ to be filled with SQL/JSON items. Only scalar column types are supported.
18720+ The <replaceable class="parameter">json_table_column</replaceable>
18721+ expression has the following syntax variants:
18722+ </para>
18723+
18724+ <variablelist>
18725+ <varlistentry>
18726+ <term>
18727+ <literal><replaceable>name</replaceable> <replaceable>type</replaceable>
18728+ [ PATH <replaceable>json_path_specification</replaceable> ]</literal>
18729+ </term>
18730+ <listitem>
18731+
18732+ <para>
18733+ Inserts a single SQL/JSON item into each row of
18734+ the specified column.
18735+ </para>
18736+ <para>
18737+ The provided <literal>PATH</literal> expression parses the
18738+ row pattern defined by <replaceable>json_api_common_syntax</replaceable>
18739+ and fills the column with produced SQL/JSON items, one for each row.
18740+ If the <literal>PATH</literal> expression is omitted,
18741+ <function>JSON_TABLE</function> uses the
18742+ <literal>$.<replaceable>name</replaceable></literal> path expression,
18743+ where <replaceable>name</replaceable> is the provided column name.
18744+ In this case, the column name must correspond to one of the
18745+ keys within the SQL/JSON item produced by the row pattern.
18746+ </para>
18747+ <para>
18748+ Optionally, you can add <literal>ON EMPTY</literal> and
18749+ <literal>ON ERROR</literal> clauses to define how to handle
18750+ missing values or structural errors. These clauses have the same syntax
18751+ and semantics as in <xref linkend="functions-jsonvalue"/>.
18752+ </para>
18753+ </listitem>
18754+ </varlistentry>
18755+
18756+ <varlistentry>
18757+ <term>
18758+ <literal><replaceable>name</replaceable> <replaceable>type</replaceable> FORMAT <replaceable>json_representation</replaceable>
18759+ [ PATH <replaceable>json_path_specification</replaceable> ]</literal>
18760+ </term>
18761+ <listitem>
18762+
18763+ <para>
18764+ Gerenates a column and inserts a composite SQL/JSON
18765+ item into each row of this column.
18766+ </para>
18767+ <para>
18768+ The provided <literal>PATH</literal> expression parses the
18769+ row pattern defined by <replaceable>json_api_common_syntax</replaceable>
18770+ and fills the column with produced SQL/JSON items, one for each row.
18771+ If the <literal>PATH</literal> expression is omitted,
18772+ <function>JSON_TABLE</function> uses the
18773+ <literal>$.<replaceable>name</replaceable></literal> path expression,
18774+ where <replaceable>name</replaceable> is the provided column name.
18775+ In this case, the column name must correspond to one of the
18776+ keys within the SQL/JSON item produced by the row pattern.
18777+ </para>
18778+ <para>
18779+ Optionally, you can add <literal>WRAPPER</literal>, <literal>QUOTES</literal>,
18780+ <literal>ON EMPTY</literal> and <literal>ON ERROR</literal> clauses
18781+ to define additional settings for the returned SQL/JSON items.
18782+ These clauses have the same syntax and semantics as
18783+ in <xref linkend="functions-jsonquery"/>.
18784+ </para>
18785+ </listitem>
18786+ </varlistentry>
18787+
18788+ <varlistentry>
18789+ <term>
18790+ <literal>NESTED PATH <replaceable>json_path_specification</replaceable> [ AS <replaceable>json_path_name</replaceable> ]
18791+ COLUMNS ( <replaceable>json_table_column</replaceable> [, ...] )</literal>
18792+ </term>
18793+ <listitem>
18794+
18795+ <para>
18796+ Extracts SQL/JSON items from nested levels of the row pattern,
18797+ gerenates one or more columns as defined by the <literal>COLUMNS</literal>
18798+ subclause, and inserts the extracted SQL/JSON items into each row of these columns.
18799+ The <replaceable>json_table_column</replaceable> expression in the
18800+ <literal>COLUMNS</literal> subclause uses the same syntax as in the
18801+ parent <literal>COLUMNS</literal> clause.
18802+ </para>
18803+
18804+ <para>
18805+ The <literal>NESTED PATH</literal> syntax is recursive,
18806+ so you can go down multiple nested levels by specifying several
18807+ <literal>NESTED PATH</literal> subclauses within each other.
18808+ It allows to unnest the hierarchy of JSON objects and arrays
18809+ in a single function invocation rather than chaining several
18810+ <function>JSON_TABLE</function> expressions in an SQL statement.
18811+ </para>
18812+
18813+ </listitem>
18814+ </varlistentry>
18815+
18816+ <varlistentry>
18817+ <term>
18818+ <literal><replaceable>name</replaceable> FOR ORDINALITY</literal>
18819+ </term>
18820+ <listitem>
18821+
18822+ <para>
18823+ Adds an ordinality column that provides sequential row numbering.
18824+ You can have only one ordinality column per table. Row numbering
18825+ is 1-based. For child rows that result from the <literal>NESTED PATH</literal>
18826+ clauses, the parent row number is repeated.
18827+ </para>
18828+ </listitem>
18829+ </varlistentry>
18830+ </variablelist>
18831+
18832+ </listitem>
18833+ </varlistentry>
18834+
18835+ </variablelist>
18836+
18837+ </refsect1>
18838+
18839+ <refsect1>
18840+ <title>Examples</title>
18841+
18842+ <para>
18843+ Query the <structname>my_films</structname> table holding
18844+ some JSON data about the films and create a view that
18845+ distributes the film genre, title, and director between separate columns:
18846+ <screen>
18847+ SELECT jt.* FROM
18848+ my_films,
18849+ JSON_TABLE ( js, '$.favorites[*]' COLUMNS (
18850+ id FOR ORDINALITY,
18851+ kind text PATH '$.kind',
18852+ NESTED PATH '$.films[*]' COLUMNS (
18853+ title text PATH '$.title',
18854+ director text PATH '$.director'))) AS jt;
18855+ ----+----------+------------------+-------------------
18856+ id | kind | title | director
18857+ ----+----------+------------------+-------------------
18858+ 1 | comedy | Bananas | Woody Allen
18859+ 1 | comedy | The Dinner Game | Francis Veber
18860+ 2 | horror | Psycho | Alfred Hitchcock
18861+ 3 | thriller | Vertigo | Hitchcock
18862+ 4 | drama | Yojimbo | Akira Kurosawa
18863+ (5 rows)
18864+ </screen>
18865+ </para>
18866+
18867+ </refsect1>
18868+ </refentry>
1858518869
1858618870 </sect3>
1858718871
0 commit comments