PostgreSQL Source Code git master
pg_locale.c File Reference
#include "postgres.h"
#include <time.h>
#include "access/htup_details.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_database.h"
#include "common/hashfn.h"
#include "common/string.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/formatting.h"
#include "utils/guc_hooks.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/pg_locale.h"
#include "utils/syscache.h"
#include "lib/simplehash.h"
Include dependency graph for pg_locale.c:

Go to the source code of this file.

Data Structures

struct  collation_cache_entry
 

Macros

#define PGLOCALE_SUPPORT_ERROR(provider)    elog(ERROR, "unsupported collprovider for %s: %c", __func__, provider)
 
#define TEXTBUFLEN   1024
 
#define MAX_L10N_DATA   80
 
#define SH_PREFIX   collation_cache
 
#define SH_ELEMENT_TYPE   collation_cache_entry
 
#define SH_KEY_TYPE   Oid
 
#define SH_KEY   collid
 
#define SH_HASH_KEY(tb, key)   murmurhash32((uint32) key)
 
#define SH_EQUAL(tb, a, b)   (a == b)
 
#define SH_GET_HASH(tb, a)   a->hash
 
#define SH_SCOPE   static inline
 
#define SH_STORE_HASH
 
#define SH_DECLARE
 
#define SH_DEFINE
 

Functions

pg_locale_t create_pg_locale_builtin (Oid collid, MemoryContext context)
 
char * get_collation_actual_version_builtin (const char *collcollate)
 
pg_locale_t create_pg_locale_icu (Oid collid, MemoryContext context)
 
pg_locale_t create_pg_locale_libc (Oid collid, MemoryContext context)
 
char * get_collation_actual_version_libc (const char *collcollate)
 
