diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 2042b4dac3c3387a94e95a74e07581c1c261e04e..068ba771ea858892ab9da6a9570fb2cd2f652a7b 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.88 2000/07/25 04:30:42 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.89 2000/07/26 23:46:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -40,9 +40,23 @@
 #include "utils/syscache.h"
 
 
+/*
+ * DoneMatchingIndexKeys() - MACRO
+ *
+ * Determine whether we should continue matching index keys in a clause.
+ * Depends on if there are more to match or if this is a functional index.
+ * In the latter case we stop after the first match since the there can
+ * be only key (i.e. the function's return value) and the attributes in
+ * keys list represent the arguments to the function.  -mer 3 Oct. 1991
+ */
+#define DoneMatchingIndexKeys(indexkeys, index) \
+		(indexkeys[0] == 0 || \
+		 (index->indproc != InvalidOid))
+
 #define is_indexable_operator(clause,opclass,relam,indexkey_on_left) \
 	(indexable_operator(clause,opclass,relam,indexkey_on_left) != InvalidOid)
 
+
 static void match_index_orclauses(RelOptInfo *rel, IndexOptInfo *index,
 					  List *restrictinfo_list);
 static List *match_index_orclause(RelOptInfo *rel, IndexOptInfo *index,
@@ -354,10 +368,11 @@ match_index_orclause(RelOptInfo *rel,
  * index, or if it is an AND clause any of whose members is an opclause
  * that matches the index.
  *
- * We currently only look to match the first key of an index against
- * 'or' subclauses.  There are cases where a later key of a multi-key
- * index could be used (if other top-level clauses match earlier keys
- * of the index), but our poor brains are hurting already...
+ * For multi-key indexes, we only look for matches to the first key;
+ * without such a match the index is useless.  If the clause is an AND
+ * then we may be able to extract additional subclauses to use with the
+ * later indexkeys, but we need not worry about that until
+ * extract_or_indexqual_conditions() is called (if it ever is).
  */
 static bool
 match_or_subclause_to_indexkey(RelOptInfo *rel,
@@ -404,19 +419,45 @@ extract_or_indexqual_conditions(RelOptInfo *rel,
 								Expr *orsubclause)
 {
 	List	   *quals = NIL;
-	int			indexkey = index->indexkeys[0];
-	Oid			opclass = index->classlist[0];
 
 	if (and_clause((Node *) orsubclause))
 	{
-		List	   *item;
+		/*
+		 * Extract relevant sub-subclauses in indexkey order.  This is just
+		 * like group_clauses_by_indexkey() except that the input and output
+		 * are lists of bare clauses, not of RestrictInfo nodes.
+		 */
+		int		   *indexkeys = index->indexkeys;
+		Oid		   *classes = index->classlist;
 
-		foreach(item, orsubclause->args)
+		do
 		{
-			if (match_clause_to_indexkey(rel, index, indexkey, opclass,
-										 lfirst(item), false))
-				quals = lappend(quals, lfirst(item));
-		}
+			int			curIndxKey = indexkeys[0];
+			Oid			curClass = classes[0];
+			List	   *clausegroup = NIL;
+			List	   *item;
+
+			foreach(item, orsubclause->args)
+			{
+				if (match_clause_to_indexkey(rel, index,
+											 curIndxKey, curClass,
+											 lfirst(item), false))
+					clausegroup = lappend(clausegroup, lfirst(item));
+			}
+
+			/*
+			 * If no clauses match this key, we're done; we don't want to look
+			 * at keys to its right.
+			 */
+			if (clausegroup == NIL)
+				break;
+
+			quals = nconc(quals, clausegroup);
+
+			indexkeys++;
+			classes++;
+		} while (!DoneMatchingIndexKeys(indexkeys, index));
+
 		if (quals == NIL)
 			elog(ERROR, "extract_or_indexqual_conditions: no matching clause");
 	}
@@ -435,19 +476,6 @@ extract_or_indexqual_conditions(RelOptInfo *rel,
  ****************************************************************************/
 
 
-/*
- * DoneMatchingIndexKeys() - MACRO
- *
- * Determine whether we should continue matching index keys in a clause.
- * Depends on if there are more to match or if this is a functional index.
- * In the latter case we stop after the first match since the there can
- * be only key (i.e. the function's return value) and the attributes in
- * keys list represent the arguments to the function.  -mer 3 Oct. 1991
- */
-#define DoneMatchingIndexKeys(indexkeys, index) \
-		(indexkeys[0] == 0 || \
-		 (index->indproc != InvalidOid))
-
 /*
  * group_clauses_by_indexkey
  *	  Generates a list of restriction clauses that can be used with an index.