v3-0001-Add-tests-for-jsonpath-.-on-arrays.patch

application/octet-stream

Filename: v3-0001-Add-tests-for-jsonpath-.-on-arrays.patch
Type: application/octet-stream
Part: 0
Message: Re: Patch bug: Fix jsonpath .* on Arrays

Patch

Format: format-patch
Series: patch v3-0001
Subject: Add tests for jsonpath `.*` on arrays
File+
src/backend/utils/adt/jsonpath_exec.c 6 1
src/test/regress/expected/jsonb_jsonpath.out 50 0
src/test/regress/sql/jsonb_jsonpath.sql 11 0
From eefe7a08e7c365082954c0026a13dad41f713744 Mon Sep 17 00:00:00 2001
From: "David E. Wheeler" <david@justatheory.com>
Date: Mon, 8 Jul 2024 12:08:00 -0400
Subject: [PATCH v3] Add tests for jsonpath `.*` on arrays

There was no coverage for the path to unwrap an array before applying
`.*` to it, so add tests that explicitly test `.*` for both objects and
arrays, showing how no results are returned for an array of scalars, but
results are returned when the array contains an object. Also test the
behavior in strict mode with and without the silent parameter, and with
the `@?` operator.

Unrelated but potentially useful to future source readers: document
`GetJsonPathVar` and `CountJsonPathVars`.
---
 src/backend/utils/adt/jsonpath_exec.c        |  7 ++-
 src/test/regress/expected/jsonb_jsonpath.out | 50 ++++++++++++++++++++
 src/test/regress/sql/jsonb_jsonpath.sql      | 11 +++++
 3 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c
index d79c929822..bf69f0d824 100644
--- a/src/backend/utils/adt/jsonpath_exec.c
+++ b/src/backend/utils/adt/jsonpath_exec.c
@@ -2978,7 +2978,8 @@ getJsonPathItem(JsonPathExecContext *cxt, JsonPathItem *item,
 }
 
 /*
- * Returns the computed value of a JSON path variable with given name.
+ * Definition of JsonPathGetVarCallback for when JsonPathExecContext.vars
+ * is specified as a List value.
  */
 static JsonbValue *
 GetJsonPathVar(void *cxt, char *varName, int varNameLen,
@@ -3025,6 +3026,10 @@ GetJsonPathVar(void *cxt, char *varName, int varNameLen,
 	return result;
 }
 
+/*
+ * Definition of JsonPathCountVarsCallback for when JsonPathExecContext.vars
+ * is specified as a List value.
+ */
 static int
 CountJsonPathVars(void *cxt)
 {
diff --git a/src/test/regress/expected/jsonb_jsonpath.out b/src/test/regress/expected/jsonb_jsonpath.out
index a6112e86fa..7bb4eb1bc2 100644
--- a/src/test/regress/expected/jsonb_jsonpath.out
+++ b/src/test/regress/expected/jsonb_jsonpath.out
@@ -1135,6 +1135,56 @@ select jsonb_path_query('{"a": [1, 2]}', 'lax $.a * 3', silent => true);
 ------------------
 (0 rows)
 
+-- any key on arrays with and without unwrapping.
+select jsonb_path_query('{"a": [1,2,3], "b": [3,4,5]}', '$.*');
+ jsonb_path_query 
+------------------
+ [1, 2, 3]
+ [3, 4, 5]
+(2 rows)
+
+select jsonb_path_query('[1,2,3]', '$.*');
+ jsonb_path_query 
+------------------
+(0 rows)
+
+select jsonb_path_query('[1,2,3,{"b": [3,4,5]}]', 'lax $.*');
+ jsonb_path_query 
+------------------
+ [3, 4, 5]
+(1 row)
+
+select jsonb_path_query('[1,2,3,{"b": [3,4,5]}]', 'strict $.*');
+ERROR:  jsonpath wildcard member accessor can only be applied to an object
+select jsonb_path_query('[1,2,3,{"b": [3,4,5]}]', 'strict $.*', NULL, true);
+ jsonb_path_query 
+------------------
+(0 rows)
+
+select jsonb '{"a": [1,2,3], "b": [3,4,5]}' @? '$.*';
+ ?column? 
+----------
+ t
+(1 row)
+
+select jsonb '[1,2,3]' @? '$.*';
+ ?column? 
+----------
+ f
+(1 row)
+
+select jsonb '[1,2,3,{"b": [3,4,5]}]' @? 'lax $.*';
+ ?column? 
+----------
+ t
+(1 row)
+
+select jsonb '[1,2,3,{"b": [3,4,5]}]' @? 'strict $.*';
+ ?column? 
+----------
+ 
+(1 row)
+
 -- extension: boolean expressions
 select jsonb_path_query('2', '$ > 1');
  jsonb_path_query 
diff --git a/src/test/regress/sql/jsonb_jsonpath.sql b/src/test/regress/sql/jsonb_jsonpath.sql
index 5e14f7759b..17f9d038c0 100644
--- a/src/test/regress/sql/jsonb_jsonpath.sql
+++ b/src/test/regress/sql/jsonb_jsonpath.sql
@@ -241,6 +241,17 @@ select jsonb_path_query('{"a": [2, 3, 4]}', 'lax -$.a');
 select jsonb_path_query('{"a": [1, 2]}', 'lax $.a * 3');
 select jsonb_path_query('{"a": [1, 2]}', 'lax $.a * 3', silent => true);
 
+-- any key on arrays with and without unwrapping.
+select jsonb_path_query('{"a": [1,2,3], "b": [3,4,5]}', '$.*');
+select jsonb_path_query('[1,2,3]', '$.*');
+select jsonb_path_query('[1,2,3,{"b": [3,4,5]}]', 'lax $.*');
+select jsonb_path_query('[1,2,3,{"b": [3,4,5]}]', 'strict $.*');
+select jsonb_path_query('[1,2,3,{"b": [3,4,5]}]', 'strict $.*', NULL, true);
+select jsonb '{"a": [1,2,3], "b": [3,4,5]}' @? '$.*';
+select jsonb '[1,2,3]' @? '$.*';
+select jsonb '[1,2,3,{"b": [3,4,5]}]' @? 'lax $.*';
+select jsonb '[1,2,3,{"b": [3,4,5]}]' @? 'strict $.*';
+
 -- extension: boolean expressions
 select jsonb_path_query('2', '$ > 1');
 select jsonb_path_query('2', '$ <= 1');
-- 
2.45.2