aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/indexam.sgml3
-rw-r--r--src/backend/access/spgist/spgscan.c35
2 files changed, 30 insertions, 8 deletions
diff --git a/doc/src/sgml/indexam.sgml b/doc/src/sgml/indexam.sgml
index beb99d1831a..d758a4987dc 100644
--- a/doc/src/sgml/indexam.sgml
+++ b/doc/src/sgml/indexam.sgml
@@ -614,7 +614,8 @@ amendscan (IndexScanDesc scan);
</programlisting>
End a scan and release resources. The <literal>scan</literal> struct itself
should not be freed, but any locks or pins taken internally by the
- access method must be released.
+ access method must be released, as well as any other memory allocated
+ by <function>ambeginscan</function> and other scan-related functions.
</para>
<para>
diff --git a/src/backend/access/spgist/spgscan.c b/src/backend/access/spgist/spgscan.c
index a63fde2c8af..c883ae95e48 100644
--- a/src/backend/access/spgist/spgscan.c
+++ b/src/backend/access/spgist/spgscan.c
@@ -294,10 +294,18 @@ spgbeginscan(Relation rel, int keysz, int orderbysz)
/* Set up indexTupDesc and xs_hitupdesc in case it's an index-only scan */
so->indexTupDesc = scan->xs_hitupdesc = RelationGetDescr(rel);
+ /* Allocate various arrays needed for order-by scans */
if (scan->numberOfOrderBys > 0)
{
- so->zeroDistances = palloc(sizeof(double) * scan->numberOfOrderBys);
- so->infDistances = palloc(sizeof(double) * scan->numberOfOrderBys);
+ /* This will be filled in spgrescan, but allocate the space here */
+ so->orderByTypes = (Oid *)
+ palloc(sizeof(Oid) * scan->numberOfOrderBys);
+
+ /* These arrays have constant contents, so we can fill them now */
+ so->zeroDistances = (double *)
+ palloc(sizeof(double) * scan->numberOfOrderBys);
+ so->infDistances = (double *)
+ palloc(sizeof(double) * scan->numberOfOrderBys);
for (i = 0; i < scan->numberOfOrderBys; i++)
{
@@ -305,9 +313,12 @@ spgbeginscan(Relation rel, int keysz, int orderbysz)
so->infDistances[i] = get_float8_infinity();
}
- scan->xs_orderbyvals = palloc0(sizeof(Datum) * scan->numberOfOrderBys);
- scan->xs_orderbynulls = palloc(sizeof(bool) * scan->numberOfOrderBys);
- memset(scan->xs_orderbynulls, true, sizeof(bool) * scan->numberOfOrderBys);
+ scan->xs_orderbyvals = (Datum *)
+ palloc0(sizeof(Datum) * scan->numberOfOrderBys);
+ scan->xs_orderbynulls = (bool *)
+ palloc(sizeof(bool) * scan->numberOfOrderBys);
+ memset(scan->xs_orderbynulls, true,
+ sizeof(bool) * scan->numberOfOrderBys);
}
fmgr_info_copy(&so->innerConsistentFn,
@@ -336,6 +347,7 @@ spgrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
memmove(scan->keyData, scankey,
scan->numberOfKeys * sizeof(ScanKeyData));
+ /* initialize order-by data if needed */
if (orderbys && scan->numberOfOrderBys > 0)
{
int i;
@@ -343,8 +355,6 @@ spgrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
memmove(scan->orderByData, orderbys,
scan->numberOfOrderBys * sizeof(ScanKeyData));
- so->orderByTypes = (Oid *) palloc(sizeof(Oid) * scan->numberOfOrderBys);
-
for (i = 0; i < scan->numberOfOrderBys; i++)
{
ScanKey skey = &scan->orderByData[i];
@@ -380,11 +390,22 @@ spgendscan(IndexScanDesc scan)
MemoryContextDelete(so->tempCxt);
MemoryContextDelete(so->traversalCxt);
+ if (so->keyData)
+ pfree(so->keyData);
+
+ if (so->state.deadTupleStorage)
+ pfree(so->state.deadTupleStorage);
+
if (scan->numberOfOrderBys > 0)
{
+ pfree(so->orderByTypes);
pfree(so->zeroDistances);
pfree(so->infDistances);
+ pfree(scan->xs_orderbyvals);
+ pfree(scan->xs_orderbynulls);
}
+
+ pfree(so);
}
/*