@@ -92,27 +92,12 @@ extern char *get_collation_actual_version_builtin(const char *collcollate);
9292/* pg_locale_icu.c */
9393#ifdef USE_ICU
9494extern UCollator * pg_ucol_open (const char * loc_str );
95- extern int strncoll_icu (const char * arg1 , ssize_t len1 ,
96- const char * arg2 , ssize_t len2 ,
97- pg_locale_t locale );
98- extern size_t strnxfrm_icu (char * dest , size_t destsize ,
99- const char * src , ssize_t srclen ,
100- pg_locale_t locale );
101- extern size_t strnxfrm_prefix_icu (char * dest , size_t destsize ,
102- const char * src , ssize_t srclen ,
103- pg_locale_t locale );
10495extern char * get_collation_actual_version_icu (const char * collcollate );
10596#endif
10697extern pg_locale_t create_pg_locale_icu (Oid collid , MemoryContext context );
10798
10899/* pg_locale_libc.c */
109100extern pg_locale_t create_pg_locale_libc (Oid collid , MemoryContext context );
110- extern int strncoll_libc (const char * arg1 , ssize_t len1 ,
111- const char * arg2 , ssize_t len2 ,
112- pg_locale_t locale );
113- extern size_t strnxfrm_libc (char * dest , size_t destsize ,
114- const char * src , ssize_t srclen ,
115- pg_locale_t locale );
116101extern char * get_collation_actual_version_libc (const char * collcollate );
117102
118103extern size_t strlower_builtin (char * dst , size_t dstsize , const char * src ,
@@ -1244,6 +1229,9 @@ create_pg_locale(Oid collid, MemoryContext context)
12441229
12451230 result -> is_default = false;
12461231
1232+ Assert ((result -> collate_is_c && result -> collate == NULL ) ||
1233+ (!result -> collate_is_c && result -> collate != NULL ));
1234+
12471235 datum = SysCacheGetAttr (COLLOID , tp , Anum_pg_collation_collversion ,
12481236 & isnull );
12491237 if (!isnull )
@@ -1467,19 +1455,7 @@ pg_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen,
14671455int
14681456pg_strcoll (const char * arg1 , const char * arg2 , pg_locale_t locale )
14691457{
1470- int result ;
1471-
1472- if (locale -> provider == COLLPROVIDER_LIBC )
1473- result = strncoll_libc (arg1 , -1 , arg2 , -1 , locale );
1474- #ifdef USE_ICU
1475- else if (locale -> provider == COLLPROVIDER_ICU )
1476- result = strncoll_icu (arg1 , -1 , arg2 , -1 , locale );
1477- #endif
1478- else
1479- /* shouldn't happen */
1480- PGLOCALE_SUPPORT_ERROR (locale -> provider );
1481-
1482- return result ;
1458+ return locale -> collate -> strncoll (arg1 , -1 , arg2 , -1 , locale );
14831459}
14841460
14851461/*
@@ -1500,51 +1476,25 @@ int
15001476pg_strncoll (const char * arg1 , ssize_t len1 , const char * arg2 , ssize_t len2 ,
15011477 pg_locale_t locale )
15021478{
1503- int result ;
1504-
1505- if (locale -> provider == COLLPROVIDER_LIBC )
1506- result = strncoll_libc (arg1 , len1 , arg2 , len2 , locale );
1507- #ifdef USE_ICU
1508- else if (locale -> provider == COLLPROVIDER_ICU )
1509- result = strncoll_icu (arg1 , len1 , arg2 , len2 , locale );
1510- #endif
1511- else
1512- /* shouldn't happen */
1513- PGLOCALE_SUPPORT_ERROR (locale -> provider );
1514-
1515- return result ;
1479+ return locale -> collate -> strncoll (arg1 , len1 , arg2 , len2 , locale );
15161480}
15171481
15181482/*
15191483 * Return true if the collation provider supports pg_strxfrm() and
15201484 * pg_strnxfrm(); otherwise false.
15211485 *
1522- * Unfortunately, it seems that strxfrm() for non-C collations is broken on
1523- * many common platforms; testing of multiple versions of glibc reveals that,
1524- * for many locales, strcoll() and strxfrm() do not return consistent
1525- * results. While no other libc other than Cygwin has so far been shown to
1526- * have a problem, we take the conservative course of action for right now and
1527- * disable this categorically. (Users who are certain this isn't a problem on
1528- * their system can define TRUST_STRXFRM.)
15291486 *
15301487 * No similar problem is known for the ICU provider.
15311488 */
15321489bool
15331490pg_strxfrm_enabled (pg_locale_t locale )
15341491{
1535- if (locale -> provider == COLLPROVIDER_LIBC )
1536- #ifdef TRUST_STRXFRM
1537- return true;
1538- #else
1539- return false;
1540- #endif
1541- else if (locale -> provider == COLLPROVIDER_ICU )
1542- return true ;
1543- else
1544- /* shouldn't happen */
1545- PGLOCALE_SUPPORT_ERROR (locale -> provider );
1546-
1547- return false; /* keep compiler quiet */
1492+ /*
1493+ * locale->collate->strnxfrm is still a required method, even if it may
1494+ * have the wrong behavior, because the planner uses it for estimates in
1495+ * some cases.
1496+ */
1497+ return locale -> collate -> strxfrm_is_safe ;
15481498}
15491499
15501500/*
@@ -1555,19 +1505,7 @@ pg_strxfrm_enabled(pg_locale_t locale)
15551505size_t
15561506pg_strxfrm (char * dest , const char * src , size_t destsize , pg_locale_t locale )
15571507{
1558- size_t result = 0 ; /* keep compiler quiet */
1559-
1560- if (locale -> provider == COLLPROVIDER_LIBC )
1561- result = strnxfrm_libc (dest , destsize , src , -1 , locale );
1562- #ifdef USE_ICU
1563- else if (locale -> provider == COLLPROVIDER_ICU )
1564- result = strnxfrm_icu (dest , destsize , src , -1 , locale );
1565- #endif
1566- else
1567- /* shouldn't happen */
1568- PGLOCALE_SUPPORT_ERROR (locale -> provider );
1569-
1570- return result ;
1508+ return locale -> collate -> strnxfrm (dest , destsize , src , -1 , locale );
15711509}
15721510
15731511/*
@@ -1593,19 +1531,7 @@ size_t
15931531pg_strnxfrm (char * dest , size_t destsize , const char * src , ssize_t srclen ,
15941532 pg_locale_t locale )
15951533{
1596- size_t result = 0 ; /* keep compiler quiet */
1597-
1598- if (locale -> provider == COLLPROVIDER_LIBC )
1599- result = strnxfrm_libc (dest , destsize , src , srclen , locale );
1600- #ifdef USE_ICU
1601- else if (locale -> provider == COLLPROVIDER_ICU )
1602- result = strnxfrm_icu (dest , destsize , src , srclen , locale );
1603- #endif
1604- else
1605- /* shouldn't happen */
1606- PGLOCALE_SUPPORT_ERROR (locale -> provider );
1607-
1608- return result ;
1534+ return locale -> collate -> strnxfrm (dest , destsize , src , srclen , locale );
16091535}
16101536
16111537/*
@@ -1615,15 +1541,7 @@ pg_strnxfrm(char *dest, size_t destsize, const char *src, ssize_t srclen,
16151541bool
16161542pg_strxfrm_prefix_enabled (pg_locale_t locale )
16171543{
1618- if (locale -> provider == COLLPROVIDER_LIBC )
1619- return false;
1620- else if (locale -> provider == COLLPROVIDER_ICU )
1621- return true;
1622- else
1623- /* shouldn't happen */
1624- PGLOCALE_SUPPORT_ERROR (locale -> provider );
1625-
1626- return false; /* keep compiler quiet */
1544+ return (locale -> collate -> strnxfrm_prefix != NULL );
16271545}
16281546
16291547/*
@@ -1635,7 +1553,7 @@ size_t
16351553pg_strxfrm_prefix (char * dest , const char * src , size_t destsize ,
16361554 pg_locale_t locale )
16371555{
1638- return pg_strnxfrm_prefix (dest , destsize , src , -1 , locale );
1556+ return locale -> collate -> strnxfrm_prefix (dest , destsize , src , -1 , locale );
16391557}
16401558
16411559/*
@@ -1660,16 +1578,7 @@ size_t
16601578pg_strnxfrm_prefix (char * dest , size_t destsize , const char * src ,
16611579 ssize_t srclen , pg_locale_t locale )
16621580{
1663- size_t result = 0 ; /* keep compiler quiet */
1664-
1665- #ifdef USE_ICU
1666- if (locale -> provider == COLLPROVIDER_ICU )
1667- result = strnxfrm_prefix_icu (dest , destsize , src , -1 , locale );
1668- else
1669- #endif
1670- PGLOCALE_SUPPORT_ERROR (locale -> provider );
1671-
1672- return result ;
1581+ return locale -> collate -> strnxfrm_prefix (dest , destsize , src , srclen , locale );
16731582}
16741583
16751584/*
0 commit comments