aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/gin
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2016-03-13 16:44:10 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2016-03-13 16:44:10 -0400
commitaa9c4e71ceccf239a268b0b6611a9260d0f94a74 (patch)
treea558a2f563a2c4c97d8b6751ec971724593f95a9 /src/backend/access/gin
parenta7915f114aad83c93548dffe6c947e7f441fc175 (diff)
downloadpostgresql-aa9c4e71ceccf239a268b0b6611a9260d0f94a74.tar.gz
postgresql-aa9c4e71ceccf239a268b0b6611a9260d0f94a74.zip
Fix memory leak in repeated GIN index searches.
Commit d88976cfa1302e8d removed this code from ginFreeScanKeys(): - if (entry->list) - pfree(entry->list); evidently in the belief that that ItemPointer array is allocated in the keyCtx and so would be reclaimed by the following MemoryContextReset. Unfortunately, it isn't and it won't. It'd likely be a good idea for that to become so, but as a simple and back-patchable fix in the meantime, restore this code to ginFreeScanKeys(). Also, add a similar pfree to where startScanEntry() is about to zero out entry->list. I am not sure if there are any code paths where this change prevents a leak today, but it seems like cheap future-proofing. In passing, make the initial allocation of so->entries[] use palloc not palloc0. The code doesn't depend on unused entries being zero; if it did, the array-enlargement code in ginFillScanEntry() would be wrong. So using palloc0 initially can only serve to confuse readers about what the invariant is. Per report from Felipe de Jesús Molina Bravo, via Jaime Casanova in <CAJGNTeMR1ndMU2Thpr8GPDUfiHTV7idELJRFusA5UXUGY1y-eA@mail.gmail.com>
Diffstat (limited to 'src/backend/access/gin')
-rw-r--r--src/backend/access/gin/ginget.c2
-rw-r--r--src/backend/access/gin/ginscan.c4
2 files changed, 5 insertions, 1 deletions
diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c
index 54b2db88a68..ee2eb633468 100644
--- a/src/backend/access/gin/ginget.c
+++ b/src/backend/access/gin/ginget.c
@@ -302,6 +302,8 @@ restartScanEntry:
entry->buffer = InvalidBuffer;
ItemPointerSetMin(&entry->curItem);
entry->offset = InvalidOffsetNumber;
+ if (entry->list)
+ pfree(entry->list);
entry->list = NULL;
entry->nlist = 0;
entry->matchBitmap = NULL;
diff --git a/src/backend/access/gin/ginscan.c b/src/backend/access/gin/ginscan.c
index ac3a92b1981..81e4a6ac6ae 100644
--- a/src/backend/access/gin/ginscan.c
+++ b/src/backend/access/gin/ginscan.c
@@ -249,6 +249,8 @@ ginFreeScanKeys(GinScanOpaque so)
if (entry->buffer != InvalidBuffer)
ReleaseBuffer(entry->buffer);
+ if (entry->list)
+ pfree(entry->list);
if (entry->matchIterator)
tbm_end_iterate(entry->matchIterator);
if (entry->matchBitmap)
@@ -288,7 +290,7 @@ ginNewScanKey(IndexScanDesc scan)
so->totalentries = 0;
so->allocentries = 32;
so->entries = (GinScanEntry *)
- palloc0(so->allocentries * sizeof(GinScanEntry));
+ palloc(so->allocentries * sizeof(GinScanEntry));
so->isVoidRes = false;