PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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/relcache.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 strfold_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 strfold_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)
 
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)
 
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 66 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 57 of file pg_locale.c.

◆ SH_DECLARE

#define SH_DECLARE

Definition at line 158 of file pg_locale.c.

◆ SH_DEFINE

#define SH_DEFINE

Definition at line 159 of file pg_locale.c.

◆ SH_ELEMENT_TYPE

#define SH_ELEMENT_TYPE   collation_cache_entry

Definition at line 150 of file pg_locale.c.

◆ SH_EQUAL

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

Definition at line 154 of file pg_locale.c.

◆ SH_GET_HASH

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

Definition at line 155 of file pg_locale.c.

◆ SH_HASH_KEY

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

Definition at line 153 of file pg_locale.c.

◆ SH_KEY

#define SH_KEY   collid

Definition at line 152 of file pg_locale.c.

◆ SH_KEY_TYPE

#define SH_KEY_TYPE   Oid

Definition at line 151 of file pg_locale.c.

◆ SH_PREFIX

#define SH_PREFIX   collation_cache

Definition at line 149 of file pg_locale.c.

◆ SH_SCOPE

#define SH_SCOPE   static inline

Definition at line 156 of file pg_locale.c.

◆ SH_STORE_HASH

#define SH_STORE_HASH

Definition at line 157 of file pg_locale.c.

◆ TEXTBUFLEN

#define TEXTBUFLEN   1024

Definition at line 64 of file pg_locale.c.

Function Documentation

◆ assign_locale_messages()

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

Definition at line 428 of file pg_locale.c.

429{
430 /*
431 * LC_MESSAGES category does not exist everywhere, but accept it anyway.
432 * We ignore failure, as per comment above.
433 */
434#ifdef LC_MESSAGES
435 (void) pg_perm_setlocale(LC_MESSAGES, newval);
436#endif
437}
#define newval
char * pg_perm_setlocale(int category, const char *locale)
Definition: pg_locale.c:191

References newval, and pg_perm_setlocale().

◆ assign_locale_monetary()

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

Definition at line 365 of file pg_locale.c.

366{
368}
static bool CurrentLocaleConvValid
Definition: pg_locale.c:134

References CurrentLocaleConvValid.

◆ assign_locale_numeric()

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

Definition at line 377 of file pg_locale.c.

378{
380}

References CurrentLocaleConvValid.

◆ assign_locale_time()

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

Definition at line 389 of file pg_locale.c.

390{
391 CurrentLCTimeValid = false;
392}
static bool CurrentLCTimeValid
Definition: pg_locale.c:135

References CurrentLCTimeValid.

◆ builtin_locale_encoding()

int builtin_locale_encoding ( const char *  locale)

Definition at line 1472 of file pg_locale.c.

1473{
1474 if (strcmp(locale, "C") == 0)
1475 return -1;
1476 else if (strcmp(locale, "C.UTF-8") == 0)
1477 return PG_UTF8;
1478 else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
1479 return PG_UTF8;
1480
1481
1482 ereport(ERROR,
1483 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1484 errmsg("invalid locale name \"%s\" for builtin provider",
1485 locale)));
1486
1487 return 0; /* keep compiler quiet */
1488}
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#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 1496 of file pg_locale.c.

