From a3ed622b63bb897e58b66e1e589113c6e6c45e80 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 6 Apr 2001 02:06:48 +0000 Subject: [PATCH] Since plpgsql keeps its compiled function parsetrees until backend exit, it needs to ensure that data structures attached to fmgr info records in the trees will stick around that long, too. Current code was crashing on cases like datatypes with old-style I/O functions. --- src/pl/plpgsql/src/pl_comp.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c index 213bedb28d..22bb9e03a8 100644 --- a/src/pl/plpgsql/src/pl_comp.c +++ b/src/pl/plpgsql/src/pl_comp.c @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.28 2001/03/22 06:16:21 momjian Exp $ + * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.29 2001/04/06 02:06:48 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -85,6 +85,28 @@ int plpgsql_DumpExecTree = 0; PLpgSQL_function *plpgsql_curr_compile; +/* + * This routine is a crock, and so is everyplace that calls it. The problem + * is that the compiled form of a plpgsql function is allocated permanently + * (mostly via malloc()) and never released until backend exit. Subsidiary + * data structures such as fmgr info records therefore must live forever + * as well. A better implementation would store all this stuff in a per- + * function memory context that could be reclaimed at need. In the meantime, + * fmgr_info must be called in TopMemoryContext so that whatever it might + * allocate, and whatever the eventual function might allocate using fn_mcxt, + * will live forever too. + */ +static void +perm_fmgr_info(Oid functionId, FmgrInfo *finfo) +{ + MemoryContext oldcontext; + + oldcontext = MemoryContextSwitchTo(TopMemoryContext); + fmgr_info(functionId, finfo); + MemoryContextSwitchTo(oldcontext); +} + + /* ---------- * plpgsql_compile Given a pg_proc's oid, make * an execution tree for it. @@ -184,7 +206,7 @@ plpgsql_compile(Oid fn_oid, int functype) function->fn_retbyval = typeStruct->typbyval; function->fn_rettyplen = typeStruct->typlen; function->fn_rettypelem = typeStruct->typelem; - fmgr_info(typeStruct->typinput, &(function->fn_retinput)); + perm_fmgr_info(typeStruct->typinput, &(function->fn_retinput)); } ReleaseSysCache(typeTup); @@ -257,7 +279,7 @@ plpgsql_compile(Oid fn_oid, int functype) var->datatype->typname = DatumGetCString(DirectFunctionCall1(nameout, NameGetDatum(&(typeStruct->typname)))); var->datatype->typoid = procStruct->proargtypes[i]; - fmgr_info(typeStruct->typinput, &(var->datatype->typinput)); + perm_fmgr_info(typeStruct->typinput, &(var->datatype->typinput)); var->datatype->typelem = typeStruct->typelem; var->datatype->typbyval = typeStruct->typbyval; var->datatype->atttypmod = -1; @@ -607,7 +629,7 @@ plpgsql_parse_word(char *word) typ->typname = DatumGetCString(DirectFunctionCall1(nameout, NameGetDatum(&(typeStruct->typname)))); typ->typoid = typeTup->t_data->t_oid; - fmgr_info(typeStruct->typinput, &(typ->typinput)); + perm_fmgr_info(typeStruct->typinput, &(typ->typinput)); typ->typelem = typeStruct->typelem; typ->typbyval = typeStruct->typbyval; typ->atttypmod = -1; @@ -923,7 +945,7 @@ plpgsql_parse_wordtype(char *word) typ->typname = DatumGetCString(DirectFunctionCall1(nameout, NameGetDatum(&(typeStruct->typname)))); typ->typoid = typeTup->t_data->t_oid; - fmgr_info(typeStruct->typinput, &(typ->typinput)); + perm_fmgr_info(typeStruct->typinput, &(typ->typinput)); typ->typelem = typeStruct->typelem; typ->typbyval = typeStruct->typbyval; typ->atttypmod = -1; @@ -1066,7 +1088,7 @@ plpgsql_parse_dblwordtype(char *string) typ->typname = DatumGetCString(DirectFunctionCall1(nameout, NameGetDatum(&(typeStruct->typname)))); typ->typoid = typetup->t_data->t_oid; - fmgr_info(typeStruct->typinput, &(typ->typinput)); + perm_fmgr_info(typeStruct->typinput, &(typ->typinput)); typ->typelem = typeStruct->typelem; typ->typbyval = typeStruct->typbyval; typ->atttypmod = attrStruct->atttypmod; @@ -1200,7 +1222,7 @@ plpgsql_parse_wordrowtype(char *string) var->datatype = malloc(sizeof(PLpgSQL_type)); var->datatype->typname = strdup(NameStr(typeStruct->typname)); var->datatype->typoid = typetup->t_data->t_oid; - fmgr_info(typeStruct->typinput, &(var->datatype->typinput)); + perm_fmgr_info(typeStruct->typinput, &(var->datatype->typinput)); var->datatype->typelem = typeStruct->typelem; var->datatype->typbyval = typeStruct->typbyval; var->datatype->atttypmod = attrStruct->atttypmod;