size_t strlower_builtin (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
size_t strtitle_builtin (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
size_t strupper_builtin (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
size_t strlower_icu (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
size_t strtitle_icu (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
size_t strupper_icu (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
size_t strlower_libc (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
size_t strtitle_libc (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
size_t strupper_libc (char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
 
char * pg_perm_setlocale (int category, const char *locale)
 
bool check_locale (int category, const char *locale, char **canonname)
 
bool check_locale_monetary (char **newval, void **extra, GucSource source)
 
void assign_locale_monetary (const char *newval, void *extra)
 
bool check_locale_numeric (char **newval, void **extra, GucSource source)
 
void assign_locale_numeric (const char *newval, void *extra)
 
bool check_locale_time (char **newval, void **extra, GucSource source)
 
void assign_locale_time (const char *newval, void *extra)
 
bool check_locale_messages (char **newval, void **extra, GucSource source)
 
void assign_locale_messages (const char *newval, void *extra)
 
static void free_struct_lconv (struct lconv *s)
 
static bool struct_lconv_is_valid (struct lconv *s)
 
static void db_encoding_convert (int encoding, char **str)
 
struct lconv * PGLC_localeconv (void)
 
static void cache_single_string (char **dst, const char *src, int encoding)
 
void cache_locale_time (void)
 
static pg_locale_t create_pg_locale (Oid collid, MemoryContext context)
 
void init_database_collation (void)
 
pg_locale_t pg_newlocale_from_collation (Oid collid)
 
char * get_collation_actual_version (char collprovider, const char *collcollate)
 
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)
 
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)
 
int builtin_locale_encoding (const char *locale)
 
const char * builtin_validate_locale (int encoding, const char *locale)
 
char * icu_language_tag (const char *loc_str, int elevel)
 
void icu_validate_locale (const char *loc_str)
 

Variables

char * locale_messages
 
char * locale_monetary
 
char * locale_numeric
 
char * locale_time
 
int icu_validation_level = WARNING
 
char * localized_abbrev_days [7+1]
 
char * localized_full_days [7+1]
 
char * localized_abbrev_months [12+1]
 
char * localized_full_months [12+1]
 
bool database_ctype_is_c = false
 
static pg_locale_t default_locale = NULL
 
static bool CurrentLocaleConvValid = false
 
static bool CurrentLCTimeValid = false
 
static MemoryContext CollationCacheContext = NULL
 
static collation_cache_hash * CollationCache = NULL
 
static Oid last_collation_cache_oid = InvalidOid
 
static pg_locale_t last_collation_cache_locale = NULL
 

Macro Definition Documentation

◆ MAX_L10N_DATA

#define MAX_L10N_DATA   80

Definition at line 86 of file pg_locale.c.

◆ PGLOCALE_SUPPORT_ERROR

#define PGLOCALE_SUPPORT_ERROR (   provider)     elog(ERROR, "unsupported collprovider for %s: %c", __func__, provider)

Definition at line 77 of file pg_locale.c.

◆ SH_DECLARE

#define SH_DECLARE

Definition at line 174 of file pg_locale.c.

◆ SH_DEFINE

#define SH_DEFINE

Definition at line 175 of file pg_locale.c.

◆ SH_ELEMENT_TYPE

#define SH_ELEMENT_TYPE   collation_cache_entry

Definition at line 166 of file pg_locale.c.

◆ SH_EQUAL

#define SH_EQUAL (   tb,
  a,
  b 
)    (a == b)

Definition at line 170 of file pg_locale.c.

◆ SH_GET_HASH

#define SH_GET_HASH (   tb,
  a 
)    a->hash

Definition at line 171 of file pg_locale.c.

◆ SH_HASH_KEY

#define SH_HASH_KEY (   tb,
  key 
)    murmurhash32((uint32) key)

Definition at line 169 of file pg_locale.c.

◆ SH_KEY

#define SH_KEY   collid

Definition at line 168 of file pg_locale.c.

◆ SH_KEY_TYPE

#define SH_KEY_TYPE   Oid

Definition at line 167 of file pg_locale.c.

◆ SH_PREFIX

#define SH_PREFIX   collation_cache

Definition at line 165 of file pg_locale.c.

◆ SH_SCOPE

#define SH_SCOPE   static inline

Definition at line 172 of file pg_locale.c.

◆ SH_STORE_HASH

#define SH_STORE_HASH

Definition at line 173 of file pg_locale.c.

◆ TEXTBUFLEN

#define TEXTBUFLEN   1024

Definition at line 84 of file pg_locale.c.

Function Documentation

◆ assign_locale_messages()

void assign_locale_messages ( const char *  newval,
void *  extra 
)

Definition at line 444 of file pg_locale.c.

445{
446 /*
447 * LC_MESSAGES category does not exist everywhere, but accept it anyway.
448 * We ignore failure, as per comment above.
449 */
450#ifdef LC_MESSAGES
451 (void) pg_perm_setlocale(LC_MESSAGES, newval);
452#endif
453}
#define newval
char * pg_perm_setlocale(int category, const char *locale)
Definition: pg_locale.c:207

References newval, and pg_perm_setlocale().

◆ assign_locale_monetary()

void assign_locale_monetary ( const char *  newval,
void *  extra 
)

Definition at line 381 of file pg_locale.c.

382{
384}
static bool CurrentLocaleConvValid
Definition: pg_locale.c:150

References CurrentLocaleConvValid.

◆ assign_locale_numeric()

void assign_locale_numeric ( const char *  newval,
void *  extra 
)

Definition at line 393 of file pg_locale.c.

394{
396}

References CurrentLocaleConvValid.

◆ assign_locale_time()

void assign_locale_time ( const char *  newval,
void *  extra 
)

Definition at line 405 of file pg_locale.c.

406{
407 CurrentLCTimeValid = false;
408}
static bool CurrentLCTimeValid
Definition: pg_locale.c:151

References CurrentLCTimeValid.

◆ builtin_locale_encoding()

int builtin_locale_encoding ( const char *  locale)

Definition at line 1589 of file pg_locale.c.

1590{
1591 if (strcmp(locale, "C") == 0)
1592 return -1;
1593 else if (strcmp(locale, "C.UTF-8") == 0)
1594 return PG_UTF8;
1595 else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
1596 return PG_UTF8;
1597
1598
1599 ereport(ERROR,
1600 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1601 errmsg("invalid locale name \"%s\" for builtin provider",
1602 locale)));
1603
1604 return 0; /* keep compiler quiet */
1605}
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
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 1613 of file pg_locale.c.

1614{
1615 const char *canonical_name = NULL;
1616 int required_encoding;
1617
1618 if (strcmp(locale, "C") == 0)
1619 canonical_name = "C";
1620 else if (strcmp(locale, "C.UTF-8") == 0 || strcmp(locale, "C.UTF8") == 0)
1621 canonical_name = "C.UTF-8";
1622 else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
1623 canonical_name = "PG_UNICODE_FAST";
1624
1625 if (!canonical_name)
1626 ereport(ERROR,
1627 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1628 errmsg("invalid locale name \"%s\" for builtin provider",
1629 locale)));
1630
1631 required_encoding = builtin_locale_encoding(canonical_name);
1632 if (required_encoding >= 0 && encoding != required_encoding)
1633 ereport(ERROR,
1634 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1635 errmsg("encoding \"%s\" does not match locale \"%s\"",
1637
1638 return canonical_name;
1639}
int32 encoding
Definition: pg_database.h:41
int builtin_locale_encoding(const char *locale)
Definition: pg_locale.c:1589
#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 823 of file pg_locale.c.

824{
825 char buf[(2 * 7 + 2 * 12) * MAX_L10N_DATA];
826 char *bufptr;
827 time_t timenow;
828 struct tm *timeinfo;
829 struct tm timeinfobuf;
830 bool strftimefail = false;
831 int encoding;
832 int i;
833 char *save_lc_time;
834#ifdef WIN32
835 char *save_lc_ctype;
836#endif
837
838 /* did we do this already? */
840 return;
841
842 elog(DEBUG3, "cache_locale_time() executed; locale: \"%s\"", locale_time);
843
844 /*
845 * As in PGLC_localeconv(), it's critical that we not throw error while
846 * libc's locale settings have nondefault values. Hence, we just call
847 * strftime() within the critical section, and then convert and save its
848 * results afterwards.
849 */
850
851 /* Save prevailing value of time locale */
852 save_lc_time = setlocale(LC_TIME, NULL);
853 if (!save_lc_time)
854 elog(ERROR, "setlocale(NULL) failed");
855 save_lc_time = pstrdup(save_lc_time);
856
857#ifdef WIN32
858
859 /*
860 * On Windows, it appears that wcsftime() internally uses LC_CTYPE, so we
861 * must set it here. This code looks the same as what PGLC_localeconv()
862 * does, but the underlying reason is different: this does NOT determine
863 * the encoding we'll get back from strftime_win32().
864 */
865
866 /* Save prevailing value of ctype locale */
867 save_lc_ctype = setlocale(LC_CTYPE, NULL);
868 if (!save_lc_ctype)
869 elog(ERROR, "setlocale(NULL) failed");
870 save_lc_ctype = pstrdup(save_lc_ctype);
871
872 /* use lc_time to set the ctype */
873 setlocale(LC_CTYPE, locale_time);
874#endif
875
876 setlocale(LC_TIME, locale_time);
877
878 /* We use times close to current time as data for strftime(). */
879 timenow = time(NULL);
880 timeinfo = gmtime_r(&timenow, &timeinfobuf);
881
882 /* Store the strftime results in MAX_L10N_DATA-sized portions of buf[] */
883 bufptr = buf;
884
885 /*
886 * MAX_L10N_DATA is sufficient buffer space for every known locale, and
887 * POSIX defines no strftime() errors. (Buffer space exhaustion is not an
888 * error.) An implementation might report errors (e.g. ENOMEM) by
889 * returning 0 (or, less plausibly, a negative value) and setting errno.
890 * Report errno just in case the implementation did that, but clear it in
891 * advance of the calls so we don't emit a stale, unrelated errno.
892 */
893 errno = 0;
894
895 /* localized days */
896 for (i = 0; i < 7; i++)
897 {
898 timeinfo->tm_wday = i;
899 if (strftime(bufptr, MAX_L10N_DATA, "%a", timeinfo) <= 0)
900 strftimefail = true;
901 bufptr += MAX_L10N_DATA;
902 if (strftime(bufptr, MAX_L10N_DATA, "%A", timeinfo) <= 0)
903 strftimefail = true;
904 bufptr += MAX_L10N_DATA;
905 }
906
907 /* localized months */
908 for (i = 0; i < 12; i++)
909 {
910 timeinfo->tm_mon = i;
911 timeinfo->tm_mday = 1; /* make sure we don't have invalid date */
912 if (strftime(bufptr, MAX_L10N_DATA, "%b", timeinfo) <= 0)
913 strftimefail = true;
914 bufptr += MAX_L10N_DATA;
915 if (strftime(bufptr, MAX_L10N_DATA, "%B", timeinfo) <= 0)
916 strftimefail = true;
917 bufptr += MAX_L10N_DATA;
918 }
919
920 /*
921 * Restore the prevailing locale settings; as in PGLC_localeconv(),
922 * failure to do so is fatal.
923 */
924#ifdef WIN32
925 if (!setlocale(LC_CTYPE, save_lc_ctype))
926 elog(FATAL, "failed to restore LC_CTYPE to \"%s\"", save_lc_ctype);
927#endif
928 if (!setlocale(LC_TIME, save_lc_time))
929 elog(FATAL, "failed to restore LC_TIME to \"%s\"", save_lc_time);
930
931 /*
932 * At this point we've done our best to clean up, and can throw errors, or
933 * call functions that might throw errors, with a clean conscience.
934 */
935 if (strftimefail)
936 elog(ERROR, "strftime() failed: %m");
937
938 /* Release the pstrdup'd locale names */
939 pfree(save_lc_time);
940#ifdef WIN32
941 pfree(save_lc_ctype);
942#endif
943
944#ifndef WIN32
945
946 /*
947 * As in PGLC_localeconv(), we must convert strftime()'s output from the
948 * encoding implied by LC_TIME to the database encoding. If we can't
949 * identify the LC_TIME encoding, just perform encoding validation.
950 */
952 if (encoding < 0)
954
955#else
956
957 /*
958 * On Windows, strftime_win32() always returns UTF8 data, so convert from
959 * that if necessary.
960 */
962
963#endif /* WIN32 */
964
965 bufptr = buf;
966
967 /* localized days */
968 for (i = 0; i < 7; i++)
969 {
971 bufptr += MAX_L10N_DATA;
973 bufptr += MAX_L10N_DATA;
974 }
975 localized_abbrev_days[7] = NULL;
976 localized_full_days[7] = NULL;
977
978 /* localized months */
979 for (i = 0; i < 12; i++)
980 {
982 bufptr += MAX_L10N_DATA;
984 bufptr += MAX_L10N_DATA;
985 }
986 localized_abbrev_months[12] = NULL;
987 localized_full_months[12] = NULL;
988
989 CurrentLCTimeValid = true;
990}
#define DEBUG3
Definition: elog.h:28
#define FATAL
Definition: elog.h:41
#define elog(elevel,...)
Definition: elog.h:225
int i
Definition: isn.c:72
static struct pg_tm tm
Definition: localtime.c:104
char * pstrdup(const char *in)
Definition: mcxt.c:1696
void pfree(void *pointer)
Definition: mcxt.c:1521
char * localized_full_months[12+1]
Definition: pg_locale.c:142
char * locale_time
Definition: pg_locale.c:128
static void cache_single_string(char **dst, const char *src, int encoding)
Definition: pg_locale.c:800
#define MAX_L10N_DATA
Definition: pg_locale.c:86
char * localized_abbrev_months[12+1]
Definition: pg_locale.c:141
char * localized_full_days[7+1]
Definition: pg_locale.c:140
char * localized_abbrev_days[7+1]
Definition: pg_locale.c:139
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 setlocale(a, b)
Definition: win32_port.h:475

References buf, cache_single_string(), CurrentLCTimeValid, DEBUG3, elog, encoding, ERROR, FATAL, i, locale_time, localized_abbrev_days, localized_abbrev_months, localized_full_days, localized_full_months, MAX_L10N_DATA, pfree(), pg_get_encoding_from_locale(), PG_SQL_ASCII, PG_UTF8, pstrdup(), setlocale, and tm.

Referenced by DCH_from_char(), and DCH_to_char().

◆ cache_single_string()

static void cache_single_string ( char **  dst,
const char *  src,
int  encoding 
)
static

Definition at line 800 of file pg_locale.c.

801{
802 char *ptr;
803 char *olddst;
804
805 /* Convert the string to the database encoding, or validate it's OK */
806 ptr = pg_any_to_server(src, strlen(src), encoding);
807
808 /* Store the string in long-lived storage, replacing any previous value */
809 olddst = *dst;
811 if (olddst)
812 pfree(olddst);
813
814 /* Might as well clean up any palloc'd conversion result, too */
815 if (ptr != src)
816 pfree(ptr);
817}
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:676
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1683
MemoryContext TopMemoryContext
Definition: mcxt.c:149

References encoding, MemoryContextStrdup(), pfree(), pg_any_to_server(), and TopMemoryContext.

Referenced by cache_locale_time().

◆ check_locale()

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

Definition at line 310 of file pg_locale.c.

311{
312 char *save;
313 char *res;
314
315 /* Don't let Windows' non-ASCII locale names in. */
316 if (!pg_is_ascii(locale))
317 {
319 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
320 errmsg("locale name \"%s\" contains non-ASCII characters",
321 locale)));
322 return false;
323 }
324
325 if (canonname)
326 *canonname = NULL; /* in case of failure */
327
328 save = setlocale(category, NULL);
329 if (!save)
330 return false; /* won't happen, we hope */
331
332 /* save may be pointing at a modifiable scratch variable, see above. */
333 save = pstrdup(save);
334
335 /* set the locale with setlocale, to see if it accepts it. */
336 res = setlocale(category, locale);
337
338 /* save canonical name if requested. */
339 if (res && canonname)
340 *canonname = pstrdup(res);
341
342 /* restore old value. */
343 if (!setlocale(category, save))
344 elog(WARNING, "failed to restore old locale \"%s\"", save);
345 pfree(save);
346
347 /* Don't let Windows' non-ASCII locale names out. */
348 if (canonname && *canonname && !pg_is_ascii(*canonname))
349 {
351 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
352 errmsg("locale name \"%s\" contains non-ASCII characters",
353 *canonname)));
354 pfree(*canonname);
355 *canonname = NULL;
356 return false;
357 }
358
359 return (res != NULL);
360}
#define WARNING
Definition: elog.h:36
bool pg_is_ascii(const char *str)
Definition: string.c:132

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

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