1497{
1498 const char *canonical_name = NULL;
1499 int required_encoding;
1500
1501 if (strcmp(locale, "C") == 0)
1502 canonical_name = "C";
1503 else if (strcmp(locale, "C.UTF-8") == 0 || strcmp(locale, "C.UTF8") == 0)
1504 canonical_name = "C.UTF-8";
1505 else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
1506 canonical_name = "PG_UNICODE_FAST";
1507
1508 if (!canonical_name)
1509 ereport(ERROR,
1510 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1511 errmsg("invalid locale name \"%s\" for builtin provider",
1512 locale)));
1513
1514 required_encoding = builtin_locale_encoding(canonical_name);
1515 if (required_encoding >= 0 && encoding != required_encoding)
1516 ereport(ERROR,
1517 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1518 errmsg("encoding \"%s\" does not match locale \"%s\"",
1520
1521 return canonical_name;
1522}
int32 encoding
Definition: pg_database.h:41
int builtin_locale_encoding(const char *locale)
Definition: pg_locale.c:1472
#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 721 of file pg_locale.c.

722{
723 char buf[(2 * 7 + 2 * 12) * MAX_L10N_DATA];
724 char *bufptr;
725 time_t timenow;
726 struct tm *timeinfo;
727 struct tm timeinfobuf;
728 bool strftimefail = false;
729 int encoding;
730 int i;
732
733 /* did we do this already? */
735 return;
736
737 elog(DEBUG3, "cache_locale_time() executed; locale: \"%s\"", locale_time);
738
739 errno = ENOENT;
740#ifdef WIN32
741 locale = _create_locale(LC_ALL, locale_time);
742 if (locale == (locale_t) 0)
743 _dosmaperr(GetLastError());
744#else
745 locale = newlocale(LC_ALL_MASK, locale_time, (locale_t) 0);
746#endif
747 if (!locale)
749
750 /* We use times close to current time as data for strftime(). */
751 timenow = time(NULL);
752 timeinfo = gmtime_r(&timenow, &timeinfobuf);
753
754 /* Store the strftime results in MAX_L10N_DATA-sized portions of buf[] */
755 bufptr = buf;
756
757 /*
758 * MAX_L10N_DATA is sufficient buffer space for every known locale, and
759 * POSIX defines no strftime() errors. (Buffer space exhaustion is not an
760 * error.) An implementation might report errors (e.g. ENOMEM) by
761 * returning 0 (or, less plausibly, a negative value) and setting errno.
762 * Report errno just in case the implementation did that, but clear it in
763 * advance of the calls so we don't emit a stale, unrelated errno.
764 */
765 errno = 0;
766
767 /* localized days */
768 for (i = 0; i < 7; i++)
769 {
770 timeinfo->tm_wday = i;
771 if (strftime_l(bufptr, MAX_L10N_DATA, "%a", timeinfo, locale) <= 0)
772 strftimefail = true;
773 bufptr += MAX_L10N_DATA;
774 if (strftime_l(bufptr, MAX_L10N_DATA, "%A", timeinfo, locale) <= 0)
775 strftimefail = true;
776 bufptr += MAX_L10N_DATA;
777 }
778
779 /* localized months */
780 for (i = 0; i < 12; i++)
781 {
782 timeinfo->tm_mon = i;
783 timeinfo->tm_mday = 1; /* make sure we don't have invalid date */
784 if (strftime_l(bufptr, MAX_L10N_DATA, "%b", timeinfo, locale) <= 0)
785 strftimefail = true;
786 bufptr += MAX_L10N_DATA;
787 if (strftime_l(bufptr, MAX_L10N_DATA, "%B", timeinfo, locale) <= 0)
788 strftimefail = true;
789 bufptr += MAX_L10N_DATA;
790 }
791
792#ifdef WIN32
793 _free_locale(locale);
794#else
795 freelocale(locale);
796#endif
797
798 /*
799 * At this point we've done our best to clean up, and can throw errors, or
800 * call functions that might throw errors, with a clean conscience.
801 */
802 if (strftimefail)
803 elog(ERROR, "strftime_l() failed");
804
805#ifndef WIN32
806
807 /*
808 * As in PGLC_localeconv(), we must convert strftime()'s output from the
809 * encoding implied by LC_TIME to the database encoding. If we can't
810 * identify the LC_TIME encoding, just perform encoding validation.
811 */
813 if (encoding < 0)
815
816#else
817
818 /*
819 * On Windows, strftime_win32() always returns UTF8 data, so convert from
820 * that if necessary.
821 */
823
824#endif /* WIN32 */
825
826 bufptr = buf;
827
828 /* localized days */
829 for (i = 0; i < 7; i++)
830 {
832 bufptr += MAX_L10N_DATA;
834 bufptr += MAX_L10N_DATA;
835 }
836 localized_abbrev_days[7] = NULL;
837 localized_full_days[7] = NULL;
838
839 /* localized months */
840 for (i = 0; i < 12; i++)
841 {
843 bufptr += MAX_L10N_DATA;
845 bufptr += MAX_L10N_DATA;
846 }
847 localized_abbrev_months[12] = NULL;
848 localized_full_months[12] = NULL;
849
850 CurrentLCTimeValid = true;
851}
#define DEBUG3
Definition: elog.h:28
#define elog(elevel,...)
Definition: elog.h:225
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:126
char * locale_time
Definition: pg_locale.c:112
static void cache_single_string(char **dst, const char *src, int encoding)
Definition: pg_locale.c:698
#define MAX_L10N_DATA
Definition: pg_locale.c:66
char * localized_abbrev_months[12+1]
Definition: pg_locale.c:125
char * localized_full_days[7+1]
Definition: pg_locale.c:124
char * localized_abbrev_days[7+1]
Definition: pg_locale.c:123
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().

◆ cache_single_string()

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

Definition at line 698 of file pg_locale.c.

699{
700 char *ptr;
701 char *olddst;
702
703 /* Convert the string to the database encoding, or validate it's OK */
704 ptr = pg_any_to_server(src, strlen(src), encoding);
705
706 /* Store the string in long-lived storage, replacing any previous value */
707 olddst = *dst;
709 if (olddst)
710 pfree(olddst);
711
712 /* Might as well clean up any palloc'd conversion result, too */
713 if (ptr != src)
714 pfree(ptr);
715}
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:677
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1690
void pfree(void *pointer)
Definition: mcxt.c:1528
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 294 of file pg_locale.c.

295{
296 char *save;
297 char *res;
298
299 /* Don't let Windows' non-ASCII locale names in. */
300 if (!pg_is_ascii(locale))
301 {
303 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
304 errmsg("locale name \"%s\" contains non-ASCII characters",
305 locale)));
306 return false;
307 }
308
309 if (canonname)
310 *canonname = NULL; /* in case of failure */
311
312 save = setlocale(category, NULL);
313 if (!save)
314 return false; /* won't happen, we hope */
315
316 /* save may be pointing at a modifiable scratch variable, see above. */
317 save = pstrdup(save);
318
319 /* set the locale with setlocale, to see if it accepts it. */
320 res = setlocale(category, locale);
321
322 /* save canonical name if requested. */
323 if (res && canonname)
324 *canonname = pstrdup(res);
325
326 /* restore old value. */
327 if (!setlocale(category, save))
328 elog(WARNING, "failed to restore old locale \"%s\"", save);
329 pfree(save);
330
331 /* Don't let Windows' non-ASCII locale names out. */
332 if (canonname && *canonname && !pg_is_ascii(*canonname))
333 {
335 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
336 errmsg("locale name \"%s\" contains non-ASCII characters",
337 *canonname)));
338 pfree(*canonname);
339 *canonname = NULL;
340 return false;
341 }
342
343 return (res != NULL);
344}
#define WARNING
Definition: elog.h:36
char * pstrdup(const char *in)
Definition: mcxt.c:1703
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().

