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 1wRKFp-002GIW-3A for pgsql-hackers@arkaria.postgresql.org; Mon, 25 May 2026 01:37:18 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wRKFm-00HOPB-2W for pgsql-hackers@arkaria.postgresql.org; Mon, 25 May 2026 01:37:15 +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 1wRKFm-00HOP3-0W for pgsql-hackers@lists.postgresql.org; Mon, 25 May 2026 01:37:15 +0000 Received: from mail-qk1-x733.google.com ([2607:f8b0:4864:20::733]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wRKFk-00000000dDm-3URQ for pgsql-hackers@lists.postgresql.org; Mon, 25 May 2026 01:37:13 +0000 Received: by mail-qk1-x733.google.com with SMTP id af79cd13be357-90d042fa745so1645911085a.1 for ; Sun, 24 May 2026 18:37:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1779673031; cv=none; d=google.com; s=arc-20240605; b=BwroY/5WKZ/DM21SGnrN6MBziY9rgsVgunHNZbVmaF+06oM5c0/q0j+zF9p/0ggg+Y dyjdccAYB2McHCiKWoyx/hhUHgcpNTFypIBFq1HbIJaqfRukp7KzF4+jUGQPWV/hOJrn MhRynaG6v6nWNLGut1AJJdkjhXlzL9t0DSyXz4KKzQq4aYus1gkdRfKUifd9F5xfTVfe raEdqu6ofEdl2QTygJPfK4aLJgkmb1Zack0KBKHBwSaVPN5onctDoMdG8ynz1nlbGkEZ BrVqzGzyQsV2TNN/qm4LtDLNjmCKTIC0/fsnxt27nYboS/Prhh1VI1db2uHu9rmjcYO5 MSdw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=7Di8f6bDIOmuJpqOjfRULPNHw4FcTVM766J9Nq+H4VE=; fh=SPV9F5v2BJw7N3mhuMzMmgTgm0VrgH5WiLofplhwEgo=; b=RXxZEhDHNMEOTZLrIZPTpuQJihJP0ntaRuWMIazsh/iPCU4wekbKd0DabJuz64yUXk omJBe4bYadgX3L6YTxo0r+G+HLXxbzwHyXn2yWikMQVZiVvQ8jiDaet+gSNxojJHk6EE 2Qtou7h4G7afat0Ze1RPvEGOr6ctGFLR9n4ErpK93IrC1f/Oha3hNqCzLYNRVBIT+jcg FdWbs6mSvL2Dl5YYwwi1yoHf14EXO2eH6uLLtLT+LLhKL4vcOJ8xn3wY7fOJiMdV0Q2t K/jj82Q2JwuFGGQMPRNJViIDWnVHrBjvhs2rHyTvDx4XLrsg31vG671uoswA7BAHJJvf hFkA==; 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=1779673031; x=1780277831; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=7Di8f6bDIOmuJpqOjfRULPNHw4FcTVM766J9Nq+H4VE=; b=rCpw5HiBTlUx7fcqf97nYRikWase+GTgShOrAuw7+E63nnQvtvnv9R3zsNFKufgcv9 ZC/VNpphHX/0UIX0WBeTg96JjEIlIo76J3boe58kZJQ3zLl1fpVf9a6uORKNj130QpKn Imoyk5CO8mUpmMCy/L/CAuEKStVbbY3ex0SLuJixa55DBbQVjzv9FmKeMv9gvKm3XqVK 4qV0WFrpJzeDvLf28ECvylameZed1BnD8KnorzGNat1sXpecYqbnOb1LbazjJQ2HUnfl 7xqVXkO+kNWfOTN/sry1V8IVz7yK/UuwFUUBuP0uz+8CPSBEfmiI+7c2Abg4FUMe0VJ0 3iqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779673031; x=1780277831; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=7Di8f6bDIOmuJpqOjfRULPNHw4FcTVM766J9Nq+H4VE=; b=PCAObOoTw7VEKY65vwmsl4ilBAhzIT6CONQaigT96bRa+rUlrmrtwK/sPoPIVoJfKL 6tc0NCPnrh1YeXUJZK0DMLx4df/aV+XW6pxwtaT6hEN8aW/WBvt/xP5DBee/qlgsDZEG PZSAZ2oEyy5llnBVccbfiEolQwK5XaasWastFpQnVZU5skDzlfs4B+l6IT6j75aY6xTf j+oJTvTXs1bjjHcAxGKOA8UV/Risfy4+gLQz4Go3IoBVi5DikoLcJcxtbQstl7gK/7QV TQKlpGOJymLVhuc7tdyirB6KNUehEr7smHPwBOKXlFvWCi1Vvfk3AoSxY+qQlpxZpJH5 ugOg== X-Forwarded-Encrypted: i=1; AFNElJ+TC8zYBohXfcrAXUMf4Gw+FNnA+uokfR6CrkPjM1yAnU2NKX5EL/VsXShJkUcfUph4XLdcKMHba2Kr6C3F@lists.postgresql.org X-Gm-Message-State: AOJu0YzDrYUH8jM1osSU/zzVm9xpsO9YOssIT5OZDZ6IhnF8+wu4pvna XrylrrsX9CCTDobPm9Wa6kp8GlqWUT0d2ab915B12GOO+Rm5KvljRdh6Up34XHYzo8B/mm3iK9Z YTQI2JWhwIyq+zX9WjhAR8f4HENKN1cE= X-Gm-Gg: Acq92OGiQN6+u7DuN1d25TABNwzbgapewgH3KXOCFNvnCeFM+iDHHjzsYd2UXLwwqxj vxfTQT59ry5jS4grMjFDghGbu1jE8EH9AT85nfc7NfeB27caSeh5WV7a/lWlGDGbdM8fPrKHsrN Qv9mv4ah4XUWujNrejmvPFMtA8pzhkUW1nbYxO0U7/OTPwqhvcKjzlafc3jJI5kpyjjmt5MZoAb yAfxVBPB+JLn32o+Yd1XL+uy9JuXsbAv32f8ThNe+NA0+jnl6jJuT2n4cnNGOT+ZjeB54IY0A7k DPofHgo= X-Received: by 2002:a05:620a:17aa:b0:8da:ec5c:7bf4 with SMTP id af79cd13be357-914b49808f5mr1809828785a.45.1779673030581; Sun, 24 May 2026 18:37:10 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Peter Smith Date: Mon, 25 May 2026 11:36:42 +1000 X-Gm-Features: AVHnY4JYd0xfHACr6pG4QUx1UX-x0KrZGbPsewmOb-Z1Tm81IIEV-bHul5Kz20o Message-ID: Subject: Re: Proposal: Conflict log history table for Logical Replication To: vignesh C Cc: shveta malik , Dilip Kumar , Nisha Moond , Amit Kapila , Masahiko Sawada , Bharath Rupireddy , PostgreSQL Hackers , shveta malik Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi Vignesh, Some review comments for v38-0001/0002 combined. ====== src/backend/commands/subscriptioncmds.c AlterSubscriptionConflictLogDestination: 1. * Update the conflict log table associated with a subscription when its * conflict log destination is changed. Somehow, that 'its' sounded awkward to me. SUGGESTION. When the subscription's 'conflict_log_destination' is changed, update the conflict log table if required. ~~~ 2. + * If the new destination requires a conflict log table and none was previously + * required, this function validates an existing conflict log table identified + * by the subscription specific naming convention or creates a new one. What does this mean: "validates an existing conflict log table". How is there an "existing" CLT when you already said "none was previously required". Maybe this needs more explanation. If it is talking about "not already associated with another subscription", then it should just say that. Anyway, it seems validation that the comment claims this function is doing is not done here at all, but is really done by 'create_conflict_log_table'. ~~~ 3. +static bool +AlterSubscriptionConflictLogDestination(Subscription *sub, + ConflictLogDest logdest, + Oid *conflicttablerelid) 3a. There was no forward declaration of this static function, but there was for all the others. ~ 3b. Static functions should use snake-case names. ~~~ 4. Personally, I think it is more natural to read LEFT-TO-RIGHT, OLD-THEN-NEW, etc., so I felt that the has_oldtable check should always come before want_table. Also, the 'ifs' seemed tricky because it's not obvious what has/need_table combinations are missing. e.g. The following seems easier to me. And probably lots of comments could be moved to here in the code as well, instead of in the function comment. SUGGESTION if (has_old_table) { /* There is a CLT already. */ if (!want_table) { /* Remove it. */ drop_subscription_dependencies(sub->oid, sub->name, sub->conflictlogrelid); update_relid = true; } } else { /* There was no previous CLT. */ if (want_table) { /* Create one. */ relid = create_conflict_log_table(sub->oid, sub->name, sub->owner); update_relid = true; } } ~~~ 5. +static void +drop_subscription_dependencies(Oid subid, char *subname, + Oid subconflictlogrelid) +{ + ObjectAddress object; + char *conflictrelname; + + conflictrelname = get_rel_name(subconflictlogrelid); + + /* + * By using PERFORM_DELETION_SKIP_ORIGINAL, we ensure that only the + * conflict log table is deleted while the subscription remains. + */ + ObjectAddressSet(object, SubscriptionRelationId, subid); + performDeletion(&object, DROP_CASCADE, + PERFORM_DELETION_INTERNAL | + PERFORM_DELETION_SKIP_ORIGINAL); + + ereport(NOTICE, + errmsg("dropped conflict log table \"%s\" for subscription \"%s\"", + get_qualified_objname(PG_CONFLICT_NAMESPACE, conflictrelname), + subname)); +} + One day, this function might do more than just remove the CLT, so IMO all this function body should be within a check: if (OidIsValid(subconflictlogrelid)) { /* Drop any dependent CLT */ ... } ~~~ DropSubscription 6. + if (OidIsValid(subconflictlogrelid)) + drop_subscription_dependencies(subid, subname, subconflictlogrelid); Make it unconditional. Instead, add the condition inside the 'drop_subscription_dependencies', per the previous review comment #5. ====== src/test/regress/sql/subscription.sql 7. +-- +-- PUBLICATION: Verify conflict log tables are not publishable +-- +-- pg_relation_is_publishable should return false for internal conflict log +-- tables to prevent them from being accidentally included in publications +-- Everywhere else, you had removed the word "internal", but this one (maybe others?) was missed. ====== Kind Regards, Peter Smith. Fujitsu Australia