Re: Bug in jsonb_path_exists (maybe _match) one-element scalar/variable jsonpath handling

Поиск
Список
Период
Сортировка
От Alexander Korotkov
Тема Re: Bug in jsonb_path_exists (maybe _match) one-element scalar/variable jsonpath handling
Дата
Msg-id CAPpHfdvuHTjZLOWy1BEr0b1qw=mNXqw0OEndnLsdaw85ftDc-A@mail.gmail.com
обсуждение исходный текст
Ответ на Bug in jsonb_path_exists (maybe _match) one-element scalar/variable jsonpath handling  ("David G. Johnston" <david.g.johnston@gmail.com>)
Ответы Re: Bug in jsonb_path_exists (maybe _match) one-element scalar/variable jsonpath handling
Re: Bug in jsonb_path_exists (maybe _match) one-element scalar/variable jsonpath handling
Список pgsql-bugs
Hi, David!

Thank you for the report.

On Thu, Nov 24, 2022 at 8:31 AM David G. Johnston
<david.g.johnston@gmail.com> wrote:
> The following query produces an incorrect result.  It should error (or at worse produce "false"), but it instead
produces"true" (this applies to @? too) 
>
> select jsonb_path_exists('{"foo": true}'::jsonb, '$bar', '{}', false);

Yes, this definitely looks incorrect.

> Specifically, since exists doesn't care about values, just presence, found is false, and since the variable is the
onlything present, hasNext is also false.  Thus we simply return jperOK without ever checking to see what the variable
actuallyis. This results in the exists code producing a true result. 
>
> Looking at this more, it isn't just the variable case that ends up producing the wrong answer.  Going by the
principlethat any function call of jsonb_path_exists that returns true should produce said match when executing
jsonb_path_match,this is also broken for the rest (probably) of the matched types in the case group.  And indeed, if
thevariable "bar" is defined the error in the match case just changes to "single boolean result is expected". 

Variable case is definitely broken, but I don't think other cases are
broken.  If we're checking for existence and there is a constant, we
can immediately return true because constant exists indeed.  That
logic doesn't work for variable, which could be non-existent.

> select jsonb_path_exists('{"foo": true}'::jsonb, '"bar"', '{}', false); -- true (bar in double quotes)
> select jsonb_path_match('{"foo": true}'::jsonb, '"bar"', '{}', false); -- ERROR:  single boolean result is expected
> select jsonb_path_match('{"foo": true}'::jsonb, '$bar', '{"bar":"foo"}', false); -- same error as above, as expected
>
> I expect the missing variable specification to produce jperError and the rest of the block to produce jperNotFound.
The"single boolean result expected" error seems incorrect though I'm not sure where that is coming from.  But I'm also
notconsidering, or am even aware of, what the standard we are guided by here says should actually happen. 

I think jsonb_path_match() behaves correctly, it expects jsonpatch
expression to return single boolend and throws an error otherwise.
BTW, do you mean something like this: jsonb_path_match() equivalent to
jsonb_path_match() expression?

select jsonb_path_match('{"foo": true}'::jsonb, 'exists($bar)',
'{"bar":"foo"}', false);

Draft patch fixing the issue is attached.  Let me know what you think
about this.

------
Regards,
Alexander Korotkov

Вложения

В списке pgsql-bugs по дате отправления:

Предыдущее
От: Amit Kapila
Дата:
Сообщение: Re: Incorrect messages emitted from pgoutput when using column lists
Следующее
От: "David G. Johnston"
Дата:
Сообщение: Re: Bug in jsonb_path_exists (maybe _match) one-element scalar/variable jsonpath handling