JSON_TABLE: propagate table-level ON ERROR to columns per SQL standard

Per ISO/IEC 9075-2:2023, 7.11 <JSON table>, Syntax Rules 1)e)iv) and
1)f)xi), a regular or formatted JSON_TABLE column that does not specify
its own ON ERROR clause takes its default error behavior from the
table-level ON ERROR clause: with ERROR ON ERROR on the table, the
column behaves as ERROR ON ERROR; otherwise the column defaults to
NULL ON ERROR.

PostgreSQL instead always defaulted such columns to NULL ON ERROR, so

  SELECT * FROM JSON_TABLE(jsonb '"err"', '$'
                           COLUMNS (a int PATH '$') ERROR ON ERROR) jt;

returned a NULL row where the standard requires an error.  The
documentation stated the divergence as if it were a rule, saying that
the table-level clause "does not affect the errors that occur when
evaluating columns".

Implement the standard behavior in the JSON_TABLE syntactic
transformation: when a column lacks its own ON ERROR clause and the
table-level behavior is ERROR ON ERROR, synthesize an implicit ERROR ON
ERROR for the column before it is transformed into a JsonExpr.  A column
with its own ON ERROR clause is unaffected.  EXISTS columns are not
covered by those syntax rules, so they keep their FALSE ON ERROR
default.  A JSON_TABLE stored in a view is now deparsed with the
previously implicit ERROR ON ERROR shown explicitly on the affected
columns, which is a semantically equivalent, round-trip-stable form.

86ab7f4c721d introduced this cascade as part of the PLAN clause and
af6fad879fbf reverted it, on the grounds that it should be a deliberate
and separately documented change rather than a side effect of an
unrelated feature.  This is that change.

Do not back-patch.  A query that specifies ERROR ON ERROR at the table
level and relies on its columns still yielding NULL now raises an error
instead of returning rows.  Nothing is silently wrong in the released
branches: the table-level clause is ignored for columns consistently,
and that is what the documentation has promised since PostgreSQL 17, so
users could reasonably have depended on it.

Discussion: 
https://postgr.es/m/CAPpHfdtDXseGhrL14a2asOkwGnFTVrDk8SQc3iWZgWEEhXXMGw%40mail.gmail.com
Reviewed-by: Nikita Malakhov <[email protected]>

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/e73841ffbceea314cf9fa3f64a5eae9f87a46449

Modified Files
--------------
doc/src/sgml/func/func-json.sgml                | 16 ++++++++++----
src/backend/parser/parse_jsontable.c            | 29 ++++++++++++++++++++-----
src/test/regress/expected/sqljson_jsontable.out | 28 ++++++++++++++++++------
src/test/regress/sql/sqljson_jsontable.sql      | 17 ++++++++++-----
4 files changed, 68 insertions(+), 22 deletions(-)

Reply via email to