|
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