summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorJeff Davis <jdavis@postgresql.org>2025-12-10 11:56:11 -0800
committerJeff Davis <jdavis@postgresql.org>2025-12-10 11:56:11 -0800
commit630706ced04e3a7a7f0070f4e8fb88f7503a1016 (patch)
treeb8404abec080f2b193a685548649bb937ade2f34 /src/backend
parent1e493158d3d25771ed066028c00cbbdb41573496 (diff)
Add pg_iswcased().
True if character has multiple case forms. Will be a useful multibyte-aware replacement for char_is_cased(). Reviewed-by: Chao Li <li.evan.chao@gmail.com> Reviewed-by: Peter Eisentraut <peter@eisentraut.org> Discussion: https://postgr.es/m/450ceb6260cad30d7afdf155d991a9caafee7c0d.camel@j-davis.com
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/utils/adt/pg_locale.c11
-rw-r--r--src/backend/utils/adt/pg_locale_builtin.c7
-rw-r--r--src/backend/utils/adt/pg_locale_icu.c7
-rw-r--r--src/backend/utils/adt/pg_locale_libc.c17
4 files changed, 42 insertions, 0 deletions
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index b00663b9585..70933ee3843 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1588,6 +1588,17 @@ pg_iswxdigit(pg_wchar wc, pg_locale_t locale)
return locale->ctype->wc_isxdigit(wc, locale);
}
+bool
+pg_iswcased(pg_wchar wc, pg_locale_t locale)
+{
+ /* for the C locale, Cased and Alpha are equivalent */
+ if (locale->ctype == NULL)
+ return (wc <= (pg_wchar) 127 &&
+ (pg_char_properties[wc] & PG_ISALPHA));
+ else
+ return locale->ctype->wc_iscased(wc, locale);
+}
+
pg_wchar
pg_towupper(pg_wchar wc, pg_locale_t locale)
{
diff --git a/src/backend/utils/adt/pg_locale_builtin.c b/src/backend/utils/adt/pg_locale_builtin.c
index 1021e0d129b..0d4c754a267 100644
--- a/src/backend/utils/adt/pg_locale_builtin.c
+++ b/src/backend/utils/adt/pg_locale_builtin.c
@@ -186,6 +186,12 @@ wc_isxdigit_builtin(pg_wchar wc, pg_locale_t locale)
}
static bool
+wc_iscased_builtin(pg_wchar wc, pg_locale_t locale)
+{
+ return pg_u_prop_cased(to_char32(wc));
+}
+
+static bool
char_is_cased_builtin(char ch, pg_locale_t locale)
{
return IS_HIGHBIT_SET(ch) ||
@@ -220,6 +226,7 @@ static const struct ctype_methods ctype_methods_builtin = {
.wc_isspace = wc_isspace_builtin,
.wc_isxdigit = wc_isxdigit_builtin,
.char_is_cased = char_is_cased_builtin,
+ .wc_iscased = wc_iscased_builtin,
.wc_tolower = wc_tolower_builtin,
.wc_toupper = wc_toupper_builtin,
};
diff --git a/src/backend/utils/adt/pg_locale_icu.c b/src/backend/utils/adt/pg_locale_icu.c
index f5a0cc8fe41..e8820666b2d 100644
--- a/src/backend/utils/adt/pg_locale_icu.c
+++ b/src/backend/utils/adt/pg_locale_icu.c
@@ -223,6 +223,12 @@ wc_isxdigit_icu(pg_wchar wc, pg_locale_t locale)
return u_isxdigit(wc);
}
+static bool
+wc_iscased_icu(pg_wchar wc, pg_locale_t locale)
+{
+ return u_hasBinaryProperty(wc, UCHAR_CASED);
+}
+
static const struct ctype_methods ctype_methods_icu = {
.strlower = strlower_icu,
.strtitle = strtitle_icu,
@@ -239,6 +245,7 @@ static const struct ctype_methods ctype_methods_icu = {
.wc_isspace = wc_isspace_icu,
.wc_isxdigit = wc_isxdigit_icu,
.char_is_cased = char_is_cased_icu,
+ .wc_iscased = wc_iscased_icu,
.wc_toupper = toupper_icu,
.wc_tolower = tolower_icu,
};
diff --git a/src/backend/utils/adt/pg_locale_libc.c b/src/backend/utils/adt/pg_locale_libc.c
index fa871690e0c..3d841f818a5 100644
--- a/src/backend/utils/adt/pg_locale_libc.c
+++ b/src/backend/utils/adt/pg_locale_libc.c
@@ -185,6 +185,13 @@ wc_isxdigit_libc_sb(pg_wchar wc, pg_locale_t locale)
}
static bool
+wc_iscased_libc_sb(pg_wchar wc, pg_locale_t locale)
+{
+ return isupper_l((unsigned char) wc, locale->lt) ||
+ islower_l((unsigned char) wc, locale->lt);
+}
+
+static bool
wc_isdigit_libc_mb(pg_wchar wc, pg_locale_t locale)
{
return iswdigit_l((wint_t) wc, locale->lt);
@@ -249,6 +256,13 @@ wc_isxdigit_libc_mb(pg_wchar wc, pg_locale_t locale)
}
static bool
+wc_iscased_libc_mb(pg_wchar wc, pg_locale_t locale)
+{
+ return iswupper_l((wint_t) wc, locale->lt) ||
+ iswlower_l((wint_t) wc, locale->lt);
+}
+
+static bool
char_is_cased_libc(char ch, pg_locale_t locale)
{
bool is_multibyte = pg_database_encoding_max_length() > 1;
@@ -332,6 +346,7 @@ static const struct ctype_methods ctype_methods_libc_sb = {
.wc_isspace = wc_isspace_libc_sb,
.wc_isxdigit = wc_isxdigit_libc_sb,
.char_is_cased = char_is_cased_libc,
+ .wc_iscased = wc_iscased_libc_sb,
.wc_toupper = toupper_libc_sb,
.wc_tolower = tolower_libc_sb,
};
@@ -357,6 +372,7 @@ static const struct ctype_methods ctype_methods_libc_other_mb = {
.wc_isspace = wc_isspace_libc_sb,
.wc_isxdigit = wc_isxdigit_libc_sb,
.char_is_cased = char_is_cased_libc,
+ .wc_iscased = wc_iscased_libc_sb,
.wc_toupper = toupper_libc_sb,
.wc_tolower = tolower_libc_sb,
};
@@ -378,6 +394,7 @@ static const struct ctype_methods ctype_methods_libc_utf8 = {
.wc_isspace = wc_isspace_libc_mb,
.wc_isxdigit = wc_isxdigit_libc_mb,
.char_is_cased = char_is_cased_libc,
+ .wc_iscased = wc_iscased_libc_mb,
.wc_toupper = toupper_libc_mb,
.wc_tolower = tolower_libc_mb,
};