Skip to content

Commit d1af54c

Browse files
committed
Make sure fmgr_info() fills in fn_oid last, so that no partially
initialized FmgrInfo structs linger after elog.
1 parent cb8b40e commit d1af54c

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

src/backend/utils/fmgr/fmgr.c

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.51 2001/03/22 03:59:59 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.52 2001/05/19 09:28:08 petere Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -57,8 +57,8 @@ typedef struct
5757
} Oldstyle_fnextra;
5858

5959

60-
static void fmgr_info_C_lang(FmgrInfo *finfo, HeapTuple procedureTuple);
61-
static void fmgr_info_other_lang(FmgrInfo *finfo, HeapTuple procedureTuple);
60+
static void fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
61+
static void fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
6262
static Datum fmgr_oldstyle(PG_FUNCTION_ARGS);
6363
static Datum fmgr_untrusted(PG_FUNCTION_ARGS);
6464

@@ -123,7 +123,11 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
123123
Form_pg_proc procedureStruct;
124124
char *prosrc;
125125

126-
finfo->fn_oid = functionId;
126+
/*
127+
* fn_oid *must* be filled in last. Code may assume that is fn_oid is valid,
128+
* the whole struct is valid. Some FmgrInfo struct's do survive elogs.
129+
*/
130+
finfo->fn_oid = InvalidOid;
127131
finfo->fn_extra = NULL;
128132
finfo->fn_mcxt = CurrentMemoryContext;
129133

@@ -138,6 +142,7 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
138142
finfo->fn_strict = fbp->strict;
139143
finfo->fn_retset = fbp->retset;
140144
finfo->fn_addr = fbp->func;
145+
finfo->fn_oid = functionId;
141146
return;
142147
}
143148

@@ -158,6 +163,7 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
158163
{
159164
/* This isn't really supported anymore... */
160165
finfo->fn_addr = fmgr_untrusted;
166+
finfo->fn_oid = functionId;
161167
ReleaseSysCache(procedureTuple);
162168
return;
163169
}
@@ -187,26 +193,28 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
187193
break;
188194

189195
case ClanguageId:
190-
fmgr_info_C_lang(finfo, procedureTuple);
196+
fmgr_info_C_lang(functionId, finfo, procedureTuple);
191197
break;
192198

193199
case SQLlanguageId:
194200
finfo->fn_addr = fmgr_sql;
195201
break;
196202

197203
default:
198-
fmgr_info_other_lang(finfo, procedureTuple);
204+
fmgr_info_other_lang(functionId, finfo, procedureTuple);
199205
break;
200206
}
201207

208+
finfo->fn_oid = functionId;
202209
ReleaseSysCache(procedureTuple);
203210
}
204211

205212
/*
206-
* Special fmgr_info processing for C-language functions
213+
* Special fmgr_info processing for C-language functions. Note that
214+
* finfo->fn_oid is not valid yet.
207215
*/
208216
static void
209-
fmgr_info_C_lang(FmgrInfo *finfo, HeapTuple procedureTuple)
217+
fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
210218
{
211219
Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
212220
Datum prosrcattr,
@@ -224,14 +232,14 @@ fmgr_info_C_lang(FmgrInfo *finfo, HeapTuple procedureTuple)
224232
Anum_pg_proc_prosrc, &isnull);
225233
if (isnull)
226234
elog(ERROR, "fmgr: Could not extract prosrc for %u from pg_proc",
227-
finfo->fn_oid);
235+
functionId);
228236
prosrcstring = DatumGetCString(DirectFunctionCall1(textout, prosrcattr));
229237

230238
probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
231239
Anum_pg_proc_probin, &isnull);
232240
if (isnull)
233241
elog(ERROR, "fmgr: Could not extract probin for %u from pg_proc",
234-
finfo->fn_oid);
242+
functionId);
235243
probinstring = DatumGetCString(DirectFunctionCall1(textout, probinattr));
236244

237245
/* Look up the function itself */
@@ -276,10 +284,11 @@ fmgr_info_C_lang(FmgrInfo *finfo, HeapTuple procedureTuple)
276284
}
277285

278286
/*
279-
* Special fmgr_info processing for other-language functions
287+
* Special fmgr_info processing for other-language functions. Note
288+
* that finfo->fn_oid is not valid yet.
280289
*/
281290
static void
282-
fmgr_info_other_lang(FmgrInfo *finfo, HeapTuple procedureTuple)
291+
fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
283292
{
284293
Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
285294
Oid language = procedureStruct->prolang;
@@ -312,7 +321,7 @@ fmgr_info_other_lang(FmgrInfo *finfo, HeapTuple procedureTuple)
312321
else
313322
{
314323
elog(ERROR, "fmgr_info: function %u: unsupported language %u",
315-
finfo->fn_oid, language);
324+
functionId, language);
316325
}
317326
ReleaseSysCache(languageTuple);
318327
}

0 commit comments

Comments
 (0)