aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dunstan <andrew@dunslane.net>2024-06-17 10:31:29 -0400
committerAndrew Dunstan <andrew@dunslane.net>2024-06-17 10:31:29 -0400
commit653d3969bb013f14c4a6884a253ad9676caf8166 (patch)
treec12871a8d357b249f3a3ee8268883d2febcce932
parent81d20fbf7a03f5e385700c90aec883c96b32ddc6 (diff)
downloadpostgresql-653d3969bb013f14c4a6884a253ad9676caf8166.tar.gz
postgresql-653d3969bb013f14c4a6884a253ad9676caf8166.zip
Teach jsonpath string() to unwrap in lax mode
This was an ommission in commit 66ea94e, and brings it into compliance with both other methods and the standard. Per complaint from David Wheeler. Author: David Wheeler, Jeevan Chalke Reviewed-by: Chapman Flack Discussion: https://postgr.es/m/A64AE04F-4410-42B7-A141-7A7349260F4D@justatheory.com
-rw-r--r--doc/src/sgml/func.sgml5
-rw-r--r--src/backend/utils/adt/jsonpath_exec.c3
-rw-r--r--src/test/regress/expected/jsonb_jsonpath.out12
-rw-r--r--src/test/regress/sql/jsonb_jsonpath.sql1
4 files changed, 19 insertions, 2 deletions
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 17c44bc3384..2609269610b 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -17792,7 +17792,10 @@ ERROR: jsonpath member accessor can only be applied to an object
methods available in <type>jsonpath</type>. Note that while the unary
operators and methods can be applied to multiple values resulting from a
preceding path step, the binary operators (addition etc.) can only be
- applied to single values.
+ applied to single values. In lax mode, methods applied to an array will be
+ executed for each value in the array. The exceptions are
+ <literal>.type()</literal> and <literal>.size()</literal>, which apply to
+ the array itself.
</para>
<table id="functions-sqljson-op-table">
diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c
index ceb30033e1c..c30d059a762 100644
--- a/src/backend/utils/adt/jsonpath_exec.c
+++ b/src/backend/utils/adt/jsonpath_exec.c
@@ -1606,6 +1606,9 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
JsonbValue jbv;
char *tmp = NULL;
+ if (unwrap && JsonbType(jb) == jbvArray)
+ return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
+
switch (JsonbType(jb))
{
case jbvString:
diff --git a/src/test/regress/expected/jsonb_jsonpath.out b/src/test/regress/expected/jsonb_jsonpath.out
index c3f8e8249db..a6112e86fa7 100644
--- a/src/test/regress/expected/jsonb_jsonpath.out
+++ b/src/test/regress/expected/jsonb_jsonpath.out
@@ -2525,7 +2525,10 @@ select jsonb_path_query('null', '$.string()', silent => true);
(0 rows)
select jsonb_path_query('[]', '$.string()');
-ERROR: jsonpath item method .string() can only be applied to a bool, string, numeric, or datetime value
+ jsonb_path_query
+------------------
+(0 rows)
+
select jsonb_path_query('[]', 'strict $.string()');
ERROR: jsonpath item method .string() can only be applied to a bool, string, numeric, or datetime value
select jsonb_path_query('{}', '$.string()');
@@ -2576,6 +2579,13 @@ select jsonb_path_query('1234', '$.string().type()');
"string"
(1 row)
+select jsonb_path_query('[2, true]', '$.string()');
+ jsonb_path_query
+------------------
+ "2"
+ "true"
+(2 rows)
+
select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp().string()');
ERROR: cannot convert value from timestamptz to timestamp without time zone usage
HINT: Use *_tz() function for time zone support.
diff --git a/src/test/regress/sql/jsonb_jsonpath.sql b/src/test/regress/sql/jsonb_jsonpath.sql
index cbd2db533d4..5e14f7759bb 100644
--- a/src/test/regress/sql/jsonb_jsonpath.sql
+++ b/src/test/regress/sql/jsonb_jsonpath.sql
@@ -586,6 +586,7 @@ select jsonb_path_query('"1.23aaa"', '$.string()');
select jsonb_path_query('1234', '$.string()');
select jsonb_path_query('true', '$.string()');
select jsonb_path_query('1234', '$.string().type()');
+select jsonb_path_query('[2, true]', '$.string()');
select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp().string()');
select jsonb_path_query_tz('"2023-08-15 12:34:56 +5:30"', '$.timestamp().string()'); -- should work
select jsonb_path_query_array('[1.23, "yes", false]', '$[*].string()');