ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
+ so->keyCtx = AllocSetContextCreate(CurrentMemoryContext,
+ "Gin scan key context",
+ ALLOCSET_DEFAULT_MINSIZE,
+ ALLOCSET_DEFAULT_INITSIZE,
+ ALLOCSET_DEFAULT_MAXSIZE);
initGinState(&so->ginstate, scan->indexRelation);
scan->opaque = so;
}
}
+/*
+ * Release current scan keys, if any.
+ */
void
ginFreeScanKeys(GinScanOpaque so)
{
if (so->keys == NULL)
return;
- for (i = 0; i < so->nkeys; i++)
- {
- GinScanKey key = so->keys + i;
-
- pfree(key->scanEntry);
- pfree(key->entryRes);
- if (key->requiredEntries)
- pfree(key->requiredEntries);
- if (key->additionalEntries)
- pfree(key->additionalEntries);
- }
-
- pfree(so->keys);
- so->keys = NULL;
- so->nkeys = 0;
-
for (i = 0; i < so->totalentries; i++)
{
GinScanEntry entry = so->entries[i];
if (entry->buffer != InvalidBuffer)
ReleaseBuffer(entry->buffer);
- if (entry->list)
- pfree(entry->list);
if (entry->matchIterator)
tbm_end_iterate(entry->matchIterator);
if (entry->matchBitmap)
tbm_free(entry->matchBitmap);
- pfree(entry);
}
- pfree(so->entries);
+ MemoryContextResetAndDeleteChildren(so->keyCtx);
+
+ so->keys = NULL;
+ so->nkeys = 0;
so->entries = NULL;
so->totalentries = 0;
}
GinScanOpaque so = (GinScanOpaque) scan->opaque;
int i;
bool hasNullQuery = false;
+ MemoryContext oldCtx;
+
+ /*
+ * Allocate all the scan key information in the key context. (If
+ * extractQuery leaks anything there, it won't be reset until the end of
+ * scan or rescan, but that's OK.)
+ */
+ oldCtx = MemoryContextSwitchTo(so->keyCtx);
/* if no scan keys provided, allocate extra EVERYTHING GinScanKey */
so->keys = (GinScanKey)
RelationGetRelationName(scan->indexRelation))));
}
+ MemoryContextSwitchTo(oldCtx);
+
pgstat_count_index_scan(scan->indexRelation);
}
ginFreeScanKeys(so);
MemoryContextDelete(so->tempCtx);
+ MemoryContextDelete(so->keyCtx);
pfree(so);