◆ check_locale_messages()

bool check_locale_messages ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 421 of file pg_locale.c.

422{
423 if (**newval == '\0')
424 {
425 if (source == PGC_S_DEFAULT)
426 return true;
427 else
428 return false;
429 }
430
431 /*
432 * LC_MESSAGES category does not exist everywhere, but accept it anyway
433 *
434 * On Windows, we can't even check the value, so accept blindly
435 */
436#if defined(LC_MESSAGES) && !defined(WIN32)
437 return check_locale(LC_MESSAGES, *newval, NULL);
438#else
439 return true;
440#endif
441}
@ PGC_S_DEFAULT
Definition: guc.h:109
bool check_locale(int category, const char *locale, char **canonname)
Definition: pg_locale.c:310
static rewind_source * source
Definition: pg_rewind.c:89

References check_locale(), newval, PGC_S_DEFAULT, and source.

◆ check_locale_monetary()

bool check_locale_monetary ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 375 of file pg_locale.c.

376{
377 return check_locale(LC_MONETARY, *newval, NULL);
378}

References check_locale(), and newval.

◆ check_locale_numeric()

bool check_locale_numeric ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 387 of file pg_locale.c.

388{
389 return check_locale(LC_NUMERIC, *newval, NULL);
390}

References check_locale(), and newval.

◆ check_locale_time()

bool check_locale_time ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 399 of file pg_locale.c.

400{
401 return check_locale(LC_TIME, *newval, NULL);
402}

References check_locale(), and newval.

◆ create_pg_locale()

static pg_locale_t create_pg_locale ( Oid  collid,
MemoryContext  context 
)
static

Definition at line 1207 of file pg_locale.c.

1208{
1209 HeapTuple tp;
1210 Form_pg_collation collform;
1211 pg_locale_t result;
1212 Datum datum;
1213 bool isnull;
1214
1215 tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
1216 if (!HeapTupleIsValid(tp))
1217 elog(ERROR, "cache lookup failed for collation %u", collid);
1218 collform = (Form_pg_collation) GETSTRUCT(tp);
1219
1220 if (collform->collprovider == COLLPROVIDER_BUILTIN)
1221 result = create_pg_locale_builtin(collid, context);
1222 else if (collform->collprovider == COLLPROVIDER_ICU)
1223 result = create_pg_locale_icu(collid, context);
1224 else if (collform->collprovider == COLLPROVIDER_LIBC)
1225 result = create_pg_locale_libc(collid, context);
1226 else
1227 /* shouldn't happen */
1228 PGLOCALE_SUPPORT_ERROR(collform->collprovider);
1229
1230 result->is_default = false;
1231
1232 Assert((result->collate_is_c && result->collate == NULL) ||
1233 (!result->collate_is_c && result->collate != NULL));
1234
1235 datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collversion,
1236 &isnull);
1237 if (!isnull)
1238 {
1239 char *actual_versionstr;
1240 char *collversionstr;
1241
1242 collversionstr = TextDatumGetCString(datum);
1243
1244 if (collform->collprovider == COLLPROVIDER_LIBC)
1245 datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collcollate);
1246 else
1247 datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
1248
1249 actual_versionstr = get_collation_actual_version(collform->collprovider,
1250 TextDatumGetCString(datum));
1251 if (!actual_versionstr)
1252 {
1253 /*
1254 * This could happen when specifying a version in CREATE COLLATION
1255 * but the provider does not support versioning, or manually
1256 * creating a mess in the catalogs.
1257 */
1258 ereport(ERROR,
1259 (errmsg("collation \"%s\" has no actual version, but a version was recorded",
1260 NameStr(collform->collname))));
1261 }
1262
1263 if (strcmp(actual_versionstr, collversionstr) != 0)
1265 (errmsg("collation \"%s\" has version mismatch",
1266 NameStr(collform->collname)),
1267 errdetail("The collation in the database was created using version %s, "
1268 "but the operating system provides version %s.",
1269 collversionstr, actual_versionstr),
1270 errhint("Rebuild all objects affected by this collation and run "
1271 "ALTER COLLATION %s REFRESH VERSION, "
1272 "or build PostgreSQL with the right library version.",
1273 quote_qualified_identifier(get_namespace_name(collform->collnamespace),
1274 NameStr(collform->collname)))));
1275 }
1276
1277 ReleaseSysCache(tp);
1278
1279 return result;
1280}
#define TextDatumGetCString(d)
Definition: builtins.h:98
#define NameStr(name)
Definition: c.h:703
#define Assert(condition)
Definition: c.h:815
Oid collid
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errhint(const char *fmt,...)
Definition: elog.c:1317
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3366
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:58
pg_locale_t create_pg_locale_libc(Oid collid, MemoryContext context)
char * get_collation_actual_version(char collprovider, const char *collcollate)
Definition: pg_locale.c:1377
pg_locale_t create_pg_locale_builtin(Oid collid, MemoryContext context)
#define PGLOCALE_SUPPORT_ERROR(provider)
Definition: pg_locale.c:77
pg_locale_t create_pg_locale_icu(Oid collid, MemoryContext context)
uintptr_t Datum
Definition: postgres.h:69
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
char * quote_qualified_identifier(const char *qualifier, const char *ident)
Definition: ruleutils.c:13024
const struct collate_methods * collate
Definition: pg_locale.h:104
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:600
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition: syscache.c:631

References Assert, pg_locale_struct::collate, pg_locale_struct::collate_is_c, collid, create_pg_locale_builtin(), create_pg_locale_icu(), create_pg_locale_libc(), elog, ereport, errdetail(), errhint(), errmsg(), ERROR, get_collation_actual_version(), get_namespace_name(), GETSTRUCT, HeapTupleIsValid, pg_locale_struct::is_default, NameStr, ObjectIdGetDatum(), PGLOCALE_SUPPORT_ERROR, quote_qualified_identifier(), ReleaseSysCache(), SearchSysCache1(), SysCacheGetAttr(), SysCacheGetAttrNotNull(), TextDatumGetCString, and WARNING.

Referenced by pg_newlocale_from_collation().

◆ create_pg_locale_builtin()

pg_locale_t create_pg_locale_builtin ( Oid  collid,
MemoryContext  context 
)

Definition at line 111 of file pg_locale_builtin.c.

112{
113 const char *locstr;
114 pg_locale_t result;
115
116 if (collid == DEFAULT_COLLATION_OID)
117 {
118 HeapTuple tp;
119 Datum datum;
120
122 if (!HeapTupleIsValid(tp))
123 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
124 datum = SysCacheGetAttrNotNull(DATABASEOID, tp,
125 Anum_pg_database_datlocale);
126 locstr = TextDatumGetCString(datum);
127 ReleaseSysCache(tp);
128 }
129 else
130 {
131 HeapTuple tp;
132 Datum datum;
133
135 if (!HeapTupleIsValid(tp))
136 elog(ERROR, "cache lookup failed for collation %u", collid);
137 datum = SysCacheGetAttrNotNull(COLLOID, tp,
138 Anum_pg_collation_colllocale);
139 locstr = TextDatumGetCString(datum);
140 ReleaseSysCache(tp);
141 }
142
144
145 result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct));
146
147 result->info.builtin.locale = MemoryContextStrdup(context, locstr);
148 result->info.builtin.casemap_full = (strcmp(locstr, "PG_UNICODE_FAST") == 0);
149 result->provider = COLLPROVIDER_BUILTIN;
150 result->deterministic = true;
151 result->collate_is_c = true;
152 result->ctype_is_c = (strcmp(locstr, "C") == 0);
153
154 return result;
155}
Oid MyDatabaseId
Definition: globals.c:93
int GetDatabaseEncoding(void)
Definition: mbutils.c:1261
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1215
const char * builtin_validate_locale(int encoding, const char *locale)
Definition: pg_locale.c:1613
struct pg_locale_struct::@158::@159 builtin
union pg_locale_struct::@158 info
const char * locale
Definition: pg_locale.h:110
bool deterministic
Definition: pg_locale.h:99

