PostgreSQL Source Code git master
pg_locale.h File Reference
#include "mb/pg_wchar.h"
Include dependency graph for pg_locale.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  collate_methods
 
struct  ctype_methods
 
struct  pg_locale_struct
 

Macros

#define LOCALE_NAME_BUFLEN   128
 
#define UNICODE_CASEMAP_LEN   3
 
#define UNICODE_CASEMAP_BUFSZ   (UNICODE_CASEMAP_LEN * sizeof(char32_t))
 

Typedefs

typedef struct pg_locale_structpg_locale_t
 

Functions

bool check_locale (int category, const char *locale, char **canonname)
 
char * pg_perm_setlocale (int category, const char *locale)
 
struct lconv * PGLC_localeconv (void)
 
void cache_locale_time (void)
 
void init_database_collation (void)
 
pg_locale_t pg_database_locale (void)
 
pg_locale_t pg_newlocale_from_collation (Oid collid)
 
char * get_collation_actual_version (char collprovider, const char *collcollate)
 
bool char_is_cased (char ch, pg_locale_t locale)
 
bool char_tolower_enabled (pg_locale_t locale)
 
char char_tolower (unsigned char ch, pg_locale_t locale)
 
size_t pg_strlower (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
size_t pg_strtitle (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
size_t pg_strupper (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
size_t pg_strfold (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
int pg_strcoll (const char *arg1, const char *arg2, pg_locale_t locale)
 
int pg_strncoll (const char *arg1, ssize_t len1, const char *arg2, ssize_t len2, pg_locale_t locale)
 
bool pg_strxfrm_enabled (pg_locale_t locale)
 
size_t pg_strxfrm (char *dest, const char *src, size_t destsize, pg_locale_t locale)
 
size_t pg_strnxfrm (char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
bool pg_strxfrm_prefix_enabled (pg_locale_t locale)
 
size_t pg_strxfrm_prefix (char *dest, const char *src, size_t destsize, pg_locale_t locale)
 
size_t pg_strnxfrm_prefix (char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
bool pg_iswdigit (pg_wchar wc, pg_locale_t locale)
 
bool pg_iswalpha (pg_wchar wc, pg_locale_t locale)
 
bool pg_iswalnum (pg_wchar wc, pg_locale_t locale)
 
bool pg_iswupper (pg_wchar wc, pg_locale_t locale)
 
bool pg_iswlower (pg_wchar wc, pg_locale_t locale)
 
bool pg_iswgraph (pg_wchar wc, pg_locale_t locale)
 
bool pg_iswprint (pg_wchar wc, pg_locale_t locale)
 
bool pg_iswpunct (pg_wchar wc, pg_locale_t locale)
 
bool pg_iswspace (pg_wchar wc, pg_locale_t locale)
 
bool pg_iswxdigit (pg_wchar wc, pg_locale_t locale)
 
pg_wchar pg_towupper (pg_wchar wc, pg_locale_t locale)
 
pg_wchar pg_towlower (pg_wchar wc, pg_locale_t locale)
 
int builtin_locale_encoding (const char *locale)
 
const char * builtin_validate_locale (int encoding, const char *locale)
 
void icu_validate_locale (const char *loc_str)
 
char * icu_language_tag (const char *loc_str, int elevel)
 
void report_newlocale_failure (const char *localename)
 
size_t wchar2char (char *to, const wchar_t *from, size_t tolen, locale_t loc)
 

Variables

PGDLLIMPORT char * locale_messages
 
PGDLLIMPORT char * locale_monetary
 
PGDLLIMPORT char * locale_numeric
 
PGDLLIMPORT char * locale_time
 
PGDLLIMPORT int icu_validation_level
 
PGDLLIMPORT char * localized_abbrev_days []
 
PGDLLIMPORT char * localized_full_days []
 
PGDLLIMPORT char * localized_abbrev_months []
 
PGDLLIMPORT char * localized_full_months []
 

Macro Definition Documentation

◆ LOCALE_NAME_BUFLEN

#define LOCALE_NAME_BUFLEN   128

Definition at line 27 of file pg_locale.h.

◆ UNICODE_CASEMAP_BUFSZ

#define UNICODE_CASEMAP_BUFSZ   (UNICODE_CASEMAP_LEN * sizeof(char32_t))

Definition at line 41 of file pg_locale.h.

◆ UNICODE_CASEMAP_LEN

#define UNICODE_CASEMAP_LEN   3

Definition at line 40 of file pg_locale.h.

Typedef Documentation

◆ pg_locale_t

typedef struct pg_locale_struct* pg_locale_t

Definition at line 69 of file pg_locale.h.

Function Documentation

◆ builtin_locale_encoding()

int builtin_locale_encoding ( const char *  locale)

Definition at line 1663 of file pg_locale.c.

1664{
1665 if (strcmp(locale, "C") == 0)
1666 return -1;
1667 else if (strcmp(locale, "C.UTF-8") == 0)
1668 return PG_UTF8;
1669 else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
1670 return PG_UTF8;
1671
1672
1673 ereport(ERROR,
1674 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1675 errmsg("invalid locale name \"%s\" for builtin provider",
1676 locale)));
1677
1678 return 0; /* keep compiler quiet */
1679}
int errcode(int sqlerrcode)
Definition: elog.c:863
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
static char * locale
Definition: initdb.c:140
@ PG_UTF8
Definition: pg_wchar.h:232

References ereport, errcode(), errmsg(), ERROR, locale, and PG_UTF8.

Referenced by builtin_validate_locale(), and DefineCollation().

◆ builtin_validate_locale()

const char * builtin_validate_locale ( int  encoding,
const char *  locale 
)

Definition at line 1687 of file pg_locale.c.

1688{
1689 const char *canonical_name = NULL;
1690 int required_encoding;
1691
1692 if (strcmp(locale, "C") == 0)
1693 canonical_name = "C";
1694 else if (strcmp(locale, "C.UTF-8") == 0 || strcmp(locale, "C.UTF8") == 0)
1695 canonical_name = "C.UTF-8";
1696 else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
1697 canonical_name = "PG_UNICODE_FAST";
1698
1699 if (!canonical_name)
1700 ereport(ERROR,
1701 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1702 errmsg("invalid locale name \"%s\" for builtin provider",
1703 locale)));
1704
1705 required_encoding = builtin_locale_encoding(canonical_name);
1706 if (required_encoding >= 0 && encoding != required_encoding)
1707 ereport(ERROR,
1708 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1709 errmsg("encoding \"%s\" does not match locale \"%s\"",
1711
1712 return canonical_name;
1713}
int32 encoding
Definition: pg_database.h:41
int builtin_locale_encoding(const char *locale)
Definition: pg_locale.c:1663
#define pg_encoding_to_char
Definition: pg_wchar.h:630

References builtin_locale_encoding(), encoding, ereport, errcode(), errmsg(), ERROR, locale, and pg_encoding_to_char.

Referenced by create_pg_locale_builtin(), createdb(), and DefineCollation().

◆ cache_locale_time()

void cache_locale_time ( void  )

Definition at line 699 of file pg_locale.c.

700{
701 char buf[(2 * 7 + 2 * 12) * MAX_L10N_DATA];
702 char *bufptr;
703 time_t timenow;
704 struct tm *timeinfo;
705 struct tm timeinfobuf;
706 bool strftimefail = false;
707 int encoding;
708 int i;
710
711 /* did we do this already? */
713 return;
714
715 elog(DEBUG3, "cache_locale_time() executed; locale: \"%s\"", locale_time);
716
717 errno = ENOENT;
718#ifdef WIN32
719 locale = _create_locale(LC_ALL, locale_time);
720 if (locale == (locale_t) 0)
721 _dosmaperr(GetLastError());
722#else
723 locale = newlocale(LC_ALL_MASK, locale_time, (locale_t) 0);
724#endif
725 if (!locale)
727
728 /* We use times close to current time as data for strftime(). */
729 timenow = time(NULL);
730 timeinfo = gmtime_r(&timenow, &timeinfobuf);
731
732 /* Store the strftime results in MAX_L10N_DATA-sized portions of buf[] */
733 bufptr = buf;
734
735 /*
736 * MAX_L10N_DATA is sufficient buffer space for every known locale, and
737 * POSIX defines no strftime() errors. (Buffer space exhaustion is not an
738 * error.) An implementation might report errors (e.g. ENOMEM) by
739 * returning 0 (or, less plausibly, a negative value) and setting errno.
740 * Report errno just in case the implementation did that, but clear it in
741 * advance of the calls so we don't emit a stale, unrelated errno.
742 */
743 errno = 0;
744
745 /* localized days */
746 for (i = 0; i < 7; i++)
747 {
748 timeinfo->tm_wday = i;
749 if (strftime_l(bufptr, MAX_L10N_DATA, "%a", timeinfo, locale) <= 0)
750 strftimefail = true;
751 bufptr += MAX_L10N_DATA;
752 if (strftime_l(bufptr, MAX_L10N_DATA, "%A", timeinfo, locale) <= 0)
753 strftimefail = true;
754 bufptr += MAX_L10N_DATA;
755 }
756
757 /* localized months */
758 for (i = 0; i < 12; i++)
759 {
760 timeinfo->tm_mon = i;
761 timeinfo->tm_mday = 1; /* make sure we don't have invalid date */
762 if (strftime_l(bufptr, MAX_L10N_DATA, "%b", timeinfo, locale) <= 0)
763 strftimefail = true;
764 bufptr += MAX_L10N_DATA;
765 if (strftime_l(bufptr, MAX_L10N_DATA, "%B", timeinfo, locale) <= 0)
766 strftimefail = true;
767 bufptr += MAX_L10N_DATA;
768 }
769
770#ifdef WIN32
771 _free_locale(locale);
772#else
773 freelocale(locale);
774#endif
775
776 /*
777 * At this point we've done our best to clean up, and can throw errors, or
778 * call functions that might throw errors, with a clean conscience.
779 */
780 if (strftimefail)
781 elog(ERROR, "strftime_l() failed");
782
783#ifndef WIN32
784
785 /*
786 * As in PGLC_localeconv(), we must convert strftime()'s output from the
787 * encoding implied by LC_TIME to the database encoding. If we can't
788 * identify the LC_TIME encoding, just perform encoding validation.
789 */
791 if (encoding < 0)
793
794#else
795
796 /*
797 * On Windows, strftime_win32() always returns UTF8 data, so convert from
798 * that if necessary.
799 */
801
802#endif /* WIN32 */
803
804 bufptr = buf;
805
806 /* localized days */
807 for (i = 0; i < 7; i++)
808 {
810 bufptr += MAX_L10N_DATA;
812 bufptr += MAX_L10N_DATA;
813 }
814 localized_abbrev_days[7] = NULL;
815 localized_full_days[7] = NULL;
816
817 /* localized months */
818 for (i = 0; i < 12; i++)
819 {
821 bufptr += MAX_L10N_DATA;
823 bufptr += MAX_L10N_DATA;
824 }
825 localized_abbrev_months[12] = NULL;
826 localized_full_months[12] = NULL;
827
828 CurrentLCTimeValid = true;
829}
#define DEBUG3
Definition: elog.h:28
#define elog(elevel,...)
Definition: elog.h:226
int i
Definition: isn.c:77
static struct pg_tm tm
Definition: localtime.c:104
char * localized_full_months[12+1]
Definition: pg_locale.c:101
static bool CurrentLCTimeValid
Definition: pg_locale.c:107
char * locale_time
Definition: pg_locale.c:87
static void cache_single_string(char **dst, const char *src, int encoding)
Definition: pg_locale.c:676
#define MAX_L10N_DATA
Definition: pg_locale.c:66
char * localized_abbrev_months[12+1]
Definition: pg_locale.c:100
char * localized_full_days[7+1]
Definition: pg_locale.c:99
char * localized_abbrev_days[7+1]
Definition: pg_locale.c:98
void report_newlocale_failure(const char *localename)
static char * buf
Definition: pg_test_fsync.c:72
@ PG_SQL_ASCII
Definition: pg_wchar.h:226
int pg_get_encoding_from_locale(const char *ctype, bool write_message)
Definition: chklocale.c:301
#define locale_t
Definition: win32_port.h:432
void _dosmaperr(unsigned long)
Definition: win32error.c:177

References _dosmaperr(), buf, cache_single_string(), CurrentLCTimeValid, DEBUG3, elog, encoding, ERROR, i, locale, locale_t, locale_time, localized_abbrev_days, localized_abbrev_months, localized_full_days, localized_full_months, MAX_L10N_DATA, pg_get_encoding_from_locale(), PG_SQL_ASCII, PG_UTF8, report_newlocale_failure(), and tm.

Referenced by DCH_from_char(), and DCH_to_char().

◆ char_is_cased()

bool char_is_cased ( char  ch,
pg_locale_t  locale 
)

Definition at line 1625 of file pg_locale.c.

1626{
1627 if (locale->ctype == NULL)
1628 return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
1629 return locale->ctype->char_is_cased(ch, locale);
1630}

References locale.

Referenced by pattern_char_isalpha().

◆ char_tolower()

char char_tolower ( unsigned char  ch,
pg_locale_t  locale 
)

Definition at line 1651 of file pg_locale.c.

1652{
1653 if (locale->ctype == NULL)
1654 return pg_ascii_tolower(ch);
1655 return locale->ctype->char_tolower(ch, locale);
1656}
static unsigned char pg_ascii_tolower(unsigned char ch)
Definition: port.h:188

References locale, and pg_ascii_tolower().

Referenced by SB_lower_char().

◆ char_tolower_enabled()

bool char_tolower_enabled ( pg_locale_t  locale)

Definition at line 1638 of file pg_locale.c.

1639{
1640 if (locale->ctype == NULL)
1641 return true;
1642 return (locale->ctype->char_tolower != NULL);
1643}

References locale.

Referenced by Generic_Text_IC_like().

◆ check_locale()

bool check_locale ( int  category,
const char *  locale,
char **  canonname 
)

Definition at line 272 of file pg_locale.c.

273{
274 char *save;
275 char *res;
276
277 /* Don't let Windows' non-ASCII locale names in. */
278 if (!pg_is_ascii(locale))
279 {
281 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
282 errmsg("locale name \"%s\" contains non-ASCII characters",
283 locale)));
284 return false;
285 }
286
287 if (canonname)
288 *canonname = NULL; /* in case of failure */
289
290 save = setlocale(category, NULL);
291 if (!save)
292 return false; /* won't happen, we hope */
293
294 /* save may be pointing at a modifiable scratch variable, see above. */
295 save = pstrdup(save);
296
297 /* set the locale with setlocale, to see if it accepts it. */
298 res = setlocale(category, locale);
299
300 /* save canonical name if requested. */
301 if (res && canonname)
302 *canonname = pstrdup(res);
303
304 /* restore old value. */
305 if (!setlocale(category, save))
306 elog(WARNING, "failed to restore old locale \"%s\"", save);
307 pfree(save);
308
309 /* Don't let Windows' non-ASCII locale names out. */
310 if (canonname && *canonname && !pg_is_ascii(*canonname))
311 {
313 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
314 errmsg("locale name \"%s\" contains non-ASCII characters",
315 *canonname)));
316 pfree(*canonname);
317 *canonname = NULL;
318 return false;
319 }
320
321 return (res != NULL);
322}
#define WARNING
Definition: elog.h:36
char * pstrdup(const char *in)
Definition: mcxt.c:1759
void pfree(void *pointer)
Definition: mcxt.c:1594
bool pg_is_ascii(const char *str)
Definition: string.c:132
#define setlocale(a, b)
Definition: win32_port.h:475

References elog, ereport, errcode(), errmsg(), locale, pfree(), pg_is_ascii(), pstrdup(), setlocale, and WARNING.

Referenced by check_locale_messages(), check_locale_monetary(), check_locale_numeric(), check_locale_time(), and createdb().

◆ get_collation_actual_version()

char * get_collation_actual_version ( char  collprovider,
const char *  collcollate 
)

Definition at line 1244 of file pg_locale.c.

1245{
1246 char *collversion = NULL;
1247
1248 if (collprovider == COLLPROVIDER_BUILTIN)
1249 collversion = get_collation_actual_version_builtin(collcollate);
1250#ifdef USE_ICU
1251 else if (collprovider == COLLPROVIDER_ICU)
1252 collversion = get_collation_actual_version_icu(collcollate);
1253#endif
1254 else if (collprovider == COLLPROVIDER_LIBC)
1255 collversion = get_collation_actual_version_libc(collcollate);
1256
1257 return collversion;
1258}
char * get_collation_actual_version_libc(const char *collcollate)
char * get_collation_actual_version_builtin(const char *collcollate)

References get_collation_actual_version_builtin(), and get_collation_actual_version_libc().

Referenced by AlterCollation(), AlterDatabaseRefreshColl(), CheckMyDatabase(), create_pg_locale(), createdb(), DefineCollation(), pg_collation_actual_version(), pg_database_collation_actual_version(), and pg_import_system_collations().

◆ icu_language_tag()

char * icu_language_tag ( const char *  loc_str,
int  elevel 
)

Definition at line 1727 of file pg_locale.c.

1728{
1729#ifdef USE_ICU
1730 UErrorCode status;
1731 char *langtag;
1732 size_t buflen = 32; /* arbitrary starting buffer size */
1733 const bool strict = true;
1734
1735 /*
1736 * A BCP47 language tag doesn't have a clearly-defined upper limit (cf.
1737 * RFC5646 section 4.4). Additionally, in older ICU versions,
1738 * uloc_toLanguageTag() doesn't always return the ultimate length on the
1739 * first call, necessitating a loop.
1740 */
1741 langtag = palloc(buflen);
1742 while (true)
1743 {
1744 status = U_ZERO_ERROR;
1745 uloc_toLanguageTag(loc_str, langtag, buflen, strict, &status);
1746
1747 /* try again if the buffer is not large enough */
1748 if ((status == U_BUFFER_OVERFLOW_ERROR ||
1749 status == U_STRING_NOT_TERMINATED_WARNING) &&
1750 buflen < MaxAllocSize)
1751 {
1752 buflen = Min(buflen * 2, MaxAllocSize);
1753 langtag = repalloc(langtag, buflen);
1754 continue;
1755 }
1756
1757 break;
1758 }
1759
1760 if (U_FAILURE(status))
1761 {
1762 pfree(langtag);
1763
1764 if (elevel > 0)
1765 ereport(elevel,
1766 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1767 errmsg("could not convert locale name \"%s\" to language tag: %s",
1768 loc_str, u_errorName(status))));
1769 return NULL;
1770 }
1771
1772 return langtag;
1773#else /* not USE_ICU */
1774 ereport(ERROR,
1775 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1776 errmsg("ICU is not supported in this build")));
1777 return NULL; /* keep compiler quiet */
1778#endif /* not USE_ICU */
1779}
#define Min(x, y)
Definition: c.h:1006
#define MaxAllocSize
Definition: fe_memutils.h:22
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1610
void * palloc(Size size)
Definition: mcxt.c:1365

