From 26d2c5dc8dc24febee8c3dd472407d7bbdcc245d Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Thu, 12 Mar 2015 15:29:58 +0100 Subject: [PATCH] Fix memory leaks in GIN index vacuum. Per bug #12850 by Walter Nordmann. Backpatch to 9.4 where the leak was introduced. --- src/backend/access/gin/ginvacuum.c | 34 ++++++++++++++++++------------ 1 file changed, 20 insertions(+), 14 deletions(-) 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); } } } -- 2.40.0