@@ -17912,6 +17912,11 @@ FROM films AS f;
17912
17912
<link linkend="functions-jsonquery"><literal>JSON_QUERY</literal></link>
17913
17913
</para>
17914
17914
</listitem>
17915
+ <listitem>
17916
+ <para>
17917
+ <xref linkend="functions-jsontable"/>
17918
+ </para>
17919
+ </listitem>
17915
17920
</itemizedlist>
17916
17921
17917
17922
<para>
@@ -18582,6 +18587,285 @@ FROM
18582
18587
</sect5>
18583
18588
</sect4>
18584
18589
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>
18585
18869
18586
18870
</sect3>
18587
18871
0 commit comments