diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index 9876767f425..46f64a30a16 100644 --- a/src/backend/utils/fmgr/fmgr.c +++ b/src/backend/utils/fmgr/fmgr.c @@ -152,7 +152,7 @@ fmgr_lookupByName(const char *name) void fmgr_info(Oid functionId, FmgrInfo *finfo) { - fmgr_info_cxt(functionId, finfo, CurrentMemoryContext); + fmgr_info_cxt_security(functionId, finfo, CurrentMemoryContext, false); } /* @@ -167,8 +167,7 @@ fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt) /* * This one does the actual work. ignore_security is ordinarily false - * but is set to true by fmgr_security_definer to avoid infinite - * recursive lookups. + * but is set to true when we need to avoid recursion. */ static void fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt, @@ -218,7 +217,8 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt, /* * If it has prosecdef set, or non-null proconfig, use - * fmgr_security_definer call handler. + * fmgr_security_definer call handler --- unless we are being called again + * by fmgr_security_definer or fmgr_info_other_lang. */ if (!ignore_security && (procedureStruct->prosecdef || @@ -388,7 +388,13 @@ fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple) elog(ERROR, "cache lookup failed for language %u", language); languageStruct = (Form_pg_language) GETSTRUCT(languageTuple); - fmgr_info(languageStruct->lanplcallfoid, &plfinfo); + /* + * Look up the language's call handler function, ignoring any attributes + * that would normally cause insertion of fmgr_security_definer. We + * need to get back a bare pointer to the actual C-language function. + */ + fmgr_info_cxt_security(languageStruct->lanplcallfoid, &plfinfo, + CurrentMemoryContext, true); finfo->fn_addr = plfinfo.fn_addr; /*