[PATCH v1] Match jsonpath variable names exactly when checking mutability

From: Tomás Senart <ts(at)perfloop(dot)ai>
To: pgsql-hackers(at)lists(dot)postgresql(dot)org
Cc: Amit Langote <amitlangote09(at)gmail(dot)com>
Subject: [PATCH v1] Match jsonpath variable names exactly when checking mutability
Date: 2026-11-10 15:12:42
Message-ID: CAEEBa3VS8xnenaeLB_JUu2Nku6w6CLpaRvjf3BbXayfOt+eSbg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

Commit 0f271e8e8d9 made GetJsonPathVar() require an exact match between
a jsonpath variable and a PASSING argument name. The mutability check
in jspIsMutableWalker() still compares only the length of the
variable's name, so an earlier PASSING argument named "aa" can decide
the datatype of $a. CREATE INDEX can then accept an expression whose
result depends on TimeZone, or reject an expression that is immutable.

Reproduction on master (952bab8b74d):

CREATE TABLE t (js jsonb, n int, ts timestamp, tz timestamptz);
INSERT INTO t VALUES ('{}', 1, '2024-01-01', '2024-01-01 00:00:00+00');

SET TimeZone = 'UTC';
CREATE INDEX t_idx ON t ((JSON_EXISTS(js, 'lax $ ? ($a == $b)'
PASSING n AS aa, ts AS a, tz AS b)));
-- succeeds; $a is a timestamp and $b a timestamptz, so the
-- comparison depends on TimeZone

SET TimeZone = 'Asia/Tokyo';
SET enable_seqscan = off;
SELECT count(*) FROM t WHERE JSON_EXISTS(js, 'lax $ ? ($a == $b)'
PASSING n AS aa, ts AS a, tz AS b);
-- 1 (Index Scan using t_idx)

RESET enable_seqscan;
SET enable_indexscan = off;
SET enable_bitmapscan = off;
SELECT count(*) FROM t WHERE JSON_EXISTS(js, 'lax $ ? ($a == $b)'
PASSING n AS aa, ts AS a, tz AS b);
-- 0 (Seq Scan)

With the patch, the CREATE INDEX fails with "functions in index
expression must be marked IMMUTABLE".

The attached patch also requires equal name lengths in
jspIsMutableWalker(), as GetJsonPathVar() does, and adds two
regression tests to sqljson_queryfuncs. The change adds one strlen()
for each PASSING argument that the check examines; it does not change
how expressions are evaluated. make check and make installcheck pass.
The code came with SQL/JSON in 17, so I think it should be back-patched
there.

Indexes whose definitions were incorrectly accepted as immutable can
return wrong results and should be dropped or replaced with expressions
that are truly immutable. REINDEX does not make those definitions
safe. Restoring their current definitions from a dump will now fail at
CREATE INDEX.

The bug was found and fixed by Perfloop. I am the contact. Feel free
to rework the patch however you prefer.

Regards,
Tomás Senart

Attachment Content-Type Size
v1-0001-Match-jsonpath-variable-names-exactly-when-checki.patch text/x-patch 5.0 KB

Browse pgsql-hackers by date

  From Date Subject
Previous Message Mahendrakar Srinivasarao 2026-11-10 14:24:02 Re: [PATCH] doc: Fix description of relative extension "directory" setting