Make sure fmgr_info() fills in fn_oid last, so that no partially

initialized FmgrInfo structs linger after elog.
This commit is contained in:
Peter Eisentraut 2001-05-19 09:28:08 +00:00
parent cb8b40e6d5
commit d1af54cf6d
1 changed files with 22 additions and 13 deletions

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.51 2001/03/22 03:59:59 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.52 2001/05/19 09:28:08 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -57,8 +57,8 @@ typedef struct
} Oldstyle_fnextra; } Oldstyle_fnextra;
static void fmgr_info_C_lang(FmgrInfo *finfo, HeapTuple procedureTuple); static void fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
static void fmgr_info_other_lang(FmgrInfo *finfo, HeapTuple procedureTuple); static void fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple);
static Datum fmgr_oldstyle(PG_FUNCTION_ARGS); static Datum fmgr_oldstyle(PG_FUNCTION_ARGS);
static Datum fmgr_untrusted(PG_FUNCTION_ARGS); static Datum fmgr_untrusted(PG_FUNCTION_ARGS);
@ -123,7 +123,11 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
Form_pg_proc procedureStruct; Form_pg_proc procedureStruct;
char *prosrc; char *prosrc;
finfo->fn_oid = functionId; /*
* fn_oid *must* be filled in last. Code may assume that is fn_oid is valid,
* the whole struct is valid. Some FmgrInfo struct's do survive elogs.
*/
finfo->fn_oid = InvalidOid;
finfo->fn_extra = NULL; finfo->fn_extra = NULL;
finfo->fn_mcxt = CurrentMemoryContext; finfo->fn_mcxt = CurrentMemoryContext;
@ -138,6 +142,7 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
finfo->fn_strict = fbp->strict; finfo->fn_strict = fbp->strict;
finfo->fn_retset = fbp->retset; finfo->fn_retset = fbp->retset;
finfo->fn_addr = fbp->func; finfo->fn_addr = fbp->func;
finfo->fn_oid = functionId;
return; return;
} }
@ -158,6 +163,7 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
{ {
/* This isn't really supported anymore... */ /* This isn't really supported anymore... */
finfo->fn_addr = fmgr_untrusted; finfo->fn_addr = fmgr_untrusted;
finfo->fn_oid = functionId;
ReleaseSysCache(procedureTuple); ReleaseSysCache(procedureTuple);
return; return;
} }
@ -187,7 +193,7 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
break; break;
case ClanguageId: case ClanguageId:
fmgr_info_C_lang(finfo, procedureTuple); fmgr_info_C_lang(functionId, finfo, procedureTuple);
break; break;
case SQLlanguageId: case SQLlanguageId:
@ -195,18 +201,20 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
break; break;
default: default:
fmgr_info_other_lang(finfo, procedureTuple); fmgr_info_other_lang(functionId, finfo, procedureTuple);
break; break;
} }
finfo->fn_oid = functionId;
ReleaseSysCache(procedureTuple); ReleaseSysCache(procedureTuple);
} }
/* /*
* Special fmgr_info processing for C-language functions * Special fmgr_info processing for C-language functions. Note that
* finfo->fn_oid is not valid yet.
*/ */
static void static void
fmgr_info_C_lang(FmgrInfo *finfo, HeapTuple procedureTuple) fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
{ {
Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple); Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
Datum prosrcattr, Datum prosrcattr,
@ -224,14 +232,14 @@ fmgr_info_C_lang(FmgrInfo *finfo, HeapTuple procedureTuple)
Anum_pg_proc_prosrc, &isnull); Anum_pg_proc_prosrc, &isnull);
if (isnull) if (isnull)
elog(ERROR, "fmgr: Could not extract prosrc for %u from pg_proc", elog(ERROR, "fmgr: Could not extract prosrc for %u from pg_proc",
finfo->fn_oid); functionId);
prosrcstring = DatumGetCString(DirectFunctionCall1(textout, prosrcattr)); prosrcstring = DatumGetCString(DirectFunctionCall1(textout, prosrcattr));
probinattr = SysCacheGetAttr(PROCOID, procedureTuple, probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
Anum_pg_proc_probin, &isnull); Anum_pg_proc_probin, &isnull);
if (isnull) if (isnull)
elog(ERROR, "fmgr: Could not extract probin for %u from pg_proc", elog(ERROR, "fmgr: Could not extract probin for %u from pg_proc",
finfo->fn_oid); functionId);
probinstring = DatumGetCString(DirectFunctionCall1(textout, probinattr)); probinstring = DatumGetCString(DirectFunctionCall1(textout, probinattr));
/* Look up the function itself */ /* Look up the function itself */
@ -276,10 +284,11 @@ fmgr_info_C_lang(FmgrInfo *finfo, HeapTuple procedureTuple)
} }
/* /*
* Special fmgr_info processing for other-language functions * Special fmgr_info processing for other-language functions. Note
* that finfo->fn_oid is not valid yet.
*/ */
static void static void
fmgr_info_other_lang(FmgrInfo *finfo, HeapTuple procedureTuple) fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
{ {
Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple); Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
Oid language = procedureStruct->prolang; Oid language = procedureStruct->prolang;
@ -312,7 +321,7 @@ fmgr_info_other_lang(FmgrInfo *finfo, HeapTuple procedureTuple)
else else
{ {
elog(ERROR, "fmgr_info: function %u: unsupported language %u", elog(ERROR, "fmgr_info: function %u: unsupported language %u",
finfo->fn_oid, language); functionId, language);
} }
ReleaseSysCache(languageTuple); ReleaseSysCache(languageTuple);
} }