Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8bd5342

Browse files
author
Amit Kapila
committed
Invalidate relcache for publications defined for all tables.
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
1 parent aa37a43 commit 8bd5342

File tree

5 files changed

+68
-1
lines changed

5 files changed

+68
-1
lines changed

src/backend/catalog/dependency.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1460,6 +1460,10 @@ doDeletion(const ObjectAddress *object, int flags)
14601460
RemovePublicationRelById(object->objectId);
14611461
break;
14621462

1463+
case OCLASS_PUBLICATION:
1464+
RemovePublicationById(object->objectId);
1465+
break;
1466+
14631467
case OCLASS_CAST:
14641468
case OCLASS_COLLATION:
14651469
case OCLASS_CONVERSION:
@@ -1478,7 +1482,6 @@ doDeletion(const ObjectAddress *object, int flags)
14781482
case OCLASS_USER_MAPPING:
14791483
case OCLASS_DEFACL:
14801484
case OCLASS_EVENT_TRIGGER:
1481-
case OCLASS_PUBLICATION:
14821485
case OCLASS_TRANSFORM:
14831486
DropObjectById(object);
14841487
break;

src/backend/commands/publicationcmds.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt)
234234
PublicationAddTables(puboid, rels, true, NULL);
235235
CloseTableList(rels);
236236
}
237+
else if (stmt->for_all_tables)
238+
{
239+
/* Invalidate relcache so that publication info is rebuilt. */
240+
CacheInvalidateRelcacheAll();
241+
}
237242

238243
table_close(rel, RowExclusiveLock);
239244

@@ -504,6 +509,35 @@ RemovePublicationRelById(Oid proid)
504509
table_close(rel, RowExclusiveLock);
505510
}
506511

512+
/*
513+
* Remove the publication by mapping OID.
514+
*/
515+
void
516+
RemovePublicationById(Oid pubid)
517+
{
518+
Relation rel;
519+
HeapTuple tup;
520+
Form_pg_publication pubform;
521+
522+
rel = table_open(PublicationRelationId, RowExclusiveLock);
523+
524+
tup = SearchSysCache1(PUBLICATIONOID, ObjectIdGetDatum(pubid));
525+
if (!HeapTupleIsValid(tup))
526+
elog(ERROR, "cache lookup failed for publication %u", pubid);
527+
528+
pubform = (Form_pg_publication)GETSTRUCT(tup);
529+
530+
/* Invalidate relcache so that publication info is rebuilt. */
531+
if (pubform->puballtables)
532+
CacheInvalidateRelcacheAll();
533+
534+
CatalogTupleDelete(rel, &tup->t_self);
535+
536+
ReleaseSysCache(tup);
537+
538+
table_close(rel, RowExclusiveLock);
539+
}
540+
507541
/*
508542
* Open relations specified by a PublicationTable list.
509543
* In the returned list of PublicationRelInfo, tables are locked

src/include/commands/publicationcmds.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
extern ObjectAddress CreatePublication(ParseState *pstate, CreatePublicationStmt *stmt);
2222
extern void AlterPublication(ParseState *pstate, AlterPublicationStmt *stmt);
23+
extern void RemovePublicationById(Oid pubid);
2324
extern void RemovePublicationRelById(Oid proid);
2425

2526
extern ObjectAddress AlterPublicationOwner(const char *name, Oid newOwnerId);

src/test/regress/expected/publication.out

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,21 @@ Tables:
158158

159159
DROP TABLE testpub_parted1;
160160
DROP PUBLICATION testpub_forparted, testpub_forparted1;
161+
-- Test cache invalidation FOR ALL TABLES publication
162+
SET client_min_messages = 'ERROR';
163+
CREATE TABLE testpub_tbl4(a int);
164+
INSERT INTO testpub_tbl4 values(1);
165+
UPDATE testpub_tbl4 set a = 2;
166+
CREATE PUBLICATION testpub_foralltables FOR ALL TABLES;
167+
RESET client_min_messages;
168+
-- fail missing REPLICA IDENTITY
169+
UPDATE testpub_tbl4 set a = 3;
170+
ERROR: cannot update table "testpub_tbl4" because it does not have a replica identity and publishes updates
171+
HINT: To enable updating the table, set REPLICA IDENTITY using ALTER TABLE.
172+
DROP PUBLICATION testpub_foralltables;
173+
-- should pass after dropping the publication
174+
UPDATE testpub_tbl4 set a = 3;
175+
DROP TABLE testpub_tbl4;
161176
-- fail - view
162177
CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_view;
163178
ERROR: cannot add relation "testpub_view" to publication

src/test/regress/sql/publication.sql

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,20 @@ ALTER PUBLICATION testpub_forparted SET (publish_via_partition_root = true);
9393
DROP TABLE testpub_parted1;
9494
DROP PUBLICATION testpub_forparted, testpub_forparted1;
9595

96+
-- Test cache invalidation FOR ALL TABLES publication
97+
SET client_min_messages = 'ERROR';
98+
CREATE TABLE testpub_tbl4(a int);
99+
INSERT INTO testpub_tbl4 values(1);
100+
UPDATE testpub_tbl4 set a = 2;
101+
CREATE PUBLICATION testpub_foralltables FOR ALL TABLES;
102+
RESET client_min_messages;
103+
-- fail missing REPLICA IDENTITY
104+
UPDATE testpub_tbl4 set a = 3;
105+
DROP PUBLICATION testpub_foralltables;
106+
-- should pass after dropping the publication
107+
UPDATE testpub_tbl4 set a = 3;
108+
DROP TABLE testpub_tbl4;
109+
96110
-- fail - view
97111
CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_view;
98112
SET client_min_messages = 'ERROR';

0 commit comments

Comments
 (0)