Skip to content

Commit b4cc19a

Browse files
committed
Throw error in jsonb_path_match() when result is not single boolean
jsonb_path_match() checks if jsonb document matches jsonpath query. Therefore, jsonpath query should return single boolean. Currently, if result of jsonpath is not a single boolean, NULL is returned independently whether silent mode is on or off. But that appears to be wrong when silent mode is off. This commit makes jsonb_path_match() throw an error in this case. Author: Nikita Glukhov
1 parent 2e64350 commit b4cc19a

File tree

3 files changed

+80
-9
lines changed

3 files changed

+80
-9
lines changed

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,6 @@ jsonb_path_match(PG_FUNCTION_ARGS)
320320
{
321321
Jsonb *jb = PG_GETARG_JSONB_P(0);
322322
JsonPath *jp = PG_GETARG_JSONPATH_P(1);
323-
JsonbValue *jbv;
324323
JsonValueList found = {0};
325324
Jsonb *vars = NULL;
326325
bool silent = true;
@@ -333,18 +332,27 @@ jsonb_path_match(PG_FUNCTION_ARGS)
333332

334333
(void) executeJsonPath(jp, vars, jb, !silent, &found);
335334

336-
if (JsonValueListLength(&found) < 1)
337-
PG_RETURN_NULL();
338-
339-
jbv = JsonValueListHead(&found);
340-
341335
PG_FREE_IF_COPY(jb, 0);
342336
PG_FREE_IF_COPY(jp, 1);
343337

344-
if (jbv->type != jbvBool)
345-
PG_RETURN_NULL();
338+
if (JsonValueListLength(&found) == 1)
339+
{
340+
JsonbValue *jbv = JsonValueListHead(&found);
341+
342+
if (jbv->type == jbvBool)
343+
PG_RETURN_BOOL(jbv->val.boolean);
344+
345+
if (jbv->type == jbvNull)
346+
PG_RETURN_NULL();
347+
}
348+
349+
if (!silent)
350+
ereport(ERROR,
351+
(errcode(ERRCODE_SINGLETON_JSON_ITEM_REQUIRED),
352+
errmsg(ERRMSG_SINGLETON_JSON_ITEM_REQUIRED),
353+
errdetail("expression should return a singleton boolean")));
346354

347-
PG_RETURN_BOOL(jbv->val.boolean);
355+
PG_RETURN_NULL();
348356
}
349357

350358
/*

src/test/regress/expected/jsonb_jsonpath.out

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1769,6 +1769,57 @@ SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.
17691769
f
17701770
(1 row)
17711771

1772+
SELECT jsonb_path_match('true', '$', silent => false);
1773+
jsonb_path_match
1774+
------------------
1775+
t
1776+
(1 row)
1777+
1778+
SELECT jsonb_path_match('false', '$', silent => false);
1779+
jsonb_path_match
1780+
------------------
1781+
f
1782+
(1 row)
1783+
1784+
SELECT jsonb_path_match('null', '$', silent => false);
1785+
jsonb_path_match
1786+
------------------
1787+
1788+
(1 row)
1789+
1790+
SELECT jsonb_path_match('1', '$', silent => true);
1791+
jsonb_path_match
1792+
------------------
1793+
1794+
(1 row)
1795+
1796+
SELECT jsonb_path_match('1', '$', silent => false);
1797+
ERROR: singleton SQL/JSON item required
1798+
DETAIL: expression should return a singleton boolean
1799+
SELECT jsonb_path_match('"a"', '$', silent => false);
1800+
ERROR: singleton SQL/JSON item required
1801+
DETAIL: expression should return a singleton boolean
1802+
SELECT jsonb_path_match('{}', '$', silent => false);
1803+
ERROR: singleton SQL/JSON item required
1804+
DETAIL: expression should return a singleton boolean
1805+
SELECT jsonb_path_match('[true]', '$', silent => false);
1806+
ERROR: singleton SQL/JSON item required
1807+
DETAIL: expression should return a singleton boolean
1808+
SELECT jsonb_path_match('{}', 'lax $.a', silent => false);
1809+
ERROR: singleton SQL/JSON item required
1810+
DETAIL: expression should return a singleton boolean
1811+
SELECT jsonb_path_match('{}', 'strict $.a', silent => false);
1812+
ERROR: SQL/JSON member not found
1813+
DETAIL: JSON object does not contain key "a"
1814+
SELECT jsonb_path_match('{}', 'strict $.a', silent => true);
1815+
jsonb_path_match
1816+
------------------
1817+
1818+
(1 row)
1819+
1820+
SELECT jsonb_path_match('[true, true]', '$[*]', silent => false);
1821+
ERROR: singleton SQL/JSON item required
1822+
DETAIL: expression should return a singleton boolean
17721823
SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 1';
17731824
?column?
17741825
----------

src/test/regress/sql/jsonb_jsonpath.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,18 @@ SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 1)');
366366
SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.a > $min && @.a < $max)', vars => '{"min": 1, "max": 4}');
367367
SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.a > $min && @.a < $max)', vars => '{"min": 3, "max": 4}');
368368

369+
SELECT jsonb_path_match('true', '$', silent => false);
370+
SELECT jsonb_path_match('false', '$', silent => false);
371+
SELECT jsonb_path_match('null', '$', silent => false);
372+
SELECT jsonb_path_match('1', '$', silent => true);
373+
SELECT jsonb_path_match('1', '$', silent => false);
374+
SELECT jsonb_path_match('"a"', '$', silent => false);
375+
SELECT jsonb_path_match('{}', '$', silent => false);
376+
SELECT jsonb_path_match('[true]', '$', silent => false);
377+
SELECT jsonb_path_match('{}', 'lax $.a', silent => false);
378+
SELECT jsonb_path_match('{}', 'strict $.a', silent => false);
379+
SELECT jsonb_path_match('{}', 'strict $.a', silent => true);
380+
SELECT jsonb_path_match('[true, true]', '$[*]', silent => false);
369381
SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 1';
370382
SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 2';
371383
SELECT jsonb_path_match('[{"a": 1}, {"a": 2}]', '$[*].a > 1');

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy