diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c
new file mode 100644
index bed10f8..e4fec34
*** a/contrib/pg_upgrade/check.c
--- b/contrib/pg_upgrade/check.c
*************** static void check_for_prepared_transacti
*** 21,26 ****
--- 21,27 ----
  static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
  static void check_for_reg_data_type_usage(ClusterInfo *cluster);
  static void get_bin_version(ClusterInfo *cluster);
+ static char *get_canonical_locale_name(int category, const char *locale);
  
  
  /*
*************** set_locale_and_encoding(ClusterInfo *clu
*** 359,366 ****
  		i_datcollate = PQfnumber(res, "datcollate");
  		i_datctype = PQfnumber(res, "datctype");
  
! 		ctrl->lc_collate = pg_strdup(PQgetvalue(res, 0, i_datcollate));
! 		ctrl->lc_ctype = pg_strdup(PQgetvalue(res, 0, i_datctype));
  
  		PQclear(res);
  	}
--- 360,382 ----
  		i_datcollate = PQfnumber(res, "datcollate");
  		i_datctype = PQfnumber(res, "datctype");
  
! 		if (GET_MAJOR_VERSION(cluster->major_version) < 902)
! 		{
! 			/*
! 			 *	Pre-9.2 did not canonicalize the supplied locale names
! 			 *	to match what the system returns, while 9.2+ does, so
! 			 *	convert pre-9.2 to match.
! 			 */
! 			ctrl->lc_collate = get_canonical_locale_name(LC_COLLATE,
! 							   pg_strdup(PQgetvalue(res, 0, i_datcollate)));
! 			ctrl->lc_ctype = get_canonical_locale_name(LC_CTYPE,
! 							   pg_strdup(PQgetvalue(res, 0, i_datctype)));
!  		}
! 		else
! 		{
! 	 		ctrl->lc_collate = pg_strdup(PQgetvalue(res, 0, i_datcollate));
! 			ctrl->lc_ctype = pg_strdup(PQgetvalue(res, 0, i_datctype));
! 		}
  
  		PQclear(res);
  	}
*************** static void
*** 390,405 ****
  check_locale_and_encoding(ControlData *oldctrl,
  						  ControlData *newctrl)
  {
! 	/* These are often defined with inconsistent case, so use pg_strcasecmp(). */
  	if (pg_strcasecmp(oldctrl->lc_collate, newctrl->lc_collate) != 0)
  		pg_log(PG_FATAL,
! 			   "old and new cluster lc_collate values do not match\n");
  	if (pg_strcasecmp(oldctrl->lc_ctype, newctrl->lc_ctype) != 0)
  		pg_log(PG_FATAL,
! 			   "old and new cluster lc_ctype values do not match\n");
  	if (pg_strcasecmp(oldctrl->encoding, newctrl->encoding) != 0)
  		pg_log(PG_FATAL,
! 			   "old and new cluster encoding values do not match\n");
  }
  
  
--- 406,428 ----
  check_locale_and_encoding(ControlData *oldctrl,
  						  ControlData *newctrl)
  {
! 	/*
! 	 *	These are often defined with inconsistent case, so use pg_strcasecmp().
! 	 *	They also often use inconsistent hyphenation, which we cannot fix, e.g.
! 	 *	UTF-8 vs. UTF8, so at least we display the mismatching values.
! 	 */
  	if (pg_strcasecmp(oldctrl->lc_collate, newctrl->lc_collate) != 0)
  		pg_log(PG_FATAL,
! 			   "lc_collate cluster values do not match:  old \"%s\", new \"%s\"\n",
! 			   oldctrl->lc_collate, newctrl->lc_collate);
  	if (pg_strcasecmp(oldctrl->lc_ctype, newctrl->lc_ctype) != 0)
  		pg_log(PG_FATAL,
! 			   "lc_ctype cluster values do not match:  old \"%s\", new \"%s\"\n",
! 			   oldctrl->lc_ctype, newctrl->lc_ctype);
  	if (pg_strcasecmp(oldctrl->encoding, newctrl->encoding) != 0)
  		pg_log(PG_FATAL,
! 			   "encoding cluster values do not match:  old \"%s\", new \"%s\"\n",
! 			   oldctrl->encoding, newctrl->encoding);
  }
  
  
*************** get_bin_version(ClusterInfo *cluster)
*** 931,933 ****
--- 954,993 ----
  
  	cluster->bin_version = (pre_dot * 100 + post_dot) * 100;
  }
+ 
+ 
+ /*
+  * get_canonical_locale_name
+  *
+  * Send the locale name to the system, and hope we get back a canonical
+  * version.  This should match the backend's check_locale() function.
+  */
+ static char *
+ get_canonical_locale_name(int category, const char *locale)
+ {
+ 	char	   *save;
+ 	char	   *res;
+ 
+ 	save = setlocale(category, NULL);
+ 	if (!save)
+         pg_log(PG_FATAL, "failed to get the current locale\n");
+ 
+ 	/* 'save' may be pointing at a modifiable scratch variable, so copy it. */
+ 	save = pg_strdup(save);
+ 
+ 	/* set the locale with setlocale, to see if it accepts it. */
+ 	res = setlocale(category, locale);
+ 
+ 	if (!res)
+         pg_log(PG_FATAL, "failed to get system local name for \"%s\"\n", res);
+ 
+ 	res = pg_strdup(res);
+ 
+ 	/* restore old value. */
+ 	if (!setlocale(category, save))
+         pg_log(PG_FATAL, "failed to restore old locale \"%s\"\n", save);
+ 
+ 	free(save);
+ 
+ 	return res;
+ }
