Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wP74t-000S5O-2v for pgsql-hackers@arkaria.postgresql.org; Mon, 18 May 2026 23:08:52 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wP74q-003QvC-2D for pgsql-hackers@arkaria.postgresql.org; Mon, 18 May 2026 23:08:49 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wP74q-003Qv4-0t for pgsql-hackers@lists.postgresql.org; Mon, 18 May 2026 23:08:49 +0000 Received: from mail-qt1-x82a.google.com ([2607:f8b0:4864:20::82a]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wP74o-00000000Ez5-2Afg for pgsql-hackers@lists.postgresql.org; Mon, 18 May 2026 23:08:48 +0000 Received: by mail-qt1-x82a.google.com with SMTP id d75a77b69052e-516389a9b70so34658031cf.3 for ; Mon, 18 May 2026 16:08:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1779145726; cv=none; d=google.com; s=arc-20240605; b=jP/YGWNRiFQSMPqo++jN61q5LQu8g4PHixoXeWdIhNhMTdYPqqe2/d1zlwMX9hR9J7 9XS5yylOO/te7AwHjPQHN7+EtPpRdOhasG5zBD5F5KnFtjJFBUylPEGIi8tGBHcZx97q ddv6Nf4DD5cPIoP3tPp0qGapCdFZZ+VmPK284doOoTuJ1vJ56UVGzMpGVUyuAvolvQSy Y7Z+bbZ3Co4W1rlrXoC75TdUepU37arfq+QtSLYVczWorTkwhLmKuIwxM1SUlUWUobbL CjGqv8GNF/Er34mhX5OXkm2+m4x2lQTb4sUoQyjaxKyYVaeqJ87nWx1oYLJ5OvgyiJ9R Phhg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=to:subject:message-id:date:from:mime-version:dkim-signature; bh=dUlH58qdbLGes3/Dz1Ds2MSs3hVTJ9D5LsOy7AEyjls=; fh=dxJXJbLzq9Nah1LUdsj4QTuQ3JoDScd0wp1YHY64NXM=; b=URUMB+Wssq+Et32YM5Q4G7nKWZv+xEmKCxpEesy/I5pCiVj45Li2uMX4a33P2lN+5U lGpk4nnqZOZClps66EfFEhmSMpO7flxPT72oIwWVU5ZdxIXGxpFSUyWzdCsnMpRk4LGY H+WwMGXT5/uigbPPjJK/VPYRLnSzbdN4n6Amf61f1dBbZ2K2/zE0Fp/RIVtOIKCKvsjT v0RtrzbjbEMEZEw+jbva4Oy5QFBCd4LfZa4SAH5cVPtACf5zjYJ2hhPfdRox4gNIne4B Vl+1H+L+cwvKmRhwnt0H/ZsdakNLZBrZICuWtJzdbP27Fs7eAR/qwd7H0wVYmtjOQFg4 yjVQ==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779145726; x=1779750526; darn=lists.postgresql.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=dUlH58qdbLGes3/Dz1Ds2MSs3hVTJ9D5LsOy7AEyjls=; b=IVawNCxXuQ7+/Cih9Q7Bfk3K+v6iaUaTDE5mYeaYkf3lpyxMlEu6A3jnQTfKbXSCdD SYNvw2px/IMDFR+nvhX9K9gziaes7zWUcTac3rBBnWtT/2oYYE7GmvetsnTGj757L1+C fOmM3lWuHVL2fN1Q27Dx4foC1oFjfMBzEu6adkJCsbAhI6aU8x/XjGfUmNELnJ+vS6my IdToTEM+xvKkSmU6lsZ5fvBJMd5LDjYebqiYvZuzEI3ELgJyZR6R4alXa7ekx+zmtb47 ypTekDS/pR0Z8Uzur86BEjDU6Kks+BSpzeN+NekSUfSX8WgwNLmHRsYiiqfpJTe+tyB4 X/xA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779145726; x=1779750526; h=to:subject:message-id:date:from:mime-version:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=dUlH58qdbLGes3/Dz1Ds2MSs3hVTJ9D5LsOy7AEyjls=; b=Vm0bwtZnSANnINoL/tn3w89t4AFv3P0v3lUSsQHOyTo9TAxnJBwWm0iROCXyPWMAoQ BRJhpzwwZdsnfonyggwlL4XjH76DX5Xe0YuWcm4Hq6iPi2a9itaTMPXrgtYFQNpCvC+c 4CW23DQ2QHhjbfjRQ8gLra0uuN7YL+8x+FFArPitNzo5rU12gKFdnLy5FEB6DACeer+9 xGChd6xUZZ3Ssk1/7sKLdh0S7gXTD9V9OqJh2WYyA9TcGo1WWx0pryIiPk6lWnXm6Exu zAxGpLmraTv5oWti5G7GMO+ZEeIFMAygX9vOkbIv41NBRxA14kvA3m27aLkUKpoOPKY8 d0WA== X-Gm-Message-State: AOJu0Yx9MQ3iqBfkGTEJd3RqS3dBDIq+6BlXU4zGNOy8PmlFbxKKaDeY NAT+P+RR7RbqM4VcH+26VR8qquagA/xjCNf23QxqsGcV/XYjwWAbWVx4A1+j8X3W7qdyJDfg/9j +yjzf/EbvzhxfNdpFFJw/pT8pioNMAvefkymB X-Gm-Gg: Acq92OFZq/ykQDiLwo0YPIuKZzdtCpaqCjaOO6O3dANO2X+dNvj8S+7jDRJZxmBDVra XUoG2mnxKQsNr2ZT/78xolyx5ogu9v7Mhl+Gi5xTH5UeixjDPLnt5Z+VIxsOTo+T4+tOMzstM6e B/650RMh3vOm4q5WkngmjMWKdh8+in7go5xcTFM1x3Kbq82YEaGNbuhGqg0zpi9qfTtyxESBZp8 Qdvs4iwwawsyeI8fnvSmOP9w2vns5PizHopQDhdsANCtfwi7kxKQJkF4WGC5Y7HhzDkqhI4OliJ FsBdVpa2vpwDcS8EVQ== X-Received: by 2002:a05:622a:5910:b0:50f:c5d3:a18c with SMTP id d75a77b69052e-5165a007133mr232972861cf.20.1779145726216; Mon, 18 May 2026 16:08:46 -0700 (PDT) MIME-Version: 1.0 From: Peter Smith Date: Tue, 19 May 2026 09:08:18 +1000 X-Gm-Features: AVHnY4IP5SKaXva4E3ZZJ_Gy9XOSRVKxmhwszXruhZa1Mi_s9sccNeYM0iA0ElY Message-ID: Subject: Make the logical replication conflict messages more like each other To: PostgreSQL Hackers Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi, (This was first suggested by me in thread [1], but it was deemed out of scope, so I have now separated it here.) I was looking at the many messages related to logical replication conflicts (in conflict.c, function errdetail_apply_conflict). Currently, the wording for the errmsgdetail seems a bit inconsistent to me. I felt that because all of these messages are closely related, they should all resemble each other more than they do now. ~~~ CURRENT CT_INSERT_EXISTS CT_UPDATE_EXISTS CT_MULTIPLE_UNIQUE_CONFLICTS * Could not apply remote change: %s.\n * Could not apply remote change.\n - Key already exists in unique index \"%s\", modified locally in transaction %u at %s: %s. - Key already exists in unique index \"%s\", modified locally in transaction %u at %s. - Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s: %s. - Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s. - Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s: %s. - Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s. - Key already exists in unique index \"%s\", modified in transaction %u: %s. - Key already exists in unique index \"%s\", modified in transaction %u. CT_UPDATE_ORIGIN_DIFFERS - Updating the row that was modified locally in transaction %u at %s: %s. - Updating the row that was modified locally in transaction %u at %s. - Updating the row that was modified by a different origin \"%s\" in transaction %u at %s: %s. - Updating the row that was modified by a different origin \"%s\" in transaction %u at %s. - Updating the row that was modified by a non-existent origin in transaction %u at %s: %s. - Updating the row that was modified by a non-existent origin in transaction %u at %s. CT_UPDATE_DELETED * Could not find the row to be updated: %s.\n * Could not find the row to be updated.\n - The row to be updated was deleted locally in transaction %u at %s - The row to be updated was deleted by a different origin \"%s\" in transaction %u at %s - The row to be updated was deleted by a non-existent origin in transaction %u at %s - The row to be updated was deleted CT_UPDATE_MISSING * Could not find the row to be updated: %s. * Could not find the row to be updated. CT_DELETE_ORIGIN_DIFFERS - Deleting the row that was modified locally in transaction %u at %s: %s. - Deleting the row that was modified locally in transaction %u at %s. - Deleting the row that was modified by a different origin \"%s\" in transaction %u at %s: %s. - Deleting the row that was modified by a different origin \"%s\" in transaction %u at %s. - Deleting the row that was modified by a non-existent origin in transaction %u at %s: %s. - Deleting the row that was modified by a non-existent origin in transaction %u at %s. CT_DELETE_MISSING * Could not find the row to be deleted: %s. * Could not find the row to be deleted. ~~~ Some proposed changes: e.g. Only some cases (CT_UPDATE_DELETED, CT_INSERT_EXISTS, CT_UPDATE_EXISTS, etc.) currently give the general reason, followed on the next line by the details for the conflict. I think all these conflict messages should use this pattern e.g. All errdetail messages should have a period to terminate them. e.g. Use more consistent wording for all conflicts: "The row to update", "The row to delete", etc. e.g. The words "the row to be updated" do not need to be repeated for the same conflict message. e.g. The suggested wording makes the messages much closer to the DOCS [2] descriptions (Compare the CURRENT messages above with the following SUGGESTIONS below) SUGGESTIONS (or something like this...) CT_INSERT_EXISTS CT_UPDATE_EXISTS CT_MULTIPLE_UNIQUE_CONFLICTS * The row to insert violates a constraint: %s.\n * The row to insert violates a constraint.\n * The row to update violates a constraint: %s.\n * The row to update violates a constraint.\n * The row to insert or update violates a constraint: %s.\n * The row to insert or update violates a constraint.\n - Key already exists in unique index \"%s\", modified locally in transaction %u at %s: %s. - Key already exists in unique index \"%s\", modified locally in transaction %u at %s. - Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s: %s. - Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s. - Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s: %s. - Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s. - Key already exists in unique index \"%s\", modified in transaction %u: %s. - Key already exists in unique index \"%s\", modified in transaction %u. CT_UPDATE_ORIGIN_DIFFERS * The row to update was modified by another origin.\n - It was modified locally in transaction %u at %s: %s. - It was modified locally in transaction %u at %s. - It was modified by a different origin \"%s\" in transaction %u at %s: %s. - It was modified by a different origin \"%s\" in transaction %u at %s. - It was modified by a non-existent origin in transaction %u at %s: %s. - It was modified by a non-existent origin in transaction %u at %s. CT_UPDATE_DELETED * The row to update was already deleted: %s.\n * The row to update was already deleted.\n - It was deleted locally in transaction %u at %s. - It was deleted by a different origin \"%s\" in transaction %u at %s. - It was deleted by a non-existent origin in transaction %u at %s. CT_UPDATE_MISSING * The row to update was not found: %s. * The row to update was not found. CT_DELETE_ORIGIN_DIFFERS * The row to delete was modified by another origin.\n - It was modified locally in transaction %u at %s: %s. - It was modified locally in transaction %u at %s. - It was modified by a different origin \"%s\" in transaction %u at %s: %s. - It was modified by a different origin \"%s\" in transaction %u at %s. - It was modified by a non-existent origin in transaction %u at %s: %s. - It was modified by a non-existent origin in transaction %u at %s. CT_DELETE_MISSING * The row to delete was not found: %s. * The row to delete was not found. ~~~ Anyway, this is just a suggestion. I won't make the patch for this unless/until there is agreement that proceeding would be worthwhile. ====== [1] https://www.postgresql.org/message-id/CAHut%2BPvicB-bAqo4XpsPOnr%3DLi_jop6i4kpcy%2BVK_MYsEFFeqg%40mail.gmail.com [2] https://www.postgresql.org/docs/devel/logical-replication-conflicts.html Kind Regards, Peter Smith. Fujitsu Australia.