]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Invalidate relcache for publications defined for all tables.
authorAmit Kapila <akapila@postgresql.org>
Wed, 8 Sep 2021 05:29:21 +0000 (10:59 +0530)
committerAmit Kapila <akapila@postgresql.org>
Wed, 8 Sep 2021 05:50:42 +0000 (11:20 +0530)
Updates/Deletes on a relation were allowed even without replica identity
after we define the publication for all tables. This would later lead to
an error on subscribers. The reason was that for such publications we were
not invalidating the relcache and the publication information for
relations was not getting rebuilt. Similarly, we were not invalidating the
relcache after dropping of such publications which will prohibit
Updates/Deletes without replica identity even without any publication.

Author: Vignesh C and Hou Zhijie
Reviewed-by: Hou Zhijie, Kyotaro Horiguchi, Amit Kapila
Backpatch-through: 10, where it was introduced
Discussion: https://postgr.es/m/CALDaNm0pF6zeWqCA8TCe2sDuwFAy8fCqba=nHampCKag-qLixg@mail.gmail.com

src/backend/commands/publicationcmds.c
src/test/regress/expected/publication.out
src/test/regress/sql/publication.sql

index 675ee96b0facf28df01f844711daca205dbd06a3..e933b1f9351183da4d8019e8145de1f21c7a4645 100644 (file)
@@ -224,6 +224,11 @@ CreatePublication(CreatePublicationStmt *stmt)
                PublicationAddTables(puboid, rels, true, NULL);
                CloseTableList(rels);
        }
+       else if (stmt->for_all_tables)
+       {
+               /* Invalidate relcache so that publication info is rebuilt. */
+               CacheInvalidateRelcacheAll();
+       }
 
        heap_close(rel, RowExclusiveLock);
 
@@ -438,6 +443,7 @@ RemovePublicationById(Oid pubid)
 {
        Relation        rel;
        HeapTuple       tup;
+       Form_pg_publication pubform;
 
        rel = heap_open(PublicationRelationId, RowExclusiveLock);
 
@@ -446,6 +452,12 @@ RemovePublicationById(Oid pubid)
        if (!HeapTupleIsValid(tup))
                elog(ERROR, "cache lookup failed for publication %u", pubid);
 
+       pubform = (Form_pg_publication) GETSTRUCT(tup);
+
+       /* Invalidate relcache so that publication info is rebuilt. */
+       if (pubform->puballtables)
+               CacheInvalidateRelcacheAll();
+
        CatalogTupleDelete(rel, &tup->t_self);
 
        ReleaseSysCache(tup);
index afbbdd543dfb41fb1643fea92cb65c7933ebd682..adaa5ac81cb638bcf8dc6cf608f2d9e4bff14ed8 100644 (file)
@@ -107,6 +107,21 @@ Tables:
 
 DROP TABLE testpub_tbl3, testpub_tbl3a;
 DROP PUBLICATION testpub3, testpub4;
+-- Test cache invalidation FOR ALL TABLES publication
+SET client_min_messages = 'ERROR';
+CREATE TABLE testpub_tbl4(a int);
+INSERT INTO testpub_tbl4 values(1);
+UPDATE testpub_tbl4 set a = 2;
+CREATE PUBLICATION testpub_foralltables FOR ALL TABLES;
+RESET client_min_messages;
+-- fail missing REPLICA IDENTITY
+UPDATE testpub_tbl4 set a = 3;
+ERROR:  cannot update table "testpub_tbl4" because it does not have a replica identity and publishes updates
+HINT:  To enable updating the table, set REPLICA IDENTITY using ALTER TABLE.
+DROP PUBLICATION testpub_foralltables;
+-- should pass after dropping the publication
+UPDATE testpub_tbl4 set a = 3;
+DROP TABLE testpub_tbl4;
 -- fail - view
 CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_view;
 ERROR:  "testpub_view" is not a table
index 815410b3c5a8354917a3fb3e0621af439b8f4047..1071334825a39fbf1ef94e356164f6a2f88d7c6d 100644 (file)
@@ -60,6 +60,20 @@ CREATE PUBLICATION testpub4 FOR TABLE ONLY testpub_tbl3;
 DROP TABLE testpub_tbl3, testpub_tbl3a;
 DROP PUBLICATION testpub3, testpub4;
 
+-- Test cache invalidation FOR ALL TABLES publication
+SET client_min_messages = 'ERROR';
+CREATE TABLE testpub_tbl4(a int);
+INSERT INTO testpub_tbl4 values(1);
+UPDATE testpub_tbl4 set a = 2;
+CREATE PUBLICATION testpub_foralltables FOR ALL TABLES;
+RESET client_min_messages;
+-- fail missing REPLICA IDENTITY
+UPDATE testpub_tbl4 set a = 3;
+DROP PUBLICATION testpub_foralltables;
+-- should pass after dropping the publication
+UPDATE testpub_tbl4 set a = 3;
+DROP TABLE testpub_tbl4;
+
 -- fail - view
 CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_view;
 CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_tbl1, pub_test.testpub_nopk;