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 );
6262static Datum fmgr_oldstyle (PG_FUNCTION_ARGS );
6363static Datum fmgr_untrusted (PG_FUNCTION_ARGS );
6464
@@ -123,7 +123,11 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
123123Form_pg_proc procedureStruct ;
124124char * 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 ;
127131finfo -> fn_extra = NULL ;
128132finfo -> fn_mcxt = CurrentMemoryContext ;
129133
@@ -138,6 +142,7 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
138142finfo -> fn_strict = fbp -> strict ;
139143finfo -> fn_retset = fbp -> retset ;
140144finfo -> fn_addr = fbp -> func ;
145+ finfo -> fn_oid = functionId ;
141146return ;
142147}
143148
@@ -158,6 +163,7 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
158163{
159164/* This isn't really supported anymore... */
160165finfo -> fn_addr = fmgr_untrusted ;
166+ finfo -> fn_oid = functionId ;
161167ReleaseSysCache (procedureTuple );
162168return ;
163169}
@@ -187,26 +193,28 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
187193break ;
188194
189195case ClanguageId :
190- fmgr_info_C_lang (finfo ,procedureTuple );
196+ fmgr_info_C_lang (functionId , finfo ,procedureTuple );
191197break ;
192198
193199case SQLlanguageId :
194200finfo -> fn_addr = fmgr_sql ;
195201break ;
196202
197203default :
198- fmgr_info_other_lang (finfo ,procedureTuple );
204+ fmgr_info_other_lang (functionId , finfo ,procedureTuple );
199205break ;
200206}
201207
208+ finfo -> fn_oid = functionId ;
202209ReleaseSysCache (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 */
208216static void
209- fmgr_info_C_lang (FmgrInfo * finfo ,HeapTuple procedureTuple )
217+ fmgr_info_C_lang (Oid functionId , FmgrInfo * finfo ,HeapTuple procedureTuple )
210218{
211219Form_pg_proc procedureStruct = (Form_pg_proc )GETSTRUCT (procedureTuple );
212220Datum prosrcattr ,
@@ -224,14 +232,14 @@ fmgr_info_C_lang(FmgrInfo *finfo, HeapTuple procedureTuple)
224232Anum_pg_proc_prosrc ,& isnull );
225233if (isnull )
226234elog (ERROR ,"fmgr: Could not extract prosrc for %u from pg_proc" ,
227- finfo -> fn_oid );
235+ functionId );
228236prosrcstring = DatumGetCString (DirectFunctionCall1 (textout ,prosrcattr ));
229237
230238probinattr = SysCacheGetAttr (PROCOID ,procedureTuple ,
231239Anum_pg_proc_probin ,& isnull );
232240if (isnull )
233241elog (ERROR ,"fmgr: Could not extract probin for %u from pg_proc" ,
234- finfo -> fn_oid );
242+ functionId );
235243probinstring = 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 */
281290static void
282- fmgr_info_other_lang (FmgrInfo * finfo ,HeapTuple procedureTuple )
291+ fmgr_info_other_lang (Oid functionId , FmgrInfo * finfo ,HeapTuple procedureTuple )
283292{
284293Form_pg_proc procedureStruct = (Form_pg_proc )GETSTRUCT (procedureTuple );
285294Oid language = procedureStruct -> prolang ;
@@ -312,7 +321,7 @@ fmgr_info_other_lang(FmgrInfo *finfo, HeapTuple procedureTuple)
312321else
313322{
314323elog (ERROR ,"fmgr_info: function %u: unsupported language %u" ,
315- finfo -> fn_oid ,language );
324+ functionId ,language );
316325}
317326ReleaseSysCache (languageTuple );
318327}