From 565caaa79af9a6b3853b161b0652527e716326b8 Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Fri, 6 Sep 2024 10:13:03 +0900 Subject: [PATCH] SQL/JSON: Fix default ON ERROR behavior for JSON_TABLE Use EMPTY ARRAY instead of EMPTY. This change does not affect the runtime behavior of JSON_TABLE(), which continues to return an empty relation ON ERROR. It only alters whether the default ON ERROR behavior is shown in the deparsed output. Reported-by: Jian He Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com Backpatch-through: 17 --- src/backend/parser/parse_expr.c | 4 +-- src/backend/utils/adt/ruleutils.c | 2 +- .../regress/expected/sqljson_jsontable.out | 25 +++++++++++++++++++ src/test/regress/sql/sqljson_jsontable.sql | 5 ++++ 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 56e413da9f5..36c1b7a88f2 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -4603,13 +4603,13 @@ transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func) } /* - * Assume EMPTY ON ERROR when ON ERROR is not specified. + * Assume EMPTY ARRAY ON ERROR when ON ERROR is not specified. * * ON EMPTY cannot be specified at the top level but it can be for * the individual columns. */ jsexpr->on_error = transformJsonBehavior(pstate, func->on_error, - JSON_BEHAVIOR_EMPTY, + JSON_BEHAVIOR_EMPTY_ARRAY, jsexpr->returning); break; diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 371b46e7a2d..cd9c3eddd1d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -11875,7 +11875,7 @@ get_json_table(TableFunc *tf, deparse_context *context, bool showimplicit) get_json_table_columns(tf, castNode(JsonTablePathScan, tf->plan), context, showimplicit); - if (jexpr->on_error->btype != JSON_BEHAVIOR_EMPTY) + if (jexpr->on_error->btype != JSON_BEHAVIOR_EMPTY_ARRAY) get_json_behavior(jexpr->on_error, context, "ERROR"); if (PRETTY_INDENT(context)) diff --git a/src/test/regress/expected/sqljson_jsontable.out b/src/test/regress/expected/sqljson_jsontable.out index ebfde38a056..5c7aaa6159d 100644 --- a/src/test/regress/expected/sqljson_jsontable.out +++ b/src/test/regress/expected/sqljson_jsontable.out @@ -1150,3 +1150,28 @@ EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') ER Table Function Call: JSON_TABLE('"a"'::jsonb, '$' AS json_table_path_0 COLUMNS (a text PATH '$') ERROR ON ERROR) (3 rows) +-- Test JSON_TABLE() deparsing -- don't emit default ON ERROR behavior +EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$')); + QUERY PLAN +----------------------------------------------------------------------------------------------------- + Table Function Scan on "json_table" (cost=0.01..1.00 rows=100 width=32) + Output: a + Table Function Call: JSON_TABLE('"a"'::jsonb, '$' AS json_table_path_0 COLUMNS (a text PATH '$')) +(3 rows) + +EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') EMPTY ON ERROR); + QUERY PLAN +----------------------------------------------------------------------------------------------------- + Table Function Scan on "json_table" (cost=0.01..1.00 rows=100 width=32) + Output: a + Table Function Call: JSON_TABLE('"a"'::jsonb, '$' AS json_table_path_0 COLUMNS (a text PATH '$')) +(3 rows) + +EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') EMPTY ARRAY ON ERROR); + QUERY PLAN +----------------------------------------------------------------------------------------------------- + Table Function Scan on "json_table" (cost=0.01..1.00 rows=100 width=32) + Output: a + Table Function Call: JSON_TABLE('"a"'::jsonb, '$' AS json_table_path_0 COLUMNS (a text PATH '$')) +(3 rows) + diff --git a/src/test/regress/sql/sqljson_jsontable.sql b/src/test/regress/sql/sqljson_jsontable.sql index c9408878926..31bc9c9ea0c 100644 --- a/src/test/regress/sql/sqljson_jsontable.sql +++ b/src/test/regress/sql/sqljson_jsontable.sql @@ -547,3 +547,8 @@ SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int exists empty object on er -- behavior EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$')); EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') ERROR ON ERROR); + +-- Test JSON_TABLE() deparsing -- don't emit default ON ERROR behavior +EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$')); +EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') EMPTY ON ERROR); +EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') EMPTY ARRAY ON ERROR); -- 2.30.2