diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index b9439e60a8be0f7efc2c86acd391c065efe2f376..47dd3ec55b080d788c143021f6eeb8dd7d508ca2 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.222 2007/05/22 01:40:33 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.223 2007/11/07 22:37:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2668,6 +2668,7 @@ prefix_quals(Node *leftop, Oid opfamily,
 	Oid			datatype;
 	Oid			oproid;
 	Expr	   *expr;
+	FmgrInfo	ltproc;
 	Const	   *greaterstr;
 
 	Assert(pstatus != Pattern_Prefix_None);
@@ -2759,13 +2760,14 @@ prefix_quals(Node *leftop, Oid opfamily,
 	 * "x < greaterstr".
 	 *-------
 	 */
-	greaterstr = make_greater_string(prefix_const);
+	oproid = get_opfamily_member(opfamily, datatype, datatype,
+								 BTLessStrategyNumber);
+	if (oproid == InvalidOid)
+		elog(ERROR, "no < operator for opfamily %u", opfamily);
+	fmgr_info(get_opcode(oproid), &ltproc);
+	greaterstr = make_greater_string(prefix_const, &ltproc);
 	if (greaterstr)
 	{
-		oproid = get_opfamily_member(opfamily, datatype, datatype,
-									 BTLessStrategyNumber);
-		if (oproid == InvalidOid)
-			elog(ERROR, "no < operator for opfamily %u", opfamily);
 		expr = make_opclause(oproid, BOOLOID, false,
 							 (Expr *) leftop, (Expr *) greaterstr);
 		result = lappend(result,
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 5bf04d052a63ae9a292c6285f9f76c24e240e5bf..095b389eb127f1de80b47bdc2226863f870e2e0c 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.237 2007/11/07 21:00:37 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.238 2007/11/07 22:37:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -4302,17 +4302,17 @@ prefix_selectivity(VariableStatData *vardata,
 	 *	"x < greaterstr".
 	 *-------
 	 */
-	greaterstrcon = make_greater_string(prefixcon);
+	cmpopr = get_opfamily_member(opfamily, vartype, vartype,
+								 BTLessStrategyNumber);
+	if (cmpopr == InvalidOid)
+		elog(ERROR, "no < operator for opfamily %u", opfamily);
+	fmgr_info(get_opcode(cmpopr), &opproc);
+
+	greaterstrcon = make_greater_string(prefixcon, &opproc);
 	if (greaterstrcon)
 	{
 		Selectivity topsel;
 
-		cmpopr = get_opfamily_member(opfamily, vartype, vartype,
-									 BTLessStrategyNumber);
-		if (cmpopr == InvalidOid)
-			elog(ERROR, "no < operator for opfamily %u", opfamily);
-		fmgr_info(get_opcode(cmpopr), &opproc);
-
 		topsel = ineq_histogram_selectivity(vardata, &opproc, false,
 											greaterstrcon->constvalue,
 											greaterstrcon->consttype);
@@ -4589,8 +4589,17 @@ pattern_selectivity(Const *patt, Pattern_Type ptype)
  * in the form of a Const pointer; else return NULL.
  *
  * The key requirement here is that given a prefix string, say "foo",
- * we must be able to generate another string "fop" that is greater
- * than all strings "foobar" starting with "foo".
+ * we must be able to generate another string "fop" that is greater than
+ * all strings "foobar" starting with "foo".  We can test that we have
+ * generated a string greater than the prefix string, but in non-C locales
+ * that is not a bulletproof guarantee that an extension of the string might
+ * not sort after it; an example is that "foo " is less than "foo!", but it
+ * is not clear that a "dictionary" sort ordering will consider "foo!" less
+ * than "foo bar".  Therefore, this function should be used only for
+ * estimation purposes when working in a non-C locale.
+ *
+ * The caller must provide the appropriate "less than" comparison function
+ * for testing the strings.
  *
  * If we max out the righthand byte, truncate off the last character
  * and start incrementing the next.  For example, if "z" were the last
@@ -4599,20 +4608,15 @@ pattern_selectivity(Const *patt, Pattern_Type ptype)
  *
  * This could be rather slow in the worst case, but in most cases we
  * won't have to try more than one or two strings before succeeding.
- *
- * NOTE: at present this assumes we are in the C locale, so that simple
- * bytewise comparison applies.  However, we might be in a multibyte
- * encoding such as UTF8, so we do have to watch out for generating
- * invalid encoding sequences.
  */
 Const *
-make_greater_string(const Const *str_const)
+make_greater_string(const Const *str_const, FmgrInfo *ltproc)
 {
 	Oid			datatype = str_const->consttype;
 	char	   *workstr;
 	int			len;
 
-	/* Get the string and a modifiable copy */
+	/* Get a modifiable copy of the string in C-string format */
 	if (datatype == NAMEOID)
 	{
 		workstr = DatumGetCString(DirectFunctionCall1(nameout,
@@ -4660,8 +4664,18 @@ make_greater_string(const Const *str_const)
 			else
 				workstr_const = string_to_bytea_const(workstr, len);
 
-			pfree(workstr);
-			return workstr_const;
+			if (DatumGetBool(FunctionCall2(ltproc,
+										   str_const->constvalue,
+										   workstr_const->constvalue)))
+			{
+				/* Successfully made a string larger than the input */
+				pfree(workstr);
+				return workstr_const;
+			}
+
+			/* No good, release unusable value and try again */
+			pfree(DatumGetPointer(workstr_const->constvalue));
+			pfree(workstr_const);
 		}
 
 		/* restore last byte so we don't confuse pg_mbcliplen */
diff --git a/src/include/utils/selfuncs.h b/src/include/utils/selfuncs.h
index fc409d9bddd27d1159586480443d13ba116bd1a6..f92bb16d07981fab39ffd5477af6284da122657f 100644
--- a/src/include/utils/selfuncs.h
+++ b/src/include/utils/selfuncs.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/selfuncs.h,v 1.40 2007/08/31 23:35:22 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/selfuncs.h,v 1.41 2007/11/07 22:37:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -118,7 +118,7 @@ extern Pattern_Prefix_Status pattern_fixed_prefix(Const *patt,
 					 Pattern_Type ptype,
 					 Const **prefix,
 					 Const **rest);
-extern Const *make_greater_string(const Const *str_const);
+extern Const *make_greater_string(const Const *str_const, FmgrInfo *ltproc);
 
 extern Datum eqsel(PG_FUNCTION_ARGS);
 extern Datum neqsel(PG_FUNCTION_ARGS);