|
3 | 3 | * procedural language |
4 | 4 | * |
5 | 5 | * IDENTIFICATION |
6 | | - * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.28 2001/03/22 06:16:21 momjian Exp $ |
| 6 | + * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.29 2001/04/06 02:06:48 tgl Exp $ |
7 | 7 | * |
8 | 8 | * This software is copyrighted by Jan Wieck - Hamburg. |
9 | 9 | * |
@@ -85,6 +85,28 @@ int plpgsql_DumpExecTree = 0; |
85 | 85 | PLpgSQL_function *plpgsql_curr_compile; |
86 | 86 |
|
87 | 87 |
|
| 88 | +/* |
| 89 | + * This routine is a crock, and so is everyplace that calls it. The problem |
| 90 | + * is that the compiled form of a plpgsql function is allocated permanently |
| 91 | + * (mostly via malloc()) and never released until backend exit. Subsidiary |
| 92 | + * data structures such as fmgr info records therefore must live forever |
| 93 | + * as well. A better implementation would store all this stuff in a per- |
| 94 | + * function memory context that could be reclaimed at need. In the meantime, |
| 95 | + * fmgr_info must be called in TopMemoryContext so that whatever it might |
| 96 | + * allocate, and whatever the eventual function might allocate using fn_mcxt, |
| 97 | + * will live forever too. |
| 98 | + */ |
| 99 | +static void |
| 100 | +perm_fmgr_info(Oid functionId, FmgrInfo *finfo) |
| 101 | +{ |
| 102 | + MemoryContext oldcontext; |
| 103 | + |
| 104 | + oldcontext = MemoryContextSwitchTo(TopMemoryContext); |
| 105 | + fmgr_info(functionId, finfo); |
| 106 | + MemoryContextSwitchTo(oldcontext); |
| 107 | +} |
| 108 | + |
| 109 | + |
88 | 110 | /* ---------- |
89 | 111 | * plpgsql_compile Given a pg_proc's oid, make |
90 | 112 | * an execution tree for it. |
@@ -184,7 +206,7 @@ plpgsql_compile(Oid fn_oid, int functype) |
184 | 206 | function->fn_retbyval = typeStruct->typbyval; |
185 | 207 | function->fn_rettyplen = typeStruct->typlen; |
186 | 208 | function->fn_rettypelem = typeStruct->typelem; |
187 | | - fmgr_info(typeStruct->typinput, &(function->fn_retinput)); |
| 209 | + perm_fmgr_info(typeStruct->typinput, &(function->fn_retinput)); |
188 | 210 | } |
189 | 211 | ReleaseSysCache(typeTup); |
190 | 212 |
|
@@ -257,7 +279,7 @@ plpgsql_compile(Oid fn_oid, int functype) |
257 | 279 | var->datatype->typname = DatumGetCString(DirectFunctionCall1(nameout, |
258 | 280 | NameGetDatum(&(typeStruct->typname)))); |
259 | 281 | var->datatype->typoid = procStruct->proargtypes[i]; |
260 | | - fmgr_info(typeStruct->typinput, &(var->datatype->typinput)); |
| 282 | + perm_fmgr_info(typeStruct->typinput, &(var->datatype->typinput)); |
261 | 283 | var->datatype->typelem = typeStruct->typelem; |
262 | 284 | var->datatype->typbyval = typeStruct->typbyval; |
263 | 285 | var->datatype->atttypmod = -1; |
@@ -607,7 +629,7 @@ plpgsql_parse_word(char *word) |
607 | 629 | typ->typname = DatumGetCString(DirectFunctionCall1(nameout, |
608 | 630 | NameGetDatum(&(typeStruct->typname)))); |
609 | 631 | typ->typoid = typeTup->t_data->t_oid; |
610 | | - fmgr_info(typeStruct->typinput, &(typ->typinput)); |
| 632 | + perm_fmgr_info(typeStruct->typinput, &(typ->typinput)); |
611 | 633 | typ->typelem = typeStruct->typelem; |
612 | 634 | typ->typbyval = typeStruct->typbyval; |
613 | 635 | typ->atttypmod = -1; |
@@ -923,7 +945,7 @@ plpgsql_parse_wordtype(char *word) |
923 | 945 | typ->typname = DatumGetCString(DirectFunctionCall1(nameout, |
924 | 946 | NameGetDatum(&(typeStruct->typname)))); |
925 | 947 | typ->typoid = typeTup->t_data->t_oid; |
926 | | - fmgr_info(typeStruct->typinput, &(typ->typinput)); |
| 948 | + perm_fmgr_info(typeStruct->typinput, &(typ->typinput)); |
927 | 949 | typ->typelem = typeStruct->typelem; |
928 | 950 | typ->typbyval = typeStruct->typbyval; |
929 | 951 | typ->atttypmod = -1; |
@@ -1066,7 +1088,7 @@ plpgsql_parse_dblwordtype(char *string) |
1066 | 1088 | typ->typname = DatumGetCString(DirectFunctionCall1(nameout, |
1067 | 1089 | NameGetDatum(&(typeStruct->typname)))); |
1068 | 1090 | typ->typoid = typetup->t_data->t_oid; |
1069 | | - fmgr_info(typeStruct->typinput, &(typ->typinput)); |
| 1091 | + perm_fmgr_info(typeStruct->typinput, &(typ->typinput)); |
1070 | 1092 | typ->typelem = typeStruct->typelem; |
1071 | 1093 | typ->typbyval = typeStruct->typbyval; |
1072 | 1094 | typ->atttypmod = attrStruct->atttypmod; |
@@ -1200,7 +1222,7 @@ plpgsql_parse_wordrowtype(char *string) |
1200 | 1222 | var->datatype = malloc(sizeof(PLpgSQL_type)); |
1201 | 1223 | var->datatype->typname = strdup(NameStr(typeStruct->typname)); |
1202 | 1224 | var->datatype->typoid = typetup->t_data->t_oid; |
1203 | | - fmgr_info(typeStruct->typinput, &(var->datatype->typinput)); |
| 1225 | + perm_fmgr_info(typeStruct->typinput, &(var->datatype->typinput)); |
1204 | 1226 | var->datatype->typelem = typeStruct->typelem; |
1205 | 1227 | var->datatype->typbyval = typeStruct->typbyval; |
1206 | 1228 | var->datatype->atttypmod = attrStruct->atttypmod; |
|
0 commit comments