diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c
index a61e35f92d..54ae0379b3 100644
--- a/src/backend/optimizer/plan/analyzejoins.c
+++ b/src/backend/optimizer/plan/analyzejoins.c
@@ -35,7 +35,8 @@
 
 /* local functions */
 static bool join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo);
-static void remove_rel_from_query(PlannerInfo *root, int relid, int ojrelid,
+static void remove_rel_from_query(PlannerInfo *root, int relid,
+								  SpecialJoinInfo *removable_sjinfo,
 								  Relids joinrelids);
 static void remove_rel_from_restrictinfo(RestrictInfo *rinfo,
 										 int relid, int ojrelid);
@@ -93,7 +94,7 @@ restart:
 		if (sjinfo->ojrelid != 0)
 			joinrelids = bms_add_member(joinrelids, sjinfo->ojrelid);
 
-		remove_rel_from_query(root, innerrelid, sjinfo->ojrelid, joinrelids);
+		remove_rel_from_query(root, innerrelid, sjinfo, joinrelids);
 
 		/* We verify that exactly one reference gets removed from joinlist */
 		nremoved = 0;
@@ -331,10 +332,13 @@ join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo)
  * the planner's data structures that will actually be consulted later.
  */
 static void
-remove_rel_from_query(PlannerInfo *root, int relid, int ojrelid,
+remove_rel_from_query(PlannerInfo *root, int relid,
+					  SpecialJoinInfo *removable_sjinfo,
 					  Relids joinrelids)
 {
 	RelOptInfo *rel = find_base_rel(root, relid);
+	int			ojrelid = removable_sjinfo->ojrelid;
+	Relids		join_plus_commute;
 	List	   *joininfos;
 	Index		rti;
 	ListCell   *l;
@@ -454,8 +458,19 @@ remove_rel_from_query(PlannerInfo *root, int relid, int ojrelid,
 	 * outerjoin-delayed quals, which can get marked as requiring the rel in
 	 * order to force them to be evaluated at or above the join.  We can't
 	 * just discard them, though.  Only quals that logically belonged to the
-	 * outer join being discarded should be removed from the query.
-	 *
+	 * outer join being discarded should be removed from the query.  However,
+	 * we might encounter a qual that is a clone of a deletable qual with some
+	 * outer-join relids added (see deconstruct_distribute_oj_quals).  To
+	 * ensure we get rid of such clones as well, add the relids of all OJs
+	 * commutable with this one to the set we test against for
+	 * pushed-down-ness.
+	 */
+	join_plus_commute = bms_union(joinrelids,
+								  removable_sjinfo->commute_below_l);
+	join_plus_commute = bms_add_members(join_plus_commute,
+										removable_sjinfo->commute_above_r);
+
+	/*
 	 * We must make a copy of the rel's old joininfo list before starting the
 	 * loop, because otherwise remove_join_clause_from_rels would destroy the
 	 * list while we're scanning it.
@@ -467,7 +482,7 @@ remove_rel_from_query(PlannerInfo *root, int relid, int ojrelid,
 
 		remove_join_clause_from_rels(root, rinfo, rinfo->required_relids);
 
-		if (RINFO_IS_PUSHED_DOWN(rinfo, joinrelids))
+		if (RINFO_IS_PUSHED_DOWN(rinfo, join_plus_commute))
 		{
 			/*
 			 * There might be references to relid or ojrelid in the
