*** 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); }