Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3161ae8

Browse files
committed
Fix jsonpath existense checking of missing variables
The current jsonpath code assumes that the referenced variable always exists. It could only throw an error at the value valuation time. At the same time existence checking assumes variable is present without valuation, and error suppression doesn't work for missing variables. This commit makes existense checking trigger an error for missing variables. This makes the overall behavior consistent. Backpatch to 12 where jsonpath was introduced. Reported-by: David G. Johnston Discussion: https://postgr.es/m/CAKFQuwbeytffJkVnEqDyLZ%3DrQsznoTh1OgDoOF3VmOMkxcTMjA%40mail.gmail.com Author: Alexander Korotkov, David G. Johnston Backpatch-through: 12
1 parent c8ad4d8 commit 3161ae8

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

src/backend/utils/adt/jsonpath_exec.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -959,9 +959,13 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
959959
JsonbValue *v;
960960
bool hasNext = jspGetNext(jsp, &elem);
961961

962-
if (!hasNext && !found)
962+
if (!hasNext && !found && jsp->type != jpiVariable)
963963
{
964-
res = jperOk; /* skip evaluation */
964+
/*
965+
* Skip evaluation, but not for variables. We must
966+
* trigger an error for the missing variable.
967+
*/
968+
res = jperOk;
965969
break;
966970
}
967971

src/test/regress/expected/jsonb_jsonpath.out

+32
Original file line numberDiff line numberDiff line change
@@ -2212,6 +2212,14 @@ SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*] ? (@.a > 10)');
22122212
------------------
22132213
(0 rows)
22142214

2215+
SELECT jsonb_path_query('[{"a": 1}]', '$undefined_var');
2216+
ERROR: could not find jsonpath variable "undefined_var"
2217+
SELECT jsonb_path_query('[{"a": 1}]', 'false');
2218+
jsonb_path_query
2219+
------------------
2220+
false
2221+
(1 row)
2222+
22152223
SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a');
22162224
ERROR: JSON object does not contain key "a"
22172225
SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a');
@@ -2282,6 +2290,14 @@ SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].
22822290

22832291
(1 row)
22842292

2293+
SELECT jsonb_path_query_first('[{"a": 1}]', '$undefined_var');
2294+
ERROR: could not find jsonpath variable "undefined_var"
2295+
SELECT jsonb_path_query_first('[{"a": 1}]', 'false');
2296+
jsonb_path_query_first
2297+
------------------------
2298+
false
2299+
(1 row)
2300+
22852301
SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*].a ? (@ > 1)';
22862302
?column?
22872303
----------
@@ -2312,6 +2328,14 @@ SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.
23122328
f
23132329
(1 row)
23142330

2331+
SELECT jsonb_path_exists('[{"a": 1}]', '$undefined_var');
2332+
ERROR: could not find jsonpath variable "undefined_var"
2333+
SELECT jsonb_path_exists('[{"a": 1}]', 'false');
2334+
jsonb_path_exists
2335+
-------------------
2336+
t
2337+
(1 row)
2338+
23152339
SELECT jsonb_path_match('true', '$', silent => false);
23162340
jsonb_path_match
23172341
------------------
@@ -2374,6 +2398,14 @@ SELECT jsonb_path_match('[{"a": 1}, {"a": 2}]', '$[*].a > 1');
23742398
t
23752399
(1 row)
23762400

2401+
SELECT jsonb_path_match('[{"a": 1}]', '$undefined_var');
2402+
ERROR: could not find jsonpath variable "undefined_var"
2403+
SELECT jsonb_path_match('[{"a": 1}]', 'false');
2404+
jsonb_path_match
2405+
------------------
2406+
f
2407+
(1 row)
2408+
23772409
-- test string comparison (Unicode codepoint collation)
23782410
WITH str(j, num) AS
23792411
(

src/test/regress/sql/jsonb_jsonpath.sql

+8
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,8 @@ set time zone default;
532532

533533
SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*]');
534534
SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*] ? (@.a > 10)');
535+
SELECT jsonb_path_query('[{"a": 1}]', '$undefined_var');
536+
SELECT jsonb_path_query('[{"a": 1}]', 'false');
535537

536538
SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a');
537539
SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a');
@@ -547,12 +549,16 @@ SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ == 1)');
547549
SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 10)');
548550
SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 1, "max": 4}');
549551
SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 3, "max": 4}');
552+
SELECT jsonb_path_query_first('[{"a": 1}]', '$undefined_var');
553+
SELECT jsonb_path_query_first('[{"a": 1}]', 'false');
550554

551555
SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*].a ? (@ > 1)';
552556
SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*] ? (@.a > 2)';
553557
SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 1)');
554558
SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.a > $min && @.a < $max)', vars => '{"min": 1, "max": 4}');
555559
SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.a > $min && @.a < $max)', vars => '{"min": 3, "max": 4}');
560+
SELECT jsonb_path_exists('[{"a": 1}]', '$undefined_var');
561+
SELECT jsonb_path_exists('[{"a": 1}]', 'false');
556562

557563
SELECT jsonb_path_match('true', '$', silent => false);
558564
SELECT jsonb_path_match('false', '$', silent => false);
@@ -569,6 +575,8 @@ SELECT jsonb_path_match('[true, true]', '$[*]', silent => false);
569575
SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 1';
570576
SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 2';
571577
SELECT jsonb_path_match('[{"a": 1}, {"a": 2}]', '$[*].a > 1');
578+
SELECT jsonb_path_match('[{"a": 1}]', '$undefined_var');
579+
SELECT jsonb_path_match('[{"a": 1}]', 'false');
572580

573581
-- test string comparison (Unicode codepoint collation)
574582
WITH str(j, num) AS

0 commit comments

Comments
 (0)