References pg_locale_struct::builtin, builtin_validate_locale(), pg_locale_struct::casemap_full, pg_locale_struct::collate_is_c, collid, pg_locale_struct::ctype_is_c, pg_locale_struct::deterministic, elog, ERROR, GetDatabaseEncoding(), HeapTupleIsValid, pg_locale_struct::info, pg_locale_struct::locale, MemoryContextAllocZero(), MemoryContextStrdup(), MyDatabaseId, ObjectIdGetDatum(), pg_locale_struct::provider, ReleaseSysCache(), SearchSysCache1(), SysCacheGetAttrNotNull(), and TextDatumGetCString.

Referenced by create_pg_locale(), and init_database_collation().

◆ create_pg_locale_icu()

pg_locale_t create_pg_locale_icu ( Oid  collid,
MemoryContext  context 
)

Definition at line 142 of file pg_locale_icu.c.

143{
144#ifdef USE_ICU
145 bool deterministic;
146 const char *iculocstr;
147 const char *icurules = NULL;
148 UCollator *collator;
149 pg_locale_t result;
150
151 if (collid == DEFAULT_COLLATION_OID)
152 {
153 HeapTuple tp;
154 Datum datum;
155 bool isnull;
156
158 if (!HeapTupleIsValid(tp))
159 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
160
161 /* default database collation is always deterministic */
162 deterministic = true;
163 datum = SysCacheGetAttrNotNull(DATABASEOID, tp,
164 Anum_pg_database_datlocale);
165 iculocstr = TextDatumGetCString(datum);
166 datum = SysCacheGetAttr(DATABASEOID, tp,
167 Anum_pg_database_daticurules, &isnull);
168 if (!isnull)
169 icurules = TextDatumGetCString(datum);
170
171 ReleaseSysCache(tp);
172 }
173 else
174 {
175 Form_pg_collation collform;
176 HeapTuple tp;
177 Datum datum;
178 bool isnull;
179
181 if (!HeapTupleIsValid(tp))
182 elog(ERROR, "cache lookup failed for collation %u", collid);
183 collform = (Form_pg_collation) GETSTRUCT(tp);
184 deterministic = collform->collisdeterministic;
185 datum = SysCacheGetAttrNotNull(COLLOID, tp,
186 Anum_pg_collation_colllocale);
187 iculocstr = TextDatumGetCString(datum);
188 datum = SysCacheGetAttr(COLLOID, tp,
189 Anum_pg_collation_collicurules, &isnull);
190 if (!isnull)
191 icurules = TextDatumGetCString(datum);
192
193 ReleaseSysCache(tp);
194 }
195
196 collator = make_icu_collator(iculocstr, icurules);
197
198 result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct));
199 result->info.icu.locale = MemoryContextStrdup(context, iculocstr);
200 result->info.icu.ucol = collator;
201 result->provider = COLLPROVIDER_ICU;
202 result->deterministic = deterministic;
203 result->collate_is_c = false;
204 result->ctype_is_c = false;
206 result->collate = &collate_methods_icu_utf8;
207 else
208 result->collate = &collate_methods_icu;
209
210 return result;
211#else
212 /* could get here if a collation was created by a build with ICU */
214 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
215 errmsg("ICU is not supported in this build")));
216
217 return NULL;
218#endif
219}

References pg_locale_struct::collate, pg_locale_struct::collate_is_c, collid, pg_locale_struct::ctype_is_c, pg_locale_struct::deterministic, elog, ereport, errcode(), errmsg(), ERROR, GetDatabaseEncoding(), GETSTRUCT, HeapTupleIsValid, pg_locale_struct::info, pg_locale_struct::locale, MemoryContextAllocZero(), MemoryContextStrdup(), MyDatabaseId, ObjectIdGetDatum(), PG_UTF8, pg_locale_struct::provider, ReleaseSysCache(), SearchSysCache1(), SysCacheGetAttr(), SysCacheGetAttrNotNull(), and TextDatumGetCString.

Referenced by create_pg_locale(), and init_database_collation().

◆ create_pg_locale_libc()

pg_locale_t create_pg_locale_libc ( Oid  collid,
MemoryContext  context 
)

Definition at line 422 of file pg_locale_libc.c.

423{
424 const char *collate;
425 const char *ctype;
426 locale_t loc;
427 pg_locale_t result;
428
429 if (collid == DEFAULT_COLLATION_OID)
430 {
431 HeapTuple tp;
432 Datum datum;
433
435 if (!HeapTupleIsValid(tp))
436 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
437 datum = SysCacheGetAttrNotNull(DATABASEOID, tp,
438 Anum_pg_database_datcollate);
439 collate = TextDatumGetCString(datum);
440 datum = SysCacheGetAttrNotNull(DATABASEOID, tp,
441 Anum_pg_database_datctype);
442 ctype = TextDatumGetCString(datum);
443
444 ReleaseSysCache(tp);
445 }
446 else
447 {
448 HeapTuple tp;
449 Datum datum;
450
452 if (!HeapTupleIsValid(tp))
453 elog(ERROR, "cache lookup failed for collation %u", collid);
454
455 datum = SysCacheGetAttrNotNull(COLLOID, tp,
456 Anum_pg_collation_collcollate);
457 collate = TextDatumGetCString(datum);
458 datum = SysCacheGetAttrNotNull(COLLOID, tp,
459 Anum_pg_collation_collctype);
460 ctype = TextDatumGetCString(datum);
461
462 ReleaseSysCache(tp);
463 }
464
465
466 loc = make_libc_collator(collate, ctype);
467
468 result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct));
469 result->provider = COLLPROVIDER_LIBC;
470 result->deterministic = true;
471 result->collate_is_c = (strcmp(collate, "C") == 0) ||
472 (strcmp(collate, "POSIX") == 0);
473 result->ctype_is_c = (strcmp(ctype, "C") == 0) ||
474 (strcmp(ctype, "POSIX") == 0);
475 result->info.lt = loc;
476 if (!result->collate_is_c)
477 {
478#ifdef WIN32
480 result->collate = &collate_methods_libc_win32_utf8;
481 else
482#endif
483 result->collate = &collate_methods_libc;
484 }
485
486 return result;
487}
static locale_t make_libc_collator(const char *collate, const char *ctype)
static const struct collate_methods collate_methods_libc
#define locale_t
Definition: win32_port.h:432

References pg_locale_struct::collate, pg_locale_struct::collate_is_c, collate_methods_libc, collid, pg_locale_struct::ctype_is_c, pg_locale_struct::deterministic, elog, ERROR, GetDatabaseEncoding(), HeapTupleIsValid, pg_locale_struct::info, locale_t, pg_locale_struct::lt, make_libc_collator(), MemoryContextAllocZero(), MyDatabaseId, ObjectIdGetDatum(), PG_UTF8, pg_locale_struct::provider, ReleaseSysCache(), SearchSysCache1(), SysCacheGetAttrNotNull(), and TextDatumGetCString.

Referenced by create_pg_locale(), and init_database_collation().

◆ db_encoding_convert()

static void db_encoding_convert ( int  encoding,
char **  str 
)
static

Definition at line 511 of file pg_locale.c.

512{
513 char *pstr;
514 char *mstr;
515
516 /* convert the string to the database encoding */
517 pstr = pg_any_to_server(*str, strlen(*str), encoding);
518 if (pstr == *str)
519 return; /* no conversion happened */
520
521 /* need it malloc'd not palloc'd */
522 mstr = strdup(pstr);
523 if (mstr == NULL)
525 (errcode(ERRCODE_OUT_OF_MEMORY),
526 errmsg("out of memory")));
527
528 /* replace old string */
529 free(*str);
530 *str = mstr;
531
532 pfree(pstr);
533}
const char * str
#define free(a)
Definition: header.h:65

References encoding, ereport, errcode(), errmsg(), ERROR, free, pfree(), pg_any_to_server(), and str.

Referenced by PGLC_localeconv().

◆ free_struct_lconv()

static void free_struct_lconv ( struct lconv *  s)
static

Definition at line 461 of file pg_locale.c.

