mirror of
https://github.com/postgres/postgres.git
synced 2026-06-13 10:40:09 -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 *ca = NameStr(*DatumGetName(a));
|
||||||
char *cb = NameStr(*DatumGetName(b));
|
char *cb = NameStr(*DatumGetName(b));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Catalogs only use deterministic collations, so ignore column collation
|
||||||
|
* and use fast path.
|
||||||
|
*/
|
||||||
return strncmp(ca, cb, NAMEDATALEN) == 0;
|
return strncmp(ca, cb, NAMEDATALEN) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -213,6 +217,10 @@ namehashfast(Datum datum)
|
||||||
{
|
{
|
||||||
char *key = NameStr(*DatumGetName(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));
|
return hash_bytes((unsigned char *) key, strlen(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -244,17 +252,20 @@ static bool
|
||||||
texteqfast(Datum a, Datum b)
|
texteqfast(Datum a, Datum b)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The use of DEFAULT_COLLATION_OID is fairly arbitrary here. We just
|
* Catalogs only use deterministic collations, so ignore column collation
|
||||||
* want to take the fast "deterministic" path in texteq().
|
* 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
|
static uint32
|
||||||
texthashfast(Datum datum)
|
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
|
static bool
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue