diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c index f68348dcf4..c66e0a20a8 100644 --- a/src/backend/replication/pgoutput/pgoutput.c +++ b/src/backend/replication/pgoutput/pgoutput.c @@ -444,15 +444,7 @@ maybe_send_schema(LogicalDecodingContext *ctx, if (relentry->publish_as_relid != RelationGetRelid(relation)) { Relation ancestor = RelationIdGetRelation(relentry->publish_as_relid); - TupleDesc indesc = RelationGetDescr(relation); - TupleDesc outdesc = RelationGetDescr(ancestor); - MemoryContext oldctx; - - /* Map must live as long as the session does. */ - oldctx = MemoryContextSwitchTo(CacheMemoryContext); - relentry->map = convert_tuples_by_name(CreateTupleDescCopy(indesc), - CreateTupleDescCopy(outdesc)); - MemoryContextSwitchTo(oldctx); + send_relation_and_attrs(ancestor, xid, ctx); RelationClose(ancestor); } @@ -1108,6 +1100,39 @@ get_rel_sync_entry(PGOutputData *data, Oid relid) list_free(pubids); entry->publish_as_relid = publish_as_relid; + + /* + * While at it, also set the map to convert leaf partition tuples into + * the format of the table to publish the tuples as of. + */ + if (publish_as_relid != relid) + { + Relation relation = RelationIdGetRelation(relid); + Relation ancestor = RelationIdGetRelation(publish_as_relid); + TupleDesc indesc = RelationGetDescr(relation); + TupleDesc outdesc = RelationGetDescr(ancestor); + MemoryContext oldctx; + + /* Map, if any, must live as long as the session does. */ + oldctx = MemoryContextSwitchTo(CacheMemoryContext); + + /* + * TupleDescs must be copied before putting into the map, because + * they may not live as long as we want the map to live. + */ + indesc = CreateTupleDescCopy(indesc); + outdesc = CreateTupleDescCopy(outdesc); + entry->map = convert_tuples_by_name(indesc, outdesc); + if (entry->map == NULL) + { + FreeTupleDesc(indesc); + FreeTupleDesc(outdesc); + } + + MemoryContextSwitchTo(oldctx); + RelationClose(relation); + RelationClose(ancestor); + } entry->replicate_valid = true; }