462{
463 free(s->decimal_point);
464 free(s->thousands_sep);
465 free(s->grouping);
466 free(s->int_curr_symbol);
467 free(s->currency_symbol);
468 free(s->mon_decimal_point);
469 free(s->mon_thousands_sep);
470 free(s->mon_grouping);
471 free(s->positive_sign);
472 free(s->negative_sign);
473}

References free.

Referenced by PGLC_localeconv().

◆ get_collation_actual_version()

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

Definition at line 1377 of file pg_locale.c.

1378{
1379 char *collversion = NULL;
1380
1381 if (collprovider == COLLPROVIDER_BUILTIN)
1382 collversion = get_collation_actual_version_builtin(collcollate);
1383#ifdef USE_ICU
1384 else if (collprovider == COLLPROVIDER_ICU)
1385 collversion = get_collation_actual_version_icu(collcollate);
1386#endif
1387 else if (collprovider == COLLPROVIDER_LIBC)
1388 collversion = get_collation_actual_version_libc(collcollate);
1389
1390 return collversion;
1391}
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().

◆ get_collation_actual_version_builtin()

char * get_collation_actual_version_builtin ( const char *  collcollate)

Definition at line 158 of file pg_locale_builtin.c.

159{
160 /*
161 * The only two supported locales (C and C.UTF-8) are both based on memcmp
162 * and are not expected to change, but track the version anyway.
163 *
164 * Note that the character semantics may change for some locales, but the
165 * collation version only tracks changes to sort order.
166 */
167 if (strcmp(collcollate, "C") == 0)
168 return "1";
169 else if (strcmp(collcollate, "C.UTF-8") == 0)
170 return "1";
171 else if (strcmp(collcollate, "PG_UNICODE_FAST") == 0)
172 return "1";
173 else
175 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
176 errmsg("invalid locale name \"%s\" for builtin provider",
177 collcollate)));
178
179 return NULL; /* keep compiler quiet */
180}

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

Referenced by get_collation_actual_version().

◆ get_collation_actual_version_libc()

char * get_collation_actual_version_libc ( const char *  collcollate)

Definition at line 660 of file pg_locale_libc.c.

661{
662 char *collversion = NULL;
663
664 if (pg_strcasecmp("C", collcollate) != 0 &&
665 pg_strncasecmp("C.", collcollate, 2) != 0 &&
666 pg_strcasecmp("POSIX", collcollate) != 0)
667 {
668#if defined(__GLIBC__)
669 /* Use the glibc version because we don't have anything better. */
670 collversion = pstrdup(gnu_get_libc_version());
671#elif defined(LC_VERSION_MASK)
672 locale_t loc;
673
674 /* Look up FreeBSD collation version. */
675 loc = newlocale(LC_COLLATE_MASK, collcollate, NULL);
676 if (loc)
677 {
678 collversion =
679 pstrdup(querylocale(LC_COLLATE_MASK | LC_VERSION_MASK, loc));
680 freelocale(loc);
681 }
682 else
684 (errmsg("could not load locale \"%s\"", collcollate)));
685#elif defined(WIN32)
686 /*
687 * If we are targeting Windows Vista and above, we can ask for a name
688 * given a collation name (earlier versions required a location code
689 * that we don't have).
690 */
691 NLSVERSIONINFOEX version = {sizeof(NLSVERSIONINFOEX)};
692 WCHAR wide_collcollate[LOCALE_NAME_MAX_LENGTH];
693
694 MultiByteToWideChar(CP_ACP, 0, collcollate, -1, wide_collcollate,
695 LOCALE_NAME_MAX_LENGTH);
696 if (!GetNLSVersionEx(COMPARE_STRING, wide_collcollate, &version))
697 {
698 /*
699 * GetNLSVersionEx() wants a language tag such as "en-US", not a
700 * locale name like "English_United States.1252". Until those
701 * values can be prevented from entering the system, or 100%
702 * reliably converted to the more useful tag format, tolerate the
703 * resulting error and report that we have no version data.
704 */
705 if (GetLastError() == ERROR_INVALID_PARAMETER)
706 return NULL;
707
709 (errmsg("could not get collation version for locale \"%s\": error code %lu",
710 collcollate,
711 GetLastError())));
712 }
713 collversion = psprintf("%lu.%lu,%lu.%lu",
714 (version.dwNLSVersion >> 8) & 0xFFFF,
715 version.dwNLSVersion & 0xFF,
716 (version.dwDefinedVersion >> 8) & 0xFFFF,
717 version.dwDefinedVersion & 0xFF);
718#endif
719 }
720
721 return collversion;
722}
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43

References ereport, errmsg(), ERROR, locale_t, pg_strcasecmp(), pg_strncasecmp(), psprintf(), and pstrdup().

Referenced by get_collation_actual_version().

◆ icu_language_tag()

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

Definition at line 1653 of file pg_locale.c.

1654{
1655#ifdef USE_ICU
1656 UErrorCode status;
1657 char *langtag;
1658 size_t buflen = 32; /* arbitrary starting buffer size */
1659 const bool strict = true;
1660
1661 /*
1662 * A BCP47 language tag doesn't have a clearly-defined upper limit (cf.
1663 * RFC5646 section 4.4). Additionally, in older ICU versions,
1664 * uloc_toLanguageTag() doesn't always return the ultimate length on the
1665 * first call, necessitating a loop.
1666 */
1667 langtag = palloc(buflen);
1668 while (true)
1669 {
1670 status = U_ZERO_ERROR;
1671 uloc_toLanguageTag(loc_str, langtag, buflen, strict, &status);
1672
1673 /* try again if the buffer is not large enough */
1674 if ((status == U_BUFFER_OVERFLOW_ERROR ||
1675 status == U_STRING_NOT_TERMINATED_WARNING) &&
1676 buflen < MaxAllocSize)
1677 {
1678 buflen = Min(buflen * 2, MaxAllocSize);
1679 langtag = repalloc(langtag, buflen);
1680 continue;
1681 }
1682
1683 break;
1684 }
1685
1686 if (U_FAILURE(status))
1687 {
1688 pfree(langtag);
1689
1690 if (elevel > 0)
1691 ereport(elevel,
1692 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1693 errmsg("could not convert locale name \"%s\" to language tag: %s",
1694 loc_str, u_errorName(status))));
1695 return NULL;
1696 }
1697
1698 return langtag;
1699#else /* not USE_ICU */
1700 ereport(ERROR,
1701 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1702 errmsg("ICU is not supported in this build")));
1703 return NULL; /* keep compiler quiet */
1704#endif /* not USE_ICU */
1705}
#define Min(x, y)
Definition: c.h:961
#define MaxAllocSize
Definition: fe_memutils.h:22
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1541
void * palloc(Size size)
Definition: mcxt.c:1317

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 1711 of file pg_locale.c.

1712{
1713#ifdef USE_ICU
1714 UCollator *collator;
1715 UErrorCode status;
1716 char lang[ULOC_LANG_CAPACITY];
1717 bool found = false;
1718 int elevel = icu_validation_level;
1719
1720 /* no validation */
1721 if (elevel < 0)
1722 return;
1723
1724 /* downgrade to WARNING during pg_upgrade */
1725 if (IsBinaryUpgrade && elevel > WARNING)
1726 elevel = WARNING;
1727
1728 /* validate that we can extract the language */
1729 status = U_ZERO_ERROR;
1730 uloc_getLanguage(loc_str, lang, ULOC_LANG_CAPACITY, &status);
1731 if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING)
1732 {
1733 ereport(elevel,
1734 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1735 errmsg("could not get language from ICU locale \"%s\": %s",
1736 loc_str, u_errorName(status)),
1737 errhint("To disable ICU locale validation, set the parameter \"%s\" to \"%s\".",
1738 "icu_validation_level", "disabled")));
1739 return;
1740 }
1741
1742 /* check for special language name */
1743 if (strcmp(lang, "") == 0 ||
1744 strcmp(lang, "root") == 0 || strcmp(lang, "und") == 0)
1745 found = true;
1746
1747 /* search for matching language within ICU */
1748 for (int32_t i = 0; !found && i < uloc_countAvailable(); i++)
1749 {
1750 const char *otherloc = uloc_getAvailable(i);
1751 char otherlang[ULOC_LANG_CAPACITY];
1752
1753 status = U_ZERO_ERROR;
1754 uloc_getLanguage(otherloc, otherlang, ULOC_LANG_CAPACITY, &status);
1755 if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING)
1756 continue;
1757
1758 if (strcmp(lang, otherlang) == 0)
1759 found = true;
1760 }
1761
1762 if (!found)
1763 ereport(elevel,
1764 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1765 errmsg("ICU locale \"%s\" has unknown language \"%s\"",
1766 loc_str, lang),
1767 errhint("To disable ICU locale validation, set the parameter \"%s\" to \"%s\".",
1768 "icu_validation_level", "disabled")));
1769
1770 /* check that it can be opened */
1771 collator = pg_ucol_open(loc_str);
1772 ucol_close(collator);
1773#else /* not USE_ICU */
1774 /* could get here if a collation was created by a build with ICU */
1775 ereport(ERROR,
1776 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1777 errmsg("ICU is not supported in this build")));
1778#endif /* not USE_ICU */
1779}
bool IsBinaryUpgrade
Definition: globals.c:120
int icu_validation_level
Definition: pg_locale.c:130

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 1286 of file pg_locale.c.

