RE: Simplify code building the LR conflict messages

From: "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>
To: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Álvaro Herrera <alvherre(at)kurilemu(dot)de>, Peter Smith <smithpb2250(at)gmail(dot)com>, 'shveta malik' <shveta(dot)malik(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Subject: RE: Simplify code building the LR conflict messages
Date: 2026-01-16 13:50:18
Message-ID: TY7PR01MB145540C10F511D9AF40CCB395F58DA@TY7PR01MB14554.jpnprd01.prod.outlook.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Dear hackers,

Thanks for giving comments!

I intended to avoid constructing messages and it added some complexity. I
understood codes were hard to accept, attached is a simplified version. All info
like key, local tuple, remote tuple, and replica identity are shown after the
colon with the order. I also tried to reduce changes as much as possible.
Additionally, changes in ReportApplyConflict() are moved to 0002.

BTW, I found that in CT_UPDATE_ORIGIN_DIFFERS and CT_DELETE_ORIGIN_DIFFERS cases
assume localts is available because it can happen only when the commit_timestamp
is tracked. I think the assumption is OK, but can we add Assert(localts) for them?
If acceptable I can add up more top-up patch.

Rest compares DETAIL part for each conflict reasons with HEAD and patched.

CT_MULTIPLE_UNIQUE_CONFLICTS by INSERT:
HEAD)
Key already exists in unique index "foo_pkey", modified locally in transaction 801 at 2026-xxx.
Key (a)=(6); existing local row (6, 6, 6); remote row (6, 7, 8).
Key already exists in unique index "foo_b_key", modified locally in transaction 801 at 2026-xxx.
Key (b)=(7); existing local row (7, 7, 7); remote row (6, 7, 8).
Key already exists in unique index "foo_c_key", modified locally in transaction 801 at 2026-xxx.
Key (c)=(8); existing local row (8, 8, 8); remote row (6, 7, 8).

Patched)
Could not apply remote change: remote row (6, 7, 8).
Key already exists in unique index "foo_pkey", modified locally in transaction 801 at 2026-xxx: key (a)=(6), local row (6, 6, 6).
Key already exists in unique index "foo_b_key", modified locally in transaction 801 at 2026-xxx: key (b)=(7), local row (7, 7, 7).
Key already exists in unique index "foo_c_key", modified locally in transaction 801 at 2026-xxx: key (c)=(8), local row (8, 8, 8).

CT_MULTIPLE_UNIQUE_CONFLICTS by UPDATE:
HEAD)
Key already exists in unique index "foo_pkey", modified locally in transaction 801 at 2026-xxx.
Key (a)=(6); existing local row (6, 6, 6); remote row (6, 7, 8); replica identity (a)=(5).
Key already exists in unique index "foo_b_key", modified locally in transaction 801 at 2026-xxx.
Key (b)=(7); existing local row (7, 7, 7); remote row (6, 7, 8); replica identity (a)=(5).
Key already exists in unique index "foo_c_key", modified locally in transaction 801 at 2026-xxx.
Key (c)=(8); existing local row (8, 8, 8); remote row (6, 7, 8); replica identity (a)=(5).

Patched)
Could not apply remote change: remote row (6, 7, 8), replica identity (a)=(5).
Key already exists in unique index "foo_pkey", modified locally in transaction 804 at 2026-xxx: key (a)=(6), local row (6, 6, 6).
Key already exists in unique index "foo_b_key", modified locally in transaction 804 at 2026-xxx: key (b)=(7), local row (7, 7, 7).
Key already exists in unique index "foo_c_key", modified locally in transaction 804 at 2026-xxx: key (c)=(8), local row (8, 8, 8).

CT_UPDATE_ORIGIN_DIFFERS:
HEAD)
Updating the row that was modified locally in transaction 802 at 2026-xxx.
Existing local row (5, 5, 5); remote row (6, 7, 8); replica identity (a)=(5).

Patched)
Updating the row that was modified locally in transaction 802 at 2026-xxx: local row (5, 5, 5), remote row (6, 7, 8), replica identity (a)=(5).

CT_UPDATE_MISSING:
HEAD)
Could not find the row to be updated.
Remote row (6, 7, 8); replica identity (a)=(6).

Patched)
Could not find the row to be updated: remote row (6, 7, 8), replica identity (a)=(6).

CT_DELETE_ORIGIN_DIFFERS:
HEAD)
Deleting the row that was modified locally in transaction 818 at 2026-xxx.
Existing local row (5, 5, 5); replica identity (a)=(5).

Patched)
Deleting the row that was modified locally in transaction 802 at 2026-xxx: local row (5, 5, 5), replica identity (a)=(5).

CT_UPDATE_DELETED:
HEAD)
The row to be updated was deleted locally in transaction 801 at 2026-xxx.
Remote row (6, 7, 8); replica identity (a)=(5).

Patched)
Could not find the row to be updated: remote row (6, 7, 8), replica identity (a)=(5).
The row to be updated was deleted locally in transaction 801 at 2026-xxx.

CT_DELETE_MISSING:
HEAD)
Could not find the row to be deleted.
Replica identity (a)=(6).

Patched)
Could not find the row to be deleted: replica identity (a)=(6).

Best regards,
Hayato Kuroda
FUJITSU LIMITED

Attachment Content-Type Size
v4-0001-Fix-errdetail-for-logical-replication-conflict.patch application/octet-stream 35.0 KB
v4-0002-Fix-primary-error-message-for-conflicts.patch application/octet-stream 15.4 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Daniil Davydov 2026-01-16 14:10:54 Re: POC: Parallel processing of indexes in autovacuum
Previous Message Movead 2026-01-16 13:28:28 Re: Can we change pg_rewind used without wal_log_hints and data_checksums