Teach jsonpath string() to unwrap in lax mode
authorAndrew Dunstan <[email protected]>
Mon, 17 Jun 2024 14:31:29 +0000 (10:31 -0400)
committerAndrew Dunstan <[email protected]>
Mon, 17 Jun 2024 14:31:29 +0000 (10:31 -0400)
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

doc/src/sgml/func.sgml
src/backend/utils/adt/jsonpath_exec.c
src/test/regress/expected/jsonb_jsonpath.out
src/test/regress/sql/jsonb_jsonpath.sql

index 17c44bc33846449a311b97f807852b5fe659278b..2609269610b27e60876b9386442f1fa2036210ed 100644 (file)
@@ -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">
index ceb30033e1c6632b716209876a9c6a16570afd86..c30d059a7627292a6cf2cc9e2985efea24e3721a 100644 (file)
@@ -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:
index c3f8e8249dbfe6939b0a305f869a172485d07a7d..a6112e86fa7ae17f725516f2e89f5ec24b8ec2e2 100644 (file)
@@ -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.
index cbd2db533d40f015cedcd0bf9c03826fb9c78d61..5e14f7759bb64cc51d3acbf7798ed3be968f60d5 100644 (file)
@@ -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()');