References ereport, errcode(), errmsg(), ERROR, MaxAllocSize, Min, palloc(), pfree(), and repalloc().

Referenced by createdb(), DefineCollation(), and pg_import_system_collations().

◆ icu_validate_locale()

void icu_validate_locale ( const char *  loc_str)

Definition at line 1785 of file pg_locale.c.

1786{
1787#ifdef USE_ICU
1788 UCollator *collator;
1789 UErrorCode status;
1790 char lang[ULOC_LANG_CAPACITY];
1791 bool found = false;
1792 int elevel = icu_validation_level;
1793
1794 /* no validation */
1795 if (elevel < 0)
1796 return;
1797
1798 /* downgrade to WARNING during pg_upgrade */
1799 if (IsBinaryUpgrade && elevel > WARNING)
1800 elevel = WARNING;
1801
1802 /* validate that we can extract the language */
1803 status = U_ZERO_ERROR;
1804 uloc_getLanguage(loc_str, lang, ULOC_LANG_CAPACITY, &status);
1805 if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING)
1806 {
1807 ereport(elevel,
1808 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1809 errmsg("could not get language from ICU locale \"%s\": %s",
1810 loc_str, u_errorName(status)),
1811 errhint("To disable ICU locale validation, set the parameter \"%s\" to \"%s\".",
1812 "icu_validation_level", "disabled")));
1813 return;
1814 }
1815
1816 /* check for special language name */
1817 if (strcmp(lang, "") == 0 ||
1818 strcmp(lang, "root") == 0 || strcmp(lang, "und") == 0)
1819 found = true;
1820
1821 /* search for matching language within ICU */
1822 for (int32_t i = 0; !found && i < uloc_countAvailable(); i++)
1823 {
1824 const char *otherloc = uloc_getAvailable(i);
1825 char otherlang[ULOC_LANG_CAPACITY];
1826
1827 status = U_ZERO_ERROR;
1828 uloc_getLanguage(otherloc, otherlang, ULOC_LANG_CAPACITY, &status);
1829 if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING)
1830 continue;
1831
1832 if (strcmp(lang, otherlang) == 0)
1833 found = true;
1834 }
1835
1836 if (!found)
1837 ereport(elevel,
1838 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1839 errmsg("ICU locale \"%s\" has unknown language \"%s\"",
1840 loc_str, lang),
1841 errhint("To disable ICU locale validation, set the parameter \"%s\" to \"%s\".",
1842 "icu_validation_level", "disabled")));
1843
1844 /* check that it can be opened */
1845 collator = pg_ucol_open(loc_str);
1846 ucol_close(collator);
1847#else /* not USE_ICU */
1848 /* could get here if a collation was created by a build with ICU */
1849 ereport(ERROR,
1850 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1851 errmsg("ICU is not supported in this build")));
1852#endif /* not USE_ICU */
1853}
int errhint(const char *fmt,...)
Definition: elog.c:1330
bool IsBinaryUpgrade
Definition: globals.c:121
int icu_validation_level
Definition: pg_locale.c:89

