*** a/src/pl/plperl/plperl.c
--- b/src/pl/plperl/plperl.c
***************
*** 189,194 **** typedef struct plperl_query_desc
--- 189,195 ----
Oid *argtypes;
FmgrInfo *arginfuncs;
Oid *argtypioparams;
+ MemoryContext plan_ctx;
} plperl_query_desc;
/* hash table entry for query desc */
***************
*** 3211,3216 **** plperl_spi_prepare(char *query, int argc, SV **argv)
--- 3212,3218 ----
{
plperl_query_desc *qdesc;
plperl_query_entry *hash_entry;
+ MemoryContext plan_ctx;
bool found;
SPIPlanPtr plan;
int i;
***************
*** 3220,3238 **** plperl_spi_prepare(char *query, int argc, SV **argv)
check_spi_usage_allowed();
! BeginInternalSubTransaction(NULL);
! MemoryContextSwitchTo(oldcontext);
/************************************************************
* Allocate the new querydesc structure
************************************************************/
! qdesc = (plperl_query_desc *) malloc(sizeof(plperl_query_desc));
! MemSet(qdesc, 0, sizeof(plperl_query_desc));
snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc);
qdesc->nargs = argc;
! qdesc->argtypes = (Oid *) malloc(argc * sizeof(Oid));
! qdesc->arginfuncs = (FmgrInfo *) malloc(argc * sizeof(FmgrInfo));
! qdesc->argtypioparams = (Oid *) malloc(argc * sizeof(Oid));
PG_TRY();
{
--- 3222,3248 ----
check_spi_usage_allowed();
! CHECK_FOR_INTERRUPTS();
/************************************************************
* Allocate the new querydesc structure
************************************************************/
! plan_ctx = AllocSetContextCreate(TopMemoryContext,
! "PL/Perl spi_prepare cxt",
! ALLOCSET_DEFAULT_MINSIZE,
! ALLOCSET_DEFAULT_INITSIZE,
! ALLOCSET_DEFAULT_MAXSIZE);
! MemoryContextSwitchTo(plan_ctx);
! qdesc = (plperl_query_desc *) palloc0(sizeof(plperl_query_desc));
snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc);
qdesc->nargs = argc;
! qdesc->argtypes = (Oid *) palloc(argc * sizeof(Oid));
! qdesc->arginfuncs = (FmgrInfo *) palloc(argc * sizeof(FmgrInfo));
! qdesc->argtypioparams = (Oid *) palloc(argc * sizeof(Oid));
! qdesc->plan_ctx = plan_ctx;
!
! BeginInternalSubTransaction(NULL);
! MemoryContextSwitchTo(oldcontext);
PG_TRY();
{
***************
*** 3256,3262 **** plperl_spi_prepare(char *query, int argc, SV **argv)
getTypeInputInfo(typId, &typInput, &typIOParam);
qdesc->argtypes[i] = typId;
! perm_fmgr_info(typInput, &(qdesc->arginfuncs[i]));
qdesc->argtypioparams[i] = typIOParam;
}
--- 3266,3272 ----
getTypeInputInfo(typId, &typInput, &typIOParam);
qdesc->argtypes[i] = typId;
! fmgr_info_cxt(typInput, &(qdesc->arginfuncs[i]), plan_ctx);
qdesc->argtypioparams[i] = typIOParam;
}
***************
*** 3295,3304 **** plperl_spi_prepare(char *query, int argc, SV **argv)
{
ErrorData *edata;
! free(qdesc->argtypes);
! free(qdesc->arginfuncs);
! free(qdesc->argtypioparams);
! free(qdesc);
/* Save error info */
MemoryContextSwitchTo(oldcontext);
--- 3305,3311 ----
{
ErrorData *edata;
! MemoryContextDelete(plan_ctx);
/* Save error info */
MemoryContextSwitchTo(oldcontext);
***************
*** 3329,3335 **** plperl_spi_prepare(char *query, int argc, SV **argv)
* Insert a hashtable entry for the plan and return
* the key to the caller.
************************************************************/
-
hash_entry = hash_search(plperl_active_interp->query_hash, qdesc->qname,
HASH_ENTER, &found);
hash_entry->query_data = qdesc;
--- 3336,3341 ----
***************
*** 3619,3630 **** plperl_spi_freeplan(char *query)
hash_entry = hash_search(plperl_active_interp->query_hash, query,
HASH_FIND, NULL);
if (hash_entry == NULL)
! elog(ERROR, "spi_exec_prepared: Invalid prepared query passed");
qdesc = hash_entry->query_data;
if (qdesc == NULL)
! elog(ERROR, "spi_exec_freeplan: panic - plperl query_hash value vanished");
/*
* free all memory before SPI_freeplan, so if it dies, nothing will be
--- 3625,3636 ----
hash_entry = hash_search(plperl_active_interp->query_hash, query,
HASH_FIND, NULL);
if (hash_entry == NULL)
! elog(ERROR, "spi_freeplan: Invalid prepared query passed");
qdesc = hash_entry->query_data;
if (qdesc == NULL)
! elog(ERROR, "spi_freeplan: panic - plperl query_hash value vanished");
/*
* free all memory before SPI_freeplan, so if it dies, nothing will be
***************
*** 3634,3643 **** plperl_spi_freeplan(char *query)
HASH_REMOVE, NULL);
plan = qdesc->plan;
! free(qdesc->argtypes);
! free(qdesc->arginfuncs);
! free(qdesc->argtypioparams);
! free(qdesc);
SPI_freeplan(plan);
}
--- 3640,3646 ----
HASH_REMOVE, NULL);
plan = qdesc->plan;
! MemoryContextDelete(qdesc->plan_ctx);
SPI_freeplan(plan);
}