diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c index 313c87398b..f68bcde02b 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 2e760e8a3b..be05f6cf80 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); @@ -5606,10 +5611,8 @@ GetRelationPublicationActions(Relation relation) /* 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 84d6afef19..46d9db203e 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);