From eefe7a08e7c365082954c0026a13dad41f713744 Mon Sep 17 00:00:00 2001 From: "David E. Wheeler" 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