From 89f7c5d716de08f82796ac127db826e27536705c Mon Sep 17 00:00:00 2001 From: Nikita Malakhov Date: Fri, 15 May 2026 14:41:17 +0300 Subject: [PATCH] JSON_TABLE PLAN Clause (3/3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds the PLAN clauses for JSON_TABLE, which allow the user to specify how data from nested paths are joined, allowing considerable freedom in shaping the tabular output of JSON_TABLE. PLAN DEFAULT allows the user to specify the global strategies when dealing with sibling or child nested paths. The is often sufficient to achieve the necessary goal, and is considerably simpler than the full PLAN clause, which allows the user to specify the strategy to be used for each named nested path. The third patch in series provides documentation for PLAN clause. Author: Nikita Glukhov Author: Teodor Sigaev Author: Oleg Bartunov Author: Alexander Korotkov Author: Andrew Dunstan Author: Amit Langote Author: Anton Melnikov Author: Nikita Malakhov Reviewers have included (in no particular order) Andres Freund, Alexander Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu, Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby, Álvaro Herrera, jian he Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com --- doc/src/sgml/func/func-json.sgml | 170 ++++++++++++++++++++++++++++++- 1 file changed, 168 insertions(+), 2 deletions(-) diff --git a/doc/src/sgml/func/func-json.sgml b/doc/src/sgml/func/func-json.sgml index 3d97e2b5375..d6114e97341 100644 --- a/doc/src/sgml/func/func-json.sgml +++ b/doc/src/sgml/func/func-json.sgml @@ -3663,6 +3663,11 @@ JSON_TABLE ( context_item, path_expression AS json_path_name PASSING { value AS varname } , ... COLUMNS ( json_table_column , ... ) { ERROR | EMPTY ARRAY} ON ERROR + + PLAN ( json_table_plan ) | + PLAN DEFAULT ( { INNER | OUTER } , { CROSS | UNION } + | { CROSS | UNION } , { INNER | OUTER } ) + ) @@ -3679,6 +3684,16 @@ where json_table_column is: | name type EXISTS PATH path_expression { ERROR | TRUE | FALSE | UNKNOWN } ON ERROR | NESTED PATH path_expression AS json_path_name COLUMNS ( json_table_column , ... ) + +json_table_plan is: + + json_path_name { OUTER | INNER } json_table_plan_primary + | json_table_plan_primary { UNION json_table_plan_primary } ... + | json_table_plan_primary { CROSS json_table_plan_primary } ... + +json_table_plan_primary is: + + json_path_name | ( json_table_plan ) @@ -3842,6 +3857,11 @@ where json_table_column is: in a single function invocation rather than chaining several JSON_TABLE expressions in an SQL statement. + + + You can use the PLAN clause to define how + to join the columns returned by NESTED PATH clauses. + @@ -3866,9 +3886,121 @@ where json_table_column is: The optional json_path_name serves as an - identifier of the provided path_expression. - The name must be unique and distinct from the column names. + identifier of the provided json_path_specification. + The path name must be unique and distinct from the column names. + When using the PLAN clause, you must specify the names + for all the paths, including the row pattern. Each path name can appear in + the PLAN clause only once. + + + + + + + PLAN ( json_table_plan ) + + + + + Defines how to join the data returned by NESTED PATH + clauses to the constructed view. + + + To join columns with parent/child relationship, you can use: + + + + + INNER + + + + + Use INNER JOIN, so that the parent row + is omitted from the output if it does not have any child rows + after joining the data returned by NESTED PATH. + + + + + + + OUTER + + + + + Use LEFT OUTER JOIN, 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 NESTED PATH, with NULL values + inserted into the child columns if the corresponding + values are missing. + + + This is the default option for joining columns with parent/child relationship. + + + + + + To join sibling columns, you can use: + + + + + UNION + + + + + Generate one row for each value produced by each of the sibling + columns. The columns from the other siblings are set to null. + + + This is the default option for joining sibling columns. + + + + + + + CROSS + + + + + Generate one row for each combination of values from the sibling columns. + + + + + + + + + + + + PLAN DEFAULT ( OUTER | INNER , UNION | CROSS ) + + + + The terms can also be specified in reverse order. The + INNER or OUTER option defines the + joining plan for parent/child columns, while UNION or + CROSS affects joins of sibling columns. This form + of PLAN overrides the default plan for + all columns at once. Even though the path names are not included in the + PLAN DEFAULT form, to conform to the SQL/JSON standard + they must be provided for all the paths if the PLAN + clause is used. + + + PLAN DEFAULT is simpler than specifying a complete + PLAN, and is often all that is required to get the desired + output. + @@ -4082,5 +4214,39 @@ COLUMNS ( + + + Find a director that has done films in two different genres: + +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) + + + -- 2.43.0