PostgreSQL Source Code  git master
formatting.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define DCH_DATED   0x01
 
#define DCH_TIMED   0x02
 
#define DCH_ZONED   0x04
 

Functions

char * str_tolower (const char *buff, size_t nbytes, Oid collid)
 
char * str_toupper (const char *buff, size_t nbytes, Oid collid)
 
char * str_initcap (const char *buff, size_t nbytes, Oid collid)
 
char * asc_tolower (const char *buff, size_t nbytes)
 
char * asc_toupper (const char *buff, size_t nbytes)
 
char * asc_initcap (const char *buff, size_t nbytes)
 
Datum parse_datetime (text *date_txt, text *fmt, Oid collid, bool strict, Oid *typid, int32 *typmod, int *tz, bool *have_error)
 
int datetime_format_flags (const char *fmt_str, bool *have_error)
 

Macro Definition Documentation

◆ DCH_DATED

#define DCH_DATED   0x01

Definition at line 20 of file formatting.h.

◆ DCH_TIMED

#define DCH_TIMED   0x02

Definition at line 21 of file formatting.h.

◆ DCH_ZONED

#define DCH_ZONED   0x04

Definition at line 22 of file formatting.h.

Function Documentation

◆ asc_initcap()

char* asc_initcap ( const char *  buff,
size_t  nbytes 
)

Definition at line 2105 of file formatting.c.

2106 {
2107  char *result;
2108  char *p;
2109  int wasalnum = false;
2110 
2111  if (!buff)
2112  return NULL;
2113 
2114  result = pnstrdup(buff, nbytes);
2115 
2116  for (p = result; *p; p++)
2117  {
2118  char c;
2119 
2120  if (wasalnum)
2121  *p = c = pg_ascii_tolower((unsigned char) *p);
2122  else
2123  *p = c = pg_ascii_toupper((unsigned char) *p);
2124  /* we don't trust isalnum() here */
2125  wasalnum = ((c >= 'A' && c <= 'Z') ||
2126  (c >= 'a' && c <= 'z') ||
2127  (c >= '0' && c <= '9'));
2128  }
2129 
2130  return result;
2131 }
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1316
unsigned char pg_ascii_tolower(unsigned char ch)
Definition: pgstrcasecmp.c:146
unsigned char pg_ascii_toupper(unsigned char ch)
Definition: pgstrcasecmp.c:135
char * c

References pg_ascii_tolower(), pg_ascii_toupper(), and pnstrdup().

Referenced by str_initcap().

◆ asc_tolower()

char* asc_tolower ( const char *  buff,
size_t  nbytes 
)

Definition at line 2059 of file formatting.c.

2060 {
2061  char *result;
2062  char *p;
2063 
2064  if (!buff)
2065  return NULL;
2066 
2067  result = pnstrdup(buff, nbytes);
2068 
2069  for (p = result; *p; p++)
2070  *p = pg_ascii_tolower((unsigned char) *p);
2071 
2072  return result;
2073 }

References pg_ascii_tolower(), and pnstrdup().

Referenced by asc_tolower_z(), and str_tolower().

◆ asc_toupper()

char* asc_toupper ( const char *  buff,
size_t  nbytes 
)

Definition at line 2082 of file formatting.c.

2083 {
2084  char *result;
2085  char *p;
2086 
2087  if (!buff)
2088  return NULL;
2089 
2090  result = pnstrdup(buff, nbytes);
2091 
2092  for (p = result; *p; p++)
2093  *p = pg_ascii_toupper((unsigned char) *p);
2094 
2095  return result;
2096 }

References pg_ascii_toupper(), and pnstrdup().

Referenced by asc_toupper_z(), and str_toupper().

◆ datetime_format_flags()

int datetime_format_flags ( const char *  fmt_str,
bool have_error 
)

Definition at line 6716 of file formatting.c.

