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.

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)
 

Function Documentation

◆ asc_initcap()

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

Definition at line 2081 of file formatting.c.

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

Referenced by str_initcap().

2082 {
2083  char *result;
2084  char *p;
2085  int wasalnum = false;
2086 
2087  if (!buff)
2088  return NULL;
2089 
2090  result = pnstrdup(buff, nbytes);
2091 
2092  for (p = result; *p; p++)
2093  {
2094  char c;
2095 
2096  if (wasalnum)
2097  *p = c = pg_ascii_tolower((unsigned char) *p);
2098  else
2099  *p = c = pg_ascii_toupper((unsigned char) *p);
2100  /* we don't trust isalnum() here */
2101  wasalnum = ((c >= 'A' && c <= 'Z') ||
2102  (c >= 'a' && c <= 'z') ||
2103  (c >= '0' && c <= '9'));
2104  }
2105 
2106  return result;
2107 }
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1310
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

◆ asc_tolower()

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

Definition at line 2035 of file formatting.c.

References pg_ascii_tolower(), and pnstrdup().

Referenced by asc_tolower_z(), get_collation_version_for_oid(), and str_tolower().

2036 {
2037  char *result;
2038  char *p;
2039 
2040  if (!buff)
2041  return NULL;
2042 
2043  result = pnstrdup(buff, nbytes);
2044 
2045  for (p = result; *p; p++)
2046  *p = pg_ascii_tolower((unsigned char) *p);
2047 
2048  return result;
2049 }
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1310
unsigned char pg_ascii_tolower(unsigned char ch)
Definition: pgstrcasecmp.c:146

◆ asc_toupper()

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

Definition at line 2058 of file formatting.c.

References pg_ascii_toupper(), and pnstrdup().

Referenced by asc_toupper_z(), and str_toupper().

2059 {
2060  char *result;
2061  char *p;
2062 
2063  if (!buff)
2064  return NULL;
2065 
2066  result = pnstrdup(buff, nbytes);
2067 
2068  for (p = result; *p; p++)
2069  *p = pg_ascii_toupper((unsigned char) *p);
2070 
2071  return result;
2072 }
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1310
unsigned char pg_ascii_toupper(unsigned char ch)
Definition: pgstrcasecmp.c:135

◆ 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 4282 of file formatting.c.

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

Referenced by executeDateTimeMethod().

