v1-0003-SQL-JSON-Fix-JSON_TABLE-column-deparsing.patch
application/octet-stream
Filename: v1-0003-SQL-JSON-Fix-JSON_TABLE-column-deparsing.patch
Type: application/octet-stream
Part: 2
Patch
Format: format-patch
Series: patch v1-0003
Subject: SQL/JSON: Fix JSON_TABLE() column deparsing
| File | + | − |
|---|---|---|
| src/backend/utils/adt/ruleutils.c | 4 | 4 |
| src/test/regress/expected/sqljson_jsontable.out | 21 | 3 |
| src/test/regress/sql/sqljson_jsontable.sql | 5 | 0 |
From 26204e454877601a7fe4993dcc6e7790126ad7d2 Mon Sep 17 00:00:00 2001
From: Amit Langote <amitlan@postgresql.org>
Date: Fri, 30 Aug 2024 12:55:04 +0900
Subject: [PATCH v1 3/3] SQL/JSON: Fix JSON_TABLE() column deparsing
The deparsing code in get_json_expr_options() unnecessarily emitted
the default column-specific ON ERROR / EMPTY behavior when the
top-level ON ERROR behavior in JSON_TABLE was set to ERROR. Fix that
by not overriding the column-specific default, determined based on
the column's JsonExprOp in get_json_table_columns(), with
JSON_BEHAVIOR_ERROR when that is the top-level ON ERROR behavior.
Note that this only removes redundancy; the current deparsing output
is not incorrect, just redundant.
Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
---
src/backend/utils/adt/ruleutils.c | 8 +++----
.../regress/expected/sqljson_jsontable.out | 24 ++++++++++++++++---
src/test/regress/sql/sqljson_jsontable.sql | 5 ++++
3 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 0aa090be20..cd9c3eddd1 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -11719,7 +11719,6 @@ get_json_table_columns(TableFunc *tf, JsonTablePathScan *scan,
bool showimplicit)
{
StringInfo buf = context->buf;
- JsonExpr *jexpr = castNode(JsonExpr, tf->docexpr);
ListCell *lc_colname;
ListCell *lc_coltype;
ListCell *lc_coltypmod;
@@ -11772,6 +11771,10 @@ get_json_table_columns(TableFunc *tf, JsonTablePathScan *scan,
if (ordinality)
continue;
+ /*
+ * Set default_behavior to guide get_json_expr_options() on whether to
+ * to emit the ON ERROR / EMPTY clauses.
+ */
if (colexpr->op == JSON_EXISTS_OP)
{
appendStringInfoString(buf, " EXISTS");
@@ -11795,9 +11798,6 @@ get_json_table_columns(TableFunc *tf, JsonTablePathScan *scan,
default_behavior = JSON_BEHAVIOR_NULL;
}
- if (jexpr->on_error->btype == JSON_BEHAVIOR_ERROR)
- default_behavior = JSON_BEHAVIOR_ERROR;
-
appendStringInfoString(buf, " PATH ");
get_json_path_spec(colexpr->path_spec, context, showimplicit);
diff --git a/src/test/regress/expected/sqljson_jsontable.out b/src/test/regress/expected/sqljson_jsontable.out
index f25d03bc77..1a24e478eb 100644
--- a/src/test/regress/expected/sqljson_jsontable.out
+++ b/src/test/regress/expected/sqljson_jsontable.out
@@ -1158,10 +1158,28 @@ EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') EM
(3 rows)
EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') ERROR ON ERROR);
- QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------
+ 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 '$' NULL ON EMPTY NULL ON ERROR) ERROR ON ERROR)
+ Table Function Call: JSON_TABLE('"a"'::jsonb, '$' AS json_table_path_0 COLUMNS (a text PATH '$') ERROR ON ERROR)
+(3 rows)
+
+-- Test JSON_TABLE() column deparsing -- don't emit default ON ERROR / EMPTY
+-- 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 '$') ERROR 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 '$') ERROR ON ERROR)
(3 rows)
diff --git a/src/test/regress/sql/sqljson_jsontable.sql b/src/test/regress/sql/sqljson_jsontable.sql
index 932a3ecf59..6d2b5be027 100644
--- a/src/test/regress/sql/sqljson_jsontable.sql
+++ b/src/test/regress/sql/sqljson_jsontable.sql
@@ -548,3 +548,8 @@ 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);
EXPLAIN VERBOSE SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') ERROR ON ERROR);
+
+-- Test JSON_TABLE() column deparsing -- don't emit default ON ERROR / EMPTY
+-- 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);
--
2.43.0