From: Heikki Linnakangas Date: Thu, 12 Mar 2015 14:29:58 +0000 (+0100) Subject: Fix memory leaks in GIN index vacuum. X-Git-Tag: REL9_5_ALPHA1~626 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=26d2c5dc8dc24febee8c3dd472407d7bbdcc245d;p=postgresql Fix memory leaks in GIN index vacuum. Per bug #12850 by Walter Nordmann. Backpatch to 9.4 where the leak was introduced. --- diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c index 9e76df3612..eba572b0d8 100644 --- a/src/backend/access/gin/ginvacuum.c +++ b/src/backend/access/gin/ginvacuum.c @@ -432,27 +432,32 @@ ginVacuumEntryPage(GinVacuumState *gvs, Buffer buffer, BlockNumber *roots, uint3 else if (GinGetNPosting(itup) > 0) { int nitems; - ItemPointer uncompressed; + ItemPointer items_orig; + bool free_items_orig; + ItemPointer items; - /* - * Vacuum posting list with proper function for compressed and - * uncompressed format. - */ + /* Get list of item pointers from the tuple. */ if (GinItupIsCompressed(itup)) - uncompressed = ginPostingListDecode((GinPostingList *) GinGetPosting(itup), &nitems); + { + items_orig = ginPostingListDecode((GinPostingList *) GinGetPosting(itup), &nitems); + free_items_orig = true; + } else { - uncompressed = (ItemPointer) GinGetPosting(itup); + items_orig = (ItemPointer) GinGetPosting(itup); nitems = GinGetNPosting(itup); + free_items_orig = false; } - uncompressed = ginVacuumItemPointers(gvs, uncompressed, nitems, - &nitems); - if (uncompressed) + /* Remove any items from the list that need to be vacuumed. */ + items = ginVacuumItemPointers(gvs, items_orig, nitems, &nitems); + + if (free_items_orig) + pfree(items_orig); + + /* If any item pointers were removed, recreate the tuple. */ + if (items) { - /* - * Some ItemPointers were deleted, recreate tuple. - */ OffsetNumber attnum; Datum key; GinNullCategory category; @@ -461,7 +466,7 @@ ginVacuumEntryPage(GinVacuumState *gvs, Buffer buffer, BlockNumber *roots, uint3 if (nitems > 0) { - plist = ginCompressPostingList(uncompressed, nitems, GinMaxItemSize, NULL); + plist = ginCompressPostingList(items, nitems, GinMaxItemSize, NULL); plistsize = SizeOfGinPostingList(plist); } else @@ -500,6 +505,7 @@ ginVacuumEntryPage(GinVacuumState *gvs, Buffer buffer, BlockNumber *roots, uint3 RelationGetRelationName(gvs->index)); pfree(itup); + pfree(items); } } }