| From: | Ishjaap Singh <ishjaap(dot)singh07(at)gmail(dot)com> |
|---|---|
| To: | pgsql-hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Fix jsonpath printing of operations followed by an accessor |
| Date: | 2026-11-10 21:15:52 |
| Message-ID: | CA+Y2BmewUC0FwoZ_ktQFc==G5OBXVqmQjG3T6x+=YVfCNO=HrA@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi hackers,
When a jsonpath operation is followed by an accessor or method and is
itself an operand of another operator, the output function drops its
parentheses, so the printed path means something else:
SELECT '(-$.a).abs() + 1'::jsonpath;
jsonpath
--------------------
(-$."a".abs() + 1)
For {"a": -2} the original path returns 3 and the printed one -1.
Some printed forms can't be read back. '($.a + 1).abs() == 2' prints
as ($."a" + 1.abs() == 2), and on v15 and later reading that back fails
with "trailing junk after numeric literal". "!", "is unknown" and
"exists" followed by an accessor lose their outer parentheses even at
the top level: '(exists ($.a)).type()' prints as exists ($."a").type(),
which fails to parse on every version I tried.
Since pg_dump and pg_get_viewdef() use this output, a view using such a
path returns different results after a dump and restore. I saw that on
master, 19rc1 and 14.24. A jsonpath column holding a value whose printed
form doesn't parse fails to restore: the COPY errors out and the table
comes back empty. With the example above that happens on master and
19rc1; 14.24 accepts its printed form, but not the "exists" one.
The missing parentheses around operations go back to when jsonpath was
added in v12.
The attached patch parenthesizes any operation or predicate that has an
accessor after it, the same way printJsonPathItem() already handles
numeric literals. Output only changes for paths that print wrong today.
The new tests print each kind and compare query results before and
after a reparse; they fail without the code change. make check passes
and pgindent is clean.
I found this with a small fuzzer that prints random jsonpath
expressions and parses the output again. On master, every mismatch it
found was this bug; with the patch, three runs of 20,000 random
expressions found none.
The patch applies to master and REL_17 to REL_19. REL_14 to REL_16 need
small context changes; I can send versions for those if it's going to
be back-patched.
Regards,
Ishjaap Singh
| Attachment | Content-Type | Size |
|---|---|---|
| v1-0001-Fix-jsonpath-printing-of-operations-followed-by-a.patch | application/octet-stream | 8.8 KB |
| From | Date | Subject | |
|---|---|---|---|
| Previous Message | David Geier | 2026-11-10 21:00:08 | Re: Fix GIN pending cleanup race |