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, struct Node *escontext)
 
bool datetime_format_has_tz (const char *fmt_str)
 

Function Documentation

◆ asc_initcap()

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

Definition at line 2177 of file formatting.c.

2178 {
2179  char *result;
2180  char *p;
2181  int wasalnum = false;
2182 
2183  if (!buff)
2184  return NULL;
2185 
2186  result = pnstrdup(buff, nbytes);
2187 
2188  for (p = result; *p; p++)
2189  {
2190  char c;
2191 
2192  if (wasalnum)
2193  *p = c = pg_ascii_tolower((unsigned char) *p);
2194  else
2195  *p = c = pg_ascii_toupper((unsigned char) *p);
2196  /* we don't trust isalnum() here */
2197  wasalnum = ((c >= 'A' && c <= 'Z') ||
2198  (c >= 'a' && c <= 'z') ||
2199  (c >= '0' && c <= '9'));
2200  }
2201 
2202  return result;
2203 }
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1694
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 2131 of file formatting.c.

2132 {
2133  char *result;
2134  char *p;
2135 
2136  if (!buff)
2137  return NULL;
2138 
2139  result = pnstrdup(buff, nbytes);
2140 
2141  for (p = result; *p; p++)
2142  *p = pg_ascii_tolower((unsigned char) *p);
2143 
2144  return result;
2145 }

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

2155 {
2156  char *result;
2157  char *p;
2158 
2159  if (!buff)
2160  return NULL;
2161 
2162  result = pnstrdup(buff, nbytes);
2163 
2164  for (p = result; *p; p++)
2165  *p = pg_ascii_toupper((unsigned char) *p);
2166 
2167  return result;
2168 }

References pg_ascii_toupper(), and pnstrdup().

Referenced by asc_toupper_z(), and str_toupper().

◆ datetime_format_has_tz()

bool datetime_format_has_tz ( const char *  fmt_str)

Definition at line 4591 of file formatting.c.

4592 {
4593  bool incache;
4594  int fmt_len = strlen(fmt_str);
4595  int result;
4596  FormatNode *format;
4597 
4598  if (fmt_len > DCH_CACHE_SIZE)
4599  {
4600  /*
4601  * Allocate new memory if format picture is bigger than static cache
4602  * and do not use cache (call parser always)
4603  */
4604  incache = false;
4605 
4606  format = (FormatNode *) palloc((fmt_len + 1) * sizeof(FormatNode));
4607 
4608  parse_format(format, fmt_str, DCH_keywords,
4609  DCH_suff, DCH_index, DCH_FLAG, NULL);
4610  }
4611  else
4612  {
4613  /*
4614  * Use cache buffers
4615  */
4616  DCHCacheEntry *ent = DCH_cache_fetch(fmt_str, false);
4617 
4618  incache = true;
4619  format = ent->format;
4620  }
4621 
4622  result = DCH_datetime_type(format);
4623 
4624  if (!incache)
4625  pfree(format);
4626 
4627  return result & DCH_ZONED;
4628 }
static const int DCH_index[KeyWord_INDEX_SIZE]
Definition: formatting.c:948
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:1328
#define DCH_FLAG
Definition: formatting.c:99
static const KeySuffix DCH_suff[]
Definition: formatting.c:568
#define DCH_CACHE_SIZE
Definition: formatting.c:360
#define DCH_ZONED
Definition: formatting.c:1028
static int DCH_datetime_type(FormatNode *node)
Definition: formatting.c:3949
static const KeyWord DCH_keywords[]
Definition: formatting.c:775
static DCHCacheEntry * DCH_cache_fetch(const char *str, bool std)
Definition: formatting.c:4127
void pfree(void *pointer)
Definition: mcxt.c:1508
void * palloc(Size size)
Definition: mcxt.c:1304
static char format
FormatNode format[DCH_CACHE_SIZE+1]
Definition: formatting.c:370

References DCH_cache_fetch(), DCH_CACHE_SIZE, DCH_datetime_type(), DCH_FLAG, DCH_index, DCH_keywords, DCH_suff, DCH_ZONED, DCHCacheEntry::format, format, palloc(), parse_format(), and pfree().

◆ parse_datetime()

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

Definition at line 4428 of file formatting.c.