6721 {
6722  bool incache;
6723  int fmt_len = strlen(fmt_str);
6724  int result;
6725  FormatNode *format;
6726 
6727  if (fmt_len > DCH_CACHE_SIZE)
6728  {
6729  /*
6730  * Allocate new memory if format picture is bigger than static cache
6731  * and do not use cache (call parser always)
6732  */
6733  incache = false;
6734 
6735  format = (FormatNode *) palloc((fmt_len + 1) * sizeof(FormatNode));
6736 
6737  parse_format(format, fmt_str, DCH_keywords,
6738  DCH_suff, DCH_index, DCH_FLAG, NULL);
6739  }
6740  else
6741  {
6742  /*
6743  * Use cache buffers
6744  */
6745  DCHCacheEntry *ent = DCH_cache_fetch(fmt_str, false);
6746 
6747  incache = true;
6748  format = ent->format;
6749  }
6750 
6751  result = DCH_datetime_type(format, have_error);
6752 
6753  if (!incache)
static const int DCH_index[KeyWord_INDEX_SIZE]
Definition: formatting.c:979
static void parse_format(FormatNode *node, const char *str, const KeyWord *kw, const KeySuffix *suf, const int *index, uint32 flags, NUMDesc *Num)
Definition: formatting.c:1354
#define DCH_FLAG
Definition: formatting.c:140
static int DCH_datetime_type(FormatNode *node, bool *have_error)
Definition: formatting.c:3836
static const KeySuffix DCH_suff[]
Definition: formatting.c:599
#define DCH_CACHE_SIZE
Definition: formatting.c:401
static const KeyWord DCH_keywords[]
Definition: formatting.c:806
static DCHCacheEntry * DCH_cache_fetch(const char *str, bool std)
Definition: formatting.c:4021
void * palloc(Size size)
Definition: mcxt.c:1068
static char format
FormatNode format[DCH_CACHE_SIZE+1]
Definition: formatting.c:411

Referenced by jspIsMutableWalker().

◆ parse_datetime()

Datum parse_datetime ( text date_txt,
text fmt,
Oid  collid,
bool  strict,
Oid typid,
int32 typmod,
int *  tz,
bool have_error 
)

Definition at line 4324 of file formatting.c.

4327 {
4328  struct pg_tm tm;
4329  fsec_t fsec;
4330  int fprec;
4331  uint32 flags;
4332 
4333  do_to_timestamp(date_txt, fmt, collid, strict,
4334  &tm, &fsec, &fprec, &flags, have_error);
4335  CHECK_ERROR;
4336 
4337  *typmod = fprec ? fprec : -1; /* fractional part precision */
4338 
4339  if (flags & DCH_DATED)
4340  {
4341  if (flags & DCH_TIMED)
4342  {
4343  if (flags & DCH_ZONED)
4344  {
4345  TimestampTz result;
4346 
4347  if (tm.tm_zone)
4348  {
4349  int dterr = DecodeTimezone(unconstify(char *, tm.tm_zone), tz);
4350 
4351  if (dterr)
4352  DateTimeParseError(dterr, text_to_cstring(date_txt), "timestamptz");
4353  }
4354  else
4355  {
4356  /*
4357  * Time zone is present in format string, but not in input
4358  * string. Assuming do_to_timestamp() triggers no error
4359  * this should be possible only in non-strict case.
4360  */
4361  Assert(!strict);
4362 
4364  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4365  errmsg("missing time zone in input string for type timestamptz"))));
4366  }
4367 
4368  if (tm2timestamp(&tm, fsec, tz, &result) != 0)
4370  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4371  errmsg("timestamptz out of range"))));
4372 
4373  AdjustTimestampForTypmod(&result, *typmod);
4374 
4375  *typid = TIMESTAMPTZOID;
4376  return TimestampTzGetDatum(result);
4377  }
4378  else
4379  {
4380  Timestamp result;
4381 
4382  if (tm2timestamp(&tm, fsec, NULL, &result) != 0)
4384  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4385  errmsg("timestamp out of range"))));
4386 
4387  AdjustTimestampForTypmod(&result, *typmod);
4388 
4389  *typid = TIMESTAMPOID;
4390  return TimestampGetDatum(result);
4391  }
4392  }
4393  else
4394  {
4395  if (flags & DCH_ZONED)
4396  {
4398  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4399  errmsg("datetime format is zoned but not timed"))));
4400  }
4401  else
4402  {
4403  DateADT result;
4404 
4405  /* Prevent overflow in Julian-day routines */
4408  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4409  errmsg("date out of range: \"%s\"",
4410  text_to_cstring(date_txt)))));
4411 
4412  result = date2j(tm.tm_year, tm.tm_mon, tm.tm_mday) -
4414 
4415  /* Now check for just-out-of-range dates */
4416  if (!IS_VALID_DATE(result))
4418  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4419  errmsg("date out of range: \"%s\"",
4420  text_to_cstring(date_txt)))));
4421 
4422  *typid = DATEOID;
4423  return DateADTGetDatum(result);
4424  }
4425  }
4426  }
4427  else if (flags & DCH_TIMED)
4428  {
4429  if (flags & DCH_ZONED)
4430  {
4431  TimeTzADT *result = palloc(sizeof(TimeTzADT));
4432 
4433  if (tm.tm_zone)
4434  {
4435  int dterr = DecodeTimezone(unconstify(char *, tm.tm_zone), tz);
4436 
4437  if (dterr)
4438  RETURN_ERROR(DateTimeParseError(dterr, text_to_cstring(date_txt), "timetz"));
4439  }
4440  else
4441  {
4442  /*
4443  * Time zone is present in format string, but not in input
4444  * string. Assuming do_to_timestamp() triggers no error this
4445  * should be possible only in non-strict case.
4446  */
4447  Assert(!strict);
4448 
4450  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4451  errmsg("missing time zone in input string for type timetz"))));
4452  }
4453 
4454  if (tm2timetz(&tm, fsec, *tz, result) != 0)
4456  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4457  errmsg("timetz out of range"))));
4458 
4459  AdjustTimeForTypmod(&result->time, *typmod);
4460 
4461  *typid = TIMETZOID;
4462  return TimeTzADTPGetDatum(result);
4463  }
4464  else
4465  {
4466  TimeADT result;
4467 
4468  if (tm2time(&tm, fsec, &result) != 0)
4470  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4471  errmsg("time out of range"))));
4472 
4473  AdjustTimeForTypmod(&result, *typmod);
4474 
4475  *typid = TIMEOID;
4476  return TimeADTGetDatum(result);
4477  }
4478  }
4479  else
4480  {
4482  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4483  errmsg("datetime format is not dated and not timed"))));
4484  }
4485 
4486 on_error:
4487  return (Datum) 0;
4488 }
int DecodeTimezone(char *str, int *tzp)
Definition: datetime.c:3147
int date2j(int y, int m, int d)
Definition: datetime.c:284
void DateTimeParseError(int dterr, const char *str, const char *datatype)
Definition: datetime.c:4024
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:1912
void AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
Definition: timestamp.c:395
#define unconstify(underlying_type, expr)
Definition: c.h:1240
unsigned int uint32
Definition: c.h:441
int64 Timestamp
Definition: timestamp.h:38
int64 TimestampTz
Definition: timestamp.h:39
#define IS_VALID_DATE(d)
Definition: timestamp.h:229
int32 fsec_t
Definition: timestamp.h:41
#define IS_VALID_JULIAN(y, m, d)
Definition: timestamp.h:194
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:202
int tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result)
Definition: date.c:1404
int tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result)
Definition: date.c:2243
void AdjustTimeForTypmod(TimeADT *time, int32 typmod)
Definition: date.c:1633
#define TimeTzADTPGetDatum(X)
Definition: date.h:59
int32 DateADT
Definition: date.h:23
int64 TimeADT
Definition: date.h:25
#define DateADTGetDatum(X)
Definition: date.h:57
#define TimeADTGetDatum(X)
Definition: date.h:58
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define ERROR
Definition: elog.h:33
#define ereport(elevel,...)
Definition: elog.h:143
#define CHECK_ERROR
Definition: formatting.c:130
#define RETURN_ERROR(throw_error)
Definition: formatting.c:117
static void do_to_timestamp(text *date_txt, text *fmt, Oid collid, bool std, struct pg_tm *tm, fsec_t *fsec, int *fprec, uint32 *flags, bool *have_error)
Definition: formatting.c:4510
#define DCH_DATED
Definition: formatting.h:20
#define DCH_TIMED
Definition: formatting.h:21
#define DCH_ZONED
Definition: formatting.h:22
Assert(fmt[strlen(fmt) - 1] !='\n')
static void const char * fmt
static struct pg_tm tm
Definition: localtime.c:102
uintptr_t Datum
Definition: postgres.h:411
Definition: date.h:28
TimeADT time
Definition: date.h:29
Definition: pgtime.h:35
int tm_mday
Definition: pgtime.h:39
int tm_mon
Definition: pgtime.h:40
const char * tm_zone
Definition: pgtime.h:46
int tm_year
Definition: pgtime.h:41
#define TimestampTzGetDatum(X)
Definition: timestamp.h:32
#define TimestampGetDatum(X)
Definition: timestamp.h:31
char * text_to_cstring(const text *t)
Definition: varlena.c:221

