From: Tom Lane Date: Thu, 31 May 2001 17:33:03 +0000 (+0000) Subject: RI triggers would fail for datatypes using old-style equal function, X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=905f42f738ba14b45342d1ae0333cf986c703fc1;p=users%2Fbernd%2Fpostgres.git RI triggers would fail for datatypes using old-style equal function, because cached fmgr info contained reference to a shorter-lived data structure. Also guard against possibility that fmgr_info could fail, leaving an incomplete entry present in the hash table. --- diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index b8e8558dda..e5e63142d2 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -3243,7 +3243,9 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue) if (!found) { HeapTuple opr_tup; - Form_pg_operator opr_struct; + Oid opr_proc; + MemoryContext oldcontext; + FmgrInfo finfo; opr_tup = SearchSysCache(OPERNAME, PointerGetDatum("="), @@ -3251,9 +3253,22 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue) ObjectIdGetDatum(typeid), CharGetDatum('b')); if (!HeapTupleIsValid(opr_tup)) - elog(ERROR, "ri_AttributesEqual(): cannot find '=' operator " - "for type %u", typeid); - opr_struct = (Form_pg_operator) GETSTRUCT(opr_tup); + elog(ERROR, + "ri_AttributesEqual(): cannot find '=' operator for type %u", + typeid); + opr_proc = ((Form_pg_operator) GETSTRUCT(opr_tup))->oprcode; + ReleaseSysCache(opr_tup); + + /* + * Since fmgr_info could fail, call it *before* creating the + * hashtable entry --- otherwise we could elog leaving an incomplete + * entry in the hashtable. Also, because this will be a permanent + * table entry, we must make sure any subsidiary structures of the + * fmgr record are kept in TopMemoryContext. + */ + oldcontext = MemoryContextSwitchTo(TopMemoryContext); + fmgr_info(opr_proc, &finfo); + MemoryContextSwitchTo(oldcontext); entry = (RI_OpreqHashEntry *) hash_search(ri_opreq_cache, (char *) &typeid, @@ -3263,8 +3278,7 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue) elog(FATAL, "can't insert into RI operator cache"); entry->typeid = typeid; - fmgr_info(opr_struct->oprcode, &(entry->oprfmgrinfo)); - ReleaseSysCache(opr_tup); + memcpy(&(entry->oprfmgrinfo), &finfo, sizeof(FmgrInfo)); } /*