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 1w2kal-000Z8T-2L for pgsql-hackers@arkaria.postgresql.org; Wed, 18 Mar 2026 06:41:19 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w2kak-008647-1m for pgsql-hackers@arkaria.postgresql.org; Wed, 18 Mar 2026 06:41:18 +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 1w2kak-00863s-0T for pgsql-hackers@lists.postgresql.org; Wed, 18 Mar 2026 06:41:18 +0000 Received: from mail-qt1-x833.google.com ([2607:f8b0:4864:20::833]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w2kag-00000000JVs-3Crx for pgsql-hackers@lists.postgresql.org; Wed, 18 Mar 2026 06:41:17 +0000 Received: by mail-qt1-x833.google.com with SMTP id d75a77b69052e-50934b8ab60so6473561cf.0 for ; Tue, 17 Mar 2026 23:41:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1773816075; cv=none; d=google.com; s=arc-20240605; b=c1LCNmmkGQMAsiVcgzM033blyCy/B4EmP9jrvHmszjVBlCDUWlR6NlgM2x0Vov4HDn h6pelGbtL4E55AijEeqPhscZoWtMbtrfTwDgkbCfTjl9pavjxDe8Ehj0ZLOAc8kzH8wA jIMcOsFaANiBtK4WLZ12GJqCxxMUVdifscyZ82GvBgdqm3rIwBdH4dgMslm+GQhVKRuO JRtGKMGQmVD7wZsVsJvl1XwOODAA+1jdf3OnhhXGduIc32DuNgJDKkgRxB/LyBtXT7// 2kwzYc4TLyQsriL4nmnxa0qMfRbyhjE4JyOYsLkRekso5EXiz2X8XdxsuI3L892tJD5k tQFQ== 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=qRsB2DVZ7E5HpjNFlE2vtA2cCvyjoEGq9cn0Tm8nvrw=; fh=D517EFmx6sXubj3OT0PbBPahPyr80FGGNe+XfIgkIm0=; b=A2npVbL0I+eLTMPNSXVNOYTZ7sySl5ECSggYFerxdZ6Im2Re2VI552mADFyYWNLTEE ycuRZ40ZvMIwXw5jt0PNsDVSzBPO/6qXUfjumZKxHYpuVV0YxLAFk6RcGh9QuylA+9cC 1ypdbHDVf0Y3fIOr4aasIYFCOBlkoeEnh6ErGPlWpJ4PMIqWlehh0JMjOroUywqZDIBu VLeLxNxkJsyeZIJt6il1ZFBNGSpYVcm9du30za+YMn98ObtHHJw2CGNa5N03zw6/SwQh SRZ7IsOwXiSxCI63vABBBZvQCPJo4+CY0LJZs+att8qzwGzzQL4Vx5AxrI0QvCT/dGfE 7jDA==; 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=20230601; t=1773816075; x=1774420875; 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=qRsB2DVZ7E5HpjNFlE2vtA2cCvyjoEGq9cn0Tm8nvrw=; b=MYWOV7GS7IWBaBkZicVDvJ6kqMqs23WWsyDQo3hMhbpGrdBJ60fT5Wra2q1v9Jn+ZG +RaWT1itN9Hji5xpPR10GyuzwL6BhPJz+dmVJepHgak1tDEr4JBaQmtHB8p5mQ9rK/Rs h1Jepf74AFKUFhgRR5Ax7Q51+Ge9Z/vE+5dnH5zCEBiAOInBM3NnUl0j5TASbwn46D1Q V6k2GdXlKBD2fMwNFhnrTSrzPIbJYv2lrZCkt7/Tj9x9T/2ejT+hVR1/takgn4jt/w8t JK4OP+Evnf6EZCdaSIO1OsOZ1TpRao8w8GeswziucdNY/7cJyM71DHYwwQlLxIvyL9CA etCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773816075; x=1774420875; 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=qRsB2DVZ7E5HpjNFlE2vtA2cCvyjoEGq9cn0Tm8nvrw=; b=e+SvKln0w6L+6f4xgLN/aQfODe14iVT8hFfppyHKW5OasGXh+4DX+7gT1wpOJtsiIb ztM+XV+/m6Beowz8R7X1+L/eK60Kf+EpiTbvIktzOx0Ul2dcCwIxkpdSl6qOy+eOa3v+ D3mhpNuQI4gjTK1kLKfb9SLdNNZnXkpKwSkTkBYS8W4rHiYrz2xL6WFJ8XJDiPEYerrI XcpE6+0qoIbn5TpKp0my9xRWEUNboLUiXBBV3nEahokaVKAcAdFTKOJSZGSXfkfN0XWP aioQlSUje4j3yUISySWnQu7qjfyTKsA9MYNtTnAJIThDqtq8pMbKCFUivtBfpVwUSBED vMPg== X-Forwarded-Encrypted: i=1; AJvYcCViafpT2lp/1RBv6fB4tH0+D7uOYP4q+ZQexmhHgdRJ0IK96TDdd5oykG9SNiXPO00hexDXwPOA4jY3gC70@lists.postgresql.org X-Gm-Message-State: AOJu0YyeR3ESUg368lKEJZgTeARoff43p8whLe6CXlrt2mrum4IzqKou EVkB10WB7zfe9o/daNThifH8lQmz1gHTUbSMI8l11KqP80F+3v3oLo/AiUGB05qgYKAae8XXMbY 0hmjbF2NQr/9M2fUnsCE1JDsqLkIiK60= X-Gm-Gg: ATEYQzxkfZVmRoaHVMRF7KfNwq7WX4PBw464gAcF+rChS5fW+XnIoRBoScGijGzcfXK HdcuKcsV6HeCgZwu1g743ixw4H0/VbSc4minQLT4Rn98wCUztC99RYCvAJJTq4D8CP9AoA8/m8g yp6vUNZ+Q3Hp8rgDvPumCXm8j/VodHA0cNLx72DC8oc6eE7UYApuGHoYTRJgz0nNuu/0UzmMICv f/RCGH3rgT5rIHH8aVSqV3iu36N9jcsDAMTsrT5Aeh+zrTILzoIvctS/H7edP51aLtLozqIeSLj hMBnhiw= X-Received: by 2002:a05:622a:14d:b0:509:1688:f8cf with SMTP id d75a77b69052e-50b135de1edmr31942371cf.0.1773816075403; Tue, 17 Mar 2026 23:41:15 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Peter Smith Date: Wed, 18 Mar 2026 17:40:48 +1100 X-Gm-Features: AaiRm51X8p_5WqwfMyNK2HHkyyFJ72xk9jL9BjWCL9w7kYkS2n8ooZ_eqvWSGic Message-ID: Subject: Re: Skipping schema changes in publication To: vignesh C Cc: shveta malik , Amit Kapila , Masahiko Sawada , "Hayato Kuroda (Fujitsu)" , Shlok Kyal , Nisha Moond , Ashutosh Sharma , "David G. Johnston" , Dilip Kumar , "Zhijie Hou (Fujitsu)" , YeXiu <1518981153@qq.com>, Ian Lawrence Barwick , Bharath Rupireddy , 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 Vignesh. Some review comments for patch v65-0001. ====== doc/src/sgml/ref/alter_publication.sgml 1. It seems that SET ALL TABLES is not supported if the publication already has FOR TABLE. e.g alter publication pub1 set all tables; ERROR: publication "pub1" does not support ALL TABLES operations DETAIL: This operation requires the publication to be defined as FOR ALL TABLES/SEQUENCES or to be empty. e.g. alter publication pub2 set table t1; ERROR: publication "pub2" is defined as FOR ALL TABLES DETAIL: Tables or sequences cannot be added to or dropped from FOR ALL TABLES publications. I am not going to debate what rules are right or wrong. (Some rules do seem a bit ad-hoc to me, but maybe they are just erring on the safety side). But my point is that the documentation does not seem to say anything much about what the rules are e.g. it says "Adding/Setting any schema when the publication also publishes a table with a column list, and vice versa is not supported.", but OTOH it says nothing about what is supported/unsupported for SET ALL TABLES. ====== src/backend/catalog/pg_publication.c 2. +/* + * Returns true if the publication has explicitly included relation (i.e., + * not marked as EXCEPT). + */ +bool +is_table_publication(Oid pubid) To me, an "explicitly included relation" is like when you say "FOR TABLE t1", where the "t1" is explicitly named. So it's not very clear whether you consider "FOR ALL TABLES" or a "FOR TABLES IN SCHEMA" publication explicitly includes tables or not? The function comment needs to be clearer. ~~~ publication_add_relation: 3. + /* + * Determine whether EXCEPT tables require explicit relcache invalidation. + * + * For CREATE PUBLICATION with EXCEPT tables, invalidation is not needed, + * since it is handled when marking the publication as ALL TABLES. + * + * For ALTER PUBLICATION, invalidation is needed only when adding an EXCEPT + * table to a publication already marked as ALL TABLES. For publications + * that were originally empty or defined as ALL SEQUENCES and are being + * converted to ALL TABLES, invalidation is skipped here, as it is handled + * when marking the publication as ALL TABLES. + */ + inval_except_table = (stmt != NULL) && + (stmt->for_all_tables == pub->alltables); 3a. Why is this code done at the top of the function? Can you move it to be adjacent to where it is getting used? ~ 3b. I think 'alter_stmt' or 'alter_pub_stmt' might be a more informative name here, instead of the generic 'stmt' ====== src/backend/commands/publicationcmds.c 4. - TransformPubWhereClauses(rels, queryString, pubform->pubviaroot); + if (isexcept) + oldrelids = GetExcludedPublicationTables(pubid, + PUBLICATION_PART_ROOT); + else + { + oldrelids = GetIncludedPublicationRelations(pubid, + PUBLICATION_PART_ROOT); I felt there were some subtle things that the logic is using here: e.g. It seems that because this function is called... And because it is SET .... And because it is SET ALL TABLES ... Then, the tables can only be those in the EXCEPT TABLE list Maybe more comments about 'isexcept', and maybe an Assert(oldrelids != NIL); could help here (??) ~~~ AlterPublicationAllFlags: 5. + bool nulls[Natts_pg_publication]; + bool replaces[Natts_pg_publication]; + Datum values[Natts_pg_publication]; + bool dirty = false; + + if (!stmt->for_all_tables && !stmt->for_all_sequences) + return; + + pubform = (Form_pg_publication) GETSTRUCT(tup); + + memset(values, 0, sizeof(values)); + memset(nulls, false, sizeof(nulls)); + memset(replaces, false, sizeof(replaces)); AFAIK, these memsets are not needed if you just say "= {0}" where those vars are declared. ~~~ AlterPublication: 6. + relations = list_concat(relations, exceptrelations); AlterPublicationTables(stmt, tup, relations, pstate->p_sourcetext, schemaidlist != NIL); I did not quite understand this list_concat. Is this somehow asserting that `relations` must be empty when there were `exceptrelations` and vice versa, because other combinations are not supported by ALTER -- e.g. is this just a trick to so you can pass the same parameter to AlterPublicationTables? This seems related to the 'isexecpt' AlterPublicationTables function, which was also quite subtle. Bottom line is, I'm unsure what the logic is here, but it appears overly tricky to me. Would more comments help? ====== src/backend/parser/gram.y 7. + * ALL TABLES [ EXCEPT TABLE ( table_name [, ...] ) ] The CREATE/ALTER docs synopsis says "[ ONLY ] table_name [ * ]" which is different from this comment. So are ONLY and * handled properly or not? ====== src/include/nodes/parsenodes.h 8. + bool for_all_tables; /* True if SET ALL TABLES is specified */ + bool for_all_sequences; /* True if SET ALL SEQUENCES is specified */ Maybe these comments do not need to mention the keyword "SET". That way, in future if/when ADD/DROP get implemented, then this code won't need to churn again. ====== Kind Regards, Peter Smith. Fujitsu Australia