diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index d6b72f7d6862395a420f3455355c28ef7d407f10..48a3206da1ce8e51009889e37f153a5db110d7b6 100644 --- a/src/pl/tcl/pltcl.c +++ b/src/pl/tcl/pltcl.c @@ -2104,6 +2104,7 @@ static int pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { + volatile MemoryContext plan_cxt = NULL; int nargs; CONST84 char **args; pltcl_query_desc *qdesc; @@ -2132,13 +2133,24 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, /************************************************************ * Allocate the new querydesc structure + * + * struct qdesc and subsidiary data all live in plan_cxt. Note that if the + * function is recompiled for whatever reason, permanent memory leaks + * occur. FIXME someday. ************************************************************/ - qdesc = (pltcl_query_desc *) malloc(sizeof(pltcl_query_desc)); + plan_cxt = AllocSetContextCreate(TopMemoryContext, + "PL/TCL spi_prepare query", + ALLOCSET_SMALL_MINSIZE, + ALLOCSET_SMALL_INITSIZE, + ALLOCSET_SMALL_MAXSIZE); + MemoryContextSwitchTo(plan_cxt); + qdesc = (pltcl_query_desc *) palloc0(sizeof(pltcl_query_desc)); snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc); qdesc->nargs = nargs; - qdesc->argtypes = (Oid *) malloc(nargs * sizeof(Oid)); - qdesc->arginfuncs = (FmgrInfo *) malloc(nargs * sizeof(FmgrInfo)); - qdesc->argtypioparams = (Oid *) malloc(nargs * sizeof(Oid)); + qdesc->argtypes = (Oid *) palloc(nargs * sizeof(Oid)); + qdesc->arginfuncs = (FmgrInfo *) palloc(nargs * sizeof(FmgrInfo)); + qdesc->argtypioparams = (Oid *) palloc(nargs * sizeof(Oid)); + MemoryContextSwitchTo(oldcontext); /************************************************************ * Execute the prepare inside a sub-transaction, so we can cope with @@ -2166,7 +2178,7 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, getTypeInputInfo(typId, &typInput, &typIOParam); qdesc->argtypes[i] = typId; - perm_fmgr_info(typInput, &(qdesc->arginfuncs[i])); + fmgr_info_cxt(typInput, &(qdesc->arginfuncs[i]), plan_cxt); qdesc->argtypioparams[i] = typIOParam; } @@ -2193,10 +2205,7 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, { pltcl_subtrans_abort(interp, oldcontext, oldowner); - free(qdesc->argtypes); - free(qdesc->arginfuncs); - free(qdesc->argtypioparams); - free(qdesc); + MemoryContextDelete(plan_cxt); ckfree((char *) args); return TCL_ERROR;