4285 {
4286  struct pg_tm tm;
4287  fsec_t fsec;
4288  int fprec;
4289  uint32 flags;
4290 
4291  do_to_timestamp(date_txt, fmt, collid, strict,
4292  &tm, &fsec, &fprec, &flags, have_error);
4293  CHECK_ERROR;
4294 
4295  *typmod = fprec ? fprec : -1; /* fractional part precision */
4296 
4297  if (flags & DCH_DATED)
4298  {
4299  if (flags & DCH_TIMED)
4300  {
4301  if (flags & DCH_ZONED)
4302  {
4303  TimestampTz result;
4304 
4305  if (tm.tm_zone)
4306  {
4307  int dterr = DecodeTimezone(unconstify(char *, tm.tm_zone), tz);
4308 
4309  if (dterr)
4310  DateTimeParseError(dterr, text_to_cstring(date_txt), "timestamptz");
4311  }
4312  else
4313  {
4314  /*
4315  * Time zone is present in format string, but not in input
4316  * string. Assuming do_to_timestamp() triggers no error
4317  * this should be possible only in non-strict case.
4318  */
4319  Assert(!strict);
4320 
4322  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4323  errmsg("missing time zone in input string for type timestamptz"))));
4324  }
4325 
4326  if (tm2timestamp(&tm, fsec, tz, &result) != 0)
4328  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4329  errmsg("timestamptz out of range"))));
4330 
4331  AdjustTimestampForTypmod(&result, *typmod);
4332 
4333  *typid = TIMESTAMPTZOID;
4334  return TimestampTzGetDatum(result);
4335  }
4336  else
4337  {
4338  Timestamp result;
4339 
4340  if (tm2timestamp(&tm, fsec, NULL, &result) != 0)
4342  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4343  errmsg("timestamp out of range"))));
4344 
4345  AdjustTimestampForTypmod(&result, *typmod);
4346 
4347  *typid = TIMESTAMPOID;
4348  return TimestampGetDatum(result);
4349  }
4350  }
4351  else
4352  {
4353  if (flags & DCH_ZONED)
4354  {
4356  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4357  errmsg("datetime format is zoned but not timed"))));
4358  }
4359  else
4360  {
4361  DateADT result;
4362 
4363  /* Prevent overflow in Julian-day routines */
4366  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4367  errmsg("date out of range: \"%s\"",
4368  text_to_cstring(date_txt)))));
4369 
4370  result = date2j(tm.tm_year, tm.tm_mon, tm.tm_mday) -
4372 
4373  /* Now check for just-out-of-range dates */
4374  if (!IS_VALID_DATE(result))
4376  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4377  errmsg("date out of range: \"%s\"",
4378  text_to_cstring(date_txt)))));
4379 
4380  *typid = DATEOID;
4381  return DateADTGetDatum(result);
4382  }
4383  }
4384  }
4385  else if (flags & DCH_TIMED)
4386  {
4387  if (flags & DCH_ZONED)
4388  {
4389  TimeTzADT *result = palloc(sizeof(TimeTzADT));
4390 
4391  if (tm.tm_zone)
4392  {
4393  int dterr = DecodeTimezone(unconstify(char *, tm.tm_zone), tz);
4394 
4395  if (dterr)
4396  RETURN_ERROR(DateTimeParseError(dterr, text_to_cstring(date_txt), "timetz"));
4397  }
4398  else
4399  {
4400  /*
4401  * Time zone is present in format string, but not in input
4402  * string. Assuming do_to_timestamp() triggers no error this
4403  * should be possible only in non-strict case.
4404  */
4405  Assert(!strict);
4406 
4408  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4409  errmsg("missing time zone in input string for type timetz"))));
4410  }
4411 
4412  if (tm2timetz(&tm, fsec, *tz, result) != 0)
4414  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4415  errmsg("timetz out of range"))));
4416 
4417  AdjustTimeForTypmod(&result->time, *typmod);
4418 
4419  *typid = TIMETZOID;
4420  return TimeTzADTPGetDatum(result);
4421  }
4422  else
4423  {
4424  TimeADT result;
4425 
4426  if (tm2time(&tm, fsec, &result) != 0)
4428  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4429  errmsg("time out of range"))));
4430 
4431  AdjustTimeForTypmod(&result, *typmod);
4432 
4433  *typid = TIMEOID;
4434  return TimeADTGetDatum(result);
4435  }
4436  }
4437  else
4438  {
4440  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4441  errmsg("datetime format is not dated and not timed"))));
4442  }
4443 
4444 on_error:
4445  return (Datum) 0;
4446 }
void DateTimeParseError(int dterr, const char *str, const char *datatype)
Definition: datetime.c:3768
TimeADT time
Definition: date.h:29
int32 DateADT
Definition: date.h:23
int64 TimestampTz
Definition: timestamp.h:39
#define TimeTzADTPGetDatum(X)
Definition: date.h:59
int errcode(int sqlerrcode)
Definition: elog.c:698
#define DateADTGetDatum(X)
Definition: date.h:57
Definition: pgtime.h:25
#define CHECK_ERROR
Definition: formatting.c:131
#define DCH_TIMED
Definition: formatting.c:1023
#define DCH_DATED
Definition: formatting.c:1022
static struct pg_tm tm
Definition: localtime.c:102
int tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result)
Definition: date.c:2256
#define IS_VALID_DATE(d)
Definition: timestamp.h:190
void AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
Definition: timestamp.c:394
#define ERROR
Definition: elog.h:46
#define TimestampTzGetDatum(X)
Definition: timestamp.h:32
int DecodeTimezone(char *str, int *tzp)
Definition: datetime.c:2907
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
unsigned int uint32
Definition: c.h:441
int32 fsec_t
Definition: timestamp.h:41
int64 TimeADT
Definition: date.h:25
#define DCH_ZONED
Definition: formatting.c:1024
#define IS_VALID_JULIAN(y, m, d)
Definition: timestamp.h:155
const char * tm_zone
Definition: pgtime.h:37
#define TimestampGetDatum(X)
Definition: timestamp.h:31
int64 Timestamp
Definition: timestamp.h:38
#define unconstify(underlying_type, expr)
Definition: c.h:1243
uintptr_t Datum
Definition: postgres.h:411
#define TimeADTGetDatum(X)
Definition: date.h:58
int date2j(int y, int m, int d)
Definition: datetime.c:269
#define ereport(elevel,...)
Definition: elog.h:157
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:1918
#define Assert(condition)
Definition: c.h:804
int tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result)
Definition: date.c:1415
char * text_to_cstring(const text *t)
Definition: varlena.c:223
int tm_year
Definition: pgtime.h:32
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163
Definition: date.h:27
void AdjustTimeForTypmod(TimeADT *time, int32 typmod)
Definition: date.c:1646
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:4468
#define RETURN_ERROR(throw_error)
Definition: formatting.c:118