1287{
1288 HeapTuple tup;
1289 Form_pg_database dbform;
1290 pg_locale_t result;
1291
1292 Assert(default_locale == NULL);
1293
1294 /* Fetch our pg_database row normally, via syscache */
1295 tup = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
1296 if (!HeapTupleIsValid(tup))
1297 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
1298 dbform = (Form_pg_database) GETSTRUCT(tup);
1299
1300 if (dbform->datlocprovider == COLLPROVIDER_BUILTIN)
1301 result = create_pg_locale_builtin(DEFAULT_COLLATION_OID,
1303 else if (dbform->datlocprovider == COLLPROVIDER_ICU)
1304 result = create_pg_locale_icu(DEFAULT_COLLATION_OID,
1306 else if (dbform->datlocprovider == COLLPROVIDER_LIBC)
1307 result = create_pg_locale_libc(DEFAULT_COLLATION_OID,
1309 else
1310 /* shouldn't happen */
1311 PGLOCALE_SUPPORT_ERROR(dbform->datlocprovider);
1312
1313 result->is_default = true;
1314 ReleaseSysCache(tup);
1315
1316 default_locale = result;
1317}
FormData_pg_database * Form_pg_database
Definition: pg_database.h:96
static pg_locale_t default_locale
Definition: pg_locale.c:147

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

Referenced by CheckMyDatabase().

◆ pg_newlocale_from_collation()

pg_locale_t pg_newlocale_from_collation ( Oid  collid)

Definition at line 1328 of file pg_locale.c.

1329{
1330 collation_cache_entry *cache_entry;
1331 bool found;
1332
1333 if (collid == DEFAULT_COLLATION_OID)
1334 return default_locale;
1335
1336 if (!OidIsValid(collid))
1337 elog(ERROR, "cache lookup failed for collation %u", collid);
1338
1341
1342 if (CollationCache == NULL)
1343 {
1345 "collation cache",
1347 CollationCache = collation_cache_create(CollationCacheContext,
1348 16, NULL);
1349 }
1350
1351 cache_entry = collation_cache_insert(CollationCache, collid, &found);
1352 if (!found)
1353 {
1354 /*
1355 * Make sure cache entry is marked invalid, in case we fail before
1356 * setting things.
1357 */
1358 cache_entry->locale = 0;
1359 }
1360
1361 if (cache_entry->locale == 0)
1362 {
1364 }
1365
1367 last_collation_cache_locale = cache_entry->locale;
1368
1369 return cache_entry->locale;
1370}
#define OidIsValid(objectId)
Definition: c.h:732
#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:186
static pg_locale_t create_pg_locale(Oid collid, MemoryContext context)
Definition: pg_locale.c:1207
static MemoryContext CollationCacheContext
Definition: pg_locale.c:178
static collation_cache_hash * CollationCache
Definition: pg_locale.c:179
static Oid last_collation_cache_oid
Definition: pg_locale.c:185
Definition: pg_locale.c:156
pg_locale_t locale
Definition: pg_locale.c:158

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, 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_set_regex_collation(), spg_text_inner_consistent(), str_initcap(), str_tolower(), str_toupper(), 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 207 of file pg_locale.c.

208{
209 char *result;
210 const char *envvar;
211
212#ifndef WIN32
213 result = setlocale(category, locale);
214#else
215
216 /*
217 * On Windows, setlocale(LC_MESSAGES) does not work, so just assume that
218 * the given value is good and set it in the environment variables. We
219 * must ignore attempts to set to "", which means "keep using the old
220 * environment value".
221 */
222#ifdef LC_MESSAGES
223 if (category == LC_MESSAGES)
224 {
225 result = (char *) locale;
226 if (locale == NULL || locale[0] == '\0')
227 return result;
228 }
229 else
230#endif
231 result = setlocale(category, locale);
232#endif /* WIN32 */
233
234 if (result == NULL)
235 return result; /* fall out immediately on failure */
236
237 /*
238 * Use the right encoding in translated messages. Under ENABLE_NLS, let
239 * pg_bind_textdomain_codeset() figure it out. Under !ENABLE_NLS, message
240 * format strings are ASCII, but database-encoding strings may enter the
241 * message via %s. This makes the overall message encoding equal to the
242 * database encoding.
243 */
244 if (category == LC_CTYPE)
245 {
246 static char save_lc_ctype[LOCALE_NAME_BUFLEN];
247
248 /* copy setlocale() return value before callee invokes it again */
249 strlcpy(save_lc_ctype, result, sizeof(save_lc_ctype));
250 result = save_lc_ctype;
251
252#ifdef ENABLE_NLS
253 SetMessageEncoding(pg_bind_textdomain_codeset(textdomain(NULL)));
254#else
256#endif
257 }
258
259 switch (category)
260 {
261 case LC_COLLATE:
262 envvar = "LC_COLLATE";
263 break;
264 case LC_CTYPE:
265 envvar = "LC_CTYPE";
266 break;
267#ifdef LC_MESSAGES
268 case LC_MESSAGES:
269 envvar = "LC_MESSAGES";
270#ifdef WIN32
271 result = IsoLocaleName(locale);
272 if (result == NULL)
273 result = (char *) locale;
274 elog(DEBUG3, "IsoLocaleName() executed; locale: \"%s\"", result);
275#endif /* WIN32 */
276 break;
277#endif /* LC_MESSAGES */
278 case LC_MONETARY:
279 envvar = "LC_MONETARY";
280 break;
281 case LC_NUMERIC:
282 envvar = "LC_NUMERIC";
283 break;
284 case LC_TIME:
285 envvar = "LC_TIME";
286 break;
287 default:
288 elog(FATAL, "unrecognized LC category: %d", category);
289 return NULL; /* keep compiler quiet */
290 }
291
292 if (setenv(envvar, result, 1) != 0)
293 return NULL;
294
295 return result;
296}
void SetMessageEncoding(int encoding)
Definition: mbutils.c:1171
#define LOCALE_NAME_BUFLEN
Definition: pg_locale.h:20
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 1456 of file pg_locale.c.

1457{
1458 return locale->collate->strncoll(arg1, -1, arg2, -1, locale);
1459}

References locale.

Referenced by varstrfastcmp_locale().

◆ pg_strlower()

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

Definition at line 1394 of file pg_locale.c.

1396{
1397 if (locale->provider == COLLPROVIDER_BUILTIN)
1398 return strlower_builtin(dst, dstsize, src, srclen, locale);
1399#ifdef USE_ICU
1400 else if (locale->provider == COLLPROVIDER_ICU)
1401 return strlower_icu(dst, dstsize, src, srclen, locale);
1402#endif
1403 else if (locale->provider == COLLPROVIDER_LIBC)
1404 return strlower_libc(dst, dstsize, src, srclen, locale);
1405 else
1406 /* shouldn't happen */
1407 PGLOCALE_SUPPORT_ERROR(locale->provider);
1408
1409 return 0; /* keep compiler quiet */
1410}
size_t strlower_icu(char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
size_t strlower_builtin(char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
size_t strlower_libc(char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)

References locale, PGLOCALE_SUPPORT_ERROR, strlower_builtin(), strlower_icu(), and strlower_libc().

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 1476 of file pg_locale.c.

1478{
1479 return locale->collate->strncoll(arg1, len1, arg2, len2, locale);
1480}

References locale.

Referenced by MatchText(), 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 1531 of file pg_locale.c.

1533{
1534 return locale->collate->strnxfrm(dest, destsize, src, srclen, locale);
1535}

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 1578 of file pg_locale.c.

1580{
1581 return locale->collate->strnxfrm_prefix(dest, destsize, src, srclen, locale);
1582}

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 1413 of file pg_locale.c.

1415{
1416 if (locale->provider == COLLPROVIDER_BUILTIN)
1417 return strtitle_builtin(dst, dstsize, src, srclen, locale);
1418#ifdef USE_ICU
1419 else if (locale->provider == COLLPROVIDER_ICU)
1420 return strtitle_icu(dst, dstsize, src, srclen, locale);
1421#endif
1422 else if (locale->provider == COLLPROVIDER_LIBC)
1423 return strtitle_libc(dst, dstsize, src, srclen, locale);
1424 else
1425 /* shouldn't happen */
1426 PGLOCALE_SUPPORT_ERROR(locale->provider);
1427
1428 return 0; /* keep compiler quiet */
1429}
size_t strtitle_libc(char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
size_t strtitle_icu(char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
size_t strtitle_builtin(char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)

References locale, PGLOCALE_SUPPORT_ERROR, strtitle_builtin(), strtitle_icu(), and strtitle_libc().

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 1432 of file pg_locale.c.

1434{
1435 if (locale->provider == COLLPROVIDER_BUILTIN)
1436 return strupper_builtin(dst, dstsize, src, srclen, locale);
1437#ifdef USE_ICU
1438 else if (locale->provider == COLLPROVIDER_ICU)
1439 return strupper_icu(dst, dstsize, src, srclen, locale);
1440#endif
1441 else if (locale->provider == COLLPROVIDER_LIBC)
1442 return strupper_libc(dst, dstsize, src, srclen, locale);
1443 else
1444 /* shouldn't happen */
1445 PGLOCALE_SUPPORT_ERROR(locale->provider);
1446
1447 return 0; /* keep compiler quiet */
1448}
size_t strupper_icu(char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
size_t strupper_libc(char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)
size_t strupper_builtin(char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)

References locale, PGLOCALE_SUPPORT_ERROR, strupper_builtin(), strupper_icu(), and strupper_libc().

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 1506 of file pg_locale.c.

1507{
1508 return locale->collate->strnxfrm(dest, destsize, src, -1, locale);
1509}

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 1490 of file pg_locale.c.

1491{
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;
1498}

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 1553 of file pg_locale.c.

1555{
1556 return locale->collate->strnxfrm_prefix(dest, destsize, src, -1, locale);
1557}

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 1542 of file pg_locale.c.

1543{
1544 return (locale->collate->strnxfrm_prefix != NULL);
1545}

References locale.

Referenced by varstr_abbrev_convert().

◆ PGLC_localeconv()

struct lconv * PGLC_localeconv ( void  )

Definition at line 541 of file pg_locale.c.

542{
543 static struct lconv CurrentLocaleConv;
544 static bool CurrentLocaleConvAllocated = false;
545 struct lconv *extlconv;
546 struct lconv worklconv;
547 char *save_lc_monetary;
548 char *save_lc_numeric;
549#ifdef WIN32
550 char *save_lc_ctype;
551#endif
552
553 /* Did we do it already? */
555 return &CurrentLocaleConv;
556
557 /* Free any already-allocated storage */
558 if (CurrentLocaleConvAllocated)
559 {
560 free_struct_lconv(&CurrentLocaleConv);
561 CurrentLocaleConvAllocated = false;
562 }
563
564 /*
565 * This is tricky because we really don't want to risk throwing error
566 * while the locale is set to other than our usual settings. Therefore,
567 * the process is: collect the usual settings, set locale to special
568 * setting, copy relevant data into worklconv using strdup(), restore
569 * normal settings, convert data to desired encoding, and finally stash
570 * the collected data in CurrentLocaleConv. This makes it safe if we
571 * throw an error during encoding conversion or run out of memory anywhere
572 * in the process. All data pointed to by struct lconv members is
573 * allocated with strdup, to avoid premature elog(ERROR) and to allow
574 * using a single cleanup routine.
575 */
576 memset(&worklconv, 0, sizeof(worklconv));
577
578 /* Save prevailing values of monetary and numeric locales */
579 save_lc_monetary = setlocale(LC_MONETARY, NULL);
580 if (!save_lc_monetary)
581 elog(ERROR, "setlocale(NULL) failed");
582 save_lc_monetary = pstrdup(save_lc_monetary);
583
584 save_lc_numeric = setlocale(LC_NUMERIC, NULL);
585 if (!save_lc_numeric)
586 elog(ERROR, "setlocale(NULL) failed");
587 save_lc_numeric = pstrdup(save_lc_numeric);
588
589#ifdef WIN32
590
591 /*
592 * The POSIX standard explicitly says that it is undefined what happens if
593 * LC_MONETARY or LC_NUMERIC imply an encoding (codeset) different from
594 * that implied by LC_CTYPE. In practice, all Unix-ish platforms seem to
595 * believe that localeconv() should return strings that are encoded in the
596 * codeset implied by the LC_MONETARY or LC_NUMERIC locale name. Hence,
597 * once we have successfully collected the localeconv() results, we will
598 * convert them from that codeset to the desired server encoding.
599 *
600 * Windows, of course, resolutely does things its own way; on that
601 * platform LC_CTYPE has to match LC_MONETARY/LC_NUMERIC to get sane
602 * results. Hence, we must temporarily set that category as well.
603 */
604
605 /* Save prevailing value of ctype locale */
606 save_lc_ctype = setlocale(LC_CTYPE, NULL);
607 if (!save_lc_ctype)
608 elog(ERROR, "setlocale(NULL) failed");
609 save_lc_ctype = pstrdup(save_lc_ctype);
610
611 /* Here begins the critical section where we must not throw error */
612
613 /* use numeric to set the ctype */
614 setlocale(LC_CTYPE, locale_numeric);
615#endif
616
617 /* Get formatting information for numeric */
618 setlocale(LC_NUMERIC, locale_numeric);
619 extlconv = localeconv();
620
621 /* Must copy data now in case setlocale() overwrites it */
622 worklconv.decimal_point = strdup(extlconv->decimal_point);
623 worklconv.thousands_sep = strdup(extlconv->thousands_sep);
624 worklconv.grouping = strdup(extlconv->grouping);
625
626#ifdef WIN32
627 /* use monetary to set the ctype */
628 setlocale(LC_CTYPE, locale_monetary);
629#endif
630
631 /* Get formatting information for monetary */
632 setlocale(LC_MONETARY, locale_monetary);
633 extlconv = localeconv();
634
635 /* Must copy data now in case setlocale() overwrites it */
636 worklconv.int_curr_symbol = strdup(extlconv->int_curr_symbol);
637 worklconv.currency_symbol = strdup(extlconv->currency_symbol);
638 worklconv.mon_decimal_point = strdup(extlconv->mon_decimal_point);
639 worklconv.mon_thousands_sep = strdup(extlconv->mon_thousands_sep);
640 worklconv.mon_grouping = strdup(extlconv->mon_grouping);
641 worklconv.positive_sign = strdup(extlconv->positive_sign);
642 worklconv.negative_sign = strdup(extlconv->negative_sign);
643 /* Copy scalar fields as well */
644 worklconv.int_frac_digits = extlconv->int_frac_digits;
645 worklconv.frac_digits = extlconv->frac_digits;
646 worklconv.p_cs_precedes = extlconv->p_cs_precedes;
647 worklconv.p_sep_by_space = extlconv->p_sep_by_space;
648 worklconv.n_cs_precedes = extlconv->n_cs_precedes;
649 worklconv.n_sep_by_space = extlconv->n_sep_by_space;
650 worklconv.p_sign_posn = extlconv->p_sign_posn;
651 worklconv.n_sign_posn = extlconv->n_sign_posn;
652
653 /*
654 * Restore the prevailing locale settings; failure to do so is fatal.
655 * Possibly we could limp along with nondefault LC_MONETARY or LC_NUMERIC,
656 * but proceeding with the wrong value of LC_CTYPE would certainly be bad
657 * news; and considering that the prevailing LC_MONETARY and LC_NUMERIC
658 * are almost certainly "C", there's really no reason that restoring those
659 * should fail.
660 */
661#ifdef WIN32
662 if (!setlocale(LC_CTYPE, save_lc_ctype))
663 elog(FATAL, "failed to restore LC_CTYPE to \"%s\"", save_lc_ctype);
664#endif
665 if (!setlocale(LC_MONETARY, save_lc_monetary))
666 elog(FATAL, "failed to restore LC_MONETARY to \"%s\"", save_lc_monetary);
667 if (!setlocale(LC_NUMERIC, save_lc_numeric))
668 elog(FATAL, "failed to restore LC_NUMERIC to \"%s\"", save_lc_numeric);
669
670 /*
671 * At this point we've done our best to clean up, and can call functions
672 * that might possibly throw errors with a clean conscience. But let's
673 * make sure we don't leak any already-strdup'd fields in worklconv.
674 */
675 PG_TRY();
676 {
677 int encoding;
678
679 /* Release the pstrdup'd locale names */
680 pfree(save_lc_monetary);
681 pfree(save_lc_numeric);
682#ifdef WIN32
683 pfree(save_lc_ctype);
684#endif
685
686 /* If any of the preceding strdup calls failed, complain now. */
687 if (!struct_lconv_is_valid(&worklconv))
689 (errcode(ERRCODE_OUT_OF_MEMORY),
690 errmsg("out of memory")));
691
692 /*
693 * Now we must perform encoding conversion from whatever's associated
694 * with the locales into the database encoding. If we can't identify
695 * the encoding implied by LC_NUMERIC or LC_MONETARY (ie we get -1),
696 * use PG_SQL_ASCII, which will result in just validating that the
697 * strings are OK in the database encoding.
698 */
700 if (encoding < 0)
702
703 db_encoding_convert(encoding, &worklconv.decimal_point);
704 db_encoding_convert(encoding, &worklconv.thousands_sep);
705 /* grouping is not text and does not require conversion */
706
708 if (encoding < 0)
710
711 db_encoding_convert(encoding, &worklconv.int_curr_symbol);
712 db_encoding_convert(encoding, &worklconv.currency_symbol);
713 db_encoding_convert(encoding, &worklconv.mon_decimal_point);
714 db_encoding_convert(encoding, &worklconv.mon_thousands_sep);
715 /* mon_grouping is not text and does not require conversion */
716 db_encoding_convert(encoding, &worklconv.positive_sign);
717 db_encoding_convert(encoding, &worklconv.negative_sign);
718 }
719 PG_CATCH();
720 {
721 free_struct_lconv(&worklconv);
722 PG_RE_THROW();
723 }
724 PG_END_TRY();
725
726 /*
727 * Everything is good, so save the results.
728 */
729 CurrentLocaleConv = worklconv;
730 CurrentLocaleConvAllocated = true;
732 return &CurrentLocaleConv;
733}
#define PG_RE_THROW()
Definition: elog.h:412
#define PG_TRY(...)
Definition: elog.h:371
#define PG_END_TRY(...)
Definition: elog.h:396
#define PG_CATCH(...)
Definition: elog.h:381
char * locale_numeric
Definition: pg_locale.c:127
static void db_encoding_convert(int encoding, char **str)
Definition: pg_locale.c:511
static void free_struct_lconv(struct lconv *s)
Definition: pg_locale.c:461
static bool struct_lconv_is_valid(struct lconv *s)
Definition: pg_locale.c:480
char * locale_monetary
Definition: pg_locale.c:126

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

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

◆ strlower_builtin()

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

Definition at line 78 of file pg_locale_builtin.c.

80{
81 return unicode_strlower(dest, destsize, src, srclen,
82 locale->info.builtin.casemap_full);
83}
size_t unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen, bool full)
Definition: unicode_case.c:74

References generate_unaccent_rules::dest, locale, and unicode_strlower().

Referenced by pg_strlower().

◆ strlower_icu()

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

Referenced by pg_strlower().

◆ strlower_libc()

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

Definition at line 124 of file pg_locale_libc.c.

126{
128 return strlower_libc_mb(dst, dstsize, src, srclen, locale);
129 else
130 return strlower_libc_sb(dst, dstsize, src, srclen, locale);
131}
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1546
static size_t strlower_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
static size_t strlower_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)

References locale, pg_database_encoding_max_length(), strlower_libc_mb(), and strlower_libc_sb().

Referenced by pg_strlower().

◆ strtitle_builtin()

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

Definition at line 86 of file pg_locale_builtin.c.

88{
89 struct WordBoundaryState wbstate = {
90 .str = src,
91 .len = srclen,
92 .offset = 0,
93 .init = false,
94 .prev_alnum = false,
95 };
96
97 return unicode_strtitle(dest, destsize, src, srclen,
98 locale->info.builtin.casemap_full,
99 initcap_wbnext, &wbstate);
100}
static size_t initcap_wbnext(void *state)
size_t unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen, bool full, WordBoundaryNext wbnext, void *wbstate)
Definition: unicode_case.c:111

References generate_unaccent_rules::dest, initcap_wbnext(), locale, WordBoundaryState::str, and unicode_strtitle().

Referenced by pg_strtitle().

◆ strtitle_icu()

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

Referenced by pg_strtitle().

◆ strtitle_libc()

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

Definition at line 134 of file pg_locale_libc.c.

136{
138 return strtitle_libc_mb(dst, dstsize, src, srclen, locale);
139 else
140 return strtitle_libc_sb(dst, dstsize, src, srclen, locale);
141}
static size_t strtitle_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
static size_t strtitle_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)

References locale, pg_database_encoding_max_length(), strtitle_libc_mb(), and strtitle_libc_sb().

Referenced by pg_strtitle().

◆ struct_lconv_is_valid()

static bool struct_lconv_is_valid ( struct lconv *  s)
static

Definition at line 480 of file pg_locale.c.

481{
482 if (s->decimal_point == NULL)
483 return false;
484 if (s->thousands_sep == NULL)
485 return false;
486 if (s->grouping == NULL)
487 return false;
488 if (s->int_curr_symbol == NULL)
489 return false;
490 if (s->currency_symbol == NULL)
491 return false;
492 if (s->mon_decimal_point == NULL)
493 return false;
494 if (s->mon_thousands_sep == NULL)
495 return false;
496 if (s->mon_grouping == NULL)
497 return false;
498 if (s->positive_sign == NULL)
499 return false;
500 if (s->negative_sign == NULL)
501 return false;
502 return true;
503}

Referenced by PGLC_localeconv().

◆ strupper_builtin()

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

Definition at line 103 of file pg_locale_builtin.c.

105{
106 return unicode_strupper(dest, destsize, src, srclen,
107 locale->info.builtin.casemap_full);
108}
size_t unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen, bool full)
Definition: unicode_case.c:138

References generate_unaccent_rules::dest, locale, and unicode_strupper().

Referenced by pg_strupper().

◆ strupper_icu()

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

Referenced by pg_strupper().

◆ strupper_libc()

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

Definition at line 144 of file pg_locale_libc.c.

146{
148 return strupper_libc_mb(dst, dstsize, src, srclen, locale);
149 else
150 return strupper_libc_sb(dst, dstsize, src, srclen, locale);
151}
static size_t strupper_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
static size_t strupper_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)

References locale, pg_database_encoding_max_length(), strupper_libc_mb(), and strupper_libc_sb().

Referenced by pg_strupper().

Variable Documentation

◆ CollationCache

collation_cache_hash* CollationCache = NULL
static

Definition at line 179 of file pg_locale.c.

Referenced by pg_newlocale_from_collation().

◆ CollationCacheContext

MemoryContext CollationCacheContext = NULL
static

Definition at line 178 of file pg_locale.c.

Referenced by pg_newlocale_from_collation().

◆ CurrentLCTimeValid

bool CurrentLCTimeValid = false
static

Definition at line 151 of file pg_locale.c.

Referenced by assign_locale_time(), and cache_locale_time().

◆ CurrentLocaleConvValid

bool CurrentLocaleConvValid = false
static

Definition at line 150 of file pg_locale.c.

Referenced by assign_locale_monetary(), assign_locale_numeric(), and PGLC_localeconv().

◆ database_ctype_is_c

bool database_ctype_is_c = false

Definition at line 145 of file pg_locale.c.

Referenced by CheckMyDatabase(), t_isalnum(), t_isalpha(), and TParserInit().

◆ default_locale

pg_locale_t default_locale = NULL
static

Definition at line 147 of file pg_locale.c.

Referenced by init_database_collation(), and pg_newlocale_from_collation().

◆ icu_validation_level

int icu_validation_level = WARNING

Definition at line 130 of file pg_locale.c.

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

◆ last_collation_cache_locale

pg_locale_t last_collation_cache_locale = NULL
static

Definition at line 186 of file pg_locale.c.

Referenced by pg_newlocale_from_collation().

◆ last_collation_cache_oid

Oid last_collation_cache_oid = InvalidOid
static

Definition at line 185 of file pg_locale.c.

Referenced by pg_newlocale_from_collation().

◆ locale_messages

char* locale_messages

Definition at line 125 of file pg_locale.c.

◆ locale_monetary

char* locale_monetary

Definition at line 126 of file pg_locale.c.

Referenced by PGLC_localeconv().

◆ locale_numeric

char* locale_numeric

Definition at line 127 of file pg_locale.c.

Referenced by PGLC_localeconv().

◆ locale_time

char* locale_time

Definition at line 128 of file pg_locale.c.

Referenced by cache_locale_time().

◆ localized_abbrev_days

char* localized_abbrev_days[7+1]

Definition at line 139 of file pg_locale.c.

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

◆ localized_abbrev_months

char* localized_abbrev_months[12+1]

Definition at line 141 of file pg_locale.c.

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

◆ localized_full_days

char* localized_full_days[7+1]

Definition at line 140 of file pg_locale.c.

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

◆ localized_full_months

char* localized_full_months[12+1]

Definition at line 142 of file pg_locale.c.

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