🌐 AI搜索 & 代理 主页
Skip to content

Commit 1476028

Browse files
committed
Allow pg_locale_t APIs to work when ctype_is_c.
Previously, the caller needed to check ctype_is_c first for some routines and not others. Now, the APIs consistently work, and the caller can just check ctype_is_c for optimization purposes. Discussion: https://postgr.es/m/450ceb6260cad30d7afdf155d991a9caafee7c0d.camel@j-davis.com Reviewed-by: Chao Li <li.evan.chao@gmail.com>
1 parent 1cdb84b commit 1476028

File tree

2 files changed

+82
-6
lines changed

2 files changed

+82
-6
lines changed

src/backend/utils/adt/pg_locale.c

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,35 +1257,99 @@ get_collation_actual_version(char collprovider, const char *collcollate)
12571257
return collversion;
12581258
}
12591259

1260+
/* lowercasing/casefolding in C locale */
1261+
static size_t
1262+
strlower_c(char *dst, size_t dstsize, const char *src, ssize_t srclen)
1263+
{
1264+
int i;
1265+
1266+
srclen = (srclen >= 0) ? srclen : strlen(src);
1267+
for (i = 0; i < srclen && i < dstsize; i++)
1268+
dst[i] = pg_ascii_tolower(src[i]);
1269+
if (i < dstsize)
1270+
dst[i] = '\0';
1271+
return srclen;
1272+
}
1273+
1274+
/* titlecasing in C locale */
1275+
static size_t
1276+
strtitle_c(char *dst, size_t dstsize, const char *src, ssize_t srclen)
1277+
{
1278+
bool wasalnum = false;
1279+
int i;
1280+
1281+
srclen = (srclen >= 0) ? srclen : strlen(src);
1282+
for (i = 0; i < srclen && i < dstsize; i++)
1283+
{
1284+
char c = src[i];
1285+
1286+
if (wasalnum)
1287+
dst[i] = pg_ascii_tolower(c);
1288+
else
1289+
dst[i] = pg_ascii_toupper(c);
1290+
1291+
wasalnum = ((c >= '0' && c <= '9') ||
1292+
(c >= 'A' && c <= 'Z') ||
1293+
(c >= 'a' && c <= 'z'));
1294+
}
1295+
if (i < dstsize)
1296+
dst[i] = '\0';
1297+
return srclen;
1298+
}
1299+
1300+
/* uppercasing in C locale */
1301+
static size_t
1302+
strupper_c(char *dst, size_t dstsize, const char *src, ssize_t srclen)
1303+
{
1304+
int i;
1305+
1306+
srclen = (srclen >= 0) ? srclen : strlen(src);
1307+
for (i = 0; i < srclen && i < dstsize; i++)
1308+
dst[i] = pg_ascii_toupper(src[i]);
1309+
if (i < dstsize)
1310+
dst[i] = '\0';
1311+
return srclen;
1312+
}
1313+
12601314
size_t
12611315
pg_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen,
12621316
pg_locale_t locale)
12631317
{
1264-
return locale->ctype->strlower(dst, dstsize, src, srclen, locale);
1318+
if (locale->ctype == NULL)
1319+
return strlower_c(dst, dstsize, src, srclen);
1320+
else
1321+
return locale->ctype->strlower(dst, dstsize, src, srclen, locale);
12651322
}
12661323

12671324
size_t
12681325
pg_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
12691326
pg_locale_t locale)
12701327
{
1271-
return locale->ctype->strtitle(dst, dstsize, src, srclen, locale);
1328+
if (locale->ctype == NULL)
1329+
return strtitle_c(dst, dstsize, src, srclen);
1330+
else
1331+
return locale->ctype->strtitle(dst, dstsize, src, srclen, locale);
12721332
}
12731333

12741334
size_t
12751335
pg_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen,
12761336
pg_locale_t locale)
12771337
{
1278-
return locale->ctype->strupper(dst, dstsize, src, srclen, locale);
1338+
if (locale->ctype == NULL)
1339+
return strupper_c(dst, dstsize, src, srclen);
1340+
else
1341+
return locale->ctype->strupper(dst, dstsize, src, srclen, locale);
12791342
}
12801343

12811344
size_t
12821345
pg_strfold(char *dst, size_t dstsize, const char *src, ssize_t srclen,
12831346
pg_locale_t locale)
12841347
{
1285-
if (locale->ctype->strfold)
1286-
return locale->ctype->strfold(dst, dstsize, src, srclen, locale);
1348+
/* in the C locale, casefolding is the same as lowercasing */
1349+
if (locale->ctype == NULL)
1350+
return strlower_c(dst, dstsize, src, srclen);
12871351
else
1288-
return locale->ctype->strlower(dst, dstsize, src, srclen, locale);
1352+
return locale->ctype->strfold(dst, dstsize, src, srclen, locale);
12891353
}
12901354

12911355
/*
@@ -1560,6 +1624,8 @@ pg_towlower(pg_wchar wc, pg_locale_t locale)
15601624
bool
15611625
char_is_cased(char ch, pg_locale_t locale)
15621626
{
1627+
if (locale->ctype == NULL)
1628+
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
15631629
return locale->ctype->char_is_cased(ch, locale);
15641630
}
15651631

@@ -1571,6 +1637,8 @@ char_is_cased(char ch, pg_locale_t locale)
15711637
bool
15721638
char_tolower_enabled(pg_locale_t locale)
15731639
{
1640+
if (locale->ctype == NULL)
1641+
return true;
15741642
return (locale->ctype->char_tolower != NULL);
15751643
}
15761644

@@ -1582,6 +1650,8 @@ char_tolower_enabled(pg_locale_t locale)
15821650
char
15831651
char_tolower(unsigned char ch, pg_locale_t locale)
15841652
{
1653+
if (locale->ctype == NULL)
1654+
return pg_ascii_tolower(ch);
15851655
return locale->ctype->char_tolower(ch, locale);
15861656
}
15871657

src/backend/utils/adt/pg_locale_libc.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ static const struct ctype_methods ctype_methods_libc_sb = {
326326
.strlower = strlower_libc_sb,
327327
.strtitle = strtitle_libc_sb,
328328
.strupper = strupper_libc_sb,
329+
/* in libc, casefolding is the same as lowercasing */
330+
.strfold = strlower_libc_sb,
329331
.wc_isdigit = wc_isdigit_libc_sb,
330332
.wc_isalpha = wc_isalpha_libc_sb,
331333
.wc_isalnum = wc_isalnum_libc_sb,
@@ -351,6 +353,8 @@ static const struct ctype_methods ctype_methods_libc_other_mb = {
351353
.strlower = strlower_libc_mb,
352354
.strtitle = strtitle_libc_mb,
353355
.strupper = strupper_libc_mb,
356+
/* in libc, casefolding is the same as lowercasing */
357+
.strfold = strlower_libc_mb,
354358
.wc_isdigit = wc_isdigit_libc_sb,
355359
.wc_isalpha = wc_isalpha_libc_sb,
356360
.wc_isalnum = wc_isalnum_libc_sb,
@@ -372,6 +376,8 @@ static const struct ctype_methods ctype_methods_libc_utf8 = {
372376
.strlower = strlower_libc_mb,
373377
.strtitle = strtitle_libc_mb,
374378
.strupper = strupper_libc_mb,
379+
/* in libc, casefolding is the same as lowercasing */
380+
.strfold = strlower_libc_mb,
375381
.wc_isdigit = wc_isdigit_libc_mb,
376382
.wc_isalpha = wc_isalpha_libc_mb,
377383
.wc_isalnum = wc_isalnum_libc_mb,

0 commit comments

Comments
 (0)