◆ str_initcap()

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

Definition at line 1886 of file formatting.c.

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().

1887 {
1888  char *result;
1889  int wasalnum = false;
1890 
1891  if (!buff)
1892  return NULL;
1893 
1894  /* C/POSIX collations use this path regardless of database encoding */
1895  if (lc_ctype_is_c(collid))
1896  {
1897  result = asc_initcap(buff, nbytes);
1898  }
1899  else
1900  {
1901  pg_locale_t mylocale = 0;
1902 
1903  if (collid != DEFAULT_COLLATION_OID)
1904  {
1905  if (!OidIsValid(collid))
1906  {
1907  /*
1908  * This typically means that the parser could not resolve a
1909  * conflict of implicit collations, so report it that way.
1910  */
1911  ereport(ERROR,
1912  (errcode(ERRCODE_INDETERMINATE_COLLATION),
1913  errmsg("could not determine which collation to use for %s function",
1914  "initcap()"),
1915  errhint("Use the COLLATE clause to set the collation explicitly.")));
1916  }
1917  mylocale = pg_newlocale_from_collation(collid);
1918  }
1919 
1920 #ifdef USE_ICU
1921  if (mylocale && mylocale->provider == COLLPROVIDER_ICU)
1922  {
1923  int32_t len_uchar,
1924  len_conv;
1925  UChar *buff_uchar;
1926  UChar *buff_conv;
1927 
1928  len_uchar = icu_to_uchar(&buff_uchar, buff, nbytes);
1929  len_conv = icu_convert_case(u_strToTitle_default_BI, mylocale,
1930  &buff_conv, buff_uchar, len_uchar);
1931  icu_from_uchar(&result, buff_conv, len_conv);
1932  pfree(buff_uchar);
1933  pfree(buff_conv);
1934  }
1935  else
1936 #endif
1937  {
1939  {
1940  wchar_t *workspace;
1941  size_t curr_char;
1942  size_t result_size;
1943 
1944  /* Overflow paranoia */
1945  if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
1946  ereport(ERROR,
1947  (errcode(ERRCODE_OUT_OF_MEMORY),
1948  errmsg("out of memory")));
1949 
1950  /* Output workspace cannot have more codes than input bytes */
1951  workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
1952 
1953  char2wchar(workspace, nbytes + 1, buff, nbytes, mylocale);
1954 
1955  for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
1956  {
1957 #ifdef HAVE_LOCALE_T
1958  if (mylocale)
1959  {
1960  if (wasalnum)
1961  workspace[curr_char] = towlower_l(workspace[curr_char], mylocale->info.lt);
1962  else
1963  workspace[curr_char] = towupper_l(workspace[curr_char], mylocale->info.lt);
1964  wasalnum = iswalnum_l(workspace[curr_char], mylocale->info.lt);
1965  }
1966  else
1967 #endif
1968  {
1969  if (wasalnum)
1970  workspace[curr_char] = towlower(workspace[curr_char]);
1971  else
1972  workspace[curr_char] = towupper(workspace[curr_char]);
1973  wasalnum = iswalnum(workspace[curr_char]);
1974  }
1975  }
1976 
1977  /*
1978  * Make result large enough; case change might change number
1979  * of bytes
1980  */
1981  result_size = curr_char * pg_database_encoding_max_length() + 1;
1982  result = palloc(result_size);
1983 
1984  wchar2char(result, workspace, result_size, mylocale);
1985  pfree(workspace);
1986  }
1987  else
1988  {
1989  char *p;
1990 
1991  result = pnstrdup(buff, nbytes);
1992 
1993  /*
1994  * Note: we assume that toupper_l()/tolower_l() will not be so
1995  * broken as to need guard tests. When using the default
1996  * collation, we apply the traditional Postgres behavior that
1997  * forces ASCII-style treatment of I/i, but in non-default
1998  * collations you get exactly what the collation says.
1999  */
2000  for (p = result; *p; p++)
2001  {
2002 #ifdef HAVE_LOCALE_T
2003  if (mylocale)
2004  {
2005  if (wasalnum)
2006  *p = tolower_l((unsigned char) *p, mylocale->info.lt);
2007  else
2008  *p = toupper_l((unsigned char) *p, mylocale->info.lt);
2009  wasalnum = isalnum_l((unsigned char) *p, mylocale->info.lt);
2010  }
2011  else
2012 #endif
2013  {
2014  if (wasalnum)
2015  *p = pg_tolower((unsigned char) *p);
2016  else
2017  *p = pg_toupper((unsigned char) *p);
2018  wasalnum = isalnum((unsigned char) *p);
2019  }
2020  }
2021  }
2022  }
2023  }
2024 
2025  return result;
2026 }
int errhint(const char *fmt,...)
Definition: elog.c:1156
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1310
union pg_locale_struct::@141 info
#define towlower_l
Definition: win32_port.h:394
unsigned char pg_tolower(unsigned char ch)
Definition: pgstrcasecmp.c:122
int errcode(int sqlerrcode)
Definition: elog.c:698
#define tolower_l
Definition: win32_port.h:392
#define OidIsValid(objectId)
Definition: c.h:710
#define towupper_l
Definition: win32_port.h:395
void pfree(void *pointer)
Definition: mcxt.c:1169
#define isalnum_l
Definition: win32_port.h:400
#define ERROR
Definition: elog.h:46
size_t char2wchar(wchar_t *to, size_t tolen, const char *from, size_t fromlen, pg_locale_t locale)
Definition: pg_locale.c:2043
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition: pg_locale.c:1473
#define toupper_l
Definition: win32_port.h:393
#define ereport(elevel,...)
Definition: elog.h:157
char * asc_initcap(const char *buff, size_t nbytes)
Definition: formatting.c:2081
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1495
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
size_t wchar2char(char *to, const wchar_t *from, size_t tolen, pg_locale_t locale)
Definition: pg_locale.c:1972
bool lc_ctype_is_c(Oid collation)
Definition: pg_locale.c:1376
unsigned char pg_toupper(unsigned char ch)
Definition: pgstrcasecmp.c:105
#define iswalnum_l
Definition: win32_port.h:401

