15#include <unicode/ucnv.h>
16#include <unicode/ustring.h>
23#if U_ICU_VERSION_MAJOR_NUM >= 53
24#define HAVE_UCOL_STRCOLLUTF8 1
26#undef HAVE_UCOL_STRCOLLUTF8
48#define TEXTBUFLEN 1024
54extern UCollator *pg_ucol_open(
const char *loc_str);
55static UCaseMap *pg_ucasemap_open(
const char *loc_str);
57static size_t strlower_icu(
char *
dest,
size_t destsize,
const char *src,
59static size_t strtitle_icu(
char *
dest,
size_t destsize,
const char *src,
61static size_t strupper_icu(
char *
dest,
size_t destsize,
const char *src,
63static size_t strfold_icu(
char *
dest,
size_t destsize,
const char *src,
65static size_t strlower_icu_utf8(
char *
dest,
size_t destsize,
const char *src,
67static size_t strtitle_icu_utf8(
char *
dest,
size_t destsize,
const char *src,
69static size_t strupper_icu_utf8(
char *
dest,
size_t destsize,
const char *src,
71static size_t strfold_icu_utf8(
char *
dest,
size_t destsize,
const char *src,
73static size_t downcase_ident_icu(
char *dst,
size_t dstsize,
const char *src,
75static int strncoll_icu(
const char *arg1, ssize_t len1,
76 const char *arg2, ssize_t len2,
78static size_t strnxfrm_icu(
char *
dest,
size_t destsize,
79 const char *src, ssize_t srclen,
81extern char *get_collation_actual_version_icu(
const char *collcollate);
83typedef int32_t (*ICU_Convert_Func) (UChar *
dest, int32_t destCapacity,
84 const UChar *src, int32_t srcLength,
86 UErrorCode *pErrorCode);
93static UConverter *icu_converter = NULL;
95static UCollator *make_icu_collator(
const char *iculocstr,
96 const char *icurules);
97static int strncoll_icu(
const char *arg1, ssize_t len1,
98 const char *arg2, ssize_t len2,
100static size_t strnxfrm_prefix_icu(
char *
dest,
size_t destsize,
101 const char *src, ssize_t srclen,
103#ifdef HAVE_UCOL_STRCOLLUTF8
104static int strncoll_icu_utf8(
const char *arg1, ssize_t len1,
105 const char *arg2, ssize_t len2,
108static size_t strnxfrm_prefix_icu_utf8(
char *
dest,
size_t destsize,
109 const char *src, ssize_t srclen,
111static void init_icu_converter(
void);
112static size_t uchar_length(UConverter *converter,
113 const char *
str, int32_t
len);
114static int32_t uchar_convert(UConverter *converter,
115 UChar *
dest, int32_t destlen,
116 const char *src, int32_t srclen);
117static int32_t icu_to_uchar(UChar **buff_uchar,
const char *buff,
119static size_t icu_from_uchar(
char *
dest,
size_t destsize,
120 const UChar *buff_uchar, int32_t len_uchar);
121static void icu_set_collation_attributes(UCollator *collator,
const char *loc,
123static int32_t icu_convert_case(ICU_Convert_Func func,
char *
dest,
124 size_t destsize,
const char *src,
126static int32_t u_strToTitle_default_BI(UChar *
dest, int32_t destCapacity,
127 const UChar *src, int32_t srcLength,
129 UErrorCode *pErrorCode);
130static int32_t u_strFoldCase_default(UChar *
dest, int32_t destCapacity,
131 const UChar *src, int32_t srcLength,
133 UErrorCode *pErrorCode);
134static int32_t foldcase_options(
const char *
locale);
144 return u_toupper(wc);
150 return u_tolower(wc);
155 .strnxfrm = strnxfrm_icu,
156 .strnxfrm_prefix = strnxfrm_prefix_icu,
157 .strxfrm_is_safe =
true,
161#ifdef HAVE_UCOL_STRCOLLUTF8
164 .strncoll = strncoll_icu,
166 .strnxfrm = strnxfrm_icu,
167 .strnxfrm_prefix = strnxfrm_prefix_icu_utf8,
168 .strxfrm_is_safe =
true,
174 return u_isdigit(wc);
180 return u_isalpha(wc);
186 return u_isalnum(wc);
192 return u_isupper(wc);
198 return u_islower(wc);
204 return u_isgraph(wc);
210 return u_isprint(wc);
216 return u_ispunct(wc);
222 return u_isspace(wc);
228 return u_isxdigit(wc);
234 return u_hasBinaryProperty(wc, UCHAR_CASED);
239 .strtitle = strtitle_icu,
240 .strupper = strupper_icu,
241 .strfold = strfold_icu,
242 .downcase_ident = downcase_ident_icu,
243 .wc_isdigit = wc_isdigit_icu,
244 .wc_isalpha = wc_isalpha_icu,
245 .wc_isalnum = wc_isalnum_icu,
246 .wc_isupper = wc_isupper_icu,
247 .wc_islower = wc_islower_icu,
248 .wc_isgraph = wc_isgraph_icu,
249 .wc_isprint = wc_isprint_icu,
250 .wc_ispunct = wc_ispunct_icu,
251 .wc_isspace = wc_isspace_icu,
252 .wc_isxdigit = wc_isxdigit_icu,
253 .wc_iscased = wc_iscased_icu,
254 .wc_toupper = toupper_icu,
255 .wc_tolower = tolower_icu,
260 .strtitle = strtitle_icu_utf8,
261 .strupper = strupper_icu_utf8,
262 .strfold = strfold_icu_utf8,
264 .downcase_ident = NULL,
265 .wc_isdigit = wc_isdigit_icu,
266 .wc_isalpha = wc_isalpha_icu,
267 .wc_isalnum = wc_isalnum_icu,
268 .wc_isupper = wc_isupper_icu,
269 .wc_islower = wc_islower_icu,
270 .wc_isgraph = wc_isgraph_icu,
271 .wc_isprint = wc_isprint_icu,
272 .wc_ispunct = wc_ispunct_icu,
273 .wc_isspace = wc_isspace_icu,
274 .wc_isxdigit = wc_isxdigit_icu,
275 .wc_iscased = wc_iscased_icu,
276 .wc_toupper = toupper_icu,
277 .wc_tolower = tolower_icu,
288make_libc_ctype_locale(
const char *ctype)
293 loc = newlocale(LC_CTYPE_MASK, ctype, NULL);
295 loc = _create_locale(LC_ALL, ctype);
309 const char *iculocstr;
310 const char *icurules = NULL;
315 if (
collid == DEFAULT_COLLATION_OID)
326 deterministic =
true;
328 Anum_pg_database_datlocale);
331 Anum_pg_database_daticurules, &isnull);
341 Anum_pg_database_datctype);
344 loc = make_libc_ctype_locale(ctype);
360 deterministic = collform->collisdeterministic;
362 Anum_pg_collation_colllocale);
365 Anum_pg_collation_collicurules, &isnull);
372 collator = make_icu_collator(iculocstr, icurules);
376 result->icu.ucol = collator;
377 result->icu.
lt = loc;
383 result->icu.ucasemap = pg_ucasemap_open(iculocstr);
384 result->
collate = &collate_methods_icu_utf8;
385 result->
ctype = &ctype_methods_icu_utf8;
389 result->
collate = &collate_methods_icu;
390 result->
ctype = &ctype_methods_icu;
397 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
398 errmsg(
"ICU is not supported in this build")));
414fix_icu_locale_str(
const char *loc_str)
426 elog(
ERROR,
"opening default collator is not supported");
428 if (U_ICU_VERSION_MAJOR_NUM < 55)
430 char lang[ULOC_LANG_CAPACITY];
431 UErrorCode status = U_ZERO_ERROR;
433 uloc_getLanguage(loc_str, lang, ULOC_LANG_CAPACITY, &status);
434 if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING)
437 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
438 errmsg(
"could not get language from locale \"%s\": %s",
439 loc_str, u_errorName(status))));
442 if (strcmp(lang,
"und") == 0)
444 const char *
remainder = loc_str + strlen(
"und");
448 strcpy(fixed_str,
"root");
465pg_ucol_open(
const char *loc_str)
471 fixed_str = fix_icu_locale_str(loc_str);
473 status = U_ZERO_ERROR;
474 collator = ucol_open(fixed_str, &status);
475 if (U_FAILURE(status))
478 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
479 errmsg(
"could not open collator for locale \"%s\": %s",
480 loc_str, u_errorName(status))));
482 if (U_ICU_VERSION_MAJOR_NUM < 54)
484 status = U_ZERO_ERROR;
485 icu_set_collation_attributes(collator, fixed_str, &status);
491 if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING)
493 ucol_close(collator);
495 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
496 errmsg(
"could not open collator for locale \"%s\": %s",
497 loc_str, u_errorName(status))));
513pg_ucasemap_open(
const char *loc_str)
515 UErrorCode status = U_ZERO_ERROR;
519 fixed_str = fix_icu_locale_str(loc_str);
521 casemap = ucasemap_open(fixed_str, foldcase_options(fixed_str), &status);
522 if (U_FAILURE(status))
525 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
526 errmsg(
"could not open casemap for locale \"%s\": %s",
527 loc_str, u_errorName(status)));
540make_icu_collator(
const char *iculocstr,
const char *icurules)
545 return pg_ucol_open(iculocstr);
549 UCollator *collator_std_rules;
550 UCollator *collator_all_rules;
551 const UChar *std_rules;
563 icu_to_uchar(&my_rules, icurules, strlen(icurules));
565 collator_std_rules = pg_ucol_open(iculocstr);
567 std_rules = ucol_getRules(collator_std_rules, &length);
569 total = u_strlen(std_rules) + u_strlen(my_rules) + 1;
575 ucol_close(collator_std_rules);
577 (
errcode(ERRCODE_OUT_OF_MEMORY),
578 errmsg(
"out of memory")));
581 u_strcpy(all_rules, std_rules);
582 u_strcat(all_rules, my_rules);
584 ucol_close(collator_std_rules);
586 status = U_ZERO_ERROR;
587 collator_all_rules = ucol_openRules(all_rules, u_strlen(all_rules),
588 UCOL_DEFAULT, UCOL_DEFAULT_STRENGTH,
590 if (U_FAILURE(status))
593 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
594 errmsg(
"could not open collator for locale \"%s\" with rules \"%s\": %s",
595 iculocstr, icurules, u_errorName(status))));
598 return collator_all_rules;
603strlower_icu(
char *
dest,
size_t destsize,
const char *src, ssize_t srclen,
606 return icu_convert_case(u_strToLower,
dest, destsize, src, srclen,
locale);
610strtitle_icu(
char *
dest,
size_t destsize,
const char *src, ssize_t srclen,
613 return icu_convert_case(u_strToTitle_default_BI,
dest, destsize, src, srclen,
locale);
617strupper_icu(
char *
dest,
size_t destsize,
const char *src, ssize_t srclen,
620 return icu_convert_case(u_strToUpper,
dest, destsize, src, srclen,
locale);
624strfold_icu(
char *
dest,
size_t destsize,
const char *src, ssize_t srclen,
627 return icu_convert_case(u_strFoldCase_default,
dest, destsize, src, srclen,
locale);
631strlower_icu_utf8(
char *
dest,
size_t destsize,
const char *src, ssize_t srclen,
634 UErrorCode status = U_ZERO_ERROR;
637 needed = ucasemap_utf8ToLower(
locale->icu.ucasemap,
dest, destsize, src, srclen, &status);
638 if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR)
640 errmsg(
"case conversion failed: %s", u_errorName(status)));
645strtitle_icu_utf8(
char *
dest,
size_t destsize,
const char *src, ssize_t srclen,
648 UErrorCode status = U_ZERO_ERROR;
651 needed = ucasemap_utf8ToTitle(
locale->icu.ucasemap,
dest, destsize, src, srclen, &status);
652 if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR)
654 errmsg(
"case conversion failed: %s", u_errorName(status)));
659strupper_icu_utf8(
char *
dest,
size_t destsize,
const char *src, ssize_t srclen,
662 UErrorCode status = U_ZERO_ERROR;
665 needed = ucasemap_utf8ToUpper(
locale->icu.ucasemap,
dest, destsize, src, srclen, &status);
666 if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR)
668 errmsg(
"case conversion failed: %s", u_errorName(status)));
673strfold_icu_utf8(
char *
dest,
size_t destsize,
const char *src, ssize_t srclen,
676 UErrorCode status = U_ZERO_ERROR;
679 needed = ucasemap_utf8FoldCase(
locale->icu.ucasemap,
dest, destsize, src, srclen, &status);
680 if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR)
682 errmsg(
"case conversion failed: %s", u_errorName(status)));
693downcase_ident_icu(
char *dst,
size_t dstsize,
const char *src,
702 for (
i = 0;
i < srclen &&
i < dstsize;
i++)
704 unsigned char ch = (
unsigned char) src[
i];
706 if (ch >=
'A' && ch <=
'Z')
726#ifdef HAVE_UCOL_STRCOLLUTF8
728strncoll_icu_utf8(
const char *arg1, ssize_t len1,
const char *arg2, ssize_t len2,
736 status = U_ZERO_ERROR;
737 result = ucol_strcollUTF8(
locale->icu.ucol,
741 if (U_FAILURE(status))
743 (
errmsg(
"collation failed: %s", u_errorName(status))));
751strnxfrm_icu(
char *
dest,
size_t destsize,
const char *src, ssize_t srclen,
761 init_icu_converter();
763 ulen = uchar_length(icu_converter, src, srclen);
765 uchar_bsize = (ulen + 1) *
sizeof(UChar);
770 uchar = (UChar *)
buf;
772 ulen = uchar_convert(icu_converter, uchar, ulen + 1, src, srclen);
774 result_bsize = ucol_getSortKey(
locale->icu.ucol,
776 (uint8_t *)
dest, destsize);
789 Assert(result_bsize >= destsize ||
dest[result_bsize] ==
'\0');
796strnxfrm_prefix_icu_utf8(
char *
dest,
size_t destsize,
797 const char *src, ssize_t srclen,
807 uiter_setUTF8(&iter, src, srclen);
809 status = U_ZERO_ERROR;
810 result = ucol_nextSortKeyPart(
locale->icu.ucol,
816 if (U_FAILURE(status))
818 (
errmsg(
"sort key generation failed: %s",
819 u_errorName(status))));
825get_collation_actual_version_icu(
const char *collcollate)
828 UVersionInfo versioninfo;
829 char buf[U_MAX_VERSION_STRING_LENGTH];
831 collator = pg_ucol_open(collcollate);
833 ucol_getVersion(collator, versioninfo);
834 ucol_close(collator);
836 u_versionToString(versioninfo,
buf);
853icu_to_uchar(UChar **buff_uchar,
const char *buff,
size_t nbytes)
857 init_icu_converter();
859 len_uchar = uchar_length(icu_converter, buff, nbytes);
861 *buff_uchar =
palloc((len_uchar + 1) *
sizeof(**buff_uchar));
862 len_uchar = uchar_convert(icu_converter,
863 *buff_uchar, len_uchar + 1, buff, nbytes);
880icu_from_uchar(
char *
dest,
size_t destsize,
const UChar *buff_uchar, int32_t len_uchar)
885 init_icu_converter();
887 status = U_ZERO_ERROR;
888 len_result = ucnv_fromUChars(icu_converter, NULL, 0,
889 buff_uchar, len_uchar, &status);
890 if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR)
892 (
errmsg(
"%s failed: %s",
"ucnv_fromUChars",
893 u_errorName(status))));
895 if (len_result + 1 > destsize)
898 status = U_ZERO_ERROR;
899 len_result = ucnv_fromUChars(icu_converter,
dest, len_result + 1,
900 buff_uchar, len_uchar, &status);
901 if (U_FAILURE(status) ||
902 status == U_STRING_NOT_TERMINATED_WARNING)
904 (
errmsg(
"%s failed: %s",
"ucnv_fromUChars",
905 u_errorName(status))));
911convert_case_uchar(ICU_Convert_Func func,
pg_locale_t mylocale,
912 UChar **buff_dest, UChar *buff_source, int32_t len_source)
917 len_dest = len_source;
918 *buff_dest =
palloc(len_dest *
sizeof(**buff_dest));
919 status = U_ZERO_ERROR;
920 len_dest = func(*buff_dest, len_dest, buff_source, len_source,
921 mylocale->icu.
locale, &status);
922 if (status == U_BUFFER_OVERFLOW_ERROR)
926 *buff_dest =
palloc(len_dest *
sizeof(**buff_dest));
927 status = U_ZERO_ERROR;
928 len_dest = func(*buff_dest, len_dest, buff_source, len_source,
929 mylocale->icu.
locale, &status);
931 if (U_FAILURE(status))
933 (
errmsg(
"case conversion failed: %s", u_errorName(status))));
938icu_convert_case(ICU_Convert_Func func,
char *
dest,
size_t destsize,
947 len_uchar = icu_to_uchar(&buff_uchar, src, srclen);
948 len_conv = convert_case_uchar(func,
locale, &buff_conv,
949 buff_uchar, len_uchar);
950 result_len = icu_from_uchar(
dest, destsize, buff_conv, len_conv);
958u_strToTitle_default_BI(UChar *
dest, int32_t destCapacity,
959 const UChar *src, int32_t srcLength,
961 UErrorCode *pErrorCode)
963 return u_strToTitle(
dest, destCapacity, src, srcLength,
964 NULL,
locale, pErrorCode);
968u_strFoldCase_default(UChar *
dest, int32_t destCapacity,
969 const UChar *src, int32_t srcLength,
971 UErrorCode *pErrorCode)
973 return u_strFoldCase(
dest, destCapacity, src, srcLength,
974 foldcase_options(
locale), pErrorCode);
985foldcase_options(
const char *
locale)
989 UErrorCode status = U_ZERO_ERROR;
991 uloc_getLanguage(
locale, lang, 3, &status);
992 if (U_SUCCESS(status))
998 if (strcmp(lang,
"tr") == 0 || strcmp(lang,
"az") == 0)
999 options = U_FOLD_CASE_EXCLUDE_SPECIAL_I;
1016strncoll_icu(
const char *arg1, ssize_t len1,
1030#ifdef HAVE_UCOL_STRCOLLUTF8
1034 init_icu_converter();
1036 ulen1 = uchar_length(icu_converter, arg1, len1);
1037 ulen2 = uchar_length(icu_converter, arg2, len2);
1039 bufsize1 = (ulen1 + 1) *
sizeof(UChar);
1040 bufsize2 = (ulen2 + 1) *
sizeof(UChar);
1045 uchar1 = (UChar *)
buf;
1046 uchar2 = (UChar *) (
buf + bufsize1);
1048 ulen1 = uchar_convert(icu_converter, uchar1, ulen1 + 1, arg1, len1);
1049 ulen2 = uchar_convert(icu_converter, uchar2, ulen2 + 1, arg2, len2);
1051 result = ucol_strcoll(
locale->icu.ucol,
1063strnxfrm_prefix_icu(
char *
dest,
size_t destsize,
1064 const char *src, ssize_t srclen,
1073 UChar *uchar = NULL;
1080 init_icu_converter();
1082 ulen = uchar_length(icu_converter, src, srclen);
1084 uchar_bsize = (ulen + 1) *
sizeof(UChar);
1089 uchar = (UChar *)
buf;
1091 ulen = uchar_convert(icu_converter, uchar, ulen + 1, src, srclen);
1093 uiter_setString(&iter, uchar, ulen);
1095 status = U_ZERO_ERROR;
1096 result_bsize = ucol_nextSortKeyPart(
locale->icu.ucol,
1102 if (U_FAILURE(status))
1104 (
errmsg(
"sort key generation failed: %s",
1105 u_errorName(status))));
1107 return result_bsize;
1111init_icu_converter(
void)
1113 const char *icu_encoding_name;
1121 if (!icu_encoding_name)
1123 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1124 errmsg(
"encoding \"%s\" not supported by ICU",
1127 status = U_ZERO_ERROR;
1128 conv = ucnv_open(icu_encoding_name, &status);
1129 if (U_FAILURE(status))
1131 (
errmsg(
"could not open ICU converter for encoding \"%s\": %s",
1132 icu_encoding_name, u_errorName(status))));
1134 icu_converter = conv;
1143uchar_length(UConverter *converter,
const char *
str, int32_t
len)
1145 UErrorCode status = U_ZERO_ERROR;
1148 ulen = ucnv_toUChars(converter, NULL, 0,
str,
len, &status);
1149 if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR)
1151 (
errmsg(
"%s failed: %s",
"ucnv_toUChars", u_errorName(status))));
1162uchar_convert(UConverter *converter, UChar *
dest, int32_t destlen,
1163 const char *src, int32_t srclen)
1165 UErrorCode status = U_ZERO_ERROR;
1168 status = U_ZERO_ERROR;
1169 ulen = ucnv_toUChars(converter,
dest, destlen, src, srclen, &status);
1170 if (U_FAILURE(status))
1172 (
errmsg(
"%s failed: %s",
"ucnv_toUChars", u_errorName(status))));
1190icu_set_collation_attributes(UCollator *collator, const
char *loc,
1194 char *icu_locale_id;
1206 *status = U_ZERO_ERROR;
1207 len = uloc_canonicalize(loc, NULL, 0, status);
1209 *status = U_ZERO_ERROR;
1210 len = uloc_canonicalize(loc, icu_locale_id,
len + 1, status);
1211 if (U_FAILURE(*status) || *status == U_STRING_NOT_TERMINATED_WARNING)
1214 lower_str =
asc_tolower(icu_locale_id, strlen(icu_locale_id));
1216 pfree(icu_locale_id);
1218 str = strchr(lower_str,
'@');
1225 char *
e = strchr(
token,
'=');
1231 UColAttribute uattr;
1232 UColAttributeValue uvalue;
1234 *status = U_ZERO_ERROR;
1243 if (strcmp(
name,
"colstrength") == 0)
1244 uattr = UCOL_STRENGTH;
1245 else if (strcmp(
name,
"colbackwards") == 0)
1246 uattr = UCOL_FRENCH_COLLATION;
1247 else if (strcmp(
name,
"colcaselevel") == 0)
1248 uattr = UCOL_CASE_LEVEL;
1249 else if (strcmp(
name,
"colcasefirst") == 0)
1250 uattr = UCOL_CASE_FIRST;
1251 else if (strcmp(
name,
"colalternate") == 0)
1252 uattr = UCOL_ALTERNATE_HANDLING;
1253 else if (strcmp(
name,
"colnormalization") == 0)
1254 uattr = UCOL_NORMALIZATION_MODE;
1255 else if (strcmp(
name,
"colnumeric") == 0)
1256 uattr = UCOL_NUMERIC_COLLATION;
1261 if (strcmp(
value,
"primary") == 0)
1262 uvalue = UCOL_PRIMARY;
1263 else if (strcmp(
value,
"secondary") == 0)
1264 uvalue = UCOL_SECONDARY;
1265 else if (strcmp(
value,
"tertiary") == 0)
1266 uvalue = UCOL_TERTIARY;
1267 else if (strcmp(
value,
"quaternary") == 0)
1268 uvalue = UCOL_QUATERNARY;
1269 else if (strcmp(
value,
"identical") == 0)
1270 uvalue = UCOL_IDENTICAL;
1271 else if (strcmp(
value,
"no") == 0)
1273 else if (strcmp(
value,
"yes") == 0)
1275 else if (strcmp(
value,
"shifted") == 0)
1276 uvalue = UCOL_SHIFTED;
1277 else if (strcmp(
value,
"non-ignorable") == 0)
1278 uvalue = UCOL_NON_IGNORABLE;
1279 else if (strcmp(
value,
"lower") == 0)
1280 uvalue = UCOL_LOWER_FIRST;
1281 else if (strcmp(
value,
"upper") == 0)
1282 uvalue = UCOL_UPPER_FIRST;
1285 *status = U_ILLEGAL_ARGUMENT_ERROR;
1289 ucol_setAttribute(collator, uattr, uvalue, status);
#define TextDatumGetCString(d)
#define pg_attribute_unused()
#define IS_HIGHBIT_SET(ch)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
const char * get_encoding_name_for_icu(int encoding)
#define MCXT_ALLOC_NO_OOM
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
int GetDatabaseEncoding(void)
int pg_database_encoding_max_length(void)
char * MemoryContextStrdup(MemoryContext context, const char *string)
void * MemoryContextAllocZero(MemoryContext context, Size size)
char * pstrdup(const char *in)
void pfree(void *pointer)
void * palloc_extended(Size size, int flags)
FormData_pg_collation * Form_pg_collation
pg_locale_t create_pg_locale_icu(Oid collid, MemoryContext context)
void report_newlocale_failure(const char *localename)
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define pg_encoding_to_char
char * strsep(char **stringp, const char *delim)
static unsigned char pg_ascii_tolower(unsigned char ch)
static Datum ObjectIdGetDatum(Oid X)
int(* strncoll)(const char *arg1, ssize_t len1, const char *arg2, ssize_t len2, pg_locale_t locale)
size_t(* strlower)(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
const struct ctype_methods * ctype
const struct collate_methods * collate
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
static enum CaseMapResult casemap(char32_t u1, CaseKind casekind, bool full, const char *src, size_t srclen, size_t srcoff, char32_t *simple, const char32_t **special)