References ereport, errcode(), errhint(), errmsg(), ERROR, i, icu_validation_level, IsBinaryUpgrade, and WARNING.

Referenced by createdb(), and DefineCollation().

◆ init_database_collation()

void init_database_collation ( void  )

Definition at line 1128 of file pg_locale.c.

1129{
1130 HeapTuple tup;
1131 Form_pg_database dbform;
1132 pg_locale_t result;
1133
1134 Assert(default_locale == NULL);
1135
1136 /* Fetch our pg_database row normally, via syscache */
1137 tup = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
1138 if (!HeapTupleIsValid(tup))
1139 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
1140 dbform = (Form_pg_database) GETSTRUCT(tup);
1141
1142 if (dbform->datlocprovider == COLLPROVIDER_BUILTIN)
1143 result = create_pg_locale_builtin(DEFAULT_COLLATION_OID,
1145 else if (dbform->datlocprovider == COLLPROVIDER_ICU)
1146 result = create_pg_locale_icu(DEFAULT_COLLATION_OID,
1148 else if (dbform->datlocprovider == COLLPROVIDER_LIBC)
1149 result = create_pg_locale_libc(DEFAULT_COLLATION_OID,
1151 else
1152 /* shouldn't happen */
1153 PGLOCALE_SUPPORT_ERROR(dbform->datlocprovider);
1154
1155 result->is_default = true;
1156
1157 Assert((result->collate_is_c && result->collate == NULL) ||
1158 (!result->collate_is_c && result->collate != NULL));
1159
1160 Assert((result->ctype_is_c && result->ctype == NULL) ||
1161 (!result->ctype_is_c && result->ctype != NULL));
1162
1163 ReleaseSysCache(tup);
1164
1165 default_locale = result;
1166}
Oid MyDatabaseId
Definition: globals.c:94
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
MemoryContext TopMemoryContext
Definition: mcxt.c:166
FormData_pg_database * Form_pg_database
Definition: pg_database.h:96
pg_locale_t create_pg_locale_libc(Oid collid, MemoryContext context)
pg_locale_t create_pg_locale_builtin(Oid collid, MemoryContext context)
#define PGLOCALE_SUPPORT_ERROR(provider)
Definition: pg_locale.c:57
pg_locale_t create_pg_locale_icu(Oid collid, MemoryContext context)
static pg_locale_t default_locale
Definition: pg_locale.c:103
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:262
const struct ctype_methods * ctype
Definition: pg_locale.h:161
const struct collate_methods * collate
Definition: pg_locale.h:160
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:220

References Assert(), pg_locale_struct::collate, pg_locale_struct::collate_is_c, create_pg_locale_builtin(), create_pg_locale_icu(), create_pg_locale_libc(), pg_locale_struct::ctype, pg_locale_struct::ctype_is_c, default_locale, elog, ERROR, GETSTRUCT(), HeapTupleIsValid, pg_locale_struct::is_default, MyDatabaseId, ObjectIdGetDatum(), PGLOCALE_SUPPORT_ERROR, ReleaseSysCache(), SearchSysCache1(), and TopMemoryContext.

Referenced by CheckMyDatabase().

◆ pg_database_locale()

pg_locale_t pg_database_locale ( void  )

Definition at line 1172 of file pg_locale.c.

1173{
1174 return pg_newlocale_from_collation(DEFAULT_COLLATION_OID);
1175}
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition: pg_locale.c:1186

References pg_newlocale_from_collation().

Referenced by t_isalnum(), and t_isalpha().

◆ pg_iswalnum()

bool pg_iswalnum ( pg_wchar  wc,
pg_locale_t  locale 
)

Definition at line 1510 of file pg_locale.c.

1511{
1512 if (locale->ctype == NULL)
1513 return (wc <= (pg_wchar) 127 &&
1515 else
1516 return locale->ctype->wc_isalnum(wc, locale);
1517}
unsigned int pg_wchar
Definition: mbprint.c:31
#define PG_ISALNUM
Definition: pg_locale_c.h:21
static const unsigned char pg_char_properties[128]
Definition: pg_locale_c.h:29

References locale, pg_char_properties, and PG_ISALNUM.

Referenced by t_isalnum().

◆ pg_iswalpha()

bool pg_iswalpha ( pg_wchar  wc,
pg_locale_t  locale 
)

Definition at line 1500 of file pg_locale.c.

1501{
1502 if (locale->ctype == NULL)
1503 return (wc <= (pg_wchar) 127 &&
1505 else
1506 return locale->ctype->wc_isalpha(wc, locale);
1507}
#define PG_ISALPHA
Definition: pg_locale_c.h:20

References locale, pg_char_properties, and PG_ISALPHA.

Referenced by t_isalpha().

◆ pg_iswdigit()

bool pg_iswdigit ( pg_wchar  wc,
pg_locale_t  locale 
)

Definition at line 1490 of file pg_locale.c.

1491{
1492 if (locale->ctype == NULL)
1493 return (wc <= (pg_wchar) 127 &&
1495 else
1496 return locale->ctype->wc_isdigit(wc, locale);
1497}
#define PG_ISDIGIT
Definition: pg_locale_c.h:19

References locale, pg_char_properties, and PG_ISDIGIT.

◆ pg_iswgraph()

bool pg_iswgraph ( pg_wchar  wc,
pg_locale_t  locale 
)

Definition at line 1540 of file pg_locale.c.

1541{
1542 if (locale->ctype == NULL)
1543 return (wc <= (pg_wchar) 127 &&
1545 else
1546 return locale->ctype->wc_isgraph(wc, locale);
1547}
#define PG_ISGRAPH
Definition: pg_locale_c.h:24

References locale, pg_char_properties, and PG_ISGRAPH.

◆ pg_iswlower()

bool pg_iswlower ( pg_wchar  wc,
pg_locale_t  locale 
)

Definition at line 1530 of file pg_locale.c.

1531{
1532 if (locale->ctype == NULL)
1533 return (wc <= (pg_wchar) 127 &&
1535 else
1536 return locale->ctype->wc_islower(wc, locale);
1537}
#define PG_ISLOWER
Definition: pg_locale_c.h:23

References locale, pg_char_properties, and PG_ISLOWER.

◆ pg_iswprint()

bool pg_iswprint ( pg_wchar  wc,
pg_locale_t  locale 
)

Definition at line 1550 of file pg_locale.c.

1551{
1552 if (locale->ctype == NULL)
1553 return (wc <= (pg_wchar) 127 &&
1555 else
1556 return locale->ctype->wc_isprint(wc, locale);
1557}
#define PG_ISPRINT
Definition: pg_locale_c.h:25

References locale, pg_char_properties, and PG_ISPRINT.

◆ pg_iswpunct()

bool pg_iswpunct ( pg_wchar  wc,
pg_locale_t  locale 
)

Definition at line 1560 of file pg_locale.c.

1561{
1562 if (locale->ctype == NULL)
1563 return (wc <= (pg_wchar) 127 &&
1565 else
1566 return locale->ctype->wc_ispunct(wc, locale);
1567}
#define PG_ISPUNCT
Definition: pg_locale_c.h:26

References locale, pg_char_properties, and PG_ISPUNCT.

◆ pg_iswspace()

bool pg_iswspace ( pg_wchar  wc,
pg_locale_t  locale 
)

Definition at line 1570 of file pg_locale.c.

1571{
1572 if (locale->ctype == NULL)
1573 return (wc <= (pg_wchar) 127 &&
1575 else
1576 return locale->ctype->wc_isspace(wc, locale);
1577}
#define PG_ISSPACE
Definition: pg_locale_c.h:27

References locale, pg_char_properties, and PG_ISSPACE.

◆ pg_iswupper()

bool pg_iswupper ( pg_wchar  wc,
pg_locale_t  locale 
)

Definition at line 1520 of file pg_locale.c.

1521{
1522 if (locale->ctype == NULL)
1523 return (wc <= (pg_wchar) 127 &&
1525 else
1526 return locale->ctype->wc_isupper(wc, locale);
1527}
#define PG_ISUPPER
Definition: pg_locale_c.h:22

References locale, pg_char_properties, and PG_ISUPPER.

◆ pg_iswxdigit()

bool pg_iswxdigit ( pg_wchar  wc,
pg_locale_t  locale 
)

Definition at line 1580 of file pg_locale.c.

1581{
1582 if (locale->ctype == NULL)
1583 return (wc <= (pg_wchar) 127 &&
1584 ((pg_char_properties[wc] & PG_ISDIGIT) ||
1585 ((wc >= 'A' && wc <= 'F') ||
1586 (wc >= 'a' && wc <= 'f'))));
1587 else
1588 return locale->ctype->wc_isxdigit(wc, locale);
1589}

References locale, pg_char_properties, and PG_ISDIGIT.

◆ pg_newlocale_from_collation()

pg_locale_t pg_newlocale_from_collation ( Oid  collid)

Definition at line 1186 of file pg_locale.c.

1187{
1188 collation_cache_entry *cache_entry;
1189 bool found;
1190
1191 if (collid == DEFAULT_COLLATION_OID)
1192 return default_locale;
1193
1194 /*
1195 * Some callers expect C_COLLATION_OID to succeed even without catalog
1196 * access.
1197 */
1198 if (collid == C_COLLATION_OID)
1199 return &c_locale;
1200
1201 if (!OidIsValid(collid))
1202 elog(ERROR, "cache lookup failed for collation %u", collid);
1203
1205
1208
1209 if (CollationCache == NULL)
1210 {
1212 "collation cache",
1214 CollationCache = collation_cache_create(CollationCacheContext,
1215 16, NULL);
1216 }
1217
1218 cache_entry = collation_cache_insert(CollationCache, collid, &found);
1219 if (!found)
1220 {
1221 /*
1222 * Make sure cache entry is marked invalid, in case we fail before
1223 * setting things.
1224 */
1225 cache_entry->locale = NULL;
1226 }
1227
1228 if (cache_entry->locale == NULL)
1229 {
1231 }
1232
1234 last_collation_cache_locale = cache_entry->locale;
1235
1236 return cache_entry->locale;
1237}
#define OidIsValid(objectId)
Definition: c.h:777
Oid collid
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
static pg_locale_t last_collation_cache_locale
Definition: pg_locale.c:148
static struct pg_locale_struct c_locale
Definition: pg_locale.c:109
static pg_locale_t create_pg_locale(Oid collid, MemoryContext context)
Definition: pg_locale.c:1046
static MemoryContext CollationCacheContext
Definition: pg_locale.c:140
static collation_cache_hash * CollationCache
Definition: pg_locale.c:141
static Oid last_collation_cache_oid
Definition: pg_locale.c:147
static void AssertCouldGetRelation(void)
Definition: relcache.h:44
Definition: pg_locale.c:118
pg_locale_t locale
Definition: pg_locale.c:120

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, AssertCouldGetRelation(), c_locale, CollationCache, CollationCacheContext, collid, create_pg_locale(), default_locale, elog, ERROR, last_collation_cache_locale, last_collation_cache_oid, collation_cache_entry::locale, OidIsValid, and TopMemoryContext.

Referenced by bpchareq(), bpcharne(), btvarstrequalimage(), convert_string_datum(), DefineCollation(), Generic_Text_IC_like(), GenericMatchText(), hashbpchar(), hashbpcharextended(), hashtext(), hashtextextended(), like_fixed_prefix(), make_greater_string(), match_pattern_prefix(), pg_database_locale(), pg_set_regex_collation(), spg_text_inner_consistent(), str_casefold(), str_initcap(), str_tolower(), str_toupper(), text_position(), text_position_setup(), text_starts_with(), texteq(), textne(), varstr_cmp(), and varstr_sortsupport().

◆ pg_perm_setlocale()

char * pg_perm_setlocale ( int  category,
const char *  locale 
)

Definition at line 169 of file pg_locale.c.

170{
171 char *result;
172 const char *envvar;
173
174#ifndef WIN32
175 result = setlocale(category, locale);
176#else
177
178 /*
179 * On Windows, setlocale(LC_MESSAGES) does not work, so just assume that
180 * the given value is good and set it in the environment variables. We
181 * must ignore attempts to set to "", which means "keep using the old
182 * environment value".
183 */
184#ifdef LC_MESSAGES
185 if (category == LC_MESSAGES)
186 {
187 result = (char *) locale;
188 if (locale == NULL || locale[0] == '\0')
189 return result;
190 }
191 else
192#endif
193 result = setlocale(category, locale);
194#endif /* WIN32 */
195
196 if (result == NULL)
197 return result; /* fall out immediately on failure */
198
199 /*
200 * Use the right encoding in translated messages. Under ENABLE_NLS, let
201 * pg_bind_textdomain_codeset() figure it out. Under !ENABLE_NLS, message
202 * format strings are ASCII, but database-encoding strings may enter the
203 * message via %s. This makes the overall message encoding equal to the
204 * database encoding.
205 */
206 if (category == LC_CTYPE)
207 {
208 static char save_lc_ctype[LOCALE_NAME_BUFLEN];
209
210 /* copy setlocale() return value before callee invokes it again */
211 strlcpy(save_lc_ctype, result, sizeof(save_lc_ctype));
212 result = save_lc_ctype;
213
214#ifdef ENABLE_NLS
215 SetMessageEncoding(pg_bind_textdomain_codeset(textdomain(NULL)));
216#else
218#endif
219 }
220
221 switch (category)
222 {
223 case LC_COLLATE:
224 envvar = "LC_COLLATE";
225 break;
226 case LC_CTYPE:
227 envvar = "LC_CTYPE";
228 break;
229#ifdef LC_MESSAGES
230 case LC_MESSAGES:
231 envvar = "LC_MESSAGES";
232#ifdef WIN32
233 result = IsoLocaleName(locale);
234 if (result == NULL)
235 result = (char *) locale;
236 elog(DEBUG3, "IsoLocaleName() executed; locale: \"%s\"", result);
237#endif /* WIN32 */
238 break;
239#endif /* LC_MESSAGES */
240 case LC_MONETARY:
241 envvar = "LC_MONETARY";
242 break;
243 case LC_NUMERIC:
244 envvar = "LC_NUMERIC";
245 break;
246 case LC_TIME:
247 envvar = "LC_TIME";
248 break;
249 default:
250 elog(FATAL, "unrecognized LC category: %d", category);
251 return NULL; /* keep compiler quiet */
252 }
253
254 if (setenv(envvar, result, 1) != 0)
255 return NULL;
256
257 return result;
258}
#define FATAL
Definition: elog.h:41
int GetDatabaseEncoding(void)
Definition: mbutils.c:1262
void SetMessageEncoding(int encoding)
Definition: mbutils.c:1172
#define LOCALE_NAME_BUFLEN
Definition: pg_locale.h:27
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define setenv(x, y, z)
Definition: win32_port.h:545

References DEBUG3, elog, FATAL, GetDatabaseEncoding(), locale, LOCALE_NAME_BUFLEN, setenv, setlocale, SetMessageEncoding(), and strlcpy().

Referenced by assign_locale_messages(), CheckMyDatabase(), and init_locale().

◆ pg_strcoll()

int pg_strcoll ( const char *  arg1,
const char *  arg2,
pg_locale_t  locale 
)

Definition at line 1361 of file pg_locale.c.

1362{
1363 return locale->collate->strncoll(arg1, -1, arg2, -1, locale);
1364}

References locale.

Referenced by varstrfastcmp_locale().

◆ pg_strfold()

size_t pg_strfold ( char *  dst,
size_t  dstsize,
const char *  src,
ssize_t  srclen,
pg_locale_t  locale 
)

Definition at line 1345 of file pg_locale.c.

1347{
1348 /* in the C locale, casefolding is the same as lowercasing */
1349 if (locale->ctype == NULL)
1350 return strlower_c(dst, dstsize, src, srclen);
1351 else
1352 return locale->ctype->strfold(dst, dstsize, src, srclen, locale);
1353}
static size_t strlower_c(char *dst, size_t dstsize, const char *src, ssize_t srclen)
Definition: pg_locale.c:1262

References locale, and strlower_c().

Referenced by str_casefold().

◆ pg_strlower()

size_t pg_strlower ( char *  dst,
size_t  dstsize,
const char *  src,
ssize_t  srclen,
pg_locale_t  locale 
)

Definition at line 1315 of file pg_locale.c.

1317{
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);
1322}

References locale, and strlower_c().

Referenced by str_tolower().

◆ pg_strncoll()

int pg_strncoll ( const char *  arg1,
ssize_t  len1,
const char *  arg2,
ssize_t  len2,
pg_locale_t  locale 
)

Definition at line 1381 of file pg_locale.c.

1383{
1384 return locale->collate->strncoll(arg1, len1, arg2, len2, locale);
1385}

References locale.

Referenced by MatchText(), text_position_next_internal(), and varstr_cmp().

◆ pg_strnxfrm()

size_t pg_strnxfrm ( char *  dest,
size_t  destsize,
const char *  src,
ssize_t  srclen,
pg_locale_t  locale 
)

Definition at line 1436 of file pg_locale.c.

1438{
1439 return locale->collate->strnxfrm(dest, destsize, src, srclen, locale);
1440}

References generate_unaccent_rules::dest, and locale.

Referenced by hashbpchar(), hashbpcharextended(), hashtext(), and hashtextextended().

◆ pg_strnxfrm_prefix()

size_t pg_strnxfrm_prefix ( char *  dest,
size_t  destsize,
const char *  src,
ssize_t  srclen,
pg_locale_t  locale 
)

Definition at line 1483 of file pg_locale.c.

1485{
1486 return locale->collate->strnxfrm_prefix(dest, destsize, src, srclen, locale);
1487}

References generate_unaccent_rules::dest, and locale.

◆ pg_strtitle()

size_t pg_strtitle ( char *  dst,
size_t  dstsize,
const char *  src,
ssize_t  srclen,
pg_locale_t  locale 
)

Definition at line 1325 of file pg_locale.c.

1327{
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);
1332}
static size_t strtitle_c(char *dst, size_t dstsize, const char *src, ssize_t srclen)
Definition: pg_locale.c:1276

References locale, and strtitle_c().

Referenced by str_initcap().

◆ pg_strupper()

size_t pg_strupper ( char *  dst,
size_t  dstsize,
const char *  src,
ssize_t  srclen,
pg_locale_t  locale 
)

Definition at line 1335 of file pg_locale.c.

1337{
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);
1342}
static size_t strupper_c(char *dst, size_t dstsize, const char *src, ssize_t srclen)
Definition: pg_locale.c:1302

References locale, and strupper_c().

Referenced by str_toupper().

◆ pg_strxfrm()

size_t pg_strxfrm ( char *  dest,
const char *  src,
size_t  destsize,
pg_locale_t  locale 
)

Definition at line 1411 of file pg_locale.c.

1412{
1413 return locale->collate->strnxfrm(dest, destsize, src, -1, locale);
1414}

References generate_unaccent_rules::dest, and locale.

Referenced by convert_string_datum(), and varstr_abbrev_convert().

◆ pg_strxfrm_enabled()

bool pg_strxfrm_enabled ( pg_locale_t  locale)

Definition at line 1395 of file pg_locale.c.

1396{
1397 /*
1398 * locale->collate->strnxfrm is still a required method, even if it may
1399 * have the wrong behavior, because the planner uses it for estimates in
1400 * some cases.
1401 */
1402 return locale->collate->strxfrm_is_safe;
1403}

References locale.

Referenced by varstr_sortsupport().

◆ pg_strxfrm_prefix()

size_t pg_strxfrm_prefix ( char *  dest,
const char *  src,
size_t  destsize,
pg_locale_t  locale 
)

Definition at line 1458 of file pg_locale.c.

1460{
1461 return locale->collate->strnxfrm_prefix(dest, destsize, src, -1, locale);
1462}

References generate_unaccent_rules::dest, and locale.

Referenced by varstr_abbrev_convert().

◆ pg_strxfrm_prefix_enabled()

bool pg_strxfrm_prefix_enabled ( pg_locale_t  locale)

Definition at line 1447 of file pg_locale.c.

1448{
1449 return (locale->collate->strnxfrm_prefix != NULL);
1450}

References locale.

Referenced by varstr_abbrev_convert().

◆ pg_towlower()

pg_wchar pg_towlower ( pg_wchar  wc,
pg_locale_t  locale 
)

Definition at line 1605 of file pg_locale.c.

1606{
1607 if (locale->ctype == NULL)
1608 {
1609 if (wc <= (pg_wchar) 127)
1610 return pg_ascii_tolower((unsigned char) wc);
1611 return wc;
1612 }
1613 else
1614 return locale->ctype->wc_tolower(wc, locale);
1615}

References locale, and pg_ascii_tolower().

◆ pg_towupper()

pg_wchar pg_towupper ( pg_wchar  wc,
pg_locale_t  locale 
)

Definition at line 1592 of file pg_locale.c.

1593{
1594 if (locale->ctype == NULL)
1595 {
1596 if (wc <= (pg_wchar) 127)
1597 return pg_ascii_toupper((unsigned char) wc);
1598 return wc;
1599 }
1600 else
1601 return locale->ctype->wc_toupper(wc, locale);
1602}
static unsigned char pg_ascii_toupper(unsigned char ch)
Definition: port.h:177

References locale, and pg_ascii_toupper().

◆ PGLC_localeconv()

struct lconv * PGLC_localeconv ( void  )

Definition at line 503 of file pg_locale.c.

504{
505 static struct lconv CurrentLocaleConv;
506 static bool CurrentLocaleConvAllocated = false;
507 struct lconv *extlconv;
508 struct lconv tmp;
509 struct lconv worklconv = {0};
510
511 /* Did we do it already? */
513 return &CurrentLocaleConv;
514
515 /* Free any already-allocated storage */
516 if (CurrentLocaleConvAllocated)
517 {
518 free_struct_lconv(&CurrentLocaleConv);
519 CurrentLocaleConvAllocated = false;
520 }
521
522 /*
523 * Use thread-safe method of obtaining a copy of lconv from the operating
524 * system.
525 */
528 &tmp) != 0)
529 elog(ERROR,
530 "could not get lconv for LC_MONETARY = \"%s\", LC_NUMERIC = \"%s\": %m",
532
533 /* Must copy data now so we can re-encode it. */
534 extlconv = &tmp;
535 worklconv.decimal_point = strdup(extlconv->decimal_point);
536 worklconv.thousands_sep = strdup(extlconv->thousands_sep);
537 worklconv.grouping = strdup(extlconv->grouping);
538 worklconv.int_curr_symbol = strdup(extlconv->int_curr_symbol);
539 worklconv.currency_symbol = strdup(extlconv->currency_symbol);
540 worklconv.mon_decimal_point = strdup(extlconv->mon_decimal_point);
541 worklconv.mon_thousands_sep = strdup(extlconv->mon_thousands_sep);
542 worklconv.mon_grouping = strdup(extlconv->mon_grouping);
543 worklconv.positive_sign = strdup(extlconv->positive_sign);
544 worklconv.negative_sign = strdup(extlconv->negative_sign);
545 /* Copy scalar fields as well */
546 worklconv.int_frac_digits = extlconv->int_frac_digits;
547 worklconv.frac_digits = extlconv->frac_digits;
548 worklconv.p_cs_precedes = extlconv->p_cs_precedes;
549 worklconv.p_sep_by_space = extlconv->p_sep_by_space;
550 worklconv.n_cs_precedes = extlconv->n_cs_precedes;
551 worklconv.n_sep_by_space = extlconv->n_sep_by_space;
552 worklconv.p_sign_posn = extlconv->p_sign_posn;
553 worklconv.n_sign_posn = extlconv->n_sign_posn;
554
555 /* Free the contents of the object populated by pg_localeconv_r(). */
556 pg_localeconv_free(&tmp);
557
558 /* If any of the preceding strdup calls failed, complain now. */
559 if (!struct_lconv_is_valid(&worklconv))
561 (errcode(ERRCODE_OUT_OF_MEMORY),
562 errmsg("out of memory")));
563
564 PG_TRY();
565 {
566 int encoding;
567
568 /*
569 * Now we must perform encoding conversion from whatever's associated
570 * with the locales into the database encoding. If we can't identify
571 * the encoding implied by LC_NUMERIC or LC_MONETARY (ie we get -1),
572 * use PG_SQL_ASCII, which will result in just validating that the
573 * strings are OK in the database encoding.
574 */
576 if (encoding < 0)
578
579 db_encoding_convert(encoding, &worklconv.decimal_point);
580 db_encoding_convert(encoding, &worklconv.thousands_sep);
581 /* grouping is not text and does not require conversion */
582
584 if (encoding < 0)
586
587 db_encoding_convert(encoding, &worklconv.int_curr_symbol);
588 db_encoding_convert(encoding, &worklconv.currency_symbol);
589 db_encoding_convert(encoding, &worklconv.mon_decimal_point);
590 db_encoding_convert(encoding, &worklconv.mon_thousands_sep);
591 /* mon_grouping is not text and does not require conversion */
592 db_encoding_convert(encoding, &worklconv.positive_sign);
593 db_encoding_convert(encoding, &worklconv.negative_sign);
594 }
595 PG_CATCH();
596 {
597 free_struct_lconv(&worklconv);
598 PG_RE_THROW();
599 }
600 PG_END_TRY();
601
602 /*
603 * Everything is good, so save the results.
604 */
605 CurrentLocaleConv = worklconv;
606 CurrentLocaleConvAllocated = true;
608 return &CurrentLocaleConv;
609}
#define PG_RE_THROW()
Definition: elog.h:405
#define PG_TRY(...)
Definition: elog.h:372
#define PG_END_TRY(...)
Definition: elog.h:397
#define PG_CATCH(...)
Definition: elog.h:382
char * locale_numeric
Definition: pg_locale.c:86
static void db_encoding_convert(int encoding, char **str)
Definition: pg_locale.c:473
static void free_struct_lconv(struct lconv *s)
Definition: pg_locale.c:423
static bool CurrentLocaleConvValid
Definition: pg_locale.c:106
static bool struct_lconv_is_valid(struct lconv *s)
Definition: pg_locale.c:442
char * locale_monetary
Definition: pg_locale.c:85
int pg_localeconv_r(const char *lc_monetary, const char *lc_numeric, struct lconv *output)
void pg_localeconv_free(struct lconv *lconv)

References CurrentLocaleConvValid, db_encoding_convert(), elog, encoding, ereport, errcode(), errmsg(), ERROR, free_struct_lconv(), locale_monetary, locale_numeric, PG_CATCH, PG_END_TRY, pg_get_encoding_from_locale(), pg_localeconv_free(), pg_localeconv_r(), PG_RE_THROW, PG_SQL_ASCII, PG_TRY, and struct_lconv_is_valid().

Referenced by cash_in(), cash_numeric(), cash_out(), int4_cash(), int8_cash(), NUM_prepare_locale(), and numeric_cash().

◆ report_newlocale_failure()

void report_newlocale_failure ( const char *  localename)

Definition at line 1101 of file pg_locale_libc.c.

1102{
1103 int save_errno;
1104
1105 /*
1106 * Windows doesn't provide any useful error indication from
1107 * _create_locale(), and BSD-derived platforms don't seem to feel they
1108 * need to set errno either (even though POSIX is pretty clear that
1109 * newlocale should do so). So, if errno hasn't been set, assume ENOENT
1110 * is what to report.
1111 */
1112 if (errno == 0)
1113 errno = ENOENT;
1114
1115 /*
1116 * ENOENT means "no such locale", not "no such file", so clarify that
1117 * errno with an errdetail message.
1118 */
1119 save_errno = errno; /* auxiliary funcs might change errno */
1120 ereport(ERROR,
1121 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1122 errmsg("could not create locale \"%s\": %m",
1123 localename),
1124 (save_errno == ENOENT ?
1125 errdetail("The operating system could not find any locale data for the locale name \"%s\".",
1126 localename) : 0)));
1127}
int errdetail(const char *fmt,...)
Definition: elog.c:1216

References ereport, errcode(), errdetail(), errmsg(), and ERROR.

Referenced by cache_locale_time(), and make_libc_collator().

◆ wchar2char()

size_t wchar2char ( char *  to,
const wchar_t *  from,
size_t  tolen,
locale_t  loc 
)

Definition at line 1179 of file pg_locale_libc.c.

1180{
1181 size_t result;
1182
1183 if (tolen == 0)
1184 return 0;
1185
1186#ifdef WIN32
1187
1188 /*
1189 * On Windows, the "Unicode" locales assume UTF16 not UTF8 encoding, and
1190 * for some reason mbstowcs and wcstombs won't do this for us, so we use
1191 * MultiByteToWideChar().
1192 */
1194 {
1195 result = WideCharToMultiByte(CP_UTF8, 0, from, -1, to, tolen,
1196 NULL, NULL);
1197 /* A zero return is failure */
1198 if (result <= 0)
1199 result = -1;
1200 else
1201 {
1202 Assert(result <= tolen);
1203 /* Microsoft counts the zero terminator in the result */
1204 result--;
1205 }
1206 }
1207 else
1208#endif /* WIN32 */
1209 if (loc == (locale_t) 0)
1210 {
1211 /* Use wcstombs directly for the default locale */
1212 result = wcstombs(to, from, tolen);
1213 }
1214 else
1215 {
1216 /* Use wcstombs_l for nondefault locales */
1217 result = wcstombs_l(to, from, tolen, loc);
1218 }
1219
1220 return result;
1221}
static size_t wcstombs_l(char *dest, const wchar_t *src, size_t n, locale_t loc)

References Assert(), GetDatabaseEncoding(), locale_t, PG_UTF8, and wcstombs_l().

Referenced by strlower_libc_mb(), strtitle_libc_mb(), and strupper_libc_mb().

Variable Documentation

◆ icu_validation_level

PGDLLIMPORT int icu_validation_level
extern

Definition at line 89 of file pg_locale.c.

Referenced by createdb(), DefineCollation(), and icu_validate_locale().

◆ locale_messages

PGDLLIMPORT char* locale_messages
extern

Definition at line 84 of file pg_locale.c.

◆ locale_monetary

PGDLLIMPORT char* locale_monetary
extern

Definition at line 85 of file pg_locale.c.

Referenced by PGLC_localeconv().

◆ locale_numeric

PGDLLIMPORT char* locale_numeric
extern

Definition at line 86 of file pg_locale.c.

Referenced by PGLC_localeconv().

◆ locale_time

PGDLLIMPORT char* locale_time
extern

Definition at line 87 of file pg_locale.c.

Referenced by cache_locale_time().

◆ localized_abbrev_days

PGDLLIMPORT char* localized_abbrev_days[]
extern

Definition at line 98 of file pg_locale.c.

Referenced by cache_locale_time(), DCH_from_char(), and DCH_to_char().

◆ localized_abbrev_months

PGDLLIMPORT char* localized_abbrev_months[]
extern

Definition at line 100 of file pg_locale.c.

Referenced by cache_locale_time(), DCH_from_char(), and DCH_to_char().

◆ localized_full_days

PGDLLIMPORT char* localized_full_days[]
extern

Definition at line 99 of file pg_locale.c.

Referenced by cache_locale_time(), DCH_from_char(), and DCH_to_char().

◆ localized_full_months

PGDLLIMPORT char* localized_full_months[]
extern

Definition at line 101 of file pg_locale.c.

Referenced by cache_locale_time(), DCH_from_char(), and DCH_to_char().