| From: | shveta malik <shveta(dot)malik(at)gmail(dot)com> |
|---|---|
| To: | Nisha Moond <nisha(dot)moond412(at)gmail(dot)com> |
| Cc: | Peter Smith <smithpb2250(at)gmail(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Zsolt Parragi <zsolt(dot)parragi(at)percona(dot)com>, pgsql-hackers(at)lists(dot)postgresql(dot)org, shveta malik <shveta(dot)malik(at)gmail(dot)com> |
| Subject: | Re: Support EXCEPT for TABLES IN SCHEMA publications |
| Date: | 2026-07-16 04:45:41 |
| Message-ID: | CAJpy0uCGXk5FuXemW1RZkfkUvEUc35aVuAOQxfhmUhYeE-WuQA@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Wed, Jul 15, 2026 at 10:16 PM Nisha Moond <nisha(dot)moond412(at)gmail(dot)com> wrote:
>
> On Mon, Jul 13, 2026 at 3:31 PM shveta malik <shveta(dot)malik(at)gmail(dot)com> wrote:
> >
> > On Fri, Jul 10, 2026 at 5:07 PM Nisha Moond <nisha(dot)moond412(at)gmail(dot)com> wrote:
> > >
> > >
> > > Yes, that works for me as we have FOR TABLES example to follow. I've
> > > made the changes in v20.
> > >
> >
> > Thanks! I had a quick look, few initial comments:
> >
> >
> > 1)
> > GetTopMostAncestorInPublication():
> >
> > + if (ancestors == NIL)
> > + return InvalidOid;
> >
> > Should this be Assert or can there be a case where ancestors list can
> > come as NIL?
> >
>
> I found one case where ancestors can be NIL.
> Test case:
> CREATE TABLE t1 (a int) PARTITION BY RANGE (a);
> CREATE TABLE t1_part PARTITION OF t1 FOR VALUES FROM (1) TO (100);
> CREATE PUBLICATION mypub FOR TABLE t1;
>
> -- Get the partition into the pending-detach state:
> -- Session A:
> BEGIN;
> SELECT * FROM t1;
> -- leave open
>
> -- Session B (blocks, waiting on Session A's lock on t1):
> ALTER TABLE t1 DETACH PARTITION t1_part CONCURRENTLY;
>
> -- Session C, while B is blocked:
> SELECT * FROM pg_get_publication_tables('{mypub}'::text[],
> 't1_part'::regclass);
>
> In this scenario, Session C reaches GetTopMostAncestorInPublication()
> with ancestors == NIL. So I think we should keep return InvalidOid;
> rather than replacing it with an Assert.
>
> While investigating this race, I also hit assertions at places that
> call "llast_oid(ancestors)" without checking for NIL, for example in
> check_publication_add_relation() and RelationBuildPublicationDesc(). I
> fixed those by guarding with if (ancestors != NIL).
Okay, I will review.
> But due to this same race, other existing callers of llast_oid() on
> HEAD that assume ancestors is never NIL can also hit the following
> assertion:
> "TRAP: failed Assert("list != NIL"), File:
> "../../../../src/include/nodes/pg_list.h" ..."
>
> One such case is pgoutput.c:get_rel_sync_entry(). To reproduce on HEAD:
> -- create a slot
> SELECT pg_create_logical_replication_slot('myslot', 'pgoutput');
>
> -- get the partition into the pending-detach state (using same A & B
> sessions), and in session C run -
> INSERT INTO t1_part VALUES (5);
> SELECT * FROM pg_logical_slot_get_binary_changes('myslot', NULL, NULL,
> 'proto_version', '1', 'publication_names', 'mypub');
>
> I think this should be handled separately after analyzing whether
> there's a better fix than simply adding if (ancestors != NIL) guards
> at each call site.
> Note: Other callers of llast_oid(ancestors) may need similar review.
>
> Thoughts?
>
Nisha, I am not able to reproduce this on HEAD. Can you please verify
if you missed providing any steps? This I what I have tried:
Session1:
postgres=# SELECT pg_create_logical_replication_slot('myslot', 'pgoutput');
pg_create_logical_replication_slot
------------------------------------
(myslot,0/0178F5B8)
(1 row)
postgres=# CREATE TABLE t1 (a int) PARTITION BY RANGE (a);
CREATE TABLE t1_part PARTITION OF t1 FOR VALUES FROM (1) TO (100);
CREATE PUBLICATION mypub FOR TABLE t1;
CREATE TABLE
CREATE TABLE
CREATE PUBLICATION
Session2:
postgres=# BEGIN;
SELECT * FROM t1;
BEGIN
a
---
(0 rows)
Session3:
postgres=# ALTER TABLE t1 DETACH PARTITION t1_part CONCURRENTLY;
<hanging>
Session4:
postgres=# INSERT INTO t1_part VALUES (5);
SELECT * FROM pg_logical_slot_get_binary_changes('myslot', NULL, NULL,
'proto_version', '1', 'publication_names', 'mypub');
INSERT 0 1
lsn | xid | data
-----+-----+------
(0 rows)
thanks
Shveta
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Fujii Masao | 2026-07-16 04:46:26 | Re: doc: REPACK is missing from the MAINTAIN privilege documentation |
| Previous Message | Michael Paquier | 2026-07-16 04:34:58 | Re: Improve pg_stat_statements scalability |