summaryrefslogtreecommitdiff
path: root/src/pl
diff options
context:
space:
mode:
Diffstat (limited to 'src/pl')
-rw-r--r--src/pl/plperl/plperl.c10
-rw-r--r--src/pl/plpgsql/src/pl_exec.c38
-rw-r--r--src/pl/plpgsql/src/plpgsql.h3
3 files changed, 28 insertions, 23 deletions
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index f999495c87..4fe30bba27 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.155 2009/11/29 21:02:16 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.156 2009/12/29 17:40:59 heikki Exp $
*
**********************************************************************/
@@ -2107,11 +2107,7 @@ plperl_return_next(SV *sv)
tuple = plperl_build_tuple_result((HV *) SvRV(sv),
current_call_data->attinmeta);
-
- /* 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);
}
else
{
@@ -2141,14 +2137,12 @@ plperl_return_next(SV *sv)
isNull = true;
}
- /* Make sure to store the tuple in a long-lived memory context */
- MemoryContextSwitchTo(rsi->econtext->ecxt_per_query_memory);
tuplestore_putvalues(current_call_data->tuple_store,
current_call_data->ret_tdesc,
&ret, &isNull);
- 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 117da74eb0..823cdbea47 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.251 2009/11/09 00:26:55 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.252 2009/12/29 17:40:59 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2172,7 +2172,6 @@ exec_stmt_return_next(PLpgSQL_execstate *estate,
{
TupleDesc tupdesc;
int natts;
- MemoryContext oldcxt;
HeapTuple tuple = NULL;
bool free_tuple = false;
@@ -2212,10 +2211,8 @@ exec_stmt_return_next(PLpgSQL_execstate *estate,
tupdesc->attrs[0]->atttypmod,
isNull);
- oldcxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
tuplestore_putvalues(estate->tuple_store, tupdesc,
&retval, &isNull);
- MemoryContextSwitchTo(oldcxt);
}
break;
@@ -2285,10 +2282,8 @@ exec_stmt_return_next(PLpgSQL_execstate *estate,
tupdesc->attrs[0]->atttypmod,
isNull);
- oldcxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
tuplestore_putvalues(estate->tuple_store, tupdesc,
&retval, &isNull);
- MemoryContextSwitchTo(oldcxt);
exec_eval_cleanup(estate);
}
@@ -2301,9 +2296,7 @@ exec_stmt_return_next(PLpgSQL_execstate *estate,
if (HeapTupleIsValid(tuple))
{
- oldcxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
tuplestore_puttuple(estate->tuple_store, tuple);
- MemoryContextSwitchTo(oldcxt);
if (free_tuple)
heap_freetuple(tuple);
@@ -2353,14 +2346,12 @@ 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];
@@ -2372,7 +2363,6 @@ exec_stmt_return_query(PLpgSQL_execstate *estate,
heap_freetuple(tuple);
processed++;
}
- MemoryContextSwitchTo(old_cxt);
SPI_freetuptable(SPI_tuptable);
}
@@ -2394,6 +2384,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
@@ -2405,12 +2396,22 @@ 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(rsi->allowedModes & SFRM_Materialize_Random,
false, work_mem);
+
+ CurrentResourceOwner = oldowner;
MemoryContextSwitchTo(oldcxt);
estate->rettupdesc = rsi->expectedDesc;
@@ -2635,7 +2636,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->found_varno = func->found_varno;
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index 25d1c03699..b0813ba33e 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.125 2009/11/13 22:43:42 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.126 2009/12/29 17:40:59 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -701,6 +701,7 @@ typedef struct PLpgSQL_execstate
Tuplestorestate *tuple_store; /* SRFs accumulate results here */
MemoryContext tuple_store_cxt;
+ ResourceOwner tuple_store_owner;
ReturnSetInfo *rsi;
int found_varno;