aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/sort/tuplestore.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/sort/tuplestore.c')
-rw-r--r--src/backend/utils/sort/tuplestore.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/src/backend/utils/sort/tuplestore.c b/src/backend/utils/sort/tuplestore.c
index fd283e4959d..bad943bcab0 100644
--- a/src/backend/utils/sort/tuplestore.c
+++ b/src/backend/utils/sort/tuplestore.c
@@ -36,7 +36,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/sort/tuplestore.c,v 1.23.2.2 2007/08/02 17:48:57 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/sort/tuplestore.c,v 1.23.2.3 2009/12/29 17:41:35 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -46,6 +46,7 @@
#include "access/heapam.h"
#include "storage/buffile.h"
#include "utils/memutils.h"
+#include "utils/resowner.h"
#include "utils/tuplestore.h"
@@ -70,6 +71,8 @@ struct Tuplestorestate
bool interXact; /* keep open through transactions? */
long availMem; /* remaining memory available, in bytes */
BufFile *myfile; /* underlying file, or NULL if none */
+ MemoryContext context; /* memory context for holding tuples */
+ ResourceOwner resowner; /* resowner for holding temp files */
/*
* These function pointers decouple the routines that must know what kind
@@ -219,6 +222,8 @@ tuplestore_begin_common(bool randomAccess, bool interXact, int maxKBytes)
state->interXact = interXact;
state->availMem = maxKBytes * 1024L;
state->myfile = NULL;
+ state->context = CurrentMemoryContext;
+ state->resowner = CurrentResourceOwner;
state->memtupcount = 0;
state->memtupsize = 1024; /* initial guess */
@@ -244,9 +249,9 @@ tuplestore_begin_common(bool randomAccess, bool interXact, int maxKBytes)
*
* interXact: if true, the files used for on-disk storage persist beyond the
* end of the current transaction. NOTE: It's the caller's responsibility to
- * create such a tuplestore in a memory context that will also survive
- * transaction boundaries, and to ensure the tuplestore is closed when it's
- * no longer wanted.
+ * create such a tuplestore in a memory context and resource owner that will
+ * also survive transaction boundaries, and to ensure the tuplestore is closed
+ * when it's no longer wanted.
*
* maxKBytes: how much data to store in memory (any data beyond this
* amount is paged to disk). When in doubt, use work_mem.
@@ -309,6 +314,9 @@ tuplestore_ateof(Tuplestorestate *state)
void
tuplestore_puttuple(Tuplestorestate *state, void *tuple)
{
+ MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
+ ResourceOwner oldowner;
+
/*
* Copy the tuple. (Must do this even in WRITEFILE case.)
*/
@@ -339,12 +347,21 @@ tuplestore_puttuple(Tuplestorestate *state, void *tuple)
* Done if we still fit in available memory.
*/
if (!LACKMEM(state))
+ {
+ MemoryContextSwitchTo(oldcxt);
return;
+ }
/*
* Nope; time to switch to tape-based operation.
*/
- state->myfile = BufFileCreateTemp(state->interXact);
+
+ /* associate the file with the store's resource owner */
+ oldowner = CurrentResourceOwner;
+ CurrentResourceOwner = state->resowner;
+ state->myfile = BufFileCreateTemp(state->interXact);
+ CurrentResourceOwner = oldowner;
+
state->status = TSS_WRITEFILE;
dumptuples(state);
break;
@@ -370,6 +387,8 @@ tuplestore_puttuple(Tuplestorestate *state, void *tuple)
elog(ERROR, "invalid tuplestore state");
break;
}
+
+ MemoryContextSwitchTo(oldcxt);
}
/*