Skip to content

Commit 8b3eb0c

Browse files
committed
Fix error inconsistency in older ICU versions.
To support older ICU versions, we rely on icu_set_collation_attributes() to do error checking that is handled directly by ucol_open() in newer ICU versions. Commit 3b50275 introduced a slight inconsistency, where the error report includes the fixed-up locale string, rather than the locale string passed to pg_ucol_open(). Refactor slightly so that pg_ucol_open() handles the errors from both ucol_open() and icu_set_collation_attributes(), making it easier to see any differences between the error reports. It also makes pg_ucol_open() responsible for closing the UCollator on error, which seems like the right place. Discussion: https://postgr.es/m/04182066-7655-344a-b8b7-040b1b2490fb%40enterprisedb.com Reviewed-by: Peter Eisentraut
1 parent 90189ee commit 8b3eb0c

File tree

1 file changed

+34
-28
lines changed

1 file changed

+34
-28
lines changed

src/backend/utils/adt/pg_locale.c

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ static size_t uchar_length(UConverter *converter,
147147
static int32_t uchar_convert(UConverter *converter,
148148
UChar *dest, int32_t destlen,
149149
const char *str, int32_t srclen);
150-
static void icu_set_collation_attributes(UCollator *collator, const char *loc);
150+
static void icu_set_collation_attributes(UCollator *collator, const char *loc,
151+
UErrorCode *status);
151152
#endif
152153

153154
/*
@@ -2496,6 +2497,7 @@ pg_ucol_open(const char *loc_str)
24962497
{
24972498
UCollator *collator;
24982499
UErrorCode status;
2500+
const char *orig_str = loc_str;
24992501
char *fixed_str = NULL;
25002502

25012503
/*
@@ -2544,11 +2546,27 @@ pg_ucol_open(const char *loc_str)
25442546
collator = ucol_open(loc_str, &status);
25452547
if (U_FAILURE(status))
25462548
ereport(ERROR,
2549+
/* use original string for error report */
25472550
(errmsg("could not open collator for locale \"%s\": %s",
2548-
loc_str, u_errorName(status))));
2551+
orig_str, u_errorName(status))));
25492552

25502553
if (U_ICU_VERSION_MAJOR_NUM < 54)
2551-
icu_set_collation_attributes(collator, loc_str);
2554+
{
2555+
status = U_ZERO_ERROR;
2556+
icu_set_collation_attributes(collator, loc_str, &status);
2557+
2558+
/*
2559+
* Pretend the error came from ucol_open(), for consistent error
2560+
* message across ICU versions.
2561+
*/
2562+
if (U_FAILURE(status))
2563+
{
2564+
ucol_close(collator);
2565+
ereport(ERROR,
2566+
(errmsg("could not open collator for locale \"%s\": %s",
2567+
orig_str, u_errorName(status))));
2568+
}
2569+
}
25522570

25532571
if (fixed_str != NULL)
25542572
pfree(fixed_str);
@@ -2698,9 +2716,9 @@ icu_from_uchar(char **result, const UChar *buff_uchar, int32_t len_uchar)
26982716
*/
26992717
pg_attribute_unused()
27002718
static void
2701-
icu_set_collation_attributes(UCollator *collator, const char *loc)
2719+
icu_set_collation_attributes(UCollator *collator, const char *loc,
2720+
UErrorCode *status)
27022721
{
2703-
UErrorCode status;
27042722
int32_t len;
27052723
char *icu_locale_id;
27062724
char *lower_str;
@@ -2713,15 +2731,13 @@ icu_set_collation_attributes(UCollator *collator, const char *loc)
27132731
* locale ID, e.g. "und@colcaselevel=yes;colstrength=primary", by
27142732
* uloc_canonicalize().
27152733
*/
2716-
status = U_ZERO_ERROR;
2717-
len = uloc_canonicalize(loc, NULL, 0, &status);
2734+
*status = U_ZERO_ERROR;
2735+
len = uloc_canonicalize(loc, NULL, 0, status);
27182736
icu_locale_id = palloc(len + 1);
2719-
status = U_ZERO_ERROR;
2720-
len = uloc_canonicalize(loc, icu_locale_id, len + 1, &status);
2721-
if (U_FAILURE(status))
2722-
ereport(ERROR,
2723-
(errmsg("canonicalization failed for locale string \"%s\": %s",
2724-
loc, u_errorName(status))));
2737+
*status = U_ZERO_ERROR;
2738+
len = uloc_canonicalize(loc, icu_locale_id, len + 1, status);
2739+
if (U_FAILURE(*status))
2740+
return;
27252741

27262742
lower_str = asc_tolower(icu_locale_id, strlen(icu_locale_id));
27272743

@@ -2743,7 +2759,7 @@ icu_set_collation_attributes(UCollator *collator, const char *loc)
27432759
UColAttribute uattr;
27442760
UColAttributeValue uvalue;
27452761

2746-
status = U_ZERO_ERROR;
2762+
*status = U_ZERO_ERROR;
27472763

27482764
*e = '\0';
27492765
name = token;
@@ -2793,22 +2809,12 @@ icu_set_collation_attributes(UCollator *collator, const char *loc)
27932809
else if (strcmp(value, "upper") == 0)
27942810
uvalue = UCOL_UPPER_FIRST;
27952811
else
2796-
status = U_ILLEGAL_ARGUMENT_ERROR;
2797-
2798-
if (status == U_ZERO_ERROR)
2799-
ucol_setAttribute(collator, uattr, uvalue, &status);
2800-
2801-
/*
2802-
* Pretend the error came from ucol_open(), for consistent error
2803-
* message across ICU versions.
2804-
*/
2805-
if (U_FAILURE(status))
28062812
{
2807-
ucol_close(collator);
2808-
ereport(ERROR,
2809-
(errmsg("could not open collator for locale \"%s\": %s",
2810-
loc, u_errorName(status))));
2813+
*status = U_ILLEGAL_ARGUMENT_ERROR;
2814+
break;
28112815
}
2816+
2817+
ucol_setAttribute(collator, uattr, uvalue, status);
28122818
}
28132819
}
28142820

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy