From ba30a89ef3c424b4436c91373001668daef068bf Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Wed, 12 Aug 2026 07:46:48 -0700 Subject: [PATCH vPG20 2/3] Ensure all pg_locale.h APIs work with collate_is_c. Suggested-by: Andres Freund Discussion: https://postgr.es/m/v36ssaygf7grb3qzfsjhtdzi7kqd45ds56nyuf7gi5qjml4qbb@ezmfqzmhlrs2 Backpatch-through: 18 --- src/backend/utils/adt/pg_locale.c | 55 +++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index da32590396f..2b501a7b6b7 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -1441,7 +1441,10 @@ pg_downcase_ident(char *dst, size_t dstsize, const char *src, size_t srclen) int pg_strcoll(const char *arg1, const char *arg2, pg_locale_t locale) { - return locale->collate->strcoll(arg1, arg2, locale); + if (locale->collate == NULL) + return strcmp(arg1, arg2); + else + return locale->collate->strcoll(arg1, arg2, locale); } /* @@ -1459,7 +1462,16 @@ int pg_strncoll(const char *arg1, size_t len1, const char *arg2, size_t len2, pg_locale_t locale) { - return locale->collate->strncoll(arg1, len1, arg2, len2, locale); + if (locale->collate == NULL) + { + int result = memcmp(arg1, arg2, Min(len1, len2)); + + if ((result == 0) && (len1 != len2)) + result = (len1 < len2) ? -1 : 1; + return result; + } + else + return locale->collate->strncoll(arg1, len1, arg2, len2, locale); } /* @@ -1469,6 +1481,9 @@ pg_strncoll(const char *arg1, size_t len1, const char *arg2, size_t len2, bool pg_strxfrm_enabled(pg_locale_t locale) { + if (locale->collate == NULL) + return true; + /* * locale->collate->strnxfrm is still a required method, even if it may * have the wrong behavior, because the planner uses it for estimates in @@ -1485,7 +1500,10 @@ pg_strxfrm_enabled(pg_locale_t locale) size_t pg_strxfrm(char *dest, const char *src, size_t destsize, pg_locale_t locale) { - return locale->collate->strxfrm(dest, destsize, src, locale); + if (locale->collate == NULL) + return pg_strnxfrm(dest, destsize, src, strlen(src), locale); + else + return locale->collate->strxfrm(dest, destsize, src, locale); } /* @@ -1510,6 +1528,16 @@ size_t pg_strnxfrm(char *dest, size_t destsize, const char *src, size_t srclen, pg_locale_t locale) { + if (locale->collate == NULL) + { + if (destsize > srclen) + { + memcpy(dest, src, srclen); + dest[srclen] = '\0'; + } + + return srclen; + } return locale->collate->strnxfrm(dest, destsize, src, srclen, locale); } @@ -1520,7 +1548,10 @@ pg_strnxfrm(char *dest, size_t destsize, const char *src, size_t srclen, bool pg_strxfrm_prefix_enabled(pg_locale_t locale) { - return (locale->collate->strnxfrm_prefix != NULL); + if (locale->collate == NULL) + return true; + else + return (locale->collate->strnxfrm_prefix != NULL); } /* @@ -1532,7 +1563,10 @@ size_t pg_strxfrm_prefix(char *dest, const char *src, size_t destsize, pg_locale_t locale) { - return locale->collate->strxfrm_prefix(dest, destsize, src, locale); + if (locale->collate == NULL) + return pg_strnxfrm_prefix(dest, destsize, src, strlen(src), locale); + else + return locale->collate->strxfrm_prefix(dest, destsize, src, locale); } /* @@ -1556,7 +1590,16 @@ size_t pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src, size_t srclen, pg_locale_t locale) { - return locale->collate->strnxfrm_prefix(dest, destsize, src, srclen, locale); + if (locale->collate == NULL) + { + size_t len = Min(srclen, destsize); + + if (destsize > 0) + memcpy(dest, src, len); + return len; + } + else + return locale->collate->strnxfrm_prefix(dest, destsize, src, srclen, locale); } bool -- 2.43.0