}
/* i is now the last required entry. */
- MemoryContextSwitchTo(oldCtx);
+ MemoryContextSwitchTo(so->keyCtx);
key->nrequired = i + 1;
key->nadditional = key->nentries - key->nrequired;
}
else
{
+ MemoryContextSwitchTo(so->keyCtx);
+
key->nrequired = 1;
key->nadditional = 0;
key->requiredEntries = palloc(1 * sizeof(GinScanEntry));
key->requiredEntries[0] = key->scanEntry[0];
}
+ MemoryContextSwitchTo(oldCtx);
}
static void
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);