summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/prepare.c13
-rw-r--r--src/backend/executor/execQual.c5
-rw-r--r--src/backend/executor/tstoreReceiver.c5
-rw-r--r--src/backend/utils/mmgr/portalmem.c12
-rw-r--r--src/backend/utils/sort/tuplestore.c30
-rw-r--r--src/pl/plperl/plperl.c6
-rw-r--r--src/pl/plpgsql/src/pl_exec.c35
-rw-r--r--src/pl/plpgsql/src/plpgsql.h3
8 files changed, 65 insertions, 44 deletions
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 7dcd3cb5a85..f0914096789 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -10,7 +10,7 @@
* Copyright (c) 2002-2008, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.80.2.1 2008/04/02 18:32:00 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.80.2.2 2009/12/29 17:41:18 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -759,6 +759,9 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
*/
tupstore = tuplestore_begin_heap(true, false, work_mem);
+ /* generate junk in short-term context */
+ MemoryContextSwitchTo(oldcontext);
+
/* hash table might be uninitialized */
if (prepared_queries)
{
@@ -772,9 +775,6 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
Datum values[5];
bool nulls[5];
- /* generate junk in short-term context */
- MemoryContextSwitchTo(oldcontext);
-
MemSet(nulls, 0, sizeof(nulls));
values[0] = DirectFunctionCall1(textin,
@@ -792,9 +792,6 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
values[4] = BoolGetDatum(prep_stmt->from_sql);
tuple = heap_form_tuple(tupdesc, values, nulls);
-
- /* switch to appropriate context while storing the tuple */
- MemoryContextSwitchTo(per_query_ctx);
tuplestore_puttuple(tupstore, tuple);
}
}
@@ -802,8 +799,6 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
/* clean up and return the tuplestore */
tuplestore_donestoring(tupstore);
- MemoryContextSwitchTo(oldcontext);
-
rsinfo->returnMode = SFRM_Materialize;
rsinfo->setResult = tupstore;
rsinfo->setDesc = tupdesc;
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index 27e764c19a9..f26a4437da3 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.226.2.1 2008/11/15 20:53:40 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.226.2.2 2009/12/29 17:41:18 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1656,9 +1656,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?
@@ -1710,6 +1708,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 197aa3c0774..9645365ac1f 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.19.2.1 2008/12/01 17:06:27 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/tstoreReceiver.c,v 1.19.2.2 2009/12/29 17:41:18 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -95,11 +95,8 @@ static void
tstoreReceiveSlot_notoast(TupleTableSlot *slot, DestReceiver *self)
{
TStoreState *myState = (TStoreState *) self;
- MemoryContext oldcxt = MemoryContextSwitchTo(myState->cxt);
tuplestore_puttupleslot(myState->tstore, slot);
-
- MemoryContextSwitchTo(oldcxt);
}
/*
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index b977396fb42..217c6b1234b 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.106.2.1 2008/04/02 18:32:00 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.106.2.2 2009/12/29 17:41:18 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -911,6 +911,9 @@ pg_cursor(PG_FUNCTION_ARGS)
*/
tupstore = tuplestore_begin_heap(true, false, work_mem);
+ /* generate junk in short-term context */
+ MemoryContextSwitchTo(oldcontext);
+
hash_seq_init(&hash_seq, PortalHashTable);
while ((hentry = hash_seq_search(&hash_seq)) != NULL)
{
@@ -923,9 +926,6 @@ pg_cursor(PG_FUNCTION_ARGS)
if (!portal->visible)
continue;
- /* generate junk in short-term context */
- MemoryContextSwitchTo(oldcontext);
-
MemSet(nulls, 0, sizeof(nulls));
values[0] = DirectFunctionCall1(textin, CStringGetDatum(portal->name));
@@ -941,16 +941,12 @@ pg_cursor(PG_FUNCTION_ARGS)
tuple = heap_form_tuple(tupdesc, values, nulls);
- /* switch to appropriate context while storing the tuple */
- MemoryContextSwitchTo(per_query_ctx);
tuplestore_puttuple(tupstore, tuple);
}
/* clean up and return the tuplestore */
tuplestore_donestoring(tupstore);
- MemoryContextSwitchTo(oldcontext);
-
rsinfo->returnMode = SFRM_Materialize;
rsinfo->setResult = tupstore;
rsinfo->setDesc = tupdesc;
diff --git a/src/backend/utils/sort/tuplestore.c b/src/backend/utils/sort/tuplestore.c
index e297579674a..81106e513a4 100644
--- a/src/backend/utils/sort/tuplestore.c
+++ b/src/backend/utils/sort/tuplestore.c
@@ -38,7 +38,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/sort/tuplestore.c,v 1.36 2008/01/01 19:45:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/sort/tuplestore.c,v 1.36.2.1 2009/12/29 17:41:18 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -50,6 +50,7 @@
#include "executor/executor.h"
#include "storage/buffile.h"
#include "utils/memutils.h"
+#include "utils/resowner.h"
#include "utils/tuplestore.h"
@@ -74,6 +75,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
@@ -225,6 +228,8 @@ tuplestore_begin_common(int eflags, 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 */
@@ -250,9 +255,9 @@ tuplestore_begin_common(int eflags, 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.
@@ -353,6 +358,7 @@ tuplestore_puttupleslot(Tuplestorestate *state,
TupleTableSlot *slot)
{
MinimalTuple tuple;
+ MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
/*
* Form a MinimalTuple in working memory
@@ -361,6 +367,8 @@ tuplestore_puttupleslot(Tuplestorestate *state,
USEMEM(state, GetMemoryChunkSpace(tuple));
tuplestore_puttuple_common(state, (void *) tuple);
+
+ MemoryContextSwitchTo(oldcxt);
}
/*
@@ -372,17 +380,23 @@ tuplestore_puttupleslot(Tuplestorestate *state,
void
tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple)
{
+ MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
+
/*
* Copy the tuple. (Must do this even in WRITEFILE case.)
*/
tuple = COPYTUP(state, tuple);
tuplestore_puttuple_common(state, (void *) tuple);
+
+ MemoryContextSwitchTo(oldcxt);
}
static void
tuplestore_puttuple_common(Tuplestorestate *state, void *tuple)
{
+ ResourceOwner oldowner;
+
switch (state->status)
{
case TSS_INMEM:
@@ -429,7 +443,15 @@ tuplestore_puttuple_common(Tuplestorestate *state, void *tuple)
* the temp file(s) are created in suitable temp tablespaces.
*/
PrepareTempTablespaces();
+
+ /* 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;
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 0a6f8f78616..6a6fcd0db53 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -1,7 +1,7 @@
/**********************************************************************
* plperl.c - perl as a procedural language for PostgreSQL
*
- * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.136.2.5 2009/11/29 21:02:28 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.136.2.6 2009/12/29 17:41:18 heikki Exp $
*
**********************************************************************/
@@ -1995,11 +1995,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 49f6fb4c84d..b487f656725 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.202.2.5 2009/04/02 01:16:17 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.202.2.6 2009/12/29 17:41:18 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2132,11 +2132,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);
@@ -2174,21 +2170,18 @@ exec_stmt_return_query(PLpgSQL_execstate *estate,
while (true)
{
- MemoryContext old_cxt;
int i;
SPI_cursor_fetch(portal, true, 50);
if (SPI_processed == 0)
break;
- old_cxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
for (i = 0; i < SPI_processed; i++)
{
HeapTuple tuple = SPI_tuptable->vals[i];
tuplestore_puttuple(estate->tuple_store, tuple);
}
- MemoryContextSwitchTo(old_cxt);
SPI_freetuptable(SPI_tuptable);
}
@@ -2204,6 +2197,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
@@ -2215,10 +2209,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;
@@ -2330,7 +2334,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 9736befcc8f..b954f88f247 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.95.2.1 2008/10/09 16:35:13 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.95.2.2 2009/12/29 17:41:18 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -622,6 +622,7 @@ typedef struct
Tuplestorestate *tuple_store; /* SRFs accumulate results here */
MemoryContext tuple_store_cxt;
+ ResourceOwner tuple_store_owner;
ReturnSetInfo *rsi;
int trig_nargs;