mirror of
https://github.com/postgres/postgres.git
synced 2026-05-27 03:42:28 -04:00
catcache.c: use C_COLLATION_OID for texteqfast/texthashfast.
The problem report was about setting GUCs in the startup packet for a physical replication connection. Setting the GUC required an ACL check, which performed a lookup on pg_parameter_acl.parname. The catalog cache was hardwired to use DEFAULT_COLLATION_OID for texteqfast() and texthashfast(), but the database default collation was uninitialized because it's a physical walsender and never connects to a database. In versions 18 and later, this resulted in a NULL pointer dereference, while in version 17 it resulted in an ERROR. As the comments stated, using DEFAULT_COLLATION_OID was arbitrary anyway: if the collation actually mattered, it should have used the column's actual collation. (In the catalog, some text columns are the default collation and some are "C".) Fix by using C_COLLATION_OID, which doesn't require any initialization and is always available. When any deterministic collation will do, it's best to consistently use the simplest and fastest one, so this is a good idea anyway. Another problem was raised in the thread, which this commit doesn't fix (see second discussion link). Reported-by: Andrey Borodin <x4mmm@yandex-team.ru> Discussion: https://postgr.es/m/D18AD72A-5004-4EF8-AF80-10732AF677FA@yandex-team.ru Discussion: https://postgr.es/m/4524ed61a015d3496fc008644dcb999bb31916a7.camel%40j-davis.com Backpatch-through: 17
This commit is contained in:
parent
e471dc5912
commit
dbf217c1c7
1 changed files with 16 additions and 5 deletions
21
src/backend/utils/cache/catcache.c
vendored
21
src/backend/utils/cache/catcache.c
vendored
|
|
@ -205,6 +205,10 @@ nameeqfast(Datum a, Datum b)
|
|||
char *ca = NameStr(*DatumGetName(a));
|
||||
char *cb = NameStr(*DatumGetName(b));
|
||||
|
||||
/*
|
||||
* Catalogs only use deterministic collations, so ignore column collation
|
||||
* and use fast path.
|
||||
*/
|
||||
return strncmp(ca, cb, NAMEDATALEN) == 0;
|
||||
}
|
||||
|
||||
|
|
@ -213,6 +217,10 @@ namehashfast(Datum datum)
|
|||
{
|
||||
char *key = NameStr(*DatumGetName(datum));
|
||||
|
||||
/*
|
||||
* Catalogs only use deterministic collations, so ignore column collation
|
||||
* and use fast path.
|
||||
*/
|
||||
return hash_bytes((unsigned char *) key, strlen(key));
|
||||
}
|
||||
|
||||
|
|
@ -244,17 +252,20 @@ static bool
|
|||
texteqfast(Datum a, Datum b)
|
||||
{
|
||||
/*
|
||||
* The use of DEFAULT_COLLATION_OID is fairly arbitrary here. We just
|
||||
* want to take the fast "deterministic" path in texteq().
|
||||
* Catalogs only use deterministic collations, so ignore column collation
|
||||
* and use "C" locale for efficiency.
|
||||
*/
|
||||
return DatumGetBool(DirectFunctionCall2Coll(texteq, DEFAULT_COLLATION_OID, a, b));
|
||||
return DatumGetBool(DirectFunctionCall2Coll(texteq, C_COLLATION_OID, a, b));
|
||||
}
|
||||
|
||||
static uint32
|
||||
texthashfast(Datum datum)
|
||||
{
|
||||
/* analogously here as in texteqfast() */
|
||||
return DatumGetInt32(DirectFunctionCall1Coll(hashtext, DEFAULT_COLLATION_OID, datum));
|
||||
/*
|
||||
* Catalogs only use deterministic collations, so ignore column collation
|
||||
* and use "C" locale for efficiency.
|
||||
*/
|
||||
return DatumGetInt32(DirectFunctionCall1Coll(hashtext, C_COLLATION_OID, datum));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
|||
Loading…
Reference in a new issue