Fix unintentional behavior change in commit e9931bfb75.
authorJeff Davis <jdavis@postgresql.org>
Tue, 3 Dec 2024 05:59:02 +0000 (21:59 -0800)
committerJeff Davis <jdavis@postgresql.org>
Tue, 3 Dec 2024 05:59:02 +0000 (21:59 -0800)
Prior to that commit, there was special case to use ASCII case mapping
behavior for the libc provider with a single-byte encoding when that's
the default collation. Commit e9931bfb75 mistakenly eliminated that
special case; this commit restores it.

Discussion: https://postgr.es/m/01a104f0d2179d756261e90d96fd65c36ad6fcf0.camel@j-davis.com

src/backend/utils/adt/formatting.c
src/backend/utils/adt/like.c
src/backend/utils/adt/pg_locale.c
src/include/utils/pg_locale.h

index 85a7dd456196fe140eccbbccd15e5088eda1cb89..2bcc185708c79fcbcccdd8dc5132a4462b8ade56 100644 (file)
@@ -1755,7 +1755,12 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
                                 * collations you get exactly what the collation says.
                                 */
                                for (p = result; *p; p++)
-                                       *p = tolower_l((unsigned char) *p, mylocale->info.lt);
+                               {
+                                       if (mylocale->is_default)
+                                               *p = pg_tolower((unsigned char) *p);
+                                       else
+                                               *p = tolower_l((unsigned char) *p, mylocale->info.lt);
+                               }
                        }
                }
        }
@@ -1892,7 +1897,12 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
                                 * collations you get exactly what the collation says.
                                 */
                                for (p = result; *p; p++)
-                                       *p = toupper_l((unsigned char) *p, mylocale->info.lt);
+                               {
+                                       if (mylocale->is_default)
+                                               *p = pg_toupper((unsigned char) *p);
+                                       else
+                                               *p = toupper_l((unsigned char) *p, mylocale->info.lt);
+                               }
                        }
                }
        }
@@ -2090,10 +2100,20 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
                                 */
                                for (p = result; *p; p++)
                                {
-                                       if (wasalnum)
-                                               *p = tolower_l((unsigned char) *p, mylocale->info.lt);
+                                       if (mylocale->is_default)
+                                       {
+                                               if (wasalnum)
+                                                       *p = pg_tolower((unsigned char) *p);
+                                               else
+                                                       *p = pg_toupper((unsigned char) *p);
+                                       }
                                        else
-                                               *p = toupper_l((unsigned char) *p, mylocale->info.lt);
+                                       {
+                                               if (wasalnum)
+                                                       *p = tolower_l((unsigned char) *p, mylocale->info.lt);
+                                               else
+                                                       *p = toupper_l((unsigned char) *p, mylocale->info.lt);
+                                       }
                                        wasalnum = isalnum_l((unsigned char) *p, mylocale->info.lt);
                                }
                        }
index 7b3d1b5be71f4b7bf7c183ab9d4399ddfb547de9..7df50b50d155aa8a7ddb7c91a8d177c1c790b9b5 100644 (file)
@@ -95,6 +95,8 @@ SB_lower_char(unsigned char c, pg_locale_t locale)
 {
        if (locale->ctype_is_c)
                return pg_ascii_tolower(c);
+       else if (locale->is_default)
+               return pg_tolower(c);
        else
                return tolower_l(c, locale->info.lt);
 }
index 9412cad3ac547b5a1fc351bd2dd56c9824f8e8e6..91cee7714b1e133bb56930d2526843483af36ed6 100644 (file)
@@ -1216,6 +1216,7 @@ create_pg_locale(Oid collid, MemoryContext context)
 
        result->provider = collform->collprovider;
        result->deterministic = collform->collisdeterministic;
+       result->is_default = false;
 
        if (collform->collprovider == COLLPROVIDER_BUILTIN)
        {
@@ -1409,6 +1410,7 @@ init_database_collation(void)
 
 
        default_locale.provider = dbform->datlocprovider;
+       default_locale.is_default = true;
 
        /*
         * Default locale is currently always deterministic.  Nondeterministic
index 37ecf951937a44f669693fec80db1fef353bc040..4d2262b39aa760731c010f3ad47258f3de0f055c 100644 (file)
@@ -82,6 +82,7 @@ struct pg_locale_struct
        bool            deterministic;
        bool            collate_is_c;
        bool            ctype_is_c;
+       bool            is_default;
        union
        {
                struct