diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2014-08-13 11:35:51 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2014-08-13 11:35:51 -0400 |
commit | a844c29966d7c0cd6a457e9324f175349bb12df0 (patch) | |
tree | 29728762901f6667dcb035ca6fefe29ada3f6abc /src | |
parent | ab8c84db2f7af008151b848cf1d6a4672a39eecd (diff) | |
download | postgresql-a844c29966d7c0cd6a457e9324f175349bb12df0.tar.gz postgresql-a844c29966d7c0cd6a457e9324f175349bb12df0.zip |
Prevent memory leaks in parseRelOptions().
parseRelOptions() tended to leak memory in the caller's context. Most
of the time this doesn't really matter since the caller's context is
at most query-lifespan, and the function won't be invoked very many times.
However, when testing with CLOBBER_CACHE_RECURSIVELY, the same relcache
entry can get rebuilt a *lot* of times in one query, leading to significant
intraquery memory bloat if it has any reloptions. Noted while
investigating a related report from Tomas Vondra.
In passing, get rid of some Asserts that are redundant with the one
done by deconstruct_array().
As with other patches to avoid leaks in CLOBBER_CACHE testing, it doesn't
really seem worth back-patching this.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/access/common/reloptions.c | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index c7ad6f96f86..e0b81b9eb51 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -620,8 +620,6 @@ transformRelOptions(Datum oldOptions, List *defList, char *namspace, int noldoptions; int i; - Assert(ARR_ELEMTYPE(array) == TEXTOID); - deconstruct_array(array, TEXTOID, -1, false, 'i', &oldoptions, NULL, &noldoptions); @@ -777,8 +775,6 @@ untransformRelOptions(Datum options) array = DatumGetArrayTypeP(options); - Assert(ARR_ELEMTYPE(array) == TEXTOID); - deconstruct_array(array, TEXTOID, -1, false, 'i', &optiondatums, NULL, &noptions); @@ -912,14 +908,10 @@ parseRelOptions(Datum options, bool validate, relopt_kind kind, /* Done if no options */ if (PointerIsValid(DatumGetPointer(options))) { - ArrayType *array; + ArrayType *array = DatumGetArrayTypeP(options); Datum *optiondatums; int noptions; - array = DatumGetArrayTypeP(options); - - Assert(ARR_ELEMTYPE(array) == TEXTOID); - deconstruct_array(array, TEXTOID, -1, false, 'i', &optiondatums, NULL, &noptions); @@ -959,6 +951,11 @@ parseRelOptions(Datum options, bool validate, relopt_kind kind, errmsg("unrecognized parameter \"%s\"", s))); } } + + /* It's worth avoiding memory leaks in this function */ + pfree(optiondatums); + if (((void *) array) != DatumGetPointer(options)) + pfree(array); } *numrelopts = numoptions; |