4431 {
4432  struct pg_tm tm;
4433  struct fmt_tz ftz;
4434  fsec_t fsec;
4435  int fprec;
4436  uint32 flags;
4437 
4438  if (!do_to_timestamp(date_txt, fmt, collid, strict,
4439  &tm, &fsec, &ftz, &fprec, &flags, escontext))
4440  return (Datum) 0;
4441 
4442  *typmod = fprec ? fprec : -1; /* fractional part precision */
4443 
4444  if (flags & DCH_DATED)
4445  {
4446  if (flags & DCH_TIMED)
4447  {
4448  if (flags & DCH_ZONED)
4449  {
4450  TimestampTz result;
4451 
4452  if (ftz.has_tz)
4453  {
4454  *tz = ftz.gmtoffset;
4455  }
4456  else
4457  {
4458  /*
4459  * Time zone is present in format string, but not in input
4460  * string. Assuming do_to_timestamp() triggers no error
4461  * this should be possible only in non-strict case.
4462  */
4463  Assert(!strict);
4464 
4465  ereturn(escontext, (Datum) 0,
4466  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4467  errmsg("missing time zone in input string for type timestamptz")));
4468  }
4469 
4470  if (tm2timestamp(&tm, fsec, tz, &result) != 0)
4471  ereturn(escontext, (Datum) 0,
4472  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4473  errmsg("timestamptz out of range")));
4474 
4475  AdjustTimestampForTypmod(&result, *typmod, escontext);
4476 
4477  *typid = TIMESTAMPTZOID;
4478  return TimestampTzGetDatum(result);
4479  }
4480  else
4481  {
4482  Timestamp result;
4483 
4484  if (tm2timestamp(&tm, fsec, NULL, &result) != 0)
4485  ereturn(escontext, (Datum) 0,
4486  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4487  errmsg("timestamp out of range")));
4488 
4489  AdjustTimestampForTypmod(&result, *typmod, escontext);
4490 
4491  *typid = TIMESTAMPOID;
4492  return TimestampGetDatum(result);
4493  }
4494  }
4495  else
4496  {
4497  if (flags & DCH_ZONED)
4498  {
4499  ereturn(escontext, (Datum) 0,
4500  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4501  errmsg("datetime format is zoned but not timed")));
4502  }
4503  else
4504  {
4505  DateADT result;
4506 
4507  /* Prevent overflow in Julian-day routines */
4509  ereturn(escontext, (Datum) 0,
4510  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4511  errmsg("date out of range: \"%s\"",
4512  text_to_cstring(date_txt))));
4513 
4514  result = date2j(tm.tm_year, tm.tm_mon, tm.tm_mday) -
4516 
4517  /* Now check for just-out-of-range dates */
4518  if (!IS_VALID_DATE(result))
4519  ereturn(escontext, (Datum) 0,
4520  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4521  errmsg("date out of range: \"%s\"",
4522  text_to_cstring(date_txt))));
4523 
4524  *typid = DATEOID;
4525  return DateADTGetDatum(result);
4526  }
4527  }
4528  }
4529  else if (flags & DCH_TIMED)
4530  {
4531  if (flags & DCH_ZONED)
4532  {
4533  TimeTzADT *result = palloc(sizeof(TimeTzADT));
4534 
4535  if (ftz.has_tz)
4536  {
4537  *tz = ftz.gmtoffset;
4538  }
4539  else
4540  {
4541  /*
4542  * Time zone is present in format string, but not in input
4543  * string. Assuming do_to_timestamp() triggers no error this
4544  * should be possible only in non-strict case.
4545  */
4546  Assert(!strict);
4547 
4548  ereturn(escontext, (Datum) 0,
4549  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4550  errmsg("missing time zone in input string for type timetz")));
4551  }
4552 
4553  if (tm2timetz(&tm, fsec, *tz, result) != 0)
4554  ereturn(escontext, (Datum) 0,
4555  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4556  errmsg("timetz out of range")));
4557 
4558  AdjustTimeForTypmod(&result->time, *typmod);
4559 
4560  *typid = TIMETZOID;
4561  return TimeTzADTPGetDatum(result);
4562  }
4563  else
4564  {
4565  TimeADT result;
4566 
4567  if (tm2time(&tm, fsec, &result) != 0)
4568  ereturn(escontext, (Datum) 0,
4569  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4570  errmsg("time out of range")));
4571 
4572  AdjustTimeForTypmod(&result, *typmod);
4573 
4574  *typid = TIMEOID;
4575  return TimeADTGetDatum(result);
4576  }
4577  }
4578  else
4579  {
4580  ereturn(escontext, (Datum) 0,
4581  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4582  errmsg("datetime format is not dated and not timed")));
4583  }
4584 }
int date2j(int year, int month, int day)
Definition: datetime.c:286
bool AdjustTimestampForTypmod(Timestamp *time, int32 typmod, Node *escontext)
Definition: timestamp.c:366
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:1997
unsigned int uint32
Definition: c.h:493
Oid collid
int64 Timestamp
Definition: timestamp.h:38
int64 TimestampTz
Definition: timestamp.h:39
#define IS_VALID_DATE(d)
Definition: timestamp.h:262
int32 fsec_t
Definition: timestamp.h:41
#define IS_VALID_JULIAN(y, m, d)
Definition: timestamp.h:227
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:235
int tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result)
Definition: date.c:1416
int tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result)
Definition: date.c:2263
void AdjustTimeForTypmod(TimeADT *time, int32 typmod)
Definition: date.c:1645
static Datum DateADTGetDatum(DateADT X)
Definition: date.h:72
int32 DateADT
Definition: date.h:23
static Datum TimeTzADTPGetDatum(const TimeTzADT *X)
Definition: date.h:84
int64 TimeADT
Definition: date.h:25
static Datum TimeADTGetDatum(TimeADT X)
Definition: date.h:78
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ereturn(context, dummy_value,...)
Definition: elog.h:276
#define DCH_DATED
Definition: formatting.c:1026
static bool do_to_timestamp(text *date_txt, text *fmt, Oid collid, bool std, struct pg_tm *tm, fsec_t *fsec, struct fmt_tz *tz, int *fprec, uint32 *flags, Node *escontext)
Definition: formatting.c:4654
#define DCH_TIMED
Definition: formatting.c:1027
static void const char * fmt
Assert(fmt[strlen(fmt) - 1] !='\n')
static struct pg_tm tm
Definition: localtime.c:104
uintptr_t Datum
Definition: postgres.h:64
Definition: date.h:28
TimeADT time
Definition: date.h:29
int gmtoffset
Definition: formatting.c:437
Definition: pgtime.h:35
int tm_mday
Definition: pgtime.h:39
int tm_mon
Definition: pgtime.h:40
int tm_year
Definition: pgtime.h:41
static Datum TimestampTzGetDatum(TimestampTz X)
Definition: timestamp.h:52
static Datum TimestampGetDatum(Timestamp X)
Definition: timestamp.h:46
char * text_to_cstring(const text *t)
Definition: varlena.c:217