References AdjustTimeForTypmod(), AdjustTimestampForTypmod(), Assert(), CHECK_ERROR, date2j(), DateADTGetDatum, DateTimeParseError(), DCH_DATED, DCH_TIMED, DCH_ZONED, DecodeTimezone(), do_to_timestamp(), ereport, errcode(), errmsg(), ERROR, fmt, IS_VALID_DATE, IS_VALID_JULIAN, palloc(), POSTGRES_EPOCH_JDATE, RETURN_ERROR, text_to_cstring(), TimeTzADT::time, TimeADTGetDatum, TimestampGetDatum, TimestampTzGetDatum, TimeTzADTPGetDatum, tm, tm2time(), tm2timestamp(), tm2timetz(), pg_tm::tm_mday, pg_tm::tm_mon, pg_tm::tm_year, pg_tm::tm_zone, and unconstify.

Referenced by executeDateTimeMethod().

◆ str_initcap()

char* str_initcap ( const char *  buff,
size_t  nbytes,
Oid  collid 
)

Definition at line 1912 of file formatting.c.

1913 {
1914  char *result;
1915  int wasalnum = false;
1916 
1917  if (!buff)
1918  return NULL;
1919 
1920  if (!OidIsValid(collid))
1921  {
1922  /*
1923  * This typically means that the parser could not resolve a conflict
1924  * of implicit collations, so report it that way.
1925  */
1926  ereport(ERROR,
1927  (errcode(ERRCODE_INDETERMINATE_COLLATION),
1928  errmsg("could not determine which collation to use for %s function",
1929  "initcap()"),
1930  errhint("Use the COLLATE clause to set the collation explicitly.")));
1931  }
1932 
1933  /* C/POSIX collations use this path regardless of database encoding */
1934  if (lc_ctype_is_c(collid))
1935  {
1936  result = asc_initcap(buff, nbytes);
1937  }
1938  else
1939  {
1940  pg_locale_t mylocale;
1941 
1942  mylocale = pg_newlocale_from_collation(collid);
1943 
1944 #ifdef USE_ICU
1945  if (mylocale && mylocale->provider == COLLPROVIDER_ICU)
1946  {
1947  int32_t len_uchar,
1948  len_conv;
1949  UChar *buff_uchar;
1950  UChar *buff_conv;
1951 
1952  len_uchar = icu_to_uchar(&buff_uchar, buff, nbytes);
1953  len_conv = icu_convert_case(u_strToTitle_default_BI, mylocale,
1954  &buff_conv, buff_uchar, len_uchar);
1955  icu_from_uchar(&result, buff_conv, len_conv);
1956  pfree(buff_uchar);
1957  pfree(buff_conv);
1958  }
1959  else
1960 #endif
1961  {
1963  {
1964  wchar_t *workspace;
1965  size_t curr_char;
1966  size_t result_size;
1967 
1968  /* Overflow paranoia */
1969  if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
1970  ereport(ERROR,
1971  (errcode(ERRCODE_OUT_OF_MEMORY),
1972  errmsg("out of memory")));
1973 
1974  /* Output workspace cannot have more codes than input bytes */
1975  workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
1976 
1977  char2wchar(workspace, nbytes + 1, buff, nbytes, mylocale);
1978 
1979  for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
1980  {
1981 #ifdef HAVE_LOCALE_T
1982  if (mylocale)
1983  {
1984  if (wasalnum)
1985  workspace[curr_char] = towlower_l(workspace[curr_char], mylocale->info.lt);
1986  else
1987  workspace[curr_char] = towupper_l(workspace[curr_char], mylocale->info.lt);
1988  wasalnum = iswalnum_l(workspace[curr_char], mylocale->info.lt);
1989  }
1990  else
1991 #endif
1992  {
1993  if (wasalnum)
1994  workspace[curr_char] = towlower(workspace[curr_char]);
1995  else
1996  workspace[curr_char] = towupper(workspace[curr_char]);
1997  wasalnum = iswalnum(workspace[curr_char]);
1998  }
1999  }
2000 
2001  /*
2002  * Make result large enough; case change might change number
2003  * of bytes
2004  */
2005  result_size = curr_char * pg_database_encoding_max_length() + 1;
2006  result = palloc(result_size);
2007 
2008  wchar2char(result, workspace, result_size, mylocale);
2009  pfree(workspace);
2010  }
2011  else
2012  {
2013  char *p;
2014 
2015  result = pnstrdup(buff, nbytes);
2016 
2017  /*
2018  * Note: we assume that toupper_l()/tolower_l() will not be so
2019  * broken as to need guard tests. When using the default
2020  * collation, we apply the traditional Postgres behavior that
2021  * forces ASCII-style treatment of I/i, but in non-default
2022  * collations you get exactly what the collation says.
2023  */
2024  for (p = result; *p; p++)
2025  {
2026 #ifdef HAVE_LOCALE_T
2027  if (mylocale)
2028  {
2029  if (wasalnum)
2030  *p = tolower_l((unsigned char) *p, mylocale->info.lt);
2031  else
2032  *p = toupper_l((unsigned char) *p, mylocale->info.lt);
2033  wasalnum = isalnum_l((unsigned char) *p, mylocale->info.lt);
2034  }
2035  else
2036 #endif
2037  {
2038  if (wasalnum)
2039  *p = pg_tolower((unsigned char) *p);
2040  else
2041  *p = pg_toupper((unsigned char) *p);
2042  wasalnum = isalnum((unsigned char) *p);
2043  }
2044  }
2045  }
2046  }
2047  }
2048 
2049  return result;
2050 }
#define OidIsValid(objectId)
Definition: c.h:710
int errhint(const char *fmt,...)
Definition: elog.c:1151
char * asc_initcap(const char *buff, size_t nbytes)
Definition: formatting.c:2105
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1495
void pfree(void *pointer)
Definition: mcxt.c:1175
size_t wchar2char(char *to, const wchar_t *from, size_t tolen, pg_locale_t locale)
Definition: pg_locale.c:2027
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition: pg_locale.c:1518
bool lc_ctype_is_c(Oid collation)
Definition: pg_locale.c:1389
size_t char2wchar(wchar_t *to, size_t tolen, const char *from, size_t fromlen, pg_locale_t locale)
Definition: pg_locale.c:2098
unsigned char pg_toupper(unsigned char ch)
Definition: pgstrcasecmp.c:105
unsigned char pg_tolower(unsigned char ch)
Definition: pgstrcasecmp.c:122
union pg_locale_struct::@150 info
#define toupper_l
Definition: win32_port.h:403
#define iswalnum_l
Definition: win32_port.h:411
#define towupper_l
Definition: win32_port.h:405
#define towlower_l
Definition: win32_port.h:404
#define tolower_l
Definition: win32_port.h:402
#define isalnum_l
Definition: win32_port.h:410

