| From: | WGH <wgh(at)bushwhackers(dot)ru> |
|---|---|
| To: | pgsql-hackers(at)lists(dot)postgresql(dot)org |
| Subject: | Confusing behaviour of UPDATE together with FOR UPDATE subquery |
| Date: | 2026-08-24 20:35:57 |
| Message-ID: | 427b5a91-5233-4f2f-b7c3-a3c7790135f8@bushwhackers.ru |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hello!
I have recently encountered weird PostgreSQL behaviour which might be a bug (or not).
In short, it seems like a SELECT subquery with FOR UPDATE clause might silently skip rows if they're being updated by top-level UPDATE statement.
The following example simulates a job dependency graph. The
CREATE TYPE pg_temp.status AS ENUM('waiting', 'ready', 'done');
CREATE TABLE pg_temp.jobs(
job_id BIGSERIAL PRIMARY KEY,
status status NOT NULL DEFAULT 'waiting'
);
CREATE TABLE pg_temp.jobs_dependencies(
dependent BIGSERIAL REFERENCES jobs(job_id),
dependency BIGSERIAL REFERENCES jobs(job_id)
);
INSERT INTO jobs(job_id) VALUES
(1),
(20),
(21);
INSERT INTO jobs_dependencies(dependent, dependency) VALUES
(20, 1),
(21, 1);
UPDATE jobs AS dependent
SET status='ready'
WHERE
status='waiting'
AND TRUE = ALL (
SELECT (
dependency.status = 'done'
)
FROM jobs AS dependency, jobs_dependencies
WHERE jobs_dependencies.dependency = dependency.job_id AND
jobs_dependencies.dependent = dependent.job_id
FOR UPDATE OF dependency
);
SELECT * FROM jobs;
The result is wrong:
job_id | status
--------+--------
1 | ready
20 | ready
21 | ready
(3 rows)
The expected result, which is returned if you comment out "FOR UPDATE" clause, is this:
job_id | status
--------+---------
20 | waiting
21 | waiting
1 | ready
(3 rows)
I've asked some LLMs about this. I'll spare you of the details, but they came to the conclusion this is caused by TM_SelfModified handling in ExecLockRows.
Is this a bug that TM_SelfModified causes a SELECT ... FOR UPDATE subquery to skip rows silently, even though it was supposed to affect UPDATE itself only?
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Mihail Nikalayeu | 2026-08-24 20:50:45 | Re: Apply worker can pick an invalid index for REPLICA IDENTITY FULL lookups |
| Previous Message | Dmitry Dolgov | 2026-08-24 20:03:56 | Re: Randomize B-Tree page split location to avoid oscillating patterns |