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 1vq2cx-003MfN-09 for pgsql-hackers@arkaria.postgresql.org; Wed, 11 Feb 2026 05:19:04 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vq2bw-002Ulg-2s for pgsql-hackers@arkaria.postgresql.org; Wed, 11 Feb 2026 05:18:01 +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 1vq2bw-002UlY-1i for pgsql-hackers@lists.postgresql.org; Wed, 11 Feb 2026 05:18:01 +0000 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1vq2bu-000000006De-3L2x for pgsql-hackers@lists.postgresql.org; Wed, 11 Feb 2026 05:18:00 +0000 Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-3567e2b4159so175748a91.0 for ; Tue, 10 Feb 2026 21:17:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1770787075; cv=none; d=google.com; s=arc-20240605; b=JHGPnioCdPnGWbFZOwIiXgji8z8MbldT+3nezF9UIcn1jLbIZg/wXyD9mqYOJq1vjW +GOWeOvb+euEOTW3O5PeBtEKHMrBM8DqUGpstJGurd+V2DVY7e4r2ROXHmJ3MBMt6Srb B81jjCcPk+z6SRqzRiVP3mDvVTJV/T5s49i/vsjkUaANOCX4PrFsD/PY9Gaq60RzLzzY 6oK5fQj2OfUyUEPbn1Q1YkcYKoLJkDdCRZUkpFrGJeh+UeFpOTVypRwsV9PWs+0/abJx GlN6JQsODWUQzfnGF2mzL4DqcYPn6BLQYO6CuMJ+HFnfX6uMyIemYjQvLd+i+w+qn6LY V0LA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=HHq/+TqwxFg+ZgdWo9RXW6DUeSm4Z0AIfbed02mP/OI=; fh=E91yvLPm9QJuv+HsbaVCehxDgA0jZC7dX6qU6nff12g=; b=afLub8IrkqcpIGM4xrAfanAlV63+m5RiggxnMvGZiiv79yYovqe6HF/4jlGG3yVzjK drp0P3qmfQRB8Aghr0reo3gJnOzA4w6z/1hbvvCbpKdq+r2q/xowJnwnGs6HSJK+ka2O 8aDn2xQNH3R3e7QyUDErhMmK7aI300wTVNVoYZS5HnCYxFlqPP6r5nuKQVAGqI7dpfLz sam5P9k2E3AoNNzdIJ4TPzT8dLm/h5cuTacBYyqyxMFAHm1n58kCrlJuvzVZl8sn/acb N3Kzb0VTdPqPbg7Ssbe0fcC/fyMP0oeGWZEE+up2zR/0KMyrtuhmj7/SqkXXC7xY9bS6 xk9g==; 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=1770787075; x=1771391875; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=HHq/+TqwxFg+ZgdWo9RXW6DUeSm4Z0AIfbed02mP/OI=; b=cFaZLKRPzOAt6lopKa8rs/Sieze10n5/EvDhgNIXru0LaWHB13S4tH54VY3eT2wtJa 9/8UlKXkXfYaKcYuta8br0zToIbwgOGxWqKwiE769NdhpdLwxtMMHkioE+8lmURrRezt JeahEVg/OKbL+37LcixcEBUz5zA7vuWc9R3zlAkg+V4PtyT9z5Jb7tlV5S1LUfEMWEC5 fL6YNcR+gqjZwEjry1ab+Wgxwb2K+JKTsel/GlKG5opYkaOTtuSK+KAUOWJMH6e2OyGe 4zxpp+Iif3pVIgVaz16AVz1NIwmDPszPoy+TQ4SeqNPgIweahwLSnW5YY8kdM4LDOq7y nTFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770787075; x=1771391875; h=content-transfer-encoding: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=HHq/+TqwxFg+ZgdWo9RXW6DUeSm4Z0AIfbed02mP/OI=; b=TPn2O7sZcw5fltkBckdgtj/VULPVIqs3AhD0r1i5WgePqacPT6A/LZoDNelhYRQr0y w8lJ2/J7BgD9i8ZtZBnCXAfbHRxFRXXdIAI/lWQVBhxJmOSQwS7rkQXgKVpvBg6f8KvT S86S5BW84Jxge8Z46tHqnKYqY+4CnTgue8SEUQnPSY6nJGebrlCmxq+Ldwf25APdS8lW ONpSeWJvbhrcjn5YqrU1+dbMzYcErl1RhZJpBaF20QJnILzeY7eM5YjtU3eotYYBd+Bm IXSNKMgnusc5N3aboazFUIKEym4VVC7vneu82yHd6u4IamcrhurldYzAHp44R1NyF5Yu ft/w== X-Forwarded-Encrypted: i=1; AJvYcCVi/oCnN37GXYfUcfMIVMDSrfnMC5HoVer8yagXv/byEgm3PW3g+F5UY4iuMZnW0O1KHKQ8yXiI1+ygiYIU@lists.postgresql.org X-Gm-Message-State: AOJu0YxRe8RKkrXdJ0wFT1bJD7Zo3RII15zTwX+hiPf3Z8fYY1e/LQ2J oCa3tzobS1nP3A2BYVlFXghAphVKD3ZIEqe0ZwPtUC89Z4aCZxSg4utWrGKI6huttqyWlRZC6mS vlzC9Ov1JdRzJr6B5ZipNRHGKQABQHy0= X-Gm-Gg: AZuq6aKjjxQY9CHRsirS6xjBzs3aynLVI/LV5hWlbVhnF4rEwsS9CcntzC+W9QD8Seg wSzdowKnJiifGJNJmfKKrGIEsZAHLm3AgqUt9juLLu5MmfZuYYSgIz73T7DlOBCkat0yRXhTFc7 iXLiIRG+nxp8PHJDpnTu13CppFYKVryPZyfqFzDwqZ1eHwj+6G4ajSOWyz6AJdLO4MVP0LB4HU0 AFH3qchZ/nA7tnAhpvfWm7OTgf08Kvth3j82XdIGTu01mGZzU5zHZhXQw1lcuTreugsnJHSkVmy o5/Dn/Em2v/J+q9yXkzjRLTdzkE750C+XuutAFnNZoUf0k4VfYFomQ== X-Received: by 2002:a17:90b:2d44:b0:355:35b0:8b83 with SMTP id 98e67ed59e1d1-35535b08eefmr11319220a91.33.1770787075474; Tue, 10 Feb 2026 21:17:55 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: shveta malik Date: Wed, 11 Feb 2026 10:47:43 +0530 X-Gm-Features: AZwV_QhNVhBMX2i1neAK8v-jNWDf5FXeWGaHxwLRLxWtWkaoEILk45sidooekeQ Message-ID: Subject: Re: Skipping schema changes in publication To: vignesh C Cc: "David G. Johnston" , Amit Kapila , Peter Smith , Shlok Kyal , Dilip Kumar , "Zhijie Hou (Fujitsu)" , YeXiu <1518981153@qq.com>, Ian Lawrence Barwick , Bharath Rupireddy , PostgreSQL Hackers , shveta malik Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Tue, Feb 10, 2026 at 11:11=E2=80=AFPM vignesh C wr= ote: > > On Tue, 10 Feb 2026 at 11:35, shveta malik wrote= : > > > > On Mon, Feb 9, 2026 at 11:52=E2=80=AFAM David G. Johnston > > wrote: > > > > > > On Sunday, February 8, 2026, Amit Kapila wr= ote: > > >> > > >> On Mon, Feb 9, 2026 at 6:41=E2=80=AFAM Peter Smith wrote: > > >> > > >> > Hi Amit. > > >> > > > >> > I understand there can be some tricky scenarios where partitions a= re > > >> > involved, but I was not sure why "pub1: FOR ALL Tables EXCEPT (tab= 1) > > >> > and pub2: FOR TABLE tab1" is an example of contradictory behaviour= . > > >> > > > >> > Consider if the publisher has 3 tables tab1,tab2,tab3: > > >> > Here, "pub1: FOR ALL Tables EXCEPT (tab1)" is like a shorthand for > > >> > saying "pub1: FOR TABLE tab2,tab3" > > >> > So what's wrong for the subscriber to combine pub1 and pub2 in thi= s case? > > >> > > > >> > > >> It is because one of the publications (pub2) indicates to include a > > >> particular table tab1 and the other one (pub1) to exclude the same > > >> table. And things become much more complex when the Except list > > >> contains partitions as shown in Shveta's example. So, I think it mak= es > > >> sense to keep things simple at least for the first version, we can > > >> consider to uplift this restriction if we see some use cases from th= e > > >> field. > > >> > > >> > > > > > > I=E2=80=99m with Peter here - I do not think it is wise to expose the= exception listing outside the publication. Publication combinations shoul= d be purely additive in much the same way grants are in the system. Except= lists are internal shorthand for describing the positive list of tables a = publication makes available - all tables except. > > > > > > > The earlier case - > > pub1: FOR ALL TABLES EXCEPT (tab1) > > pub2: FOR TABLE tab1 WHERE (c =3D 99) > > > > seems a valid scenario, and we are currently evaluating its > > implementation feasibility under Approach 1. > > > > OTOH, subscribing to two different publications that are both defined > > as 'FOR ALL TABLES' but have different EXCEPT lists introduces > > unnecessary implementation complexity without a clear business use > > case. This becomes especially complex when the publications exclude > > different partitions of the same partitioned table. For example: > > > > pub1: FOR ALL TABLES EXCEPT (part1, part2) WITH > > (publish_via_partition_root=3Dtrue) > > pub2: FOR ALL TABLES EXCEPT (part7) WITH > > (publish_via_partition_root=3Dfalse) > > > > IMO, there is no clear need for a user to create multiple 'ALL TABLES' > > publications with different EXCEPT lists and then combine them at the > > subscriber level. Given this, to keep the patch simpler, we plan to > > emit an error for this scenario (multi-pub EXCEPTs case) for now. If a > > valid requirement emerges in the future, we can revisit and consider > > supporting it. > > I agree with this. This has been handled. > Additionally it also resolves conflicts between overlapping > publications with differing publish_via_partition_root settings. When > a partition is excluded from a "via root" publication but included in > another table publication with "via root" as false, then it is > published through its root ancestor by default to give priority to the > root table. Okay, this behaviour is the same as that of HEAD. I think the patch has not changed anything in that. So will it be right to conclude this: In the case where a subscriber subscribes to multiple publications: a) If a table or partition is included in one publication and excluded in another, we treat it as included. b) If any publisher has publish_via_partition_root =3D true, we consider this setting to apply to all publishers in that subscription. In other words, all changes are published through the topmost ancestor included in the publications. This behavior is the same as in HEAD; nothing has changed here. c) If the publications have different EXCEPT lists, this scenario is currently not supported (for the reasons stated in [1]). In such cases, we raise an error. [1]: https://www.postgresql.org/message-id/CAJpy0uC_0uvhmXyWegKGRozhpyoLGHw= HrUAK%3DWk%2BbSmzqLMoSw%40mail.gmail.com > Ex: > -- Publisher tables > CREATE TABLE tab_root (id int, range_col int) PARTITION BY RANGE (range_c= ol); > CREATE TABLE tab_part_1 PARTITION OF tab_root FOR VALUES FROM (1) TO > (1000) PARTITION BY RANGE (range_col); > CREATE TABLE tab_part_2 PARTITION OF tab_root FOR VALUES FROM (1000) > TO (2000) PARTITION BY RANGE (range_col); > CREATE TABLE tab_part_1_p1 PARTITION OF tab_part_1 FOR VALUES FROM (1) TO= (500); > CREATE TABLE tab_part_1_p2 PARTITION OF tab_part_1 FOR VALUES FROM > (500) TO (1000); > CREATE TABLE tab_part_2_p1 PARTITION OF tab_part_2 FOR VALUES FROM > (1000) TO (1500); > CREATE TABLE tab_part_2_p2 PARTITION OF tab_part_2 FOR VALUES FROM > (1500) TO (2000); > > -- Publication > CREATE PUBLICATION pub1 for ALL TABLES EXCEPT table (tab_part_1_p1, > tab_part_1_p2) WITH (PUBLISH_VIA_PARTITION_ROOT=3Dtrue); > CREATE PUBLICATION pub2 for table tab_part_1_p2 WITH > (PUBLISH_VIA_PARTITION_ROOT=3Dfalse); > > -- Subscriber tables > CREATE TABLE tab_root (id int, range_col int); > CREATE TABLE tab_part_1 (id int, range_col int); > CREATE TABLE tab_part_2 (id int, range_col int); > CREATE TABLE tab_part_1_p1 (id int, range_col int); > CREATE TABLE tab_part_1_p2 (id int, range_col int); > CREATE TABLE tab_part_2_p1 (id int, range_col int); > CREATE TABLE tab_part_2_p2 (id int, range_col int); > > Subscription with both pub1 and pub2 publications.: > create subscription sub1 connection 'dbname=3Dpostgres host=3Dlocalhost > port=3D5432' publication pub1,pub2; > > Consider the insert statements: > insert into tab_part_1_p1 values(1,100); > insert into tab_part_1_p2 values(2,600); > insert into tab_part_2_p1 values(3,1100); > insert into tab_part_2_p2 values(4,1600); > > The tab_part_2_p2 table's row is replicated to the subscriber=E2=80=99s > tab_root table, since root table publications take precedence. I think your intent was to focus on results for tab_part_1_p2 as that was included in pub2 but excluded in pub1. > postgres=3D# select * from tab_root ; > id | range_col > ----+----------- > 2 | 600 > 3 | 1100 > 4 | 1600 > (3 rows) > > The attached v42 version patch has the changes for the same. > Thanks, will review. thanks Shveta