diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index 6c97ef0280..1825daf903 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -2151,6 +2151,15 @@ apply_handle_tuple_routing(ApplyExecutionData *edata, Assert(partrelinfo != NULL); partrel = partrelinfo->ri_RelationDesc; + /* + * Check for supported relkind. We need this since partitions might be of + * unsupported relkinds; and the set of partitions can change, so checking + * at CREATE/ALTER SUBSCRIPTION would be insufficient. + */ + CheckSubscriptionRelkind(partrel->rd_rel->relkind, + get_namespace_name(RelationGetNamespace(partrel)), + RelationGetRelationName(partrel)); + /* * To perform any of the operations below, the tuple must match the * partition's rowtype. Convert if needed or just copy, using a dedicated @@ -2204,6 +2213,7 @@ apply_handle_tuple_routing(ApplyExecutionData *edata, { TupleTableSlot *localslot; ResultRelInfo *partrelinfo_new; + Relation partrel_new; bool found; /* Get the matching local tuple from the partition. */ @@ -2289,7 +2299,6 @@ apply_handle_tuple_routing(ApplyExecutionData *edata, slot_getallattrs(remoteslot); } - /* Find the new partition. */ oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); partrelinfo_new = ExecFindPartition(mtstate, relinfo, @@ -2297,6 +2306,12 @@ apply_handle_tuple_routing(ApplyExecutionData *edata, estate); MemoryContextSwitchTo(oldctx); Assert(partrelinfo_new != partrelinfo); + partrel_new = partrelinfo_new->ri_RelationDesc; + + /* Check that new partition also has supported relkind. */ + CheckSubscriptionRelkind(partrel_new->rd_rel->relkind, + get_namespace_name(RelationGetNamespace(partrel_new)), + RelationGetRelationName(partrel_new)); /* DELETE old tuple found in the old partition. */ apply_handle_delete_internal(edata, partrelinfo, @@ -2309,10 +2324,9 @@ apply_handle_tuple_routing(ApplyExecutionData *edata, * partition rowtype. */ oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); - partrel = partrelinfo_new->ri_RelationDesc; remoteslot_part = partrelinfo_new->ri_PartitionTupleSlot; if (remoteslot_part == NULL) - remoteslot_part = table_slot_create(partrel, + remoteslot_part = table_slot_create(partrel_new, &estate->es_tupleTable); map = partrelinfo_new->ri_RootToPartitionMap; if (map != NULL)