◆ str_tolower()

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

Definition at line 1638 of file formatting.c.

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().

1639 {
1640  char *result;
1641 
1642  if (!buff)
1643  return NULL;
1644 
1645  /* C/POSIX collations use this path regardless of database encoding */
1646  if (lc_ctype_is_c(collid))
1647  {
1648  result = asc_tolower(buff, nbytes);
1649  }
1650  else
1651  {
1652  pg_locale_t mylocale = 0;
1653 
1654  if (collid != DEFAULT_COLLATION_OID)
1655  {
1656  if (!OidIsValid(collid))
1657  {
1658  /*
1659  * This typically means that the parser could not resolve a
1660  * conflict of implicit collations, so report it that way.
1661  */
1662  ereport(ERROR,
1663  (errcode(ERRCODE_INDETERMINATE_COLLATION),
1664  errmsg("could not determine which collation to use for %s function",
1665  "lower()"),
1666  errhint("Use the COLLATE clause to set the collation explicitly.")));
1667  }
1668  mylocale = pg_newlocale_from_collation(collid);
1669  }
1670 
1671 #ifdef USE_ICU
1672  if (mylocale && mylocale->provider == COLLPROVIDER_ICU)
1673  {
1674  int32_t len_uchar;
1675  int32_t len_conv;
1676  UChar *buff_uchar;
1677  UChar *buff_conv;
1678 
1679  len_uchar = icu_to_uchar(&buff_uchar, buff, nbytes);
1680  len_conv = icu_convert_case(u_strToLower, mylocale,
1681  &buff_conv, buff_uchar, len_uchar);
1682  icu_from_uchar(&result, buff_conv, len_conv);
1683  pfree(buff_uchar);
1684  pfree(buff_conv);
1685  }
1686  else
1687 #endif
1688  {
1690  {
1691  wchar_t *workspace;
1692  size_t curr_char;
1693  size_t result_size;
1694 
1695  /* Overflow paranoia */
1696  if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
1697  ereport(ERROR,
1698  (errcode(ERRCODE_OUT_OF_MEMORY),
1699  errmsg("out of memory")));
1700 
1701  /* Output workspace cannot have more codes than input bytes */
1702  workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
1703 
1704  char2wchar(workspace, nbytes + 1, buff, nbytes, mylocale);
1705 
1706  for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
1707  {
1708 #ifdef HAVE_LOCALE_T
1709  if (mylocale)
1710  workspace[curr_char] = towlower_l(workspace[curr_char], mylocale->info.lt);
1711  else
1712 #endif
1713  workspace[curr_char] = towlower(workspace[curr_char]);
1714  }
1715 
1716  /*
1717  * Make result large enough; case change might change number
1718  * of bytes
1719  */
1720  result_size = curr_char * pg_database_encoding_max_length() + 1;
1721  result = palloc(result_size);
1722 
1723  wchar2char(result, workspace, result_size, mylocale);
1724  pfree(workspace);
1725  }
1726  else
1727  {
1728  char *p;
1729 
1730  result = pnstrdup(buff, nbytes);
1731 
1732  /*
1733  * Note: we assume that tolower_l() will not be so broken as
1734  * to need an isupper_l() guard test. When using the default
1735  * collation, we apply the traditional Postgres behavior that
1736  * forces ASCII-style treatment of I/i, but in non-default
1737  * collations you get exactly what the collation says.
1738  */
1739  for (p = result; *p; p++)
1740  {
1741 #ifdef HAVE_LOCALE_T
1742  if (mylocale)
1743  *p = tolower_l((unsigned char) *p, mylocale->info.lt);
1744  else
1745 #endif
1746  *p = pg_tolower((unsigned char) *p);
1747  }
1748  }
1749  }
1750  }
1751 
1752  return result;
1753 }
int errhint(const char *fmt,...)
Definition: elog.c:1156
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1310
union pg_locale_struct::@141 info
#define towlower_l
Definition: win32_port.h:394
unsigned char pg_tolower(unsigned char ch)
Definition: pgstrcasecmp.c:122
int errcode(int sqlerrcode)
Definition: elog.c:698
#define tolower_l
Definition: win32_port.h:392
#define OidIsValid(objectId)
Definition: c.h:710
void pfree(void *pointer)
Definition: mcxt.c:1169
#define ERROR
Definition: elog.h:46
size_t char2wchar(wchar_t *to, size_t tolen, const char *from, size_t fromlen, pg_locale_t locale)
Definition: pg_locale.c:2043
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition: pg_locale.c:1473
#define ereport(elevel,...)
Definition: elog.h:157
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1495
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
size_t wchar2char(char *to, const wchar_t *from, size_t tolen, pg_locale_t locale)
Definition: pg_locale.c:1972
bool lc_ctype_is_c(Oid collation)
Definition: pg_locale.c:1376
char * asc_tolower(const char *buff, size_t nbytes)
Definition: formatting.c:2035

