@@ -140,6 +140,7 @@ static char *IsoLocaleName(const char *);
140140 */
141141static UConverter * icu_converter = NULL ;
142142
143+ static UCollator * pg_ucol_open (const char * loc_str );
143144static void init_icu_converter (void );
144145static size_t uchar_length (UConverter * converter ,
145146 const char * str , int32_t len );
@@ -1430,17 +1431,8 @@ make_icu_collator(const char *iculocstr,
14301431{
14311432#ifdef USE_ICU
14321433 UCollator * collator ;
1433- UErrorCode status ;
14341434
1435- status = U_ZERO_ERROR ;
1436- collator = ucol_open (iculocstr , & status );
1437- if (U_FAILURE (status ))
1438- ereport (ERROR ,
1439- (errmsg ("could not open collator for locale \"%s\": %s" ,
1440- iculocstr , u_errorName (status ))));
1441-
1442- if (U_ICU_VERSION_MAJOR_NUM < 54 )
1443- icu_set_collation_attributes (collator , iculocstr );
1435+ collator = pg_ucol_open (iculocstr );
14441436
14451437 /*
14461438 * If rules are specified, we extract the rules of the standard collation,
@@ -1451,6 +1443,7 @@ make_icu_collator(const char *iculocstr,
14511443 const UChar * default_rules ;
14521444 UChar * agg_rules ;
14531445 UChar * my_rules ;
1446+ UErrorCode status ;
14541447 int32_t length ;
14551448
14561449 default_rules = ucol_getRules (collator , & length );
@@ -1722,16 +1715,11 @@ get_collation_actual_version(char collprovider, const char *collcollate)
17221715 if (collprovider == COLLPROVIDER_ICU )
17231716 {
17241717 UCollator * collator ;
1725- UErrorCode status ;
17261718 UVersionInfo versioninfo ;
17271719 char buf [U_MAX_VERSION_STRING_LENGTH ];
17281720
1729- status = U_ZERO_ERROR ;
1730- collator = ucol_open (collcollate , & status );
1731- if (U_FAILURE (status ))
1732- ereport (ERROR ,
1733- (errmsg ("could not open collator for locale \"%s\": %s" ,
1734- collcollate , u_errorName (status ))));
1721+ collator = pg_ucol_open (collcollate );
1722+
17351723 ucol_getVersion (collator , versioninfo );
17361724 ucol_close (collator );
17371725
@@ -2505,6 +2493,43 @@ pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
25052493}
25062494
25072495#ifdef USE_ICU
2496+
2497+ /*
2498+ * Wrapper around ucol_open() to handle API differences for older ICU
2499+ * versions.
2500+ */
2501+ static UCollator *
2502+ pg_ucol_open (const char * loc_str )
2503+ {
2504+ UCollator * collator ;
2505+ UErrorCode status ;
2506+
2507+ /*
2508+ * Must never open default collator, because it depends on the environment
2509+ * and may change at any time.
2510+ *
2511+ * NB: the default collator is not the same as the collator for the root
2512+ * locale. The root locale may be specified as the empty string, "und", or
2513+ * "root". The default collator is opened by passing NULL to ucol_open().
2514+ */
2515+ if (loc_str == NULL )
2516+ ereport (ERROR ,
2517+ (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
2518+ errmsg ("opening default collator is not supported" )));
2519+
2520+ status = U_ZERO_ERROR ;
2521+ collator = ucol_open (loc_str , & status );
2522+ if (U_FAILURE (status ))
2523+ ereport (ERROR ,
2524+ (errmsg ("could not open collator for locale \"%s\": %s" ,
2525+ loc_str , u_errorName (status ))));
2526+
2527+ if (U_ICU_VERSION_MAJOR_NUM < 54 )
2528+ icu_set_collation_attributes (collator , loc_str );
2529+
2530+ return collator ;
2531+ }
2532+
25082533static void
25092534init_icu_converter (void )
25102535{
@@ -2771,17 +2796,8 @@ check_icu_locale(const char *icu_locale)
27712796{
27722797#ifdef USE_ICU
27732798 UCollator * collator ;
2774- UErrorCode status ;
2775-
2776- status = U_ZERO_ERROR ;
2777- collator = ucol_open (icu_locale , & status );
2778- if (U_FAILURE (status ))
2779- ereport (ERROR ,
2780- (errmsg ("could not open collator for locale \"%s\": %s" ,
2781- icu_locale , u_errorName (status ))));
27822799
2783- if (U_ICU_VERSION_MAJOR_NUM < 54 )
2784- icu_set_collation_attributes (collator , icu_locale );
2800+ collator = pg_ucol_open (icu_locale );
27852801 ucol_close (collator );
27862802#else
27872803 ereport (ERROR ,
0 commit comments