Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b99ccd2

Browse files
committed
Call pg_newlocale_from_collation() also with default collation
Previously, callers of pg_newlocale_from_collation() did not call it if the collation was DEFAULT_COLLATION_OID and instead proceeded with a pg_locale_t of 0. Instead, now we call it anyway and have it return 0 if the default collation was passed. It already did this, so we just have to adjust the callers. This simplifies all the call sites and also makes future enhancements easier. After discussion and testing, the previous comment in pg_locale.c about avoiding this for performance reasons may have been mistaken since it was testing a very different patch version way back when. Reviewed-by: Julien Rouhaud <rjuju123@gmail.com> Discussion: https://www.postgresql.org/message-id/ed3baa81-7fac-7788-cc12-41e3f7917e34@enterprisedb.com
1 parent b2a76bb commit b99ccd2

File tree

8 files changed

+135
-132
lines changed

8 files changed

+135
-132
lines changed

src/backend/access/hash/hashfunc.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ hashtext(PG_FUNCTION_ARGS)
278278
errmsg("could not determine which collation to use for string hashing"),
279279
errhint("Use the COLLATE clause to set the collation explicitly.")));
280280

281-
if (!lc_collate_is_c(collid) && collid != DEFAULT_COLLATION_OID)
281+
if (!lc_collate_is_c(collid))
282282
mylocale = pg_newlocale_from_collation(collid);
283283

284284
if (!mylocale || mylocale->deterministic)
@@ -334,7 +334,7 @@ hashtextextended(PG_FUNCTION_ARGS)
334334
errmsg("could not determine which collation to use for string hashing"),
335335
errhint("Use the COLLATE clause to set the collation explicitly.")));
336336

337-
if (!lc_collate_is_c(collid) && collid != DEFAULT_COLLATION_OID)
337+
if (!lc_collate_is_c(collid))
338338
mylocale = pg_newlocale_from_collation(collid);
339339

340340
if (!mylocale || mylocale->deterministic)

src/backend/regex/regc_pg_locale.c

