diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index e34b9553bd4a0560e2226ab8894d4b3560a54320..562177296ca501070ed65f54db62b3f0dfa8d92c 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -1969,11 +1969,15 @@ mutate_eclass_expressions(PlannerInfo *root,
  * is no value in using more than one.	(But it *is* worthwhile to create
  * a separate parameterized path for each one, since that leads to different
  * join orders.)
+ *
+ * The caller can pass a Relids set of rels we aren't interested in joining
+ * to, so as to save the work of creating useless clauses.
  */
 List *
 generate_implied_equalities_for_indexcol(PlannerInfo *root,
 										 IndexOptInfo *index,
-										 int indexcol)
+										 int indexcol,
+										 Relids prohibited_rels)
 {
 	List	   *result = NIL;
 	RelOptInfo *rel = index->rel;
@@ -2050,6 +2054,10 @@ generate_implied_equalities_for_indexcol(PlannerInfo *root,
 				bms_overlap(other_em->em_relids, rel->relids))
 				continue;
 
+			/* Forget it if caller doesn't want joins to this rel */
+			if (bms_overlap(other_em->em_relids, prohibited_rels))
+				continue;
+
 			/*
 			 * Also, if this is a child rel, avoid generating a useless join
 			 * to its parent rel.
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 69fcf90e361f75eedc5ce283cbb998c6eaa532cf..6a321739100a02406aa7a45081048fae7ed2bff9 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -121,10 +121,12 @@ static void match_restriction_clauses_to_index(RelOptInfo *rel,
 								   IndexClauseSet *clauseset);
 static void match_join_clauses_to_index(PlannerInfo *root,
 							RelOptInfo *rel, IndexOptInfo *index,
+							Relids lateral_referencers,
 							IndexClauseSet *clauseset,
 							List **joinorclauses);
 static void match_eclass_clauses_to_index(PlannerInfo *root,
 							  IndexOptInfo *index,
+							  Relids lateral_referencers,
 							  IndexClauseSet *clauseset);
 static void match_clauses_to_index(IndexOptInfo *index,
 					   List *clauses,
@@ -211,22 +213,40 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
 	List	   *bitindexpaths;
 	List	   *bitjoinpaths;
 	List	   *joinorclauses;
+	Relids		lateral_referencers;
 	IndexClauseSet rclauseset;
 	IndexClauseSet jclauseset;
 	IndexClauseSet eclauseset;
-	ListCell   *ilist;
+	ListCell   *lc;
 
 	/* Skip the whole mess if no indexes */
 	if (rel->indexlist == NIL)
 		return;
 
+	/*
+	 * If there are any rels that have LATERAL references to this one, we
+	 * cannot use join quals referencing them as index quals for this one,
+	 * since such rels would have to be on the inside not the outside of a
+	 * nestloop join relative to this one.  Create a Relids set listing all
+	 * such rels, for use in checks of potential join clauses.
+	 */
+	lateral_referencers = NULL;
+	foreach(lc, root->lateral_info_list)
+	{
+		LateralJoinInfo *ljinfo = (LateralJoinInfo *) lfirst(lc);
+
+		if (bms_is_member(rel->relid, ljinfo->lateral_lhs))
+			lateral_referencers = bms_add_member(lateral_referencers,
+												 ljinfo->lateral_rhs);
+	}
+
 	/* Bitmap paths are collected and then dealt with at the end */
 	bitindexpaths = bitjoinpaths = joinorclauses = NIL;
 
 	/* Examine each index in turn */
-	foreach(ilist, rel->indexlist)
+	foreach(lc, rel->indexlist)
 	{
-		IndexOptInfo *index = (IndexOptInfo *) lfirst(ilist);
+		IndexOptInfo *index = (IndexOptInfo *) lfirst(lc);
 
 		/* Protect limited-size array in IndexClauseSets */
 		Assert(index->ncolumns <= INDEX_MAX_KEYS);
@@ -260,7 +280,7 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
 		 * EquivalenceClasses.	Also, collect join OR clauses for later.
 		 */
 		MemSet(&jclauseset, 0, sizeof(jclauseset));
-		match_join_clauses_to_index(root, rel, index,
+		match_join_clauses_to_index(root, rel, index, lateral_referencers,
 									&jclauseset, &joinorclauses);
 
 		/*
@@ -268,7 +288,8 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
 		 * the index.
 		 */
 		MemSet(&eclauseset, 0, sizeof(eclauseset));
-		match_eclass_clauses_to_index(root, index, &eclauseset);
+		match_eclass_clauses_to_index(root, index, lateral_referencers,
+									  &eclauseset);
 
 		/*
 		 * If we found any plain or eclass join clauses, decide what to do
@@ -1796,6 +1817,7 @@ match_restriction_clauses_to_index(RelOptInfo *rel, IndexOptInfo *index,
 static void
 match_join_clauses_to_index(PlannerInfo *root,
 							RelOptInfo *rel, IndexOptInfo *index,
+							Relids lateral_referencers,
 							IndexClauseSet *clauseset,
 							List **joinorclauses)
 {
@@ -1810,6 +1832,10 @@ match_join_clauses_to_index(PlannerInfo *root,
 		if (!join_clause_is_movable_to(rinfo, rel->relid))
 			continue;
 
+		/* Not useful if it conflicts with any LATERAL references */
+		if (bms_overlap(rinfo->clause_relids, lateral_referencers))
+			continue;
+
 		/* Potentially usable, so see if it matches the index or is an OR */
 		if (restriction_is_or_clause(rinfo))
 			*joinorclauses = lappend(*joinorclauses, rinfo);
@@ -1825,6 +1851,7 @@ match_join_clauses_to_index(PlannerInfo *root,
  */
 static void
 match_eclass_clauses_to_index(PlannerInfo *root, IndexOptInfo *index,
+							  Relids lateral_referencers,
 							  IndexClauseSet *clauseset)
 {
 	int			indexcol;
@@ -1837,9 +1864,11 @@ match_eclass_clauses_to_index(PlannerInfo *root, IndexOptInfo *index,
 	{
 		List	   *clauses;
 
+		/* Generate clauses, skipping any that join to lateral_referencers */
 		clauses = generate_implied_equalities_for_indexcol(root,
 														   index,
-														   indexcol);
+														   indexcol,
+														lateral_referencers);
 
 		/*
 		 * We have to check whether the results actually do match the index,
diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h
index b6fb8ee5ce93cda5de8a824528378921f43f0584..165856de0bcdf730ef49479fc6d83165bad479ab 100644
--- a/src/include/optimizer/paths.h
+++ b/src/include/optimizer/paths.h
@@ -127,7 +127,8 @@ extern void mutate_eclass_expressions(PlannerInfo *root,
 						  void *context);
 extern List *generate_implied_equalities_for_indexcol(PlannerInfo *root,
 										 IndexOptInfo *index,
-										 int indexcol);
+										 int indexcol,
+										 Relids prohibited_rels);
 extern bool have_relevant_eclass_joinclause(PlannerInfo *root,
 								RelOptInfo *rel1, RelOptInfo *rel2);
 extern bool has_relevant_eclass_joinclause(PlannerInfo *root,