◆ check_locale_messages()

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

Definition at line 405 of file pg_locale.c.

406{
407 if (**newval == '\0')
408 {
409 if (source == PGC_S_DEFAULT)
410 return true;
411 else
412 return false;
413 }
414
415 /*
416 * LC_MESSAGES category does not exist everywhere, but accept it anyway
417 *
418 * On Windows, we can't even check the value, so accept blindly
419 */
420#if defined(LC_MESSAGES) && !defined(WIN32)
421 return check_locale(LC_MESSAGES, *newval, NULL);
422#else
423 return true;
424#endif
425}
@ PGC_S_DEFAULT
Definition: guc.h:113
bool check_locale(int category, const char *locale, char **canonname)
Definition: pg_locale.c:294
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 359 of file pg_locale.c.

360{
361 return check_locale(LC_MONETARY, *newval, NULL);
362}

References check_locale(), and newval.

◆ check_locale_numeric()

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

Definition at line 371 of file pg_locale.c.

372{
373 return check_locale(LC_NUMERIC, *newval, NULL);
374}

References check_locale(), and newval.

◆ check_locale_time()

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

Definition at line 383 of file pg_locale.c.

384{
385 return check_locale(LC_TIME, *newval, NULL);
386}

References check_locale(), and newval.

◆ create_pg_locale()

static pg_locale_t create_pg_locale ( Oid  collid,
MemoryContext  context 
)
static

Definition at line 1068 of file pg_locale.c.

1069{
1070 HeapTuple tp;
1071 Form_pg_collation collform;
1072 pg_locale_t result;
1073 Datum datum;
1074 bool isnull;
1075
1076 tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
1077 if (!HeapTupleIsValid(tp))
1078 elog(ERROR, "cache lookup failed for collation %u", collid);
1079 collform = (Form_pg_collation) GETSTRUCT(tp);
1080
1081 if (collform->collprovider == COLLPROVIDER_BUILTIN)
1082 result = create_pg_locale_builtin(collid, context);
1083 else if (collform->collprovider == COLLPROVIDER_ICU)
1084 result = create_pg_locale_icu(collid, context);
1085 else if (collform->collprovider == COLLPROVIDER_LIBC)
1086 result = create_pg_locale_libc(collid, context);
1087 else
1088 /* shouldn't happen */
1089 PGLOCALE_SUPPORT_ERROR(collform->collprovider);
1090
1091 result->is_default = false;
1092
1093 Assert((result->collate_is_c && result->collate == NULL) ||
1094 (!result->collate_is_c && result->collate != NULL));
1095
1096 datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collversion,
1097 &isnull);
1098 if (!isnull)
1099 {
1100 char *actual_versionstr;
1101 char *collversionstr;
1102
1103 collversionstr = TextDatumGetCString(datum);
1104
1105 if (collform->collprovider == COLLPROVIDER_LIBC)
1106 datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collcollate);
1107 else
1108 datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
1109
1110 actual_versionstr = get_collation_actual_version(collform->collprovider,
1111 TextDatumGetCString(datum));
1112 if (!actual_versionstr)
1113 {
1114 /*
1115 * This could happen when specifying a version in CREATE COLLATION
1116 * but the provider does not support versioning, or manually
1117 * creating a mess in the catalogs.
1118 */
1119 ereport(ERROR,
1120 (errmsg("collation \"%s\" has no actual version, but a version was recorded",
1121 NameStr(collform->collname))));
1122 }
1123
1124 if (strcmp(actual_versionstr, collversionstr) != 0)
1126 (errmsg("collation \"%s\" has version mismatch",
1127 NameStr(collform->collname)),
1128 errdetail("The collation in the database was created using version %s, "
1129 "but the operating system provides version %s.",
1130 collversionstr, actual_versionstr),
1131 errhint("Rebuild all objects affected by this collation and run "
1132 "ALTER COLLATION %s REFRESH VERSION, "
1133 "or build PostgreSQL with the right library version.",
1134 quote_qualified_identifier(get_namespace_name(collform->collnamespace),
1135 NameStr(collform->collname)))));
1136 }
1137
1138 ReleaseSysCache(tp);
1139
1140 return result;
1141}
#define TextDatumGetCString(d)
Definition: builtins.h:98
#define NameStr(name)
Definition: c.h:717
Oid collid
int errdetail(const char *fmt,...)
Definition: elog.c:1204
int errhint(const char *fmt,...)
Definition: elog.c:1318
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3506
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:1240
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)
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:13113
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 123 of file pg_locale_builtin.c.

