Skip to content

Commit a326aac

Browse files
committed
Wrap ICU ucol_open().
Hide details of supporting older ICU versions in a wrapper function. The current code only needs to handle icu_set_collation_attributes(), but a subsequent commit will add additional version-specific code. Discussion: https://postgr.es/m/7ee414ad-deb5-1144-8a0e-b34ae3b71cd5@enterprisedb.com Reviewed-by: Peter Eisentraut
1 parent adedf54 commit a326aac

File tree

1 file changed

+43
-27
lines changed

1 file changed

+43
-27
lines changed

src/backend/utils/adt/pg_locale.c

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ static char *IsoLocaleName(const char *);
140140
*/
141141
static UConverter *icu_converter = NULL;
142142

143+
static UCollator *pg_ucol_open(const char *loc_str);
143144
static void init_icu_converter(void);
144145
static 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+
25082533
static void
25092534
init_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

Comments
 (0)