+18-22
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,18 @@ static const unsigned char pg_char_properties[128] = {
231231
void
232232
pg_set_regex_collation(Oid collation)
233233
{
234+
if (!OidIsValid(collation))
235+
{
236+
/*
237+
* This typically means that the parser could not resolve a
238+
* conflict of implicit collations, so report it that way.
239+
*/
240+
ereport(ERROR,
241+
(errcode(ERRCODE_INDETERMINATE_COLLATION),
242+
errmsg("could not determine which collation to use for regular expression"),
243+
errhint("Use the COLLATE clause to set the collation explicitly.")));
244+
}
245+
234246
if (lc_ctype_is_c(collation))
235247
{
236248
/* C/POSIX collations use this path regardless of database encoding */
@@ -240,28 +252,12 @@ pg_set_regex_collation(Oid collation)
240252
}
241253
else
242254
{
243-
if (collation == DEFAULT_COLLATION_OID)
244-
pg_regex_locale = 0;
245-
else if (OidIsValid(collation))
246-
{
247-
/*
248-
* NB: pg_newlocale_from_collation will fail if not HAVE_LOCALE_T;
249-
* the case of pg_regex_locale != 0 but not HAVE_LOCALE_T does not
250-
* have to be considered below.
251-
*/
252-
pg_regex_locale = pg_newlocale_from_collation(collation);
253-
}
254-
else
255-
{
256-
/*
257-
* This typically means that the parser could not resolve a
258-
* conflict of implicit collations, so report it that way.
259-
*/
260-
ereport(ERROR,
261-
(errcode(ERRCODE_INDETERMINATE_COLLATION),
262-
errmsg("could not determine which collation to use for regular expression"),
263-
errhint("Use the COLLATE clause to set the collation explicitly.")));
264-
}
255+
/*
256+
* NB: pg_newlocale_from_collation will fail if not HAVE_LOCALE_T;
257+
* the case of pg_regex_locale != 0 but not HAVE_LOCALE_T does not
258+
* have to be considered below.
259+
*/
260+
pg_regex_locale = pg_newlocale_from_collation(collation);
265261

266262
if (pg_regex_locale && !pg_regex_locale->deterministic)
267263
ereport(ERROR,

src/backend/utils/adt/formatting.c

+45-51
Original file line numberDiff line numberDiff line change
@@ -1641,31 +1641,29 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
16411641
if (!buff)
16421642
return NULL;
16431643

1644+
if (!OidIsValid(collid))
1645+
{
1646+
/*
1647+
* This typically means that the parser could not resolve a
1648+
* conflict of implicit collations, so report it that way.
1649+
*/
1650+
ereport(ERROR,
1651+
(errcode(ERRCODE_INDETERMINATE_COLLATION),
1652+
errmsg("could not determine which collation to use for %s function",
1653+
"lower()"),
1654+
errhint("Use the COLLATE clause to set the collation explicitly.")));
1655+
}
1656+
16441657
/* C/POSIX collations use this path regardless of database encoding */
16451658
if (lc_ctype_is_c(collid))
16461659
{
16471660
result = asc_tolower(buff, nbytes);
16481661
}
16491662
else
16501663
{
1651-
pg_locale_t mylocale = 0;
1664+
pg_locale_t mylocale;
16521665

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-
}
1666+
mylocale = pg_newlocale_from_collation(collid);
16691667

16701668
#ifdef USE_ICU
16711669
if (mylocale && mylocale->provider == COLLPROVIDER_ICU)
@@ -1765,31 +1763,29 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
17651763
if (!buff)
17661764
return NULL;
17671765

1766+
if (!OidIsValid(collid))
1767+
{
1768+
/*
1769+
* This typically means that the parser could not resolve a
1770+
* conflict of implicit collations, so report it that way.
1771+
*/
1772+
ereport(ERROR,
1773+
(errcode(ERRCODE_INDETERMINATE_COLLATION),
1774+
errmsg("could not determine which collation to use for %s function",
1775+
"upper()"),
1776+
errhint("Use the COLLATE clause to set the collation explicitly.")));
1777+
}
1778+
17681779
/* C/POSIX collations use this path regardless of database encoding */
17691780
if (lc_ctype_is_c(collid))
17701781
{
17711782
result = asc_toupper(buff, nbytes);
17721783
}
17731784
else
17741785
{
1775-
pg_locale_t mylocale = 0;
1786+
pg_locale_t mylocale;
17761787

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-
}
1788+
mylocale = pg_newlocale_from_collation(collid);
17931789

17941790
#ifdef USE_ICU
17951791
if (mylocale && mylocale->provider == COLLPROVIDER_ICU)
@@ -1890,31 +1886,29 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
18901886
if (!buff)
18911887
return NULL;
18921888

1889+
if (!OidIsValid(collid))
1890+
{
1891+
/*
1892+
* This typically means that the parser could not resolve a
1893+
* conflict of implicit collations, so report it that way.
1894+
*/
1895+
ereport(ERROR,
1896+
(errcode(ERRCODE_INDETERMINATE_COLLATION),
1897+
errmsg("could not determine which collation to use for %s function",
1898+
"initcap()"),
1899+
errhint("Use the COLLATE clause to set the collation explicitly.")));
1900+
}
1901+
18931902
/* C/POSIX collations use this path regardless of database encoding */
18941903
if (lc_ctype_is_c(collid))
18951904
{
18961905
result = asc_initcap(buff, nbytes);
18971906
}
18981907
else
18991908
{
1900-
pg_locale_t mylocale = 0;
1909+
pg_locale_t mylocale;
19011910

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-
}
1911+
mylocale = pg_newlocale_from_collation(collid);
19181912

19191913
#ifdef USE_ICU
19201914
if (mylocale && mylocale->provider == COLLPROVIDER_ICU)

src/backend/utils/adt/like.c

+18-19
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ SB_lower_char(unsigned char c, pg_locale_t locale, bool locale_is_c)
150150
static inline int
151151
GenericMatchText(const char *s, int slen, const char *p, int plen, Oid collation)
152152
{
153-
if (collation && !lc_ctype_is_c(collation) && collation != DEFAULT_COLLATION_OID)
153+
if (collation && !lc_ctype_is_c(collation))
154154
{
155155
pg_locale_t locale = pg_newlocale_from_collation(collation);
156156

@@ -178,28 +178,27 @@ Generic_Text_IC_like(text *str, text *pat, Oid collation)
178178
pg_locale_t locale = 0;
179179
bool locale_is_c = false;
180180

181+
if (!OidIsValid(collation))
182+
{
183+
/*
184+
* This typically means that the parser could not resolve a
185+
* conflict of implicit collations, so report it that way.
186+
*/
187+
ereport(ERROR,
188+
(errcode(ERRCODE_INDETERMINATE_COLLATION),
189+
errmsg("could not determine which collation to use for ILIKE"),
190+
errhint("Use the COLLATE clause to set the collation explicitly.")));
191+
}
192+
181193
if (lc_ctype_is_c(collation))
182194
locale_is_c = true;
183-
else if (collation != DEFAULT_COLLATION_OID)
184-
{
185-
if (!OidIsValid(collation))
186-
{
187-
/*
188-
* This typically means that the parser could not resolve a
189-
* conflict of implicit collations, so report it that way.
190-
*/
191-
ereport(ERROR,
192-
(errcode(ERRCODE_INDETERMINATE_COLLATION),
193-
errmsg("could not determine which collation to use for ILIKE"),
194-
errhint("Use the COLLATE clause to set the collation explicitly.")));
195-
}
195+
else
196196
locale = pg_newlocale_from_collation(collation);
197197

198-
if (locale && !locale->deterministic)
199-
ereport(ERROR,
200-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
201-
errmsg("nondeterministic collations are not supported for ILIKE")));
202-
}
198+
if (locale && !locale->deterministic)
199+
ereport(ERROR,
200+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
201+
errmsg("nondeterministic collations are not supported for ILIKE")));
203202

204203
/*
205204
* For efficiency reasons, in the single byte case we don't call lower()

src/backend/utils/adt/like_support.c

+13-14
Original file line numberDiff line numberDiff line change
@@ -1012,24 +1012,23 @@ like_fixed_prefix(Const *patt_const, bool case_insensitive, Oid collation,
10121012
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
10131013
errmsg("case insensitive matching not supported on type bytea")));
10141014

1015+
if (!OidIsValid(collation))
1016+
{
1017+
/*
1018+
* This typically means that the parser could not resolve a
1019+
* conflict of implicit collations, so report it that way.
1020+
*/
1021+
ereport(ERROR,
1022+
(errcode(ERRCODE_INDETERMINATE_COLLATION),
1023+
errmsg("could not determine which collation to use for ILIKE"),
1024+
errhint("Use the COLLATE clause to set the collation explicitly.")));
1025+
}
1026+
10151027
/* If case-insensitive, we need locale info */
10161028
if (lc_ctype_is_c(collation))
10171029
locale_is_c = true;
1018-
else if (collation != DEFAULT_COLLATION_OID)
1019-
{
1020-
if (!OidIsValid(collation))
1021-
{
1022-
/*
1023-
* This typically means that the parser could not resolve a
1024-
* conflict of implicit collations, so report it that way.
1025-
*/
1026-
ereport(ERROR,
1027-
(errcode(ERRCODE_INDETERMINATE_COLLATION),
1028-
errmsg("could not determine which collation to use for ILIKE"),
1029-
errhint("Use the COLLATE clause to set the collation explicitly.")));
1030-
}
1030+
else
10311031
locale = pg_newlocale_from_collation(collation);
1032-
}
10331032
}
10341033

10351034
if (typeid != BYTEAOID)

src/backend/utils/adt/pg_locale.c

-3
Original file line numberDiff line numberDiff line change
@@ -1454,8 +1454,6 @@ report_newlocale_failure(const char *localename)
14541454
*
14551455
* As a special optimization, the default/database collation returns 0.
14561456
* Callers should then revert to the non-locale_t-enabled code path.
1457-
* In fact, they shouldn't call this function at all when they are dealing
1458-
* with the default locale. That can save quite a bit in hotspots.
14591457
* Also, callers should avoid calling this before going down a C/POSIX
14601458
* fastpath, because such a fastpath should work even on platforms without
14611459
* locale_t support in the C library.
@@ -1472,7 +1470,6 @@ pg_newlocale_from_collation(Oid collid)
14721470
/* Callers must pass a valid OID */
14731471
Assert(OidIsValid(collid));
14741472

1475-
/* Return 0 for "default" collation, just in case caller forgets */
14761473
if (collid == DEFAULT_COLLATION_OID)
14771474
return (pg_locale_t) 0;
14781475

src/backend/utils/adt/varchar.c

+18-8
Original file line numberDiff line numberDiff line change
@@ -743,15 +743,20 @@ bpchareq(PG_FUNCTION_ARGS)
743743
len2;
744744
bool result;
745745
Oid collid = PG_GET_COLLATION();
746+
bool locale_is_c = false;
747+
pg_locale_t mylocale = 0;
746748

747749
check_collation_set(collid);
748750

749751
len1 = bcTruelen(arg1);
750752
len2 = bcTruelen(arg2);
751753

752-
if (lc_collate_is_c(collid) ||
753-
collid == DEFAULT_COLLATION_OID ||
754-
pg_newlocale_from_collation(collid)->deterministic)
754+
if (lc_collate_is_c(collid))
755+
locale_is_c = true;
756+
else
757+
mylocale = pg_newlocale_from_collation(collid);
758+
759+
if (locale_is_c || !mylocale || mylocale->deterministic)
755760
{
756761
/*
757762
* Since we only care about equality or not-equality, we can avoid all
@@ -783,15 +788,20 @@ bpcharne(PG_FUNCTION_ARGS)
783788
len2;
784789
bool result;
785790
Oid collid = PG_GET_COLLATION();
791+
bool locale_is_c = false;
792+
pg_locale_t mylocale = 0;
786793

787794
check_collation_set(collid);
788795

789796
len1 = bcTruelen(arg1);
790797
len2 = bcTruelen(arg2);
791798

792-
if (lc_collate_is_c(collid) ||
793-
collid == DEFAULT_COLLATION_OID ||
794-
pg_newlocale_from_collation(collid)->deterministic)
799+
if (lc_collate_is_c(collid))
800+
locale_is_c = true;
801+
else
802+
mylocale = pg_newlocale_from_collation(collid);
803+
804+
if (locale_is_c || !mylocale || mylocale->deterministic)
795805
{
796806
/*
797807
* Since we only care about equality or not-equality, we can avoid all
@@ -996,7 +1006,7 @@ hashbpchar(PG_FUNCTION_ARGS)
9961006
keydata = VARDATA_ANY(key);
9971007
keylen = bcTruelen(key);
9981008

999-
if (!lc_collate_is_c(collid) && collid != DEFAULT_COLLATION_OID)
1009+
if (!lc_collate_is_c(collid))
10001010
mylocale = pg_newlocale_from_collation(collid);
10011011

10021012
if (!mylocale || mylocale->deterministic)
@@ -1056,7 +1066,7 @@ hashbpcharextended(PG_FUNCTION_ARGS)
10561066
keydata = VARDATA_ANY(key);
10571067
keylen = bcTruelen(key);
10581068

1059-
if (!lc_collate_is_c(collid) && collid != DEFAULT_COLLATION_OID)
1069+
if (!lc_collate_is_c(collid))
10601070
mylocale = pg_newlocale_from_collation(collid);
10611071

10621072
if (!mylocale || mylocale->deterministic)

0 commit comments

Comments
 (0)