mirror of https://github.com/postgres/postgres
Make sure fmgr_info() fills in fn_oid last, so that no partially
initialized FmgrInfo structs linger after elog.
This commit is contained in:
parent
cb8b40e6d5
commit
d1af54cf6d
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue