diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 9b5c226b55b0566f6d9c396b37cdd52d802d791e..667cdce4f2410f909a19579cccd89ec5a5141304 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.41 1999/07/16 04:59:15 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.42 1999/07/27 06:23:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -147,13 +147,14 @@ update_rels_pathlist_for_joins(Query *root, List *joinrels)
 /*
  * best_innerjoin
  *	  Find the cheapest index path that has already been identified by
- *	  (indexable_joinclauses) as being a possible inner path for the given
- *	  outer relation in a nestloop join.
+ *	  indexable_joinclauses() as being a possible inner path for the given
+ *	  outer relation(s) in a nestloop join.
  *
- * 'join_paths' is a list of join nodes
- * 'outer_relid' is the relid of the outer join relation
+ * 'join_paths' is a list of potential inner indexscan join paths
+ * 'outer_relids' is the relid list of the outer join relation
  *
- * Returns the pathnode of the selected path.
+ * Returns the pathnode of the best path, or NULL if there's no
+ * usable path.
  */
 static Path *
 best_innerjoin(List *join_paths, Relids outer_relids)
@@ -165,7 +166,11 @@ best_innerjoin(List *join_paths, Relids outer_relids)
 	{
 		Path	   *path = (Path *) lfirst(join_path);
 
-		if (intMember(lfirsti(path->joinid), outer_relids) &&
+		/* path->joinid is the set of base rels that must be part of
+		 * outer_relids in order to use this inner path, because those
+		 * rels are used in the index join quals of this inner path.
+		 */
+		if (is_subset(path->joinid, outer_relids) &&
 			(cheapest == NULL ||
 			 path_is_cheaper(path, cheapest)))
 			cheapest = path;
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 9fba28759a0ca835d72e8efcb7a7dcbd08b97753..1eac677074447386e97f10da9afa3402b6f956cb 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.37 1999/07/16 04:59:15 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.38 1999/07/27 06:23:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,8 +21,6 @@
 #include "optimizer/tlist.h"
 
 static List *new_joininfo_list(List *joininfo_list, Relids join_relids);
-static bool nonoverlap_sets(List *s1, List *s2);
-static bool is_subset(List *s1, List *s2);
 static void set_joinrel_size(RelOptInfo *joinrel, RelOptInfo *outer_rel,
 				 RelOptInfo *inner_rel, JoinInfo *jinfo);
 static RelOptInfo *make_join_rel(RelOptInfo *outer_rel, RelOptInfo *inner_rel,
@@ -373,8 +371,8 @@ new_joininfo_list(List *joininfo_list, Relids join_relids)
 RelOptInfo *
 get_cheapest_complete_rel(List *join_rel_list)
 {
-	List	   *xrel = NIL;
 	RelOptInfo *final_rel = NULL;
+	List	   *xrel;
 
 	/*
 	 * find the relations that have no further joins, i.e., its joininfos
@@ -383,8 +381,8 @@ get_cheapest_complete_rel(List *join_rel_list)
 	foreach(xrel, join_rel_list)
 	{
 		RelOptInfo *rel = (RelOptInfo *) lfirst(xrel);
-		List	   *xjoininfo = NIL;
 		bool		final = true;
+		List	   *xjoininfo;
 
 		foreach(xjoininfo, rel->joininfo)
 		{
@@ -405,36 +403,6 @@ get_cheapest_complete_rel(List *join_rel_list)
 	return final_rel;
 }
 
-static bool
-nonoverlap_sets(List *s1, List *s2)
-{
-	List	   *x = NIL;
-
-	foreach(x, s1)
-	{
-		int			e = lfirsti(x);
-
-		if (intMember(e, s2))
-			return false;
-	}
-	return true;
-}
-
-static bool
-is_subset(List *s1, List *s2)
-{
-	List	   *x = NIL;
-
-	foreach(x, s1)
-	{
-		int			e = lfirsti(x);
-
-		if (!intMember(e, s2))
-			return false;
-	}
-	return true;
-}
-
 static void
 set_joinrel_size(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinInfo *jinfo)
 {
@@ -466,3 +434,39 @@ set_joinrel_size(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_r
 
 	joinrel->tuples = ntuples;
 }
+
+/*
+ * Subset-inclusion tests on integer lists.
+ *
+ * XXX these probably ought to be in nodes/list.c or some such place.
+ */
+
+bool
+nonoverlap_sets(List *s1, List *s2)
+{
+	List	   *x;
+
+	foreach(x, s1)
+	{
+		int			e = lfirsti(x);
+
+		if (intMember(e, s2))
+			return false;
+	}
+	return true;
+}
+
+bool
+is_subset(List *s1, List *s2)
+{
+	List	   *x;
+
+	foreach(x, s1)
+	{
+		int			e = lfirsti(x);
+
+		if (!intMember(e, s2))
+			return false;
+	}
+	return true;
+}
diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h
index 75d9e328458afb81ec7b32d4732e5fa214b4bb8f..f074f1eee1f5a8b7d82d70ddcc2f791cc5001d8f 100644
--- a/src/include/optimizer/paths.h
+++ b/src/include/optimizer/paths.h
@@ -1,13 +1,13 @@
 /*-------------------------------------------------------------------------
  *
  * paths.h
- *	  prototypes for various files in optimizer/paths (were separate
- *	  header files
+ *	  prototypes for various files in optimizer/path (were separate
+ *	  header files)
  *
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: paths.h,v 1.32 1999/07/27 03:51:01 tgl Exp $
+ * $Id: paths.h,v 1.33 1999/07/27 06:23:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -17,12 +17,12 @@
 #include "nodes/relation.h"
 
 /*
- * allpaths.h
+ * allpaths.c
  */
 extern RelOptInfo *make_one_rel(Query *root, List *rels);
 
 /*
- * indxpath.h
+ * indxpath.c
  *	  routines to generate index paths
  */
 extern List *create_index_paths(Query *root, RelOptInfo *rel, List *indices,
@@ -31,26 +31,26 @@ extern List *create_index_paths(Query *root, RelOptInfo *rel, List *indices,
 extern List *expand_indexqual_conditions(List *indexquals);
 
 /*
- * joinpath.h
+ * joinpath.c
  *	   routines to create join paths
  */
 extern void update_rels_pathlist_for_joins(Query *root, List *joinrels);
 
 
 /*
- * orindxpath.h
+ * orindxpath.c
  */
 extern List *create_or_index_paths(Query *root, RelOptInfo *rel, List *clauses);
 
 /*
- * hashutils.h
+ * hashutils.c
  *	  routines to deal with hash keys and clauses
  */
 extern List *group_clauses_by_hashop(List *restrictinfo_list,
 						Relids inner_relids);
 
 /*
- * joinutils.h
+ * joinutils.c
  *	  generic join method key/clause routines
  */
 extern bool order_joinkeys_by_pathkeys(List *pathkeys,
@@ -65,7 +65,7 @@ extern List *new_join_pathkeys(List *outer_pathkeys,
 				  List *join_rel_tlist, List *joinclauses);
 
 /*
- * mergeutils.h
+ * mergeutils.c
  *	  routines to deal with merge keys and clauses
  */
 extern List *group_clauses_by_order(List *restrictinfo_list,
@@ -74,7 +74,7 @@ extern MergeInfo *match_order_mergeinfo(PathOrder *ordering,
 					  List *mergeinfo_list);
 
 /*
- * joinrels.h
+ * joinrels.c
  *	  routines to determine which relations to join
  */
 extern List *make_rels_by_joins(Query *root, List *old_rels);
@@ -83,6 +83,8 @@ extern List *make_rels_by_clause_joins(Query *root, RelOptInfo *old_rel,
 extern List *make_rels_by_clauseless_joins(RelOptInfo *old_rel,
 							  List *inner_rels);
 extern RelOptInfo *get_cheapest_complete_rel(List *join_rel_list);
+extern bool nonoverlap_sets(List *s1, List *s2);
+extern bool is_subset(List *s1, List *s2);
 
 /*
  * prototypes for path/prune.c