Re: Fix replica identity checks for MERGE command on published table.
Dean Rasheed <dean.a.rasheed@gmail.com>
From: Dean Rasheed <dean.a.rasheed@gmail.com>
To: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Cc: "Zhijie Hou (Fujitsu)" <houzj.fnst@fujitsu.com>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2025-07-07T17:17:40Z
Lists: pgsql-hackers
On Mon, 14 Apr 2025 at 05:40, Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> wrote: > > I was wondering whether we should mention MERGE somewhere in the error > message like "cannot merge into table ...". But the error message is > reported depending upon the actual operation being performed and > whether it's being published by the publication, so mentioning > specific operations is better than mentioning just MERGE. So I think > the current error message is ok; and it will help point out the > operations that caused it. Yes, agreed. The error messages seem clear enough to me. > But that opens up another question: some merge operations (on the same > table) will go through and some won't if the publication publishes > only some of the operations. I am wondering, albeit quite late after > the feature has sailed, whether MERGE should be considered a separate > operation as far as publication is concerned. This topic may have been > discussed either when MERGE was implemented or when operation filters > were implemented. Sorry for the noise in that case. I don't know if it was discussed at the time, but to me the way it has been done makes sense, because replication is happening at a lower level -- individual row INSERTs, UPDATEs and DELETEs using rows identified by the replica identity key. If you tried to do it at the level of MERGE, I think it would be difficult to guarantee the same results on the replica. This makes me wonder though, does INSERT ... ON CONFLICT DO UPDATE have the same problem as MERGE? If I create a table and publication like this: CREATE TABLE foo (a int PRIMARY KEY, b text, c int); INSERT INTO foo VALUES (1, 'xxx', 10); CREATE PUBLICATION pub1 FOR TABLE foo WHERE (c > 0); plain UPDATEs are rejected: UPDATE foo SET b = 'yyy' WHERE a = 1; ERROR: cannot update table "foo" DETAIL: Column used in the publication WHERE expression is not part of the replica identity. However, INSERT ... ON CONFLICT DO UPDATE can be used to achieve the same thing: INSERT INTO foo VALUES (1) ON CONFLICT (a) DO UPDATE SET b = 'yyy'; This isn't rejected, and it replicates the change to the subscriber correctly, which makes me wonder, why do we need this restriction on filter columns? If there is some other situation where it's needed, should INSERT ... ON CONFLICT DO UPDATE also check it? Regards, Dean
Commits
-
Fix replica identity check for MERGE.
- 5481cc332b0f 15.15 landed
- 421d7a157985 16.11 landed
- 76f45be9315b 17.7 landed
- 311340f17863 18.0 landed
- fc6600fc1cd1 19 (unreleased) landed
-
Fix replica identity check for INSERT ON CONFLICT DO UPDATE.
- 0610b843c971 13.23 landed
- 5fd569ef2d62 14.20 landed
- 451b22efd9ac 15.15 landed
- 0c4d5a45dbd7 16.11 landed
- 0b934d3994ff 17.7 landed
- 344662848ac1 18.0 landed
- 5386bfb9c1f5 19 (unreleased) landed