diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c index 5c25bc1e430..a758e1a00cb 100644 --- a/src/backend/utils/adt/jsonpath_exec.c +++ b/src/backend/utils/adt/jsonpath_exec.c @@ -2130,14 +2130,15 @@ getJsonPathVariable(JsonPathExecContext *cxt, JsonPathItem *variable, JsonbValue tmp; JsonbValue *v; - if (!vars) - { - value->type = jbvNull; - return; - } - Assert(variable->type == jpiVariable); varName = jspGetString(variable, &varNameLength); + + if (!vars) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("could not find jsonpath variable \"%s\"", + pnstrdup(varName, varNameLength)))); + tmp.type = jbvString; tmp.val.string.val = varName; tmp.val.string.len = varNameLength; diff --git a/src/test/regress/expected/jsonb_jsonpath.out b/src/test/regress/expected/jsonb_jsonpath.out index 6659bc9091a..eafb421c7af 100644 --- a/src/test/regress/expected/jsonb_jsonpath.out +++ b/src/test/regress/expected/jsonb_jsonpath.out @@ -487,6 +487,13 @@ select * from jsonb_path_query('{"a": 10}', '$'); select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)'); ERROR: could not find jsonpath variable "value" +-- the @? and @@ operators supply no variables, so a variable reference +-- must be reported as undefined rather than silently treated as NULL +-- (the latter gave wrong results and could drive unbounded memory use) +select jsonb '42' @? '$"no_such_var"'; +ERROR: could not find jsonpath variable "no_such_var" +select jsonb '42' @@ '$"no_such_var" == 1'; +ERROR: could not find jsonpath variable "no_such_var" select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '1'); ERROR: "vars" argument is not an object DETAIL: Jsonpath parameters should be encoded as key-value pairs of "vars" object. diff --git a/src/test/regress/sql/jsonb_jsonpath.sql b/src/test/regress/sql/jsonb_jsonpath.sql index e0ce509264a..8163fc6713b 100644 --- a/src/test/regress/sql/jsonb_jsonpath.sql +++ b/src/test/regress/sql/jsonb_jsonpath.sql @@ -98,6 +98,11 @@ select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "string")]', silent => select * from jsonb_path_query('{"a": 10}', '$'); select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)'); +-- the @? and @@ operators supply no variables, so a variable reference +-- must be reported as undefined rather than silently treated as NULL +-- (the latter gave wrong results and could drive unbounded memory use) +select jsonb '42' @? '$"no_such_var"'; +select jsonb '42' @@ '$"no_such_var" == 1'; select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '1'); select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '[{"value" : 13}]'); select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '{"value" : 13}');