124{
125 const char *locstr;
126 pg_locale_t result;
127
128 if (collid == DEFAULT_COLLATION_OID)
129 {
130 HeapTuple tp;
131 Datum datum;
132
134 if (!HeapTupleIsValid(tp))
135 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
136 datum = SysCacheGetAttrNotNull(DATABASEOID, tp,
137 Anum_pg_database_datlocale);
138 locstr = TextDatumGetCString(datum);
139 ReleaseSysCache(tp);
140 }
141 else
142 {
143 HeapTuple tp;
144 Datum datum;
145
147 if (!HeapTupleIsValid(tp))
148 elog(ERROR, "cache lookup failed for collation %u", collid);
149 datum = SysCacheGetAttrNotNull(COLLOID, tp,
150 Anum_pg_collation_colllocale);
151 locstr = TextDatumGetCString(datum);
152 ReleaseSysCache(tp);
153 }
154
156
157 result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct));
158
159 result->info.builtin.locale = MemoryContextStrdup(context, locstr);
160 result->info.builtin.casemap_full = (strcmp(locstr, "PG_UNICODE_FAST") == 0);
161 result->provider = COLLPROVIDER_BUILTIN;
162 result->deterministic = true;
163 result->collate_is_c = true;
164 result->ctype_is_c = (strcmp(locstr, "C") == 0);
165
166 return result;
167}
Oid MyDatabaseId
Definition: globals.c:94
int GetDatabaseEncoding(void)
Definition: mbutils.c:1262
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1219
const char * builtin_validate_locale(int encoding, const char *locale)
Definition: pg_locale.c:1496
struct pg_locale_struct::@161::@162 builtin
const char * locale
Definition: pg_locale.h:110
bool deterministic
Definition: pg_locale.h:99
union pg_locale_struct::@161 info

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 421 of file pg_locale_libc.c.

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

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

496{
497 char *pstr;
498 char *mstr;
499
500 /* convert the string to the database encoding */
501 pstr = pg_any_to_server(*str, strlen(*str), encoding);
502 if (pstr == *str)
503 return; /* no conversion happened */
504
505 /* need it malloc'd not palloc'd */
506 mstr = strdup(pstr);
507 if (mstr == NULL)
509 (errcode(ERRCODE_OUT_OF_MEMORY),
510 errmsg("out of memory")));
511
512 /* replace old string */
513 free(*str);
514 *str = mstr;
515
516 pfree(pstr);
517}
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 445 of file pg_locale.c.

446{
447 free(s->decimal_point);
448 free(s->thousands_sep);
449 free(s->grouping);
450 free(s->int_curr_symbol);
451 free(s->currency_symbol);
452 free(s->mon_decimal_point);
453 free(s->mon_thousands_sep);
454 free(s->mon_grouping);
455 free(s->positive_sign);
456 free(s->negative_sign);
457}

References free.

Referenced by PGLC_localeconv().

◆ get_collation_actual_version()

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

Definition at line 1240 of file pg_locale.c.

1241{
1242 char *collversion = NULL;
1243
1244 if (collprovider == COLLPROVIDER_BUILTIN)
1245 collversion = get_collation_actual_version_builtin(collcollate);
1246#ifdef USE_ICU
1247 else if (collprovider == COLLPROVIDER_ICU)
1248 collversion = get_collation_actual_version_icu(collcollate);
1249#endif
1250 else if (collprovider == COLLPROVIDER_LIBC)
1251 collversion = get_collation_actual_version_libc(collcollate);
1252
1253 return collversion;
1254}
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 170 of file pg_locale_builtin.c.

171{
172 /*
173 * The only two supported locales (C and C.UTF-8) are both based on memcmp
174 * and are not expected to change, but track the version anyway.
175 *
176 * Note that the character semantics may change for some locales, but the
177 * collation version only tracks changes to sort order.
178 */
179 if (strcmp(collcollate, "C") == 0)
180 return "1";
181 else if (strcmp(collcollate, "C.UTF-8") == 0)
182 return "1";
183 else if (strcmp(collcollate, "PG_UNICODE_FAST") == 0)
184 return "1";
185 else
187 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
188 errmsg("invalid locale name \"%s\" for builtin provider",
189 collcollate)));
190
191 return NULL; /* keep compiler quiet */
192}

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 659 of file pg_locale_libc.c.

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

