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 1wS56t-002wJh-22 for pgsql-hackers@arkaria.postgresql.org; Wed, 27 May 2026 03:39:11 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wS55r-006un1-2E for pgsql-hackers@arkaria.postgresql.org; Wed, 27 May 2026 03:38:08 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wS55r-006umt-1D for pgsql-hackers@lists.postgresql.org; Wed, 27 May 2026 03:38:08 +0000 Received: from mail-qt1-x82e.google.com ([2607:f8b0:4864:20::82e]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wS55p-00000001d1s-3XYv for pgsql-hackers@lists.postgresql.org; Wed, 27 May 2026 03:38:07 +0000 Received: by mail-qt1-x82e.google.com with SMTP id d75a77b69052e-516d634956fso56702671cf.2 for ; Tue, 26 May 2026 20:38:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1779853083; cv=none; d=google.com; s=arc-20240605; b=jxRmo2iuuzfDumwcN9CPwZslysBGfFKuXqubN67/mTf8HSsWNdzbcSI8Evb8Kjn/W+ WaSfmTtlaXCzYU4mveiMLoYHHXAZ5cSRTDwF6vEekfIJGv1tdRU8bwp7LIn3ZSSu5zvc lo5J8fODG42b1LDhRig25oknlSpp3fbqT/Jiciy7hrzAHel/eSJS+E+320Idx2Y+SzsV aFik8dTKh2PkuYb5uHzWqVlymJODaTmmSCwsC/rmRhjtvoq9pwKPJaQ6bsUjlrwdQT6E LbrJBGqwYeM2EAw5TL8845e9G2Uc2RZ2Y5CFUR5+dpgGSrnX9YkTou5HqWR/eBbr4iq5 fhag== 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=h/W1KV6PbAmDVGyO1llUBtsGgb0qMcLoV5iXy6OQJVE=; fh=3zAONOZgXC8DFMJ7cV/A6bX4a+Us2W+otxR77Tj/+eI=; b=B2TgenfByRCXRtSzcMVggt2prA17LMJbRw57960KMBRlD02f4akGqBGTvY4ClCLcVQ 4SR2vGCoBkbBoXV3j48MbsFGbPjnpzyTjo6c/JHypAnN1RSO8XVfubfF2Q80lfqXywue WaiqyGXrd89x6+6/BVIU4es1rDcHK9ij1Mb4mAptKu62IFFyOyUuwGwkAcT0kE3W3D6Y uvxOByQfWWwB4v4mcGRZaax160XyG+csh3XVLBOpKREf7R7K5IZSzlV+HLHuTXCp50r6 PVAPVrsUTXyfmUBD3DKWUIkmmpty2F04qJe91WKgsJCHqUCut8mkonoD9V1u28UqMN4O /yFA==; 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=1779853083; x=1780457883; 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=h/W1KV6PbAmDVGyO1llUBtsGgb0qMcLoV5iXy6OQJVE=; b=koONcH/KWR8rFGrREY/H5ykKzWsG0ccwxb67tlJKa0qiWtu+s8fFCLcWL8UhvfB7i1 tYASziJX33r6xG5aNKaeEWoR8Ds3P/ATqz7KBqEanDwDXCX8mi9Ov3SKF5KdDRQMZki1 yDNk7oHrbJIpuOas/83q3xYwaUCO5lQyM0tuXGKyHFrngnMFb9LDJgajRKWc0mxT76Md CY9Ahn75XB7a+H/ZneoiiAvZEgn56wC2zfM02+LLK9U6xxSew2apKX0YY+yBk8EI76Gp zyQJHfNCABTIjaDhgvdgs12L/lFmbEHyNeOmuyATQXa2Ty8vf8s0QYhv52MYnPKlnKPd EbIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779853083; x=1780457883; 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=h/W1KV6PbAmDVGyO1llUBtsGgb0qMcLoV5iXy6OQJVE=; b=LFJLeyx03PWR286mwvpog1NMZ8NopHYFa16UxVtXGsh8zPiRxb38JVlMuzTIHoJEk7 CMqLIbuvBwFh7XlKYNRfYpg9xEHcUXPpFqpftJU7/ucsO1qLzN31UIAt0R10cE43y/6D Zxps7QeLjSbW4xNvqJ5cWwKdLlmtMe2kGhF+6ZiGNnQWzmCDFWSQYZ6VTDK0/N/8PpiK RMxuaZy4SXCEdbFFpw6rJRTaU+2zUF7oc2pLlXZPZp6dBp0bQ5tPBe/FSYOX7UQ/Sr3m SWMEITzZtNAzk2/MPkN7i1KfgUpE1ifXVyi5xLYVR+Q3yWncFf6YYkIXIPO1v7McqNJE V4Xg== X-Forwarded-Encrypted: i=1; AFNElJ91+oNnYjItb/tL8n+eDSXgfDZnLbvsb/rlGzLayu8ylEH5v93vm/721RfrESDYGi1giU+umK5g6ozMIKRx@lists.postgresql.org X-Gm-Message-State: AOJu0YxSpimakXr4tggAmWmpcUZ5RJgtLlw2HLi7z+NdVbPO+i8q0Agi Az8+ue/upSYxdunOWhkLpBZnDpFmaYy+6V4MEl+c7I5hhDqmSjgZzeqnUbYZC7bGv766EEfHMN7 H1glglLjM5CZF0goHXgty/X4cOjutUfY= X-Gm-Gg: Acq92OFZ8gjiJCFzOZWSR+SV+7i1/QBD0lgVsYXLfnWVyO1GVqODBodJYK9u8oGrzhl ruyKEbRG9pt3KW0WmsRPUELyoRbITYcx1+3Zdm2wZLAzUVXuJmjw178aTjn/3vlbu1EXEi0prq2 Iu4nLoBLGCJDN/P0TotwioSze4u9kXFhdz5nL6tbJ8ifncJm56izqGEq2bnAhmTOu6UYoW9uXTq jG9E3Ey4dp9TFGqcyb1jTM11l8xw6lx2xK5S7ivjymQiDq5qBO9+N9WKKWMX9/oLPc9oCDV3Aq5 vCusn9o= X-Received: by 2002:ac8:7f8a:0:b0:50f:ba44:ce5f with SMTP id d75a77b69052e-516d434044cmr279634811cf.22.1779853083566; Tue, 26 May 2026 20:38:03 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Peter Smith Date: Wed, 27 May 2026 13:37:32 +1000 X-Gm-Features: AVHnY4L3vLlpqs8stWNTiQ60J8FNX-GxeKMIamKDLA-vAgRFGmQjPe6tVXfXnkA Message-ID: Subject: Re: Support EXCEPT for ALL SEQUENCES publications To: Shlok Kyal Cc: shveta malik , vignesh C , 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 Shlok, No more comments for v6-0001. Below are some review comments for v6-0002. ====== doc/src/sgml/ref/alter_publication.sgml 1. SET ALL TABLES can be used to update the tables specified in the EXCEPT clause of a - FOR ALL TABLES publication. If EXCEPT - is specified with a list of tables, the existing exclusion list is replaced - with the specified tables. If EXCEPT is omitted, the - existing exclusion list is cleared. The SET clause, when - used with a publication defined with FOR TABLE or + FOR ALL TABLES publication and + SET ALL SEQUENCES can be used to update the sequences + specified in the EXCEPT clause of a + FOR ALL SEQUENCES publication. If + EXCEPT is specified with a list of tables or sequences, + the existing exclusion list is replaced with the specified tables or + sequences. If EXCEPT is omitted, the existing exclusion + list is cleared. The SET clause, when used with a + publication defined with FOR TABLE or FOR TABLES IN SCHEMA, replaces the list of tables/schemas in the publication with the specified list; the existing tables or schemas that were present in the publication will be removed. TBH, I think this part of the description is repetitive and unnecessarily difficult to read. OTOH, fixing it is probably outside the scope of this patch. Perhaps we can revisit and address all this properly after both your EXCEPT changes and Nisha's EXCEPT [1] changes get combined? ~ Examples: 2. There are many other small examples, so should you also add one also for this syntax? ====== src/backend/catalog/pg_publication.c 3. static List * get_publication_relations(Oid pubid, PublicationPartOpt pub_partopt, - bool except_flag) + bool except_flag, char pubrelkind) IIUC there should be a sanity Assert in this function to check that `pubrelkind` can only be either RELKIND_RELATION or RELKIND_SEQUENCE. ~~~ GetIncludedPublicationRelations: 4. /* * Gets list of relation oids that are associated with a publication. * * This should only be used FOR TABLE publications, the FOR ALL TABLES/SEQUENCES * should use GetAllPublicationRelations(). */ List * GetIncludedPublicationRelations(Oid pubid, PublicationPartOpt pub_partopt) { Assert(!GetPublication(pubid)->alltables); return get_publication_relations(pubid, pub_partopt, false, RELKIND_RELATION); } The comment does not match the code/assert. Shouldn't it also do assert !allsequences? ~~~ GetAllPublicationRelations: 5. exceptlist = GetExcludedPublicationRelations(pubid, pubviaroot ? PUBLICATION_PART_ROOT : - PUBLICATION_PART_LEAF); + PUBLICATION_PART_LEAF, + relkind); IIUC, that `relkind` should be renamed to pubrelkind. ====== src/backend/commands/publicationcmds.c get_delete_rels: 6. +get_delete_rels(Oid pubid, List *rels, List *oldrelids, List **delrels) Add some function comments to describe these parameters. I also wondered if it would be better to return `delrels` from this function instead of void. Let the caller accumulate them. ~~~ 7. + foreach(newlc, rels) + { + PublicationRelInfo *newpubrel; + Oid newrelid; + Bitmapset *newcolumns = NULL; + + newpubrel = (PublicationRelInfo *) lfirst(newlc); + newrelid = RelationGetRelid(newpubrel->relation); + + /* + * Validate the column list. If the column list or WHERE clause + * changes, then the validation done here will be duplicated + * inside PublicationAddRelations(). The validation is cheap + * enough that that seems harmless. + */ + newcolumns = pub_collist_validate(newpubrel->relation, + newpubrel->columns); + + /* + * Check if any of the new set of relations matches with the + * existing relations in the publication. Additionally, if the + * relation has an associated WHERE clause, check the WHERE + * expressions also match. Same for the column list. Drop the + * rest. + */ IIUC, that comment "Check if any of the new..." is really describing the purpose of this entire loop. IMO, this comment would be better put atop the "foreach(newlc, rels)". ~ 8. + if (newrelid == oldrelid) + { + if (equal(oldrelwhereclause, newpubrel->whereClause) && + bms_equal(oldcolumns, newcolumns)) + { + found = true; + break; + } + } + } Consider writing that in a simpler way. SUGGESTION found = (newrelid == oldrelid) && equal(oldrelwhereclause, newpubrel->whereClause) && bms_equal(oldcolumns, newcolumns); if (found) break; ~~~ 9. + /* + * Add the non-matched relations to a list so that they can be + * dropped. + */ + if (!found) + { + oldrel = palloc_object(PublicationRelInfo); + oldrel->whereClause = NULL; + oldrel->columns = NIL; + oldrel->except = false; + oldrel->relation = table_open(oldrelid, + ShareUpdateExclusiveLock); + *delrels = lappend(*delrels, oldrel); + } 9a. There seems to be some implicit knowledge that the later DROP is only going to care about the relation and the other whereClause/columns/etc will have nothing to do with the dropping. Maybe the comment needs to say something abouit that? ~ 9b. Maybe palloc0_object can be used instead of explicitly setting everything else you don't care about to NULL/NIL/false? ~~~ AlterPublicationRelations: 10. /* * Nothing to do if no objects, except in SET: for that it is quite * possible that user has not specified any tables in which case we need * to remove all the existing tables. */ if (!tables && stmt->action != AP_SetObjects) return; ~ The above code comment seems stale because it is not saying anything about sequences, and I think it ought to be. ~~~ 11. + CloseRelationList(seqs); CloseRelationList(rels); Everywhere else rels came before seqs. So maybe reverse these to match. ~~~ PublicationDropRelations: 12. * Remove listed tables from the publication. */ static void -PublicationDropTables(Oid pubid, List *rels, bool missing_ok) +PublicationDropRelations(Oid pubid, List *rels, bool missing_ok) The function comment should mention sequences as well. ====== [1] https://www.postgresql.org/message-id/flat/CAHut%2BPvBjw8JJOksjJsCN%2BU4Lda0vWAQTYaYy7ucuMMr8stj0w%40mail.gmail.com#0f1c9caea31ce84b161ec776fe0994b4 Kind Regards, Peter Smith. Fujitsu Australia