References AdjustTimeForTypmod(), AdjustTimestampForTypmod(), Assert(), collid, date2j(), DateADTGetDatum(), DCH_DATED, DCH_TIMED, DCH_ZONED, do_to_timestamp(), ereturn, errcode(), errmsg(), fmt, fmt_tz::gmtoffset, fmt_tz::has_tz, IS_VALID_DATE, IS_VALID_JULIAN, palloc(), POSTGRES_EPOCH_JDATE, text_to_cstring(), TimeTzADT::time, TimeADTGetDatum(), TimestampGetDatum(), TimestampTzGetDatum(), TimeTzADTPGetDatum(), tm, tm2time(), tm2timestamp(), tm2timetz(), pg_tm::tm_mday, pg_tm::tm_mon, and pg_tm::tm_year.

Referenced by executeDateTimeMethod().

◆ str_initcap()

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

Definition at line 1932 of file formatting.c.

1933 {
1934  char *result;
1935  int wasalnum = false;
1936 
1937  if (!buff)
1938  return NULL;
1939 
1940  if (!OidIsValid(collid))
1941  {
1942  /*
1943  * This typically means that the parser could not resolve a conflict
1944  * of implicit collations, so report it that way.
1945  */
1946  ereport(ERROR,
1947  (errcode(ERRCODE_INDETERMINATE_COLLATION),
1948  errmsg("could not determine which collation to use for %s function",
1949  "initcap()"),
1950  errhint("Use the COLLATE clause to set the collation explicitly.")));
1951  }
1952 
1953  /* C/POSIX collations use this path regardless of database encoding */
1954  if (lc_ctype_is_c(collid))
1955  {
1956  result = asc_initcap(buff, nbytes);
1957  }
1958  else
1959  {
1960  pg_locale_t mylocale;
1961 
1962  mylocale = pg_newlocale_from_collation(collid);
1963 
1964 #ifdef USE_ICU
1965  if (mylocale && mylocale->provider == COLLPROVIDER_ICU)
1966  {
1967  int32_t len_uchar,
1968  len_conv;
1969  UChar *buff_uchar;
1970  UChar *buff_conv;
1971 
1972  len_uchar = icu_to_uchar(&buff_uchar, buff, nbytes);
1973  len_conv = icu_convert_case(u_strToTitle_default_BI, mylocale,
1974  &buff_conv, buff_uchar, len_uchar);
1975  icu_from_uchar(&result, buff_conv, len_conv);
1976  pfree(buff_uchar);
1977  pfree(buff_conv);
1978  }
1979  else
1980 #endif
1981  if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
1982  {
1983  const unsigned char *src = (unsigned char *) buff;
1984  size_t srclen = nbytes;
1985  unsigned char *dst;
1986  size_t dstsize;
1987  int srcoff = 0;
1988  int dstoff = 0;
1989 
1991 
1992  /* overflow paranoia */
1993  if ((srclen + 1) > (INT_MAX / MAX_MULTIBYTE_CHAR_LEN))
1994  ereport(ERROR,
1995  (errcode(ERRCODE_OUT_OF_MEMORY),
1996  errmsg("out of memory")));
1997 
1998  /* result is at most srclen codepoints plus terminating NUL */
1999  dstsize = srclen * MAX_MULTIBYTE_CHAR_LEN + 1;
2000  dst = (unsigned char *) palloc(dstsize);
2001 
2002  while (srcoff < nbytes)
2003  {
2004  pg_wchar u1 = utf8_to_unicode(src + srcoff);
2005  pg_wchar u2;
2006  int u1len = unicode_utf8len(u1);
2007  int u2len;
2008 
2009  if (wasalnum)
2010  u2 = unicode_lowercase_simple(u1);
2011  else
2012  u2 = unicode_uppercase_simple(u1);
2013 
2014  u2len = unicode_utf8len(u2);
2015 
2016  Assert(dstoff + u2len + 1 <= dstsize);
2017 
2018  wasalnum = pg_u_isalnum(u2, true);
2019 
2020  unicode_to_utf8(u2, dst + dstoff);
2021  srcoff += u1len;
2022  dstoff += u2len;
2023  }
2024 
2025  Assert(dstoff + 1 <= dstsize);
2026  *(dst + dstoff) = '\0';
2027  dstoff++;
2028 
2029  /* allocate result buffer of the right size and free workspace */
2030  result = palloc(dstoff);
2031  memcpy(result, dst, dstoff);
2032  pfree(dst);
2033  }
2034  else
2035  {
2036  Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
2037 
2039  {
2040  wchar_t *workspace;
2041  size_t curr_char;
2042  size_t result_size;
2043 
2044  /* Overflow paranoia */
2045  if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
2046  ereport(ERROR,
2047  (errcode(ERRCODE_OUT_OF_MEMORY),
2048  errmsg("out of memory")));
2049 
2050  /* Output workspace cannot have more codes than input bytes */
2051  workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
2052 
2053  char2wchar(workspace, nbytes + 1, buff, nbytes, mylocale);
2054 
2055  for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
2056  {
2057  if (mylocale)
2058  {
2059  if (wasalnum)
2060  workspace[curr_char] = towlower_l(workspace[curr_char], mylocale->info.lt);
2061  else
2062  workspace[curr_char] = towupper_l(workspace[curr_char], mylocale->info.lt);
2063  wasalnum = iswalnum_l(workspace[curr_char], mylocale->info.lt);
2064  }
2065  else
2066  {
2067  if (wasalnum)
2068  workspace[curr_char] = towlower(workspace[curr_char]);
2069  else
2070  workspace[curr_char] = towupper(workspace[curr_char]);
2071  wasalnum = iswalnum(workspace[curr_char]);
2072  }
2073  }
2074 
2075  /*
2076  * Make result large enough; case change might change number
2077  * of bytes
2078  */
2079  result_size = curr_char * pg_database_encoding_max_length() + 1;
2080  result = palloc(result_size);
2081 
2082  wchar2char(result, workspace, result_size, mylocale);
2083  pfree(workspace);
2084  }
2085  else
2086  {
2087  char *p;
2088 
2089  result = pnstrdup(buff, nbytes);
2090 
2091  /*
2092  * Note: we assume that toupper_l()/tolower_l() will not be so
2093  * broken as to need guard tests. When using the default
2094  * collation, we apply the traditional Postgres behavior that
2095  * forces ASCII-style treatment of I/i, but in non-default
2096  * collations you get exactly what the collation says.
2097  */
2098  for (p = result; *p; p++)
2099  {
2100  if (mylocale)
2101  {
2102  if (wasalnum)
2103  *p = tolower_l((unsigned char) *p, mylocale->info.lt);
2104  else
2105  *p = toupper_l((unsigned char) *p, mylocale->info.lt);
2106  wasalnum = isalnum_l((unsigned char) *p, mylocale->info.lt);
2107  }
2108  else
2109  {
2110  if (wasalnum)
2111  *p = pg_tolower((unsigned char) *p);
2112  else
2113  *p = pg_toupper((unsigned char) *p);
2114  wasalnum = isalnum((unsigned char) *p);
2115  }
2116  }
2117  }
2118  }
2119  }
2120 
2121  return result;
2122 }
#define OidIsValid(objectId)
Definition: c.h:762
int errhint(const char *fmt,...)
Definition: elog.c:1319
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
char * asc_initcap(const char *buff, size_t nbytes)
Definition: formatting.c:2177
static pg_wchar utf8_to_unicode(const unsigned char *c)
Definition: mbprint.c:53
unsigned int pg_wchar
Definition: mbprint.c:31
int GetDatabaseEncoding(void)
Definition: mbutils.c:1261
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1546
size_t wchar2char(char *to, const wchar_t *from, size_t tolen, pg_locale_t locale)
Definition: pg_locale.c:3055
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition: pg_locale.c:1551
bool lc_ctype_is_c(Oid collation)
Definition: pg_locale.c:1384
size_t char2wchar(wchar_t *to, size_t tolen, const char *from, size_t fromlen, pg_locale_t locale)
Definition: pg_locale.c:3111
#define MAX_MULTIBYTE_CHAR_LEN
Definition: pg_wchar.h:33
@ PG_UTF8
Definition: pg_wchar.h:232
static unsigned char * unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
Definition: pg_wchar.h:575
static int unicode_utf8len(pg_wchar c)
Definition: pg_wchar.h:607
unsigned char pg_toupper(unsigned char ch)
Definition: pgstrcasecmp.c:105
unsigned char pg_tolower(unsigned char ch)
Definition: pgstrcasecmp.c:122
locale_t lt
Definition: pg_locale.h:83
union pg_locale_struct::@150 info
pg_wchar unicode_uppercase_simple(pg_wchar code)
Definition: unicode_case.c:44
pg_wchar unicode_lowercase_simple(pg_wchar code)
Definition: unicode_case.c:28
bool pg_u_isalnum(pg_wchar code, bool posix)
#define toupper_l
Definition: win32_port.h:426
#define iswalnum_l
Definition: win32_port.h:434
#define towupper_l
Definition: win32_port.h:428
#define towlower_l
Definition: win32_port.h:427
#define tolower_l
Definition: win32_port.h:425
#define isalnum_l
Definition: win32_port.h:433