1537{
1538#ifdef USE_ICU
1539 UErrorCode status;
1540 char *langtag;
1541 size_t buflen = 32; /* arbitrary starting buffer size */
1542 const bool strict = true;
1543
1544 /*
1545 * A BCP47 language tag doesn't have a clearly-defined upper limit (cf.
1546 * RFC5646 section 4.4). Additionally, in older ICU versions,
1547 * uloc_toLanguageTag() doesn't always return the ultimate length on the
1548 * first call, necessitating a loop.
1549 */
1550 langtag = palloc(buflen);
1551 while (true)
1552 {
1553 status = U_ZERO_ERROR;
1554 uloc_toLanguageTag(loc_str, langtag, buflen, strict, &status);
1555
1556 /* try again if the buffer is not large enough */
1557 if ((status == U_BUFFER_OVERFLOW_ERROR ||
1558 status == U_STRING_NOT_TERMINATED_WARNING) &&
1559 buflen < MaxAllocSize)
1560 {
1561 buflen = Min(buflen * 2, MaxAllocSize);
1562 langtag = repalloc(langtag, buflen);
1563 continue;
1564 }
1565
1566 break;
1567 }
1568
1569 if (U_FAILURE(status))
1570 {
1571 pfree(langtag);
1572
1573 if (elevel > 0)
1574 ereport(elevel,
1575 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1576 errmsg("could not convert locale name \"%s\" to language tag: %s",
1577 loc_str, u_errorName(status))));
1578 return NULL;
1579 }
1580
1581 return langtag;
1582#else /* not USE_ICU */
1583 ereport(ERROR,
1584 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1585 errmsg("ICU is not supported in this build")));
1586 return NULL; /* keep compiler quiet */
1587#endif /* not USE_ICU */
1588}
#define Min(x, y)
Definition: c.h:975
#define MaxAllocSize
Definition: fe_memutils.h:22
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1548
void * palloc(Size size)
Definition: mcxt.c:1321

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

1595{
1596#ifdef USE_ICU
1597 UCollator *collator;
1598 UErrorCode status;
1599 char lang[ULOC_LANG_CAPACITY];
1600 bool found = false;
1601 int elevel = icu_validation_level;
1602
1603 /* no validation */
1604 if (elevel < 0)
1605 return;
1606
1607 /* downgrade to WARNING during pg_upgrade */
1608 if (IsBinaryUpgrade && elevel > WARNING)
1609 elevel = WARNING;
1610
1611 /* validate that we can extract the language */
1612 status = U_ZERO_ERROR;
1613 uloc_getLanguage(loc_str, lang, ULOC_LANG_CAPACITY, &status);
1614 if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING)
1615 {
1616 ereport(elevel,
1617 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1618 errmsg("could not get language from ICU locale \"%s\": %s",
1619 loc_str, u_errorName(status)),
1620 errhint("To disable ICU locale validation, set the parameter \"%s\" to \"%s\".",
1621 "icu_validation_level", "disabled")));
1622 return;
1623 }
1624
1625 /* check for special language name */
1626 if (strcmp(lang, "") == 0 ||
1627 strcmp(lang, "root") == 0 || strcmp(lang, "und") == 0)
1628 found = true;
1629
1630 /* search for matching language within ICU */
1631 for (int32_t i = 0; !found && i < uloc_countAvailable(); i++)
1632 {
1633 const char *otherloc = uloc_getAvailable(i);
1634 char otherlang[ULOC_LANG_CAPACITY];
1635
1636 status = U_ZERO_ERROR;
1637 uloc_getLanguage(otherloc, otherlang, ULOC_LANG_CAPACITY, &status);
1638 if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING)
1639 continue;
1640
1641 if (strcmp(lang, otherlang) == 0)
1642 found = true;
1643 }
1644
1645 if (!found)
1646 ereport(elevel,
1647 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1648 errmsg("ICU locale \"%s\" has unknown language \"%s\"",
1649 loc_str, lang),
1650 errhint("To disable ICU locale validation, set the parameter \"%s\" to \"%s\".",
1651 "icu_validation_level", "disabled")));
1652
1653 /* check that it can be opened */
1654 collator = pg_ucol_open(loc_str);
1655 ucol_close(collator);
1656#else /* not USE_ICU */
1657 /* could get here if a collation was created by a build with ICU */
1658 ereport(ERROR,
1659 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1660 errmsg("ICU is not supported in this build")));
1661#endif /* not USE_ICU */
1662}
bool IsBinaryUpgrade
Definition: globals.c:121
int icu_validation_level
Definition: pg_locale.c:114

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

