mirror of https://github.com/postgres/postgres
Back-patch fix and test case for bug #7516.
Back-patch commits9afc648111
andb8fbbcf37f
. The first of these is really a minor code cleanup to save a few cycles, but it turns out to provide a workaround for the misoptimization problem described in bug #7516. The second commit adds a regression test case. Back-patch the fix to all active branches. The test case only works as far back as 9.0, because it relies on plpgsql which isn't installed by default before that. (I didn't have success modifying it into an all-plperl form that still provoked a crash, though this may just reflect my lack of Perl-fu.)
This commit is contained in:
parent
4da51c25a5
commit
2734af4ea9
|
@ -1023,10 +1023,15 @@ plperl_call_handler(PG_FUNCTION_ARGS)
|
|||
Datum retval;
|
||||
plperl_call_data *save_call_data = current_call_data;
|
||||
plperl_interp_desc *oldinterp = plperl_active_interp;
|
||||
plperl_call_data this_call_data;
|
||||
|
||||
/* Initialize current-call status record */
|
||||
MemSet(&this_call_data, 0, sizeof(this_call_data));
|
||||
this_call_data.fcinfo = fcinfo;
|
||||
|
||||
PG_TRY();
|
||||
{
|
||||
current_call_data = NULL;
|
||||
current_call_data = &this_call_data;
|
||||
if (CALLED_AS_TRIGGER(fcinfo))
|
||||
retval = PointerGetDatum(plperl_trigger_handler(fcinfo));
|
||||
else
|
||||
|
@ -1034,16 +1039,16 @@ plperl_call_handler(PG_FUNCTION_ARGS)
|
|||
}
|
||||
PG_CATCH();
|
||||
{
|
||||
if (current_call_data && current_call_data->prodesc)
|
||||
decrement_prodesc_refcount(current_call_data->prodesc);
|
||||
if (this_call_data.prodesc)
|
||||
decrement_prodesc_refcount(this_call_data.prodesc);
|
||||
current_call_data = save_call_data;
|
||||
activate_interpreter(oldinterp);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
if (current_call_data && current_call_data->prodesc)
|
||||
decrement_prodesc_refcount(current_call_data->prodesc);
|
||||
if (this_call_data.prodesc)
|
||||
decrement_prodesc_refcount(this_call_data.prodesc);
|
||||
current_call_data = save_call_data;
|
||||
activate_interpreter(oldinterp);
|
||||
return retval;
|
||||
|
@ -1380,13 +1385,6 @@ plperl_func_handler(PG_FUNCTION_ARGS)
|
|||
ReturnSetInfo *rsi;
|
||||
SV *array_ret = NULL;
|
||||
|
||||
/*
|
||||
* Create the call_data beforing connecting to SPI, so that it is not
|
||||
* allocated in the SPI memory context
|
||||
*/
|
||||
current_call_data = (plperl_call_data *) palloc0(sizeof(plperl_call_data));
|
||||
current_call_data->fcinfo = fcinfo;
|
||||
|
||||
if (SPI_connect() != SPI_OK_CONNECT)
|
||||
elog(ERROR, "could not connect to SPI manager");
|
||||
|
||||
|
@ -1532,13 +1530,6 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
|
|||
SV *svTD;
|
||||
HV *hvTD;
|
||||
|
||||
/*
|
||||
* Create the call_data beforing connecting to SPI, so that it is not
|
||||
* allocated in the SPI memory context
|
||||
*/
|
||||
current_call_data = (plperl_call_data *) palloc0(sizeof(plperl_call_data));
|
||||
current_call_data->fcinfo = fcinfo;
|
||||
|
||||
/* Connect to SPI manager */
|
||||
if (SPI_connect() != SPI_OK_CONNECT)
|
||||
elog(ERROR, "could not connect to SPI manager");
|
||||
|
|
Loading…
Reference in New Issue