References asc_initcap(), Assert(), char2wchar(), collid, ereport, errcode(), errhint(), errmsg(), ERROR, GetDatabaseEncoding(), pg_locale_struct::info, isalnum_l, iswalnum_l, lc_ctype_is_c(), pg_locale_struct::lt, MAX_MULTIBYTE_CHAR_LEN, OidIsValid, palloc(), pfree(), pg_database_encoding_max_length(), pg_newlocale_from_collation(), pg_tolower(), pg_toupper(), pg_u_isalnum(), PG_UTF8, pnstrdup(), pg_locale_struct::provider, tolower_l, toupper_l, towlower_l, towupper_l, unicode_lowercase_simple(), unicode_to_utf8(), unicode_uppercase_simple(), unicode_utf8len(), utf8_to_unicode(), 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 1636 of file formatting.c.

1637 {
1638  char *result;
1639 
1640  if (!buff)
1641  return NULL;
1642 
1643  if (!OidIsValid(collid))
1644  {
1645  /*
1646  * This typically means that the parser could not resolve a conflict
1647  * of implicit collations, so report it that way.
1648  */
1649  ereport(ERROR,
1650  (errcode(ERRCODE_INDETERMINATE_COLLATION),
1651  errmsg("could not determine which collation to use for %s function",
1652  "lower()"),
1653  errhint("Use the COLLATE clause to set the collation explicitly.")));
1654  }
1655 
1656  /* C/POSIX collations use this path regardless of database encoding */
1657  if (lc_ctype_is_c(collid))
1658  {
1659  result = asc_tolower(buff, nbytes);
1660  }
1661  else
1662  {
1663  pg_locale_t mylocale;
1664 
1665  mylocale = pg_newlocale_from_collation(collid);
1666 
1667 #ifdef USE_ICU
1668  if (mylocale && mylocale->provider == COLLPROVIDER_ICU)
1669  {
1670  int32_t len_uchar;
1671  int32_t len_conv;
1672  UChar *buff_uchar;
1673  UChar *buff_conv;
1674 
1675  len_uchar = icu_to_uchar(&buff_uchar, buff, nbytes);
1676  len_conv = icu_convert_case(u_strToLower, mylocale,
1677  &buff_conv, buff_uchar, len_uchar);
1678  icu_from_uchar(&result, buff_conv, len_conv);
1679  pfree(buff_uchar);
1680  pfree(buff_conv);
1681  }
1682  else
1683 #endif
1684  if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
1685  {
1686  const char *src = buff;
1687  size_t srclen = nbytes;
1688  size_t dstsize;
1689  char *dst;
1690  size_t needed;
1691 
1693 
1694  /* first try buffer of equal size plus terminating NUL */
1695  dstsize = srclen + 1;
1696  dst = palloc(dstsize);
1697 
1698  needed = unicode_strlower(dst, dstsize, src, srclen);
1699  if (needed + 1 > dstsize)
1700  {
1701  /* grow buffer if needed and retry */
1702  dstsize = needed + 1;
1703  dst = repalloc(dst, dstsize);
1704  needed = unicode_strlower(dst, dstsize, src, srclen);
1705  Assert(needed + 1 == dstsize);
1706  }
1707 
1708  Assert(dst[needed] == '\0');
1709  result = dst;
1710  }
1711  else
1712  {
1713  Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
1714 
1716  {
1717  wchar_t *workspace;
1718  size_t curr_char;
1719  size_t result_size;
1720 
1721  /* Overflow paranoia */
1722  if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
1723  ereport(ERROR,
1724  (errcode(ERRCODE_OUT_OF_MEMORY),
1725  errmsg("out of memory")));
1726 
1727  /* Output workspace cannot have more codes than input bytes */
1728  workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
1729 
1730  char2wchar(workspace, nbytes + 1, buff, nbytes, mylocale);
1731 
1732  for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
1733  {
1734  if (mylocale)
1735  workspace[curr_char] = towlower_l(workspace[curr_char], mylocale->info.lt);
1736  else
1737  workspace[curr_char] = towlower(workspace[curr_char]);
1738  }
1739 
1740  /*
1741  * Make result large enough; case change might change number
1742  * of bytes
1743  */
1744  result_size = curr_char * pg_database_encoding_max_length() + 1;
1745  result = palloc(result_size);
1746 
1747  wchar2char(result, workspace, result_size, mylocale);
1748  pfree(workspace);
1749  }
1750  else
1751  {
1752  char *p;
1753 
1754  result = pnstrdup(buff, nbytes);
1755 
1756  /*
1757  * Note: we assume that tolower_l() will not be so broken as
1758  * to need an isupper_l() guard test. When using the default
1759  * collation, we apply the traditional Postgres behavior that
1760  * forces ASCII-style treatment of I/i, but in non-default
1761  * collations you get exactly what the collation says.
1762  */
1763  for (p = result; *p; p++)
1764  {
1765  if (mylocale)
1766  *p = tolower_l((unsigned char) *p, mylocale->info.lt);
1767  else
1768  *p = pg_tolower((unsigned char) *p);
1769  }
1770  }
1771  }
1772  }
1773 
1774  return result;
1775 }
char * asc_tolower(const char *buff, size_t nbytes)
Definition: formatting.c:2131
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1528
size_t unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
Definition: unicode_case.c:68

References asc_tolower(), Assert(), char2wchar(), collid, ereport, errcode(), errhint(), errmsg(), ERROR, GetDatabaseEncoding(), pg_locale_struct::info, lc_ctype_is_c(), pg_locale_struct::lt, OidIsValid, palloc(), pfree(), pg_database_encoding_max_length(), pg_newlocale_from_collation(), pg_tolower(), PG_UTF8, pnstrdup(), pg_locale_struct::provider, repalloc(), tolower_l, towlower_l, unicode_strlower(), 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 1784 of file formatting.c.

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

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

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