Commit a844c299 authored by Tom Lane's avatar Tom Lane

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.
parent ab8c84db
...@@ -620,8 +620,6 @@ transformRelOptions(Datum oldOptions, List *defList, char *namspace, ...@@ -620,8 +620,6 @@ transformRelOptions(Datum oldOptions, List *defList, char *namspace,
int noldoptions; int noldoptions;
int i; int i;
Assert(ARR_ELEMTYPE(array) == TEXTOID);
deconstruct_array(array, TEXTOID, -1, false, 'i', deconstruct_array(array, TEXTOID, -1, false, 'i',
&oldoptions, NULL, &noldoptions); &oldoptions, NULL, &noldoptions);
...@@ -777,8 +775,6 @@ untransformRelOptions(Datum options) ...@@ -777,8 +775,6 @@ untransformRelOptions(Datum options)
array = DatumGetArrayTypeP(options); array = DatumGetArrayTypeP(options);
Assert(ARR_ELEMTYPE(array) == TEXTOID);
deconstruct_array(array, TEXTOID, -1, false, 'i', deconstruct_array(array, TEXTOID, -1, false, 'i',
&optiondatums, NULL, &noptions); &optiondatums, NULL, &noptions);
...@@ -912,14 +908,10 @@ parseRelOptions(Datum options, bool validate, relopt_kind kind, ...@@ -912,14 +908,10 @@ parseRelOptions(Datum options, bool validate, relopt_kind kind,
/* Done if no options */ /* Done if no options */
if (PointerIsValid(DatumGetPointer(options))) if (PointerIsValid(DatumGetPointer(options)))
{ {
ArrayType *array; ArrayType *array = DatumGetArrayTypeP(options);
Datum *optiondatums; Datum *optiondatums;
int noptions; int noptions;
array = DatumGetArrayTypeP(options);
Assert(ARR_ELEMTYPE(array) == TEXTOID);
deconstruct_array(array, TEXTOID, -1, false, 'i', deconstruct_array(array, TEXTOID, -1, false, 'i',
&optiondatums, NULL, &noptions); &optiondatums, NULL, &noptions);
...@@ -959,6 +951,11 @@ parseRelOptions(Datum options, bool validate, relopt_kind kind, ...@@ -959,6 +951,11 @@ parseRelOptions(Datum options, bool validate, relopt_kind kind,
errmsg("unrecognized parameter \"%s\"", s))); 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; *numrelopts = numoptions;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment