1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-05 02:22:28 +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

@@ -24,15 +24,6 @@
extern pg_locale_t create_pg_locale_builtin(Oid collid,
MemoryContext context);
extern char *get_collation_actual_version_builtin(const char *collcollate);
extern size_t strlower_builtin(char *dest, size_t destsize, const char *src,
ssize_t srclen, pg_locale_t locale);
extern size_t strtitle_builtin(char *dest, size_t destsize, const char *src,
ssize_t srclen, pg_locale_t locale);
extern size_t strupper_builtin(char *dest, size_t destsize, const char *src,
ssize_t srclen, pg_locale_t locale);
extern size_t strfold_builtin(char *dest, size_t destsize, const char *src,
ssize_t srclen, pg_locale_t locale);
struct WordBoundaryState
{
@@ -76,7 +67,7 @@ initcap_wbnext(void *state)
return wbstate->len;
}
size_t
static size_t
strlower_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
pg_locale_t locale)
{
@@ -84,7 +75,7 @@ strlower_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
locale->info.builtin.casemap_full);
}
size_t
static size_t
strtitle_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
pg_locale_t locale)
{
@@ -102,7 +93,7 @@ strtitle_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
initcap_wbnext, &wbstate);
}
size_t
static size_t
strupper_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
pg_locale_t locale)
{
@@ -110,7 +101,7 @@ strupper_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
locale->info.builtin.casemap_full);
}
size_t
static size_t
strfold_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
pg_locale_t locale)
{
@@ -118,6 +109,98 @@ strfold_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
locale->info.builtin.casemap_full);
}
static bool
wc_isdigit_builtin(pg_wchar wc, pg_locale_t locale)
{
return pg_u_isdigit(wc, !locale->info.builtin.casemap_full);
}
static bool
wc_isalpha_builtin(pg_wchar wc, pg_locale_t locale)
{
return pg_u_isalpha(wc);
}
static bool
wc_isalnum_builtin(pg_wchar wc, pg_locale_t locale)
{
return pg_u_isalnum(wc, !locale->info.builtin.casemap_full);
}
static bool
wc_isupper_builtin(pg_wchar wc, pg_locale_t locale)
{
return pg_u_isupper(wc);
}
static bool
wc_islower_builtin(pg_wchar wc, pg_locale_t locale)
{
return pg_u_islower(wc);
}
static bool
wc_isgraph_builtin(pg_wchar wc, pg_locale_t locale)
{
return pg_u_isgraph(wc);
}
static bool
wc_isprint_builtin(pg_wchar wc, pg_locale_t locale)
{
return pg_u_isprint(wc);
}
static bool
wc_ispunct_builtin(pg_wchar wc, pg_locale_t locale)
{
return pg_u_ispunct(wc, !locale->info.builtin.casemap_full);
}
static bool
wc_isspace_builtin(pg_wchar wc, pg_locale_t locale)
{
return pg_u_isspace(wc);
}
static bool
char_is_cased_builtin(char ch, pg_locale_t locale)
{
return IS_HIGHBIT_SET(ch) ||
(ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}
static pg_wchar
wc_toupper_builtin(pg_wchar wc, pg_locale_t locale)
{
return unicode_uppercase_simple(wc);
}
static pg_wchar
wc_tolower_builtin(pg_wchar wc, pg_locale_t locale)
{
return unicode_lowercase_simple(wc);
}
static const struct ctype_methods ctype_methods_builtin = {
.strlower = strlower_builtin,
.strtitle = strtitle_builtin,
.strupper = strupper_builtin,
.strfold = strfold_builtin,
.wc_isdigit = wc_isdigit_builtin,
.wc_isalpha = wc_isalpha_builtin,
.wc_isalnum = wc_isalnum_builtin,
.wc_isupper = wc_isupper_builtin,
.wc_islower = wc_islower_builtin,
.wc_isgraph = wc_isgraph_builtin,
.wc_isprint = wc_isprint_builtin,
.wc_ispunct = wc_ispunct_builtin,
.wc_isspace = wc_isspace_builtin,
.char_is_cased = char_is_cased_builtin,
.wc_tolower = wc_tolower_builtin,
.wc_toupper = wc_toupper_builtin,
};
pg_locale_t
create_pg_locale_builtin(Oid collid, MemoryContext context)
{
@@ -161,6 +244,8 @@ create_pg_locale_builtin(Oid collid, MemoryContext context)
result->deterministic = true;
result->collate_is_c = true;
result->ctype_is_c = (strcmp(locstr, "C") == 0);
if (!result->ctype_is_c)
result->ctype = &ctype_methods_builtin;
return result;
}