Case 1: ALL TABLES pub case: ----------------------------------------- Pub: CREATE TABLE t1 (a int) PARTITION BY RANGE (a); CREATE TABLE t1_part1 PARTITION OF t1 FOR VALUES FROM (1) TO (10); CREATE TABLE t1_part2 PARTITION OF t1 FOR VALUES FROM (11) TO (20); create publication pub1 for all tables; Sub: (individual tables) CREATE TABLE t1 (a int); CREATE TABLE t1_part1(a int); CREATE TABLE t1_part2(a int); create subscription sub1 connection 'dbname=postgres host=localhost user=shveta port=5433' publication pub1; Pub: INSERT INTO t1 VALUES (5), (15); Sub: (replicated to sub) postgres=# select * from t1_part1; a --- 5 (1 row) postgres=# select * from t1_part2; a ---- 15 (1 row) Now block DETACH PARTITION and check: Pub: Session A: BEGIN; SELECT * FROM t1; --do not commit Session B: --This blocks on 'A' post detach but before making some catalog changes ALTER TABLE t1 DETACH PARTITION t1_part1 CONCURRENTLY; Session C, while B is blocked: postgres=# SELECT inhdetachpending FROM pg_inherits WHERE inhrelid = 't1_part1'::regclass; inhdetachpending ------------------ t --cannot run INSERT through t1 for detached ptn: expected postgres=# INSERT INTO t1 VALUES (6), (16); ERROR: no partition of relation "t1" found for row DETAIL: Partition key of the failing row contains (a) = (6). --try usign ptn-name for detached ptn INSERT INTO t1_part1 VALUES (6); INSERT INTO t1 VALUES (16); Sub: (both t1_part1 and t1 are replicated): as pub was on ALL TABLES. postgres=# select * from t1_part1; a --- 5 6 (2 rows) postgres=# select * from t1_part2; a ---- 15 16 (2 rows) Session C, while B is blocked, check ptn-root: postgres=# select pg_partition_root('t1_part1'); pg_partition_root ------------------- t1_part1 (1 row) postgres=# select pg_partition_root('t1_part2'); pg_partition_root ------------------- t1 (1 row) pg_pub_rel and pg_pub_tables output for reference. postgres=# SELECT pr.oid, pr.prpubid, pub.pubname, c.relname AS table_name FROM pg_publication_rel pr JOIN pg_class c ON c.oid = pr.prrelid JOIN pg_namespace n ON n.oid = c.relnamespace JOIN pg_publication pub ON pub.oid = pr.prpubid; oid | prpubid | pubname | table_name -----+---------+---------+------------ (0 rows) postgres=# select * from pg_publication_tables; pubname | schemaname | tablename | attnames | rowfilter ---------+------------+-----------+----------+----------- pub1 | public | t1_part1 | {a} | pub1 | public | t1_part2 | {a} | (2 rows) ----------------------------------------- CASE 2: ptn-table pub case: ----------------------------------------- Pub: CREATE TABLE t1 (a int) PARTITION BY RANGE (a); CREATE TABLE t1_part1 PARTITION OF t1 FOR VALUES FROM (1) TO (10); CREATE TABLE t1_part2 PARTITION OF t1 FOR VALUES FROM (11) TO (20); create publication pub1 for table t1; Sub: (individual tables) CREATE TABLE t1 (a int); CREATE TABLE t1_part1(a int); CREATE TABLE t1_part2(a int); create subscription sub1 connection 'dbname=postgres host=localhost user=shveta port=5433' publication pub1; Pub: INSERT INTO t1 VALUES (5), (15); Sub: postgres=# select * from t1_part1; a --- 5 (1 row) postgres=# select * from t1_part2; a ---- 15 (1 row) Now block DETACH PARTITION and check: Pub: Session A: BEGIN; SELECT * FROM t1; --do not commit Session B: --This blocks on 'A' post detach but before making some catalog changes ALTER TABLE t1 DETACH PARTITION t1_part1 CONCURRENTLY; Session C, while B is blocked: postgres=# SELECT inhdetachpending FROM pg_inherits WHERE inhrelid = 't1_part1'::regclass; inhdetachpending ------------------ t INSERT INTO t1_part1 VALUES (6); INSERT INTO t1 VALUES (16); INSERT INTO t1_part1 VALUES (7); INSERT INTO t1 VALUES (17); Sub: (detached ptn is also replicated even though it is not part of pg_publication_tables) postgres=# select * from t1_part1; a --- 5 6 7 (3 rows) postgres=# select * from t1_part2; a ---- 15 16 17 (3 rows) --pg_publication_rel entry postgres=# SELECT pr.oid, pr.prpubid, pub.pubname, c.relname AS table_name FROM pg_publication_rel pr JOIN pg_class c ON c.oid = pr.prrelid JOIN pg_namespace n ON n.oid = c.relnamespace JOIN pg_publication pub ON pub.oid = pr.prpubid; oid | prpubid | pubname | table_name -------+---------+---------+------------ 16394 | 16393 | pub1 | t1 (1 row) postgres=# select * from pg_publication_tables; pubname | schemaname | tablename | attnames | rowfilter ---------+------------+-----------+----------+----------- pub1 | public | t1_part2 | {a} | (1 row) Once detach session is finished: SESSION A: COMMIT This will make SESSION B's DETACH proceed. After that, on SESSION C: INSERT INTO t1_part1 VALUES (9); INSERT INTO t1 VALUES (19); t1_part1 is not replicated (expected) while t1_part2 is replicated. SUB: postgres=# select * from t1_part1; a --- 5 6 7 (3 rows) postgres=# select * from t1_part2; a ---- 15 16 17 19 (4 rows)