diff options
Diffstat (limited to 'src/pl')
| -rw-r--r-- | src/pl/plperl/plperl.c | 10 | ||||
| -rw-r--r-- | src/pl/plpgsql/src/pl_exec.c | 38 | ||||
| -rw-r--r-- | src/pl/plpgsql/src/plpgsql.h | 3 |
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; |
