diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
index 354fbe4b4b..e80322cb5d 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -363,6 +363,17 @@ create_estate_for_relation(LogicalRepRelMapEntry *rel)
 	return estate;
 }
 
+/* Winds down the executor created in create_estate_for_relation(). */
+static void
+close_estate(EState *estate)
+{
+	/* Handle any queued AFTER triggers. */
+	AfterTriggerEndQuery(estate);
+	ExecResetTupleTable(estate->es_tupleTable, false);
+	ExecCloseRangeTableRelations(estate);
+	FreeExecutorState(estate);
+}
+
 /*
  * Executes default values for columns for which we can't map to remote
  * relation columns.
@@ -1173,7 +1184,7 @@ apply_handle_insert(StringInfo s)
 										RelationGetDescr(rel->localrel),
 										&TTSOpsVirtual);
 	resultRelInfo = makeNode(ResultRelInfo);
-	InitResultRelInfo(resultRelInfo, rel->localrel, 1, NULL, 0);
+	ExecInitResultRelation(estate, resultRelInfo, 1);
 
 	/* Input functions may need an active snapshot, so get one */
 	PushActiveSnapshot(GetTransactionSnapshot());
@@ -1194,11 +1205,7 @@ apply_handle_insert(StringInfo s)
 
 	PopActiveSnapshot();
 
-	/* Handle queued AFTER triggers. */
-	AfterTriggerEndQuery(estate);
-
-	ExecResetTupleTable(estate->es_tupleTable, false);
-	FreeExecutorState(estate);
+	close_estate(estate);
 
 	logicalrep_rel_close(rel, NoLock);
 
@@ -1298,7 +1305,7 @@ apply_handle_update(StringInfo s)
 										RelationGetDescr(rel->localrel),
 										&TTSOpsVirtual);
 	resultRelInfo = makeNode(ResultRelInfo);
-	InitResultRelInfo(resultRelInfo, rel->localrel, 1, NULL, 0);
+	ExecInitResultRelation(estate, resultRelInfo, 1);
 
 	/*
 	 * Populate updatedCols so that per-column triggers can fire, and so
@@ -1345,11 +1352,7 @@ apply_handle_update(StringInfo s)
 
 	PopActiveSnapshot();
 
-	/* Handle queued AFTER triggers. */
-	AfterTriggerEndQuery(estate);
-
-	ExecResetTupleTable(estate->es_tupleTable, false);
-	FreeExecutorState(estate);
+	close_estate(estate);
 
 	logicalrep_rel_close(rel, NoLock);
 
@@ -1455,7 +1458,7 @@ apply_handle_delete(StringInfo s)
 										RelationGetDescr(rel->localrel),
 										&TTSOpsVirtual);
 	resultRelInfo = makeNode(ResultRelInfo);
-	InitResultRelInfo(resultRelInfo, rel->localrel, 1, NULL, 0);
+	ExecInitResultRelation(estate, resultRelInfo, 1);
 
 	PushActiveSnapshot(GetTransactionSnapshot());
 
@@ -1474,11 +1477,7 @@ apply_handle_delete(StringInfo s)
 
 	PopActiveSnapshot();
 
-	/* Handle queued AFTER triggers. */
-	AfterTriggerEndQuery(estate);
-
-	ExecResetTupleTable(estate->es_tupleTable, false);
-	FreeExecutorState(estate);
+	close_estate(estate);
 
 	logicalrep_rel_close(rel, NoLock);
 
