diff --git a/src/backend/statistics/mvdistinct.c b/src/backend/statistics/mvdistinct.c index 4f8f578a22f..4dc6e1b1768 100644 --- a/src/backend/statistics/mvdistinct.c +++ b/src/backend/statistics/mvdistinct.c @@ -28,6 +28,7 @@ #include "catalog/pg_statistic_ext.h" #include "catalog/pg_statistic_ext_data.h" #include "statistics/extended_stats_internal.h" +#include "utils/memutils.h" #include "utils/syscache.h" #include "utils/typcache.h" #include "varatt.h" @@ -89,6 +90,7 @@ statext_ndistinct_build(double totalrows, StatsBuildData *data) int itemcnt; int numattrs = data->nattnums; int numcombs = num_combinations(numattrs); + MemoryContext cxt; result = palloc(offsetof(MVNDistinct, items) + numcombs * sizeof(MVNDistinctItem)); @@ -96,6 +98,10 @@ statext_ndistinct_build(double totalrows, StatsBuildData *data) result->type = STATS_NDISTINCT_TYPE_BASIC; result->nitems = numcombs; + cxt = AllocSetContextCreate(CurrentMemoryContext, + "ndistinct_for_combination cxt", + ALLOCSET_DEFAULT_SIZES); + itemcnt = 0; for (k = 2; k <= numattrs; k++) { @@ -109,6 +115,7 @@ statext_ndistinct_build(double totalrows, StatsBuildData *data) { MVNDistinctItem *item = &result->items[itemcnt]; int j; + MemoryContext oldcxt; item->attributes = palloc_array(AttrNumber, k); item->nattributes = k; @@ -121,8 +128,12 @@ statext_ndistinct_build(double totalrows, StatsBuildData *data) Assert(AttributeNumberIsValid(item->attributes[j])); } + /* release memory used by ndistinct calculation */ + oldcxt = MemoryContextSwitchTo(cxt); item->ndistinct = ndistinct_for_combination(totalrows, data, k, combination); + MemoryContextSwitchTo(oldcxt); + MemoryContextReset(cxt); itemcnt++; Assert(itemcnt <= result->nitems); @@ -131,6 +142,8 @@ statext_ndistinct_build(double totalrows, StatsBuildData *data) generator_free(generator); } + MemoryContextDelete(cxt); + /* must consume exactly the whole output array */ Assert(itemcnt == result->nitems);