aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/executor/execQual.c5
-rw-r--r--src/backend/executor/tstoreReceiver.c9
-rw-r--r--src/backend/utils/sort/tuplestore.c29
-rw-r--r--src/pl/plperl/plperl.c6
-rw-r--r--src/pl/plpgsql/src/pl_exec.c32
-rw-r--r--src/pl/plpgsql/src/plpgsql.h3
6 files changed, 56 insertions, 28 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index 06fe23e6376..57536cd0938 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.183.2.6 2007/02/06 17:35:34 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.183.2.7 2009/12/29 17:41:35 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1522,9 +1522,7 @@ ExecMakeTableFunctionResult(ExprState *funcexpr,
tuple = heap_form_tuple(tupdesc, &result, &fcinfo.isnull);
}
- oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
tuplestore_puttuple(tupstore, tuple);
- MemoryContextSwitchTo(oldcontext);
/*
* Are we done?
@@ -1576,6 +1574,7 @@ no_function_result:
memset(nullflags, true, natts * sizeof(bool));
tuple = heap_form_tuple(expectedDesc, nulldatums, nullflags);
MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
+
tuplestore_puttuple(tupstore, tuple);
}
}
diff --git a/src/backend/executor/tstoreReceiver.c b/src/backend/executor/tstoreReceiver.c
index fb2aa843fd6..e99ed15a955 100644
--- a/src/backend/executor/tstoreReceiver.c
+++ b/src/backend/executor/tstoreReceiver.c
@@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/tstoreReceiver.c,v 1.15.2.1 2008/12/01 17:06:41 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/tstoreReceiver.c,v 1.15.2.2 2009/12/29 17:41:35 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -95,11 +95,8 @@ static void
tstoreReceiveSlot_notoast(TupleTableSlot *slot, DestReceiver *self)
{
TStoreState *myState = (TStoreState *) self;
- MemoryContext oldcxt = MemoryContextSwitchTo(myState->cxt);
tuplestore_puttuple(myState->tstore, ExecFetchSlotTuple(slot));
-
- MemoryContextSwitchTo(oldcxt);
}
/*
@@ -116,7 +113,6 @@ tstoreReceiveSlot_detoast(TupleTableSlot *slot, DestReceiver *self)
int nfree;
int i;
HeapTuple tuple;
- MemoryContext oldcxt;
/* Make sure the tuple is fully deconstructed */
slot_getallattrs(slot);
@@ -126,6 +122,7 @@ tstoreReceiveSlot_detoast(TupleTableSlot *slot, DestReceiver *self)
* myState->outvalues[] (but we can re-use the slot's isnull array).
* Also, remember the fetched values to free afterwards.
*/
+
nfree = 0;
for (i = 0; i < natts; i++)
{
@@ -151,9 +148,7 @@ tstoreReceiveSlot_detoast(TupleTableSlot *slot, DestReceiver *self)
*/
tuple = heap_form_tuple(typeinfo,
myState->outvalues, slot->tts_isnull);
- oldcxt = MemoryContextSwitchTo(myState->cxt);
tuplestore_puttuple(myState->tstore, tuple);
- MemoryContextSwitchTo(oldcxt);
heap_freetuple(tuple);
/* And release any temporary detoasted values */
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);
}
/*
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 1fe7a6a7b2c..bbe1424e692 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -33,7 +33,7 @@
* ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.94.2.13 2009/09/28 17:30:04 adunstan Exp $
+ * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.94.2.14 2009/12/29 17:41:35 heikki Exp $
*
**********************************************************************/
@@ -1825,11 +1825,9 @@ plperl_return_next(SV *sv)
tuple = heap_form_tuple(current_call_data->ret_tdesc, &ret, &isNull);
}
- /* Make sure to store the tuple in a long-lived memory context */
- MemoryContextSwitchTo(rsi->econtext->ecxt_per_query_memory);
tuplestore_puttuple(current_call_data->tuple_store, tuple);
- MemoryContextSwitchTo(old_cxt);
+ MemoryContextSwitchTo(old_cxt);
MemoryContextReset(current_call_data->tmp_cxt);
}
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 4744097b2be..1b400341af4 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.154.2.8 2009/02/27 10:27:53 heikki Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.154.2.9 2009/12/29 17:41:35 heikki Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -2001,11 +2001,7 @@ exec_stmt_return_next(PLpgSQL_execstate *estate,
if (HeapTupleIsValid(tuple))
{
- MemoryContext oldcxt;
-
- oldcxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
tuplestore_puttuple(estate->tuple_store, tuple);
- MemoryContextSwitchTo(oldcxt);
if (free_tuple)
heap_freetuple(tuple);
@@ -2019,6 +2015,7 @@ exec_init_tuple_store(PLpgSQL_execstate *estate)
{
ReturnSetInfo *rsi = estate->rsi;
MemoryContext oldcxt;
+ ResourceOwner oldowner;
/*
* Check caller can handle a set result in the way we want
@@ -2030,10 +2027,20 @@ exec_init_tuple_store(PLpgSQL_execstate *estate)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("set-valued function called in context that cannot accept a set")));
- estate->tuple_store_cxt = rsi->econtext->ecxt_per_query_memory;
-
+ /*
+ * Switch to the right memory context and resource owner for storing
+ * the tuplestore for return set. If we're within a subtransaction opened
+ * for an exception-block, for example, we must still create the
+ * tuplestore in the resource owner that was active when this function was
+ * entered, and not in the subtransaction resource owner.
+ */
oldcxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
+ oldowner = CurrentResourceOwner;
+ CurrentResourceOwner = estate->tuple_store_owner;
+
estate->tuple_store = tuplestore_begin_heap(true, false, work_mem);
+
+ CurrentResourceOwner = oldowner;
MemoryContextSwitchTo(oldcxt);
estate->rettupdesc = rsi->expectedDesc;
@@ -2145,7 +2152,16 @@ plpgsql_estate_setup(PLpgSQL_execstate *estate,
estate->exitlabel = NULL;
estate->tuple_store = NULL;
- estate->tuple_store_cxt = NULL;
+ if (rsi)
+ {
+ estate->tuple_store_cxt = rsi->econtext->ecxt_per_query_memory;
+ estate->tuple_store_owner = CurrentResourceOwner;
+ }
+ else
+ {
+ estate->tuple_store_cxt = NULL;
+ estate->tuple_store_owner = NULL;
+ }
estate->rsi = rsi;
estate->trig_nargs = 0;
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index fef84a77dcb..5a47b9d629d 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.65.2.4 2008/10/09 16:35:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.65.2.5 2009/12/29 17:41:35 heikki Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -625,6 +625,7 @@ typedef struct
Tuplestorestate *tuple_store; /* SRFs accumulate results here */
MemoryContext tuple_store_cxt;
+ ResourceOwner tuple_store_owner;
ReturnSetInfo *rsi;
int trig_nargs;