◆ str_toupper()

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

Definition at line 1762 of file formatting.c.

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().

1763 {
1764  char *result;
1765 
1766  if (!buff)
1767  return NULL;
1768 
1769  /* C/POSIX collations use this path regardless of database encoding */
1770  if (lc_ctype_is_c(collid))
1771  {
1772  result = asc_toupper(buff, nbytes);
1773  }
1774  else
1775  {
1776  pg_locale_t mylocale = 0;
1777 
1778  if (collid != DEFAULT_COLLATION_OID)
1779  {
1780  if (!OidIsValid(collid))
1781  {
1782  /*
1783  * This typically means that the parser could not resolve a
1784  * conflict of implicit collations, so report it that way.
1785  */
1786  ereport(ERROR,
1787  (errcode(ERRCODE_INDETERMINATE_COLLATION),
1788  errmsg("could not determine which collation to use for %s function",
1789  "upper()"),
1790  errhint("Use the COLLATE clause to set the collation explicitly.")));
1791  }
1792  mylocale = pg_newlocale_from_collation(collid);
1793  }
1794 
1795 #ifdef USE_ICU
1796  if (mylocale && mylocale->provider == COLLPROVIDER_ICU)
1797  {
1798  int32_t len_uchar,
1799  len_conv;
1800  UChar *buff_uchar;
1801  UChar *buff_conv;
1802 
1803  len_uchar = icu_to_uchar(&buff_uchar, buff, nbytes);
1804  len_conv = icu_convert_case(u_strToUpper, mylocale,
1805  &buff_conv, buff_uchar, len_uchar);
1806  icu_from_uchar(&result, buff_conv, len_conv);
1807  pfree(buff_uchar);
1808  pfree(buff_conv);
1809  }
1810  else
1811 #endif
1812  {
1814  {
1815  wchar_t *workspace;
1816  size_t curr_char;
1817  size_t result_size;
1818 
1819  /* Overflow paranoia */
1820  if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
1821  ereport(ERROR,
1822  (errcode(ERRCODE_OUT_OF_MEMORY),
1823  errmsg("out of memory")));
1824 
1825  /* Output workspace cannot have more codes than input bytes */
1826  workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
1827 
1828  char2wchar(workspace, nbytes + 1, buff, nbytes, mylocale);
1829 
1830  for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
1831  {
1832 #ifdef HAVE_LOCALE_T
1833  if (mylocale)
1834  workspace[curr_char] = towupper_l(workspace[curr_char], mylocale->info.lt);
1835  else
1836 #endif
1837  workspace[curr_char] = towupper(workspace[curr_char]);
1838  }
1839 
1840  /*
1841  * Make result large enough; case change might change number
1842  * of bytes
1843  */
1844  result_size = curr_char * pg_database_encoding_max_length() + 1;
1845  result = palloc(result_size);
1846 
1847  wchar2char(result, workspace, result_size, mylocale);
1848  pfree(workspace);
1849  }
1850  else
1851  {
1852  char *p;
1853 
1854  result = pnstrdup(buff, nbytes);
1855 
1856  /*
1857  * Note: we assume that toupper_l() will not be so broken as
1858  * to need an islower_l() guard test. When using the default
1859  * collation, we apply the traditional Postgres behavior that
1860  * forces ASCII-style treatment of I/i, but in non-default
1861  * collations you get exactly what the collation says.
1862  */
1863  for (p = result; *p; p++)
1864  {
1865 #ifdef HAVE_LOCALE_T
1866  if (mylocale)
1867  *p = toupper_l((unsigned char) *p, mylocale->info.lt);
1868  else
1869 #endif
1870  *p = pg_toupper((unsigned char) *p);
1871  }
1872  }
1873  }
1874  }
1875 
1876  return result;
1877 }
int errhint(const char *fmt,...)
Definition: elog.c:1156
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1310
union pg_locale_struct::@141 info
int errcode(int sqlerrcode)
Definition: elog.c:698
#define OidIsValid(objectId)
Definition: c.h:710
#define towupper_l
Definition: win32_port.h:395
void pfree(void *pointer)
Definition: mcxt.c:1169
#define ERROR
Definition: elog.h:46
char * asc_toupper(const char *buff, size_t nbytes)
Definition: formatting.c:2058
size_t char2wchar(wchar_t *to, size_t tolen, const char *from, size_t fromlen, pg_locale_t locale)
Definition: pg_locale.c:2043
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition: pg_locale.c:1473
#define toupper_l
Definition: win32_port.h:393
#define ereport(elevel,...)
Definition: elog.h:157
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1495
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
size_t wchar2char(char *to, const wchar_t *from, size_t tolen, pg_locale_t locale)
Definition: pg_locale.c:1972
bool lc_ctype_is_c(Oid collation)
Definition: pg_locale.c:1376
unsigned char pg_toupper(unsigned char ch)
Definition: pgstrcasecmp.c:105