References asc_initcap(), char2wchar(), ereport, errcode(), errhint(), errmsg(), ERROR, pg_locale_struct::info, isalnum_l, iswalnum_l, lc_ctype_is_c(), OidIsValid, palloc(), pfree(), pg_database_encoding_max_length(), pg_newlocale_from_collation(), pg_tolower(), pg_toupper(), pnstrdup(), pg_locale_struct::provider, tolower_l, toupper_l, towlower_l, towupper_l, and wchar2char().

Referenced by initcap(), and str_initcap_z().

◆ str_tolower()

char* str_tolower ( const char *  buff,
size_t  nbytes,
Oid  collid 
)

Definition at line 1668 of file formatting.c.

1669 {
1670  char *result;
1671 
1672  if (!buff)
1673  return NULL;
1674 
1675  if (!OidIsValid(collid))
1676  {
1677  /*
1678  * This typically means that the parser could not resolve a conflict
1679  * of implicit collations, so report it that way.
1680  */
1681  ereport(ERROR,
1682  (errcode(ERRCODE_INDETERMINATE_COLLATION),
1683  errmsg("could not determine which collation to use for %s function",
1684  "lower()"),
1685  errhint("Use the COLLATE clause to set the collation explicitly.")));
1686  }
1687 
1688  /* C/POSIX collations use this path regardless of database encoding */
1689  if (lc_ctype_is_c(collid))
1690  {
1691  result = asc_tolower(buff, nbytes);
1692  }
1693  else
1694  {
1695  pg_locale_t mylocale;
1696 
1697  mylocale = pg_newlocale_from_collation(collid);
1698 
1699 #ifdef USE_ICU
1700  if (mylocale && mylocale->provider == COLLPROVIDER_ICU)
1701  {
1702  int32_t len_uchar;
1703  int32_t len_conv;
1704  UChar *buff_uchar;
1705  UChar *buff_conv;
1706 
1707  len_uchar = icu_to_uchar(&buff_uchar, buff, nbytes);
1708  len_conv = icu_convert_case(u_strToLower, mylocale,
1709  &buff_conv, buff_uchar, len_uchar);
1710  icu_from_uchar(&result, buff_conv, len_conv);
1711  pfree(buff_uchar);
1712  pfree(buff_conv);
1713  }
1714  else
1715 #endif
1716  {
1718  {
1719  wchar_t *workspace;
1720  size_t curr_char;
1721  size_t result_size;
1722 
1723  /* Overflow paranoia */
1724  if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
1725  ereport(ERROR,
1726  (errcode(ERRCODE_OUT_OF_MEMORY),
1727  errmsg("out of memory")));
1728 
1729  /* Output workspace cannot have more codes than input bytes */
1730  workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
1731 
1732  char2wchar(workspace, nbytes + 1, buff, nbytes, mylocale);
1733 
1734  for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
1735  {
1736 #ifdef HAVE_LOCALE_T
1737  if (mylocale)
1738  workspace[curr_char] = towlower_l(workspace[curr_char], mylocale->info.lt);
1739  else
1740 #endif
1741  workspace[curr_char] = towlower(workspace[curr_char]);
1742  }
1743 
1744  /*
1745  * Make result large enough; case change might change number
1746  * of bytes
1747  */
1748  result_size = curr_char * pg_database_encoding_max_length() + 1;
1749  result = palloc(result_size);
1750 
1751  wchar2char(result, workspace, result_size, mylocale);
1752  pfree(workspace);
1753  }
1754  else
1755  {
1756  char *p;
1757 
1758  result = pnstrdup(buff, nbytes);
1759 
1760  /*
1761  * Note: we assume that tolower_l() will not be so broken as
1762  * to need an isupper_l() guard test. When using the default
1763  * collation, we apply the traditional Postgres behavior that
1764  * forces ASCII-style treatment of I/i, but in non-default
1765  * collations you get exactly what the collation says.
1766  */
1767  for (p = result; *p; p++)
1768  {
1769 #ifdef HAVE_LOCALE_T
1770  if (mylocale)
1771  *p = tolower_l((unsigned char) *p, mylocale->info.lt);
1772  else
1773 #endif
1774  *p = pg_tolower((unsigned char) *p);
1775  }
1776  }
1777  }
1778  }
1779 
1780  return result;
1781 }
char * asc_tolower(const char *buff, size_t nbytes)
Definition: formatting.c:2059

