diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c
index 469a32c7b0d2e2cf8f19158d5c1b9ebeb1707a73..5fd4ee0b8249e9deda344165c7252c761d3e8a32 100644
--- a/src/backend/executor/execParallel.c
+++ b/src/backend/executor/execParallel.c
@@ -123,7 +123,7 @@ static char *
 ExecSerializePlan(Plan *plan, EState *estate)
 {
 	PlannedStmt *pstmt;
-	ListCell   *tlist;
+	ListCell   *lc;
 
 	/* We can't scribble on the original plan, so make a copy. */
 	plan = copyObject(plan);
@@ -137,9 +137,9 @@ ExecSerializePlan(Plan *plan, EState *estate)
 	 * accordingly.  This is sort of a hack; there might be better ways to do
 	 * this...
 	 */
-	foreach(tlist, plan->targetlist)
+	foreach(lc, plan->targetlist)
 	{
-		TargetEntry *tle = (TargetEntry *) lfirst(tlist);
+		TargetEntry *tle = lfirst_node(TargetEntry, lc);
 
 		tle->resjunk = false;
 	}
@@ -162,7 +162,24 @@ ExecSerializePlan(Plan *plan, EState *estate)
 	pstmt->rtable = estate->es_range_table;
 	pstmt->resultRelations = NIL;
 	pstmt->nonleafResultRelations = NIL;
-	pstmt->subplans = estate->es_plannedstmt->subplans;
+
+	/*
+	 * Transfer only parallel-safe subplans, leaving a NULL "hole" in the list
+	 * for unsafe ones (so that the list indexes of the safe ones are
+	 * preserved).  This positively ensures that the worker won't try to run,
+	 * or even do ExecInitNode on, an unsafe subplan.  That's important to
+	 * protect, eg, non-parallel-aware FDWs from getting into trouble.
+	 */
+	pstmt->subplans = NIL;
+	foreach(lc, estate->es_plannedstmt->subplans)
+	{
+		Plan	   *subplan = (Plan *) lfirst(lc);
+
+		if (subplan && !subplan->parallel_safe)
+			subplan = NULL;
+		pstmt->subplans = lappend(pstmt->subplans, subplan);
+	}
+
 	pstmt->rewindPlanIDs = NULL;
 	pstmt->rowMarks = NIL;
 	pstmt->relationOids = NIL;
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index d046e628702fe0c8d2ddd2e20639babafba4d785..cba915572ef6172f4ba0a362cf18463364ede847 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -68,7 +68,8 @@ typedef struct PlannedStmt
 	/* rtable indexes of non-leaf target relations for INSERT/UPDATE/DELETE */
 	List	   *nonleafResultRelations;
 
-	List	   *subplans;		/* Plan trees for SubPlan expressions */
+	List	   *subplans;		/* Plan trees for SubPlan expressions; note
+								 * that some could be NULL */
 
 	Bitmapset  *rewindPlanIDs;	/* indices of subplans that require REWIND */