1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-06 07:49:08 +03:00

Control ctype behavior internally with a method table.

Previously, pattern matching and case mapping behavior branched based
on the provider. Refactor to use a method table, which is less
error-prone.

This is also a step toward multiple provider versions, which we may
want to support in the future.

Reviewed-by: Andreas Karlsson <andreas@proxel.se>
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://postgr.es/m/2830211e1b6e6a2e26d845780b03e125281ea17b.camel%40j-davis.com
This commit is contained in:
Jeff Davis
2025-07-01 07:42:39 -07:00
parent d81dcc8d62
commit 5a38104b36
9 changed files with 686 additions and 508 deletions

View File

@@ -48,19 +48,22 @@
#define TEXTBUFLEN 1024
extern pg_locale_t create_pg_locale_icu(Oid collid, MemoryContext context);
extern size_t strlower_icu(char *dest, size_t destsize, const char *src,
ssize_t srclen, pg_locale_t locale);
extern size_t strtitle_icu(char *dest, size_t destsize, const char *src,
ssize_t srclen, pg_locale_t locale);
extern size_t strupper_icu(char *dest, size_t destsize, const char *src,
ssize_t srclen, pg_locale_t locale);
extern size_t strfold_icu(char *dest, size_t destsize, const char *src,
ssize_t srclen, pg_locale_t locale);
#ifdef USE_ICU
extern UCollator *pg_ucol_open(const char *loc_str);
static size_t strlower_icu(char *dest, size_t destsize, const char *src,
ssize_t srclen, pg_locale_t locale);
static size_t strtitle_icu(char *dest, size_t destsize, const char *src,
ssize_t srclen, pg_locale_t locale);
static size_t strupper_icu(char *dest, size_t destsize, const char *src,
ssize_t srclen, pg_locale_t locale);
static size_t strfold_icu(char *dest, size_t destsize, const char *src,
ssize_t srclen, pg_locale_t locale);
static int strncoll_icu(const char *arg1, ssize_t len1,
const char *arg2, ssize_t len2,
pg_locale_t locale);
static size_t strnxfrm_icu(char *dest, size_t destsize,
const char *src, ssize_t srclen,
pg_locale_t locale);
@@ -118,6 +121,25 @@ static int32_t u_strFoldCase_default(UChar *dest, int32_t destCapacity,
const char *locale,
UErrorCode *pErrorCode);
static bool
char_is_cased_icu(char ch, pg_locale_t locale)
{
return IS_HIGHBIT_SET(ch) ||
(ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}
static pg_wchar
toupper_icu(pg_wchar wc, pg_locale_t locale)
{
return u_toupper(wc);
}
static pg_wchar
tolower_icu(pg_wchar wc, pg_locale_t locale)
{
return u_tolower(wc);
}
static const struct collate_methods collate_methods_icu = {
.strncoll = strncoll_icu,
.strnxfrm = strnxfrm_icu,
@@ -136,6 +158,78 @@ static const struct collate_methods collate_methods_icu_utf8 = {
.strxfrm_is_safe = true,
};
static bool
wc_isdigit_icu(pg_wchar wc, pg_locale_t locale)
{
return u_isdigit(wc);
}
static bool
wc_isalpha_icu(pg_wchar wc, pg_locale_t locale)
{
return u_isalpha(wc);
}
static bool
wc_isalnum_icu(pg_wchar wc, pg_locale_t locale)
{
return u_isalnum(wc);
}
static bool
wc_isupper_icu(pg_wchar wc, pg_locale_t locale)
{
return u_isupper(wc);
}
static bool
wc_islower_icu(pg_wchar wc, pg_locale_t locale)
{
return u_islower(wc);
}
static bool
wc_isgraph_icu(pg_wchar wc, pg_locale_t locale)
{
return u_isgraph(wc);
}
static bool
wc_isprint_icu(pg_wchar wc, pg_locale_t locale)
{
return u_isprint(wc);
}
static bool
wc_ispunct_icu(pg_wchar wc, pg_locale_t locale)
{
return u_ispunct(wc);
}
static bool
wc_isspace_icu(pg_wchar wc, pg_locale_t locale)
{
return u_isspace(wc);
}
static const struct ctype_methods ctype_methods_icu = {
.strlower = strlower_icu,
.strtitle = strtitle_icu,
.strupper = strupper_icu,
.strfold = strfold_icu,
.wc_isdigit = wc_isdigit_icu,
.wc_isalpha = wc_isalpha_icu,
.wc_isalnum = wc_isalnum_icu,
.wc_isupper = wc_isupper_icu,
.wc_islower = wc_islower_icu,
.wc_isgraph = wc_isgraph_icu,
.wc_isprint = wc_isprint_icu,
.wc_ispunct = wc_ispunct_icu,
.wc_isspace = wc_isspace_icu,
.char_is_cased = char_is_cased_icu,
.wc_toupper = toupper_icu,
.wc_tolower = tolower_icu,
};
#endif
pg_locale_t
@@ -206,6 +300,7 @@ create_pg_locale_icu(Oid collid, MemoryContext context)
result->collate = &collate_methods_icu_utf8;
else
result->collate = &collate_methods_icu;
result->ctype = &ctype_methods_icu;
return result;
#else
@@ -379,7 +474,7 @@ make_icu_collator(const char *iculocstr, const char *icurules)
}
}
size_t
static size_t
strlower_icu(char *dest, size_t destsize, const char *src, ssize_t srclen,
pg_locale_t locale)
{
@@ -399,7 +494,7 @@ strlower_icu(char *dest, size_t destsize, const char *src, ssize_t srclen,
return result_len;
}
size_t
static size_t
strtitle_icu(char *dest, size_t destsize, const char *src, ssize_t srclen,
pg_locale_t locale)
{
@@ -419,7 +514,7 @@ strtitle_icu(char *dest, size_t destsize, const char *src, ssize_t srclen,
return result_len;
}
size_t
static size_t
strupper_icu(char *dest, size_t destsize, const char *src, ssize_t srclen,
pg_locale_t locale)
{
@@ -439,7 +534,7 @@ strupper_icu(char *dest, size_t destsize, const char *src, ssize_t srclen,
return result_len;
}
size_t
static size_t
strfold_icu(char *dest, size_t destsize, const char *src, ssize_t srclen,
pg_locale_t locale)
{