References asc_tolower(), char2wchar(), ereport, errcode(), errhint(), errmsg(), ERROR, pg_locale_struct::info, lc_ctype_is_c(), OidIsValid, palloc(), pfree(), pg_database_encoding_max_length(), pg_newlocale_from_collation(), pg_tolower(), pnstrdup(), pg_locale_struct::provider, tolower_l, towlower_l, and wchar2char().

Referenced by citext_eq(), citext_hash(), citext_hash_extended(), citext_ne(), citextcmp(), internal_citext_pattern_cmp(), lower(), ltree_strncasecmp(), seq_search_localized(), and str_tolower_z().

◆ str_toupper()

char* str_toupper ( const char *  buff,
size_t  nbytes,
Oid  collid 
)

Definition at line 1790 of file formatting.c.

1791 {
1792  char *result;
1793 
1794  if (!buff)
1795  return NULL;
1796 
1797  if (!OidIsValid(collid))
1798  {
1799  /*
1800  * This typically means that the parser could not resolve a conflict
1801  * of implicit collations, so report it that way.
1802  */
1803  ereport(ERROR,
1804  (errcode(ERRCODE_INDETERMINATE_COLLATION),
1805  errmsg("could not determine which collation to use for %s function",
1806  "upper()"),
1807  errhint("Use the COLLATE clause to set the collation explicitly.")));
1808  }
1809 
1810  /* C/POSIX collations use this path regardless of database encoding */
1811  if (lc_ctype_is_c(collid))
1812  {
1813  result = asc_toupper(buff, nbytes);
1814  }
1815  else
1816  {
1817  pg_locale_t mylocale;
1818 
1819  mylocale = pg_newlocale_from_collation(collid);
1820 
1821 #ifdef USE_ICU
1822  if (mylocale && mylocale->provider == COLLPROVIDER_ICU)
1823  {
1824  int32_t len_uchar,
1825  len_conv;
1826  UChar *buff_uchar;
1827  UChar *buff_conv;
1828 
1829  len_uchar = icu_to_uchar(&buff_uchar, buff, nbytes);
1830  len_conv = icu_convert_case(u_strToUpper, mylocale,
1831  &buff_conv, buff_uchar, len_uchar);
1832  icu_from_uchar(&result, buff_conv, len_conv);
1833  pfree(buff_uchar);
1834  pfree(buff_conv);
1835  }
1836  else
1837 #endif
1838  {
1840  {
1841  wchar_t *workspace;
1842  size_t curr_char;
1843  size_t result_size;
1844 
1845  /* Overflow paranoia */
1846  if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
1847  ereport(ERROR,
1848  (errcode(ERRCODE_OUT_OF_MEMORY),
1849  errmsg("out of memory")));
1850 
1851  /* Output workspace cannot have more codes than input bytes */
1852  workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
1853 
1854  char2wchar(workspace, nbytes + 1, buff, nbytes, mylocale);
1855 
1856  for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
1857  {
1858 #ifdef HAVE_LOCALE_T
1859  if (mylocale)
1860  workspace[curr_char] = towupper_l(workspace[curr_char], mylocale->info.lt);
1861  else
1862 #endif
1863  workspace[curr_char] = towupper(workspace[curr_char]);
1864  }
1865 
1866  /*
1867  * Make result large enough; case change might change number
1868  * of bytes
1869  */
1870  result_size = curr_char * pg_database_encoding_max_length() + 1;
1871  result = palloc(result_size);
1872 
1873  wchar2char(result, workspace, result_size, mylocale);
1874  pfree(workspace);
1875  }
1876  else
1877  {
1878  char *p;
1879 
1880  result = pnstrdup(buff, nbytes);
1881 
1882  /*
1883  * Note: we assume that toupper_l() will not be so broken as
1884  * to need an islower_l() guard test. When using the default
1885  * collation, we apply the traditional Postgres behavior that
1886  * forces ASCII-style treatment of I/i, but in non-default
1887  * collations you get exactly what the collation says.
1888  */
1889  for (p = result; *p; p++)
1890  {
1891 #ifdef HAVE_LOCALE_T
1892  if (mylocale)
1893  *p = toupper_l((unsigned char) *p, mylocale->info.lt);
1894  else
1895 #endif
1896  *p = pg_toupper((unsigned char) *p);
1897  }
1898  }
1899  }
1900  }
1901 
1902  return result;
1903 }
char * asc_toupper(const char *buff, size_t nbytes)
Definition: formatting.c:2082

References asc_toupper(), char2wchar(), ereport, errcode(), errhint(), errmsg(), ERROR, pg_locale_struct::info, lc_ctype_is_c(), OidIsValid, palloc(), pfree(), pg_database_encoding_max_length(), pg_newlocale_from_collation(), pg_toupper(), pnstrdup(), pg_locale_struct::provider, toupper_l, towupper_l, and wchar2char().

Referenced by seq_search_localized(), str_toupper_z(), and upper().