From 8ff29ffbd28edbfd78b91383e7f263542b6c029f Mon Sep 17 00:00:00 2001 From: "David E. Wheeler" Date: Mon, 8 Jul 2024 12:08:00 -0400 Subject: [PATCH] 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 d79c9298227a0..bf69f0d824001 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 a6112e86fa7ae..7bb4eb1bc276e 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 5e14f7759bb64..17f9d038c0aa9 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');