diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c
index 2ad31203697cd0c9898ef567032e84f74319899f..f96d7bb5554a177f17e9f8e2982969007509380a 100644
--- a/src/backend/optimizer/path/pathkeys.c
+++ b/src/backend/optimizer/path/pathkeys.c
@@ -11,7 +11,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.87 2007/11/02 18:54:15 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.88 2007/11/08 19:25:37 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -292,13 +292,14 @@ make_pathkey_from_sortinfo(PlannerInfo *root,
 	if (exprType((Node *) expr) != opcintype &&
 		!IsPolymorphicType(opcintype))
 	{
-		/* Strip any existing RelabelType, and add a new one */
+		/* Strip any existing RelabelType, and add a new one if needed */
 		while (expr && IsA(expr, RelabelType))
 			expr = (Expr *) ((RelabelType *) expr)->arg;
-		expr = (Expr *) makeRelabelType(expr,
-										opcintype,
-										-1,
-										COERCE_DONTCARE);
+		if (exprType((Node *) expr) != opcintype)
+			expr = (Expr *) makeRelabelType(expr,
+											opcintype,
+											-1,
+											COERCE_DONTCARE);
 	}
 
 	/* Now find or create a matching EquivalenceClass */
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index fb9b437174fb3f362dd3a879561201436e2484f9..becb8255e87b22225a8a40ed2f7506900bfd8cb5 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.232 2007/11/02 18:54:15 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.233 2007/11/08 19:25:37 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2738,7 +2738,7 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
 		/*
 		 * We can sort by any non-constant expression listed in the pathkey's
 		 * EquivalenceClass.  For now, we take the first one that corresponds
-		 * to an available Var in the tlist. If there isn't any, use the first
+		 * to an available item in the tlist. If there isn't any, use the first
 		 * one that is an expression in the input's vars.  (The non-const
 		 * restriction only matters if the EC is below_outer_join; but if it
 		 * isn't, it won't contain consts anyway, else we'd have discarded
@@ -2766,24 +2766,21 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
 
 			/*
 			 * We can also use it if the pathkey expression is a relabel
-			 * of the tlist entry.  This is needed for binary-compatible
-			 * cases (cf. make_pathkey_from_sortinfo).
+			 * of the tlist entry, or vice versa.  This is needed for
+			 * binary-compatible cases (cf. make_pathkey_from_sortinfo).
+			 * We prefer an exact match, though, so we do the basic
+			 * search first.
 			 */
-			if (IsA(em->em_expr, RelabelType))
+			tle = tlist_member_ignore_relabel((Node *) em->em_expr, tlist);
+			if (tle)
 			{
-				Expr	   *rtarg = ((RelabelType *) em->em_expr)->arg;
-
-				tle = tlist_member((Node *) rtarg, tlist);
-				if (tle)
-				{
-					pk_datatype = em->em_datatype;
-					break;			/* found expr already in tlist */
-				}
+				pk_datatype = em->em_datatype;
+				break;			/* found expr already in tlist */
 			}
 		}
 		if (!tle)
 		{
-			/* No matching Var; look for a computable expression */
+			/* No matching tlist item; look for a computable expression */
 			Expr   *sortexpr = NULL;
 
 			foreach(j, pathkey->pk_eclass->ec_members)
@@ -2798,7 +2795,7 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
 				exprvars = pull_var_clause((Node *) sortexpr, false);
 				foreach(k, exprvars)
 				{
-					if (!tlist_member(lfirst(k), tlist))
+					if (!tlist_member_ignore_relabel(lfirst(k), tlist))
 						break;
 				}
 				list_free(exprvars);
diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c
index 1e507235c53f120107dd52af7f86723ab23d89ab..e58fe7dc7f1af828bc6ff1e469b699b2fc52edc6 100644
--- a/src/backend/optimizer/util/tlist.c
+++ b/src/backend/optimizer/util/tlist.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.74 2007/01/05 22:19:33 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.75 2007/11/08 19:25:37 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,6 +44,34 @@ tlist_member(Node *node, List *targetlist)
 	return NULL;
 }
 
+/*
+ * tlist_member_ignore_relabel
+ *	  Same as above, except that we ignore top-level RelabelType nodes
+ *	  while checking for a match.  This is needed for some scenarios
+ *	  involving binary-compatible sort operations.
+ */
+TargetEntry *
+tlist_member_ignore_relabel(Node *node, List *targetlist)
+{
+	ListCell   *temp;
+
+	while (node && IsA(node, RelabelType))
+		node = (Node *) ((RelabelType *) node)->arg;
+
+	foreach(temp, targetlist)
+	{
+		TargetEntry *tlentry = (TargetEntry *) lfirst(temp);
+		Expr   *tlexpr = tlentry->expr;
+
+		while (tlexpr && IsA(tlexpr, RelabelType))
+			tlexpr = ((RelabelType *) tlexpr)->arg;
+
+		if (equal(node, tlexpr))
+			return tlentry;
+	}
+	return NULL;
+}
+
 /*
  * flatten_tlist
  *	  Create a target list that only contains unique variables.
diff --git a/src/include/optimizer/tlist.h b/src/include/optimizer/tlist.h
index 31156ebcbcc87e345cb720b43aaccd5ee4b19a10..bb127cbce2b62bedd9ed769a284be6af62091267 100644
--- a/src/include/optimizer/tlist.h
+++ b/src/include/optimizer/tlist.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/optimizer/tlist.h,v 1.45 2007/01/05 22:19:56 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/tlist.h,v 1.46 2007/11/08 19:25:37 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,6 +18,7 @@
 
 
 extern TargetEntry *tlist_member(Node *node, List *targetlist);
+extern TargetEntry *tlist_member_ignore_relabel(Node *node, List *targetlist);
 
 extern List *flatten_tlist(List *tlist);
 extern List *add_to_flat_tlist(List *tlist, List *vars);