diff options
Diffstat (limited to 'src/backend/utils/sort/tuplestore.c')
-rw-r--r-- | src/backend/utils/sort/tuplestore.c | 29 |
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); } /* |