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

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

Referenced by str_initcap().

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

References pg_ascii_tolower(), and pnstrdup().

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

2035 {
2036  char *result;
2037  char *p;
2038 
2039  if (!buff)
2040  return NULL;
2041 
2042  result = pnstrdup(buff, nbytes);
2043 
2044  for (p = result; *p; p++)
2045  *p = pg_ascii_tolower((unsigned char) *p);
2046 
2047  return result;
2048 }
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1197
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 2057 of file formatting.c.

References pg_ascii_toupper(), and pnstrdup().

Referenced by asc_toupper_z(), and str_toupper().

2058 {
2059  char *result;
2060  char *p;
2061 
2062  if (!buff)
2063  return NULL;
2064 
2065  result = pnstrdup(buff, nbytes);
2066 
2067  for (p = result; *p; p++)
2068  *p = pg_ascii_toupper((unsigned char) *p);
2069 
2070  return result;
2071 }
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1197
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 4226 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().

4229 {
4230  struct pg_tm tm;
4231  fsec_t fsec;
4232  int fprec;
4233  uint32 flags;
4234 
4235  do_to_timestamp(date_txt, fmt, collid, strict,
4236  &tm, &fsec, &fprec, &flags, have_error);
4237  CHECK_ERROR;
4238 
4239  *typmod = fprec ? fprec : -1; /* fractional part precision */
4240 
4241  if (flags & DCH_DATED)
4242  {
4243  if (flags & DCH_TIMED)
4244  {
4245  if (flags & DCH_ZONED)
4246  {
4247  TimestampTz result;
4248 
4249  if (tm.tm_zone)
4250  {
4251  int dterr = DecodeTimezone(unconstify(char *, tm.tm_zone), tz);
4252 
4253  if (dterr)
4254  DateTimeParseError(dterr, text_to_cstring(date_txt), "timestamptz");
4255  }
4256  else
4257  {
4258  /*
4259  * Time zone is present in format string, but not in input
4260  * string. Assuming do_to_timestamp() triggers no error
4261  * this should be possible only in non-strict case.
4262  */
4263  Assert(!strict);
4264 
4266  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4267  errmsg("missing time zone in input string for type timestamptz"))));
4268  }
4269 
4270  if (tm2timestamp(&tm, fsec, tz, &result) != 0)
4272  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4273  errmsg("timestamptz out of range"))));
4274 
4275  AdjustTimestampForTypmod(&result, *typmod);
4276 
4277  *typid = TIMESTAMPTZOID;
4278  return TimestampTzGetDatum(result);
4279  }
4280  else
4281  {
4282  Timestamp result;
4283 
4284  if (tm2timestamp(&tm, fsec, NULL, &result) != 0)
4286  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4287  errmsg("timestamp out of range"))));
4288 
4289  AdjustTimestampForTypmod(&result, *typmod);
4290 
4291  *typid = TIMESTAMPOID;
4292  return TimestampGetDatum(result);
4293  }
4294  }
4295  else
4296  {
4297  if (flags & DCH_ZONED)
4298  {
4300  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4301  errmsg("datetime format is zoned but not timed"))));
4302  }
4303  else
4304  {
4305  DateADT result;
4306 
4307  /* Prevent overflow in Julian-day routines */
4310  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4311  errmsg("date out of range: \"%s\"",
4312  text_to_cstring(date_txt)))));
4313 
4314  result = date2j(tm.tm_year, tm.tm_mon, tm.tm_mday) -
4316 
4317  /* Now check for just-out-of-range dates */
4318  if (!IS_VALID_DATE(result))
4320  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4321  errmsg("date out of range: \"%s\"",
4322  text_to_cstring(date_txt)))));
4323 
4324  *typid = DATEOID;
4325  return DateADTGetDatum(result);
4326  }
4327  }
4328  }
4329  else if (flags & DCH_TIMED)
4330  {
4331  if (flags & DCH_ZONED)
4332  {
4333  TimeTzADT *result = palloc(sizeof(TimeTzADT));
4334 
4335  if (tm.tm_zone)
4336  {
4337  int dterr = DecodeTimezone(unconstify(char *, tm.tm_zone), tz);
4338 
4339  if (dterr)
4340  RETURN_ERROR(DateTimeParseError(dterr, text_to_cstring(date_txt), "timetz"));
4341  }
4342  else
4343  {
4344  /*
4345  * Time zone is present in format string, but not in input
4346  * string. Assuming do_to_timestamp() triggers no error this
4347  * should be possible only in non-strict case.
4348  */
4349  Assert(!strict);
4350 
4352  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4353  errmsg("missing time zone in input string for type timetz"))));
4354  }
4355 
4356  if (tm2timetz(&tm, fsec, *tz, result) != 0)
4358  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4359  errmsg("timetz out of range"))));
4360 
4361  AdjustTimeForTypmod(&result->time, *typmod);
4362 
4363  *typid = TIMETZOID;
4364  return TimeTzADTPGetDatum(result);
4365  }
4366  else
4367  {
4368  TimeADT result;
4369 
4370  if (tm2time(&tm, fsec, &result) != 0)
4372  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4373  errmsg("time out of range"))));
4374 
4375  AdjustTimeForTypmod(&result, *typmod);
4376 
4377  *typid = TIMEOID;
4378  return TimeADTGetDatum(result);
4379  }
4380  }
4381  else
4382  {
4384  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4385  errmsg("datetime format is not dated and not timed"))));
4386  }
4387 
4388 on_error:
4389  return (Datum) 0;
4390 }
void DateTimeParseError(int dterr, const char *str, const char *datatype)
Definition: datetime.c:3723
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:610
#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:2076
#define IS_VALID_DATE(d)
Definition: timestamp.h:190
void AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
Definition: timestamp.c:392
#define ERROR
Definition: elog.h:43
#define TimestampTzGetDatum(X)
Definition: timestamp.h:32
int DecodeTimezone(char *str, int *tzp)
Definition: datetime.c:2862
int tm_mday
Definition: pgtime.h:30
int tm_mon
Definition: pgtime.h:31
unsigned int uint32
Definition: c.h:374
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:1212
uintptr_t Datum
Definition: postgres.h:367
#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:144
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:1880
#define Assert(condition)
Definition: c.h:745
int tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result)
Definition: date.c:1267
char * text_to_cstring(const text *t)
Definition: varlena.c:205
int tm_year
Definition: pgtime.h:32
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163
Definition: date.h:27
void AdjustTimeForTypmod(TimeADT *time, int32 typmod)
Definition: date.c:1498
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:4412
#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 1885 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().

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

◆ str_tolower()

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

Definition at line 1637 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().

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

◆ str_toupper()

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

Definition at line 1761 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().

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