diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c index 574d7d27fd..305f0c5594 100644 --- a/src/backend/executor/execReplication.c +++ b/src/backend/executor/execReplication.c @@ -567,7 +567,7 @@ ExecSimpleRelationDelete(ResultRelInfo *resultRelInfo, void CheckCmdReplicaIdentity(Relation rel, CmdType cmd) { - PublicationActions *pubactions; + PublicationActions pubactions; /* We only need to do checks for UPDATE and DELETE. */ if (cmd != CMD_UPDATE && cmd != CMD_DELETE) @@ -583,14 +583,14 @@ CheckCmdReplicaIdentity(Relation rel, CmdType cmd) * * Check if the table publishes UPDATES or DELETES. */ - pubactions = GetRelationPublicationActions(rel); - if (cmd == CMD_UPDATE && pubactions->pubupdate) + GetRelationPublicationActions(rel, &pubactions); + if (cmd == CMD_UPDATE && pubactions.pubupdate) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("cannot update table \"%s\" because it does not have a replica identity and publishes updates", RelationGetRelationName(rel)), errhint("To enable updating the table, set REPLICA IDENTITY using ALTER TABLE."))); - else if (cmd == CMD_DELETE && pubactions->pubdelete) + else if (cmd == CMD_DELETE && pubactions.pubdelete) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes", diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 105d8d4601..e8efae6198 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -5524,25 +5524,29 @@ RelationGetExclusionInfo(Relation indexRelation, /* * Get publication actions for the given relation. */ -struct PublicationActions * -GetRelationPublicationActions(Relation relation) +void +GetRelationPublicationActions(Relation relation, PublicationActions *pubactions) { List *puboids; ListCell *lc; MemoryContext oldcxt; Oid schemaid; - PublicationActions *pubactions = palloc0(sizeof(PublicationActions)); /* * If not publishable, it publishes no actions. (pgoutput_change() will * ignore it.) */ if (!is_publishable_relation(relation)) - return pubactions; + { + memset(pubactions, 0, sizeof(*pubactions)); + return; + } if (relation->rd_pubactions) - return memcpy(pubactions, relation->rd_pubactions, - sizeof(PublicationActions)); + { + *pubactions = *relation->rd_pubactions; + return; + } /* Fetch the publication membership info. */ puboids = GetRelationPublications(RelationGetRelid(relation)); @@ -5568,6 +5572,7 @@ GetRelationPublicationActions(Relation relation) } puboids = list_concat_unique_oid(puboids, GetAllTablesPublications()); + memset(pubactions, 0, sizeof(*pubactions)); foreach(lc, puboids) { Oid pubid = lfirst_oid(lc); @@ -5598,18 +5603,13 @@ GetRelationPublicationActions(Relation relation) } if (relation->rd_pubactions) - { pfree(relation->rd_pubactions); - relation->rd_pubactions = NULL; - } /* Now save copy of the actions in the relcache entry. */ oldcxt = MemoryContextSwitchTo(CacheMemoryContext); relation->rd_pubactions = palloc(sizeof(PublicationActions)); - memcpy(relation->rd_pubactions, pubactions, sizeof(PublicationActions)); + *relation->rd_pubactions = *pubactions; MemoryContextSwitchTo(oldcxt); - - return pubactions; } /* diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h index 82316bba54..376638f484 100644 --- a/src/include/utils/relcache.h +++ b/src/include/utils/relcache.h @@ -75,7 +75,8 @@ extern void RelationInitIndexAccessInfo(Relation relation); /* caller must include pg_publication.h */ struct PublicationActions; -extern struct PublicationActions *GetRelationPublicationActions(Relation relation); +extern void GetRelationPublicationActions(Relation relation, + struct PublicationActions *pubactions); extern void RelationInitTableAccessMethod(Relation relation);