mirror of
https://github.com/postgres/postgres.git
synced 2025-06-22 02:52:08 +03:00
Fix another ancient memory-leak bug in relcache.c.
CheckConstraintFetch() leaked a cstring in the caller's context for each CHECK constraint expression it copied into the relcache. Ordinarily that isn't problematic, but it can be during CLOBBER_CACHE testing because so many reloads can happen during a single query; so complicate the code slightly to allow freeing the cstring after use. Per testing on buildfarm member barnacle. This is exactly like the leak fixed in AttrDefaultFetch() by commit078b2ed291
. (Yes, this time I did look for other instances of the same coding pattern :-(.) Like that patch, no back-patch, since it seems unlikely that there's any problem except under very artificial test conditions. BTW, it strikes me that both of these places would require further work comparable to commitab8c84db2f
, if we ever supported defaults or check constraints on system catalogs: they both assume they are copying into an empty relcache data structure, and that conceivably wouldn't be the case during recursive reloading of a system catalog. This does not seem worth worrying about for the moment, since there is no near-term prospect of supporting any such thing. So I'll just note the possibility for the archives' sake.
This commit is contained in:
12
src/backend/utils/cache/relcache.c
vendored
12
src/backend/utils/cache/relcache.c
vendored
@ -3552,8 +3552,6 @@ CheckConstraintFetch(Relation relation)
|
|||||||
SysScanDesc conscan;
|
SysScanDesc conscan;
|
||||||
ScanKeyData skey[1];
|
ScanKeyData skey[1];
|
||||||
HeapTuple htup;
|
HeapTuple htup;
|
||||||
Datum val;
|
|
||||||
bool isnull;
|
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
|
||||||
ScanKeyInit(&skey[0],
|
ScanKeyInit(&skey[0],
|
||||||
@ -3568,6 +3566,9 @@ CheckConstraintFetch(Relation relation)
|
|||||||
while (HeapTupleIsValid(htup = systable_getnext(conscan)))
|
while (HeapTupleIsValid(htup = systable_getnext(conscan)))
|
||||||
{
|
{
|
||||||
Form_pg_constraint conform = (Form_pg_constraint) GETSTRUCT(htup);
|
Form_pg_constraint conform = (Form_pg_constraint) GETSTRUCT(htup);
|
||||||
|
Datum val;
|
||||||
|
bool isnull;
|
||||||
|
char *s;
|
||||||
|
|
||||||
/* We want check constraints only */
|
/* We want check constraints only */
|
||||||
if (conform->contype != CONSTRAINT_CHECK)
|
if (conform->contype != CONSTRAINT_CHECK)
|
||||||
@ -3590,8 +3591,11 @@ CheckConstraintFetch(Relation relation)
|
|||||||
elog(ERROR, "null conbin for rel %s",
|
elog(ERROR, "null conbin for rel %s",
|
||||||
RelationGetRelationName(relation));
|
RelationGetRelationName(relation));
|
||||||
|
|
||||||
check[found].ccbin = MemoryContextStrdup(CacheMemoryContext,
|
/* detoast and convert to cstring in caller's context */
|
||||||
TextDatumGetCString(val));
|
s = TextDatumGetCString(val);
|
||||||
|
check[found].ccbin = MemoryContextStrdup(CacheMemoryContext, s);
|
||||||
|
pfree(s);
|
||||||
|
|
||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user