1148{
1149 HeapTuple tup;
1150 Form_pg_database dbform;
1151 pg_locale_t result;
1152
1153 Assert(default_locale == NULL);
1154
1155 /* Fetch our pg_database row normally, via syscache */
1156 tup = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
1157 if (!HeapTupleIsValid(tup))
1158 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
1159 dbform = (Form_pg_database) GETSTRUCT(tup);
1160
1161 if (dbform->datlocprovider == COLLPROVIDER_BUILTIN)
1162 result = create_pg_locale_builtin(DEFAULT_COLLATION_OID,
1164 else if (dbform->datlocprovider == COLLPROVIDER_ICU)
1165 result = create_pg_locale_icu(DEFAULT_COLLATION_OID,
1167 else if (dbform->datlocprovider == COLLPROVIDER_LIBC)
1168 result = create_pg_locale_libc(DEFAULT_COLLATION_OID,
1170 else
1171 /* shouldn't happen */
1172 PGLOCALE_SUPPORT_ERROR(dbform->datlocprovider);
1173
1174 result->is_default = true;
1175 ReleaseSysCache(tup);
1176
1177 default_locale = result;
1178}
FormData_pg_database * Form_pg_database
Definition: pg_database.h:96
static pg_locale_t default_locale
Definition: pg_locale.c:131

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

1190{
1191 collation_cache_entry *cache_entry;
1192 bool found;
1193
1194 if (collid == DEFAULT_COLLATION_OID)
1195 return default_locale;
1196
1197 if (!OidIsValid(collid))
1198 elog(ERROR, "cache lookup failed for collation %u", collid);
1199
1201
1204
1205 if (CollationCache == NULL)
1206 {
1208 "collation cache",
1210 CollationCache = collation_cache_create(CollationCacheContext,
1211 16, NULL);
1212 }
1213
1214 cache_entry = collation_cache_insert(CollationCache, collid, &found);
1215 if (!found)
1216 {
1217 /*
1218 * Make sure cache entry is marked invalid, in case we fail before
1219 * setting things.
1220 */
1221 cache_entry->locale = 0;
1222 }
1223
1224 if (cache_entry->locale == 0)
1225 {
1227 }
1228
1230 last_collation_cache_locale = cache_entry->locale;
1231
1232 return cache_entry->locale;
1233}
#define OidIsValid(objectId)
Definition: c.h:746
#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:170
static pg_locale_t create_pg_locale(Oid collid, MemoryContext context)
Definition: pg_locale.c:1068
static MemoryContext CollationCacheContext
Definition: pg_locale.c:162
static collation_cache_hash * CollationCache
Definition: pg_locale.c:163
static Oid last_collation_cache_oid
Definition: pg_locale.c:169
static void AssertCouldGetRelation(void)
Definition: relcache.h:44
Definition: pg_locale.c:140
pg_locale_t locale
Definition: pg_locale.c:142

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, AssertCouldGetRelation(), 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_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 191 of file pg_locale.c.

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

1340{
1341 return locale->collate->strncoll(arg1, -1, arg2, -1, locale);
1342}

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

1316{
1317 if (locale->provider == COLLPROVIDER_BUILTIN)
1318 return strfold_builtin(dst, dstsize, src, srclen, locale);
1319#ifdef USE_ICU
1320 else if (locale->provider == COLLPROVIDER_ICU)
1321 return strfold_icu(dst, dstsize, src, srclen, locale);
1322#endif
1323 /* for libc, just use strlower */
1324 else if (locale->provider == COLLPROVIDER_LIBC)
1325 return strlower_libc(dst, dstsize, src, srclen, locale);
1326 else
1327 /* shouldn't happen */
1328 PGLOCALE_SUPPORT_ERROR(locale->provider);
1329
1330 return 0; /* keep compiler quiet */
1331}
size_t strfold_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 strfold_builtin(char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)

References locale, PGLOCALE_SUPPORT_ERROR, strfold_builtin(), strfold_icu(), and strlower_libc().

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

1259{
1260 if (locale->provider == COLLPROVIDER_BUILTIN)
1261 return strlower_builtin(dst, dstsize, src, srclen, locale);
1262#ifdef USE_ICU
1263 else if (locale->provider == COLLPROVIDER_ICU)
1264 return strlower_icu(dst, dstsize, src, srclen, locale);
1265#endif
1266 else if (locale->provider == COLLPROVIDER_LIBC)
1267 return strlower_libc(dst, dstsize, src, srclen, locale);
1268 else
1269 /* shouldn't happen */
1270 PGLOCALE_SUPPORT_ERROR(locale->provider);
1271
1272 return 0; /* keep compiler quiet */
1273}
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)

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

1361{
1362 return locale->collate->strncoll(arg1, len1, arg2, len2, locale);
1363}

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

1416{
1417 return locale->collate->strnxfrm(dest, destsize, src, srclen, locale);
1418}

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

1463{
1464 return locale->collate->strnxfrm_prefix(dest, destsize, src, srclen, locale);
1465}

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

1278{
1279 if (locale->provider == COLLPROVIDER_BUILTIN)
1280 return strtitle_builtin(dst, dstsize, src, srclen, locale);
1281#ifdef USE_ICU
1282 else if (locale->provider == COLLPROVIDER_ICU)
1283 return strtitle_icu(dst, dstsize, src, srclen, locale);
1284#endif
1285 else if (locale->provider == COLLPROVIDER_LIBC)
1286 return strtitle_libc(dst, dstsize, src, srclen, locale);
1287 else
1288 /* shouldn't happen */
1289 PGLOCALE_SUPPORT_ERROR(locale->provider);
1290
1291 return 0; /* keep compiler quiet */
1292}
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 1295 of file pg_locale.c.

1297{
1298 if (locale->provider == COLLPROVIDER_BUILTIN)
1299 return strupper_builtin(dst, dstsize, src, srclen, locale);
1300#ifdef USE_ICU
1301 else if (locale->provider == COLLPROVIDER_ICU)
1302 return strupper_icu(dst, dstsize, src, srclen, locale);
1303#endif
1304 else if (locale->provider == COLLPROVIDER_LIBC)
1305 return strupper_libc(dst, dstsize, src, srclen, locale);
1306 else
1307 /* shouldn't happen */
1308 PGLOCALE_SUPPORT_ERROR(locale->provider);
1309
1310 return 0; /* keep compiler quiet */
1311}
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 1389 of file pg_locale.c.

1390{
1391 return locale->collate->strnxfrm(dest, destsize, src, -1, locale);
1392}

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

1374{
1375 /*
1376 * locale->collate->strnxfrm is still a required method, even if it may
1377 * have the wrong behavior, because the planner uses it for estimates in
1378 * some cases.
1379 */
1380 return locale->collate->strxfrm_is_safe;
1381}

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

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

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

1426{
1427 return (locale->collate->strnxfrm_prefix != NULL);
1428}

References locale.

Referenced by varstr_abbrev_convert().

◆ PGLC_localeconv()

struct lconv * PGLC_localeconv ( void  )

Definition at line 525 of file pg_locale.c.

526{
527 static struct lconv CurrentLocaleConv;
528 static bool CurrentLocaleConvAllocated = false;
529 struct lconv *extlconv;
530 struct lconv tmp;
531 struct lconv worklconv = {0};
532
533 /* Did we do it already? */
535 return &CurrentLocaleConv;
536
537 /* Free any already-allocated storage */
538 if (CurrentLocaleConvAllocated)
539 {
540 free_struct_lconv(&CurrentLocaleConv);
541 CurrentLocaleConvAllocated = false;
542 }
543
544 /*
545 * Use thread-safe method of obtaining a copy of lconv from the operating
546 * system.
547 */
550 &tmp) != 0)
551 elog(ERROR,
552 "could not get lconv for LC_MONETARY = \"%s\", LC_NUMERIC = \"%s\": %m",
554
555 /* Must copy data now so we can re-encode it. */
556 extlconv = &tmp;
557 worklconv.decimal_point = strdup(extlconv->decimal_point);
558 worklconv.thousands_sep = strdup(extlconv->thousands_sep);
559 worklconv.grouping = strdup(extlconv->grouping);
560 worklconv.int_curr_symbol = strdup(extlconv->int_curr_symbol);
561 worklconv.currency_symbol = strdup(extlconv->currency_symbol);
562 worklconv.mon_decimal_point = strdup(extlconv->mon_decimal_point);
563 worklconv.mon_thousands_sep = strdup(extlconv->mon_thousands_sep);
564 worklconv.mon_grouping = strdup(extlconv->mon_grouping);
565 worklconv.positive_sign = strdup(extlconv->positive_sign);
566 worklconv.negative_sign = strdup(extlconv->negative_sign);
567 /* Copy scalar fields as well */
568 worklconv.int_frac_digits = extlconv->int_frac_digits;
569 worklconv.frac_digits = extlconv->frac_digits;
570 worklconv.p_cs_precedes = extlconv->p_cs_precedes;
571 worklconv.p_sep_by_space = extlconv->p_sep_by_space;
572 worklconv.n_cs_precedes = extlconv->n_cs_precedes;
573 worklconv.n_sep_by_space = extlconv->n_sep_by_space;
574 worklconv.p_sign_posn = extlconv->p_sign_posn;
575 worklconv.n_sign_posn = extlconv->n_sign_posn;
576
577 /* Free the contents of the object populated by pg_localeconv_r(). */
578 pg_localeconv_free(&tmp);
579
580 /* If any of the preceding strdup calls failed, complain now. */
581 if (!struct_lconv_is_valid(&worklconv))
583 (errcode(ERRCODE_OUT_OF_MEMORY),
584 errmsg("out of memory")));
585
586 PG_TRY();
587 {
588 int encoding;
589
590 /*
591 * Now we must perform encoding conversion from whatever's associated
592 * with the locales into the database encoding. If we can't identify
593 * the encoding implied by LC_NUMERIC or LC_MONETARY (ie we get -1),
594 * use PG_SQL_ASCII, which will result in just validating that the
595 * strings are OK in the database encoding.
596 */
598 if (encoding < 0)
600
601 db_encoding_convert(encoding, &worklconv.decimal_point);
602 db_encoding_convert(encoding, &worklconv.thousands_sep);
603 /* grouping is not text and does not require conversion */
604
606 if (encoding < 0)
608
609 db_encoding_convert(encoding, &worklconv.int_curr_symbol);
610 db_encoding_convert(encoding, &worklconv.currency_symbol);
611 db_encoding_convert(encoding, &worklconv.mon_decimal_point);
612 db_encoding_convert(encoding, &worklconv.mon_thousands_sep);
613 /* mon_grouping is not text and does not require conversion */
614 db_encoding_convert(encoding, &worklconv.positive_sign);
615 db_encoding_convert(encoding, &worklconv.negative_sign);
616 }
617 PG_CATCH();
618 {
619 free_struct_lconv(&worklconv);
620 PG_RE_THROW();
621 }
622 PG_END_TRY();
623
624 /*
625 * Everything is good, so save the results.
626 */
627 CurrentLocaleConv = worklconv;
628 CurrentLocaleConvAllocated = true;
630 return &CurrentLocaleConv;
631}
#define PG_RE_THROW()
Definition: elog.h:404
#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:111
static void db_encoding_convert(int encoding, char **str)
Definition: pg_locale.c:495
static void free_struct_lconv(struct lconv *s)
Definition: pg_locale.c:445
static bool struct_lconv_is_valid(struct lconv *s)
Definition: pg_locale.c:464
char * locale_monetary
Definition: pg_locale.c:110
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().

◆ strfold_builtin()

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

Definition at line 115 of file pg_locale_builtin.c.

117{
118 return unicode_strfold(dest, destsize, src, srclen,
119 locale->info.builtin.casemap_full);
120}
size_t unicode_strfold(char *dst, size_t dstsize, const char *src, ssize_t srclen, bool full)
Definition: unicode_case.c:189

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

Referenced by pg_strfold().

◆ strfold_icu()

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

Referenced by pg_strfold().

◆ strlower_builtin()

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

Definition at line 81 of file pg_locale_builtin.c.

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

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 123 of file pg_locale_libc.c.

125{
127 return strlower_libc_mb(dst, dstsize, src, srclen, locale);
128 else
129 return strlower_libc_sb(dst, dstsize, src, srclen, locale);
130}
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1547
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_strfold(), and 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 89 of file pg_locale_builtin.c.

91{
92 struct WordBoundaryState wbstate = {
93 .str = src,
94 .len = srclen,
95 .offset = 0,
96 .posix = !locale->info.builtin.casemap_full,
97 .init = false,
98 .prev_alnum = false,
99 };
100
101 return unicode_strtitle(dest, destsize, src, srclen,
102 locale->info.builtin.casemap_full,
103 initcap_wbnext, &wbstate);
104}
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:138

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 133 of file pg_locale_libc.c.

135{
137 return strtitle_libc_mb(dst, dstsize, src, srclen, locale);
138 else
139 return strtitle_libc_sb(dst, dstsize, src, srclen, locale);
140}
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 464 of file pg_locale.c.

465{
466 if (s->decimal_point == NULL)
467 return false;
468 if (s->thousands_sep == NULL)
469 return false;
470 if (s->grouping == NULL)
471 return false;
472 if (s->int_curr_symbol == NULL)
473 return false;
474 if (s->currency_symbol == NULL)
475 return false;
476 if (s->mon_decimal_point == NULL)
477 return false;
478 if (s->mon_thousands_sep == NULL)
479 return false;
480 if (s->mon_grouping == NULL)
481 return false;
482 if (s->positive_sign == NULL)
483 return false;
484 if (s->negative_sign == NULL)
485 return false;
486 return true;
487}

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 107 of file pg_locale_builtin.c.

109{
110 return unicode_strupper(dest, destsize, src, srclen,
111 locale->info.builtin.casemap_full);
112}
size_t unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen, bool full)
Definition: unicode_case.c:165

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 143 of file pg_locale_libc.c.

145{
147 return strupper_libc_mb(dst, dstsize, src, srclen, locale);
148 else
149 return strupper_libc_sb(dst, dstsize, src, srclen, locale);
150}
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 163 of file pg_locale.c.

Referenced by pg_newlocale_from_collation().

◆ CollationCacheContext

MemoryContext CollationCacheContext = NULL
static

Definition at line 162 of file pg_locale.c.

Referenced by pg_newlocale_from_collation().

◆ CurrentLCTimeValid

bool CurrentLCTimeValid = false
static

Definition at line 135 of file pg_locale.c.

Referenced by assign_locale_time(), and cache_locale_time().

◆ CurrentLocaleConvValid

bool CurrentLocaleConvValid = false
static

Definition at line 134 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 129 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 131 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 114 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 170 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 169 of file pg_locale.c.

Referenced by pg_newlocale_from_collation().

◆ locale_messages

char* locale_messages

Definition at line 109 of file pg_locale.c.

◆ locale_monetary

char* locale_monetary

Definition at line 110 of file pg_locale.c.

Referenced by PGLC_localeconv().

◆ locale_numeric

char* locale_numeric

Definition at line 111 of file pg_locale.c.

Referenced by PGLC_localeconv().

◆ locale_time

char* locale_time

Definition at line 112 of file pg_locale.c.

Referenced by cache_locale_time().

◆ localized_abbrev_days

char* localized_abbrev_days[7+1]

Definition at line 123 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 125 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 124 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 126 of file pg_locale.c.

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