1818 * Portions Copyright (c) 2000-2001, PostgreSQL Global Development Group
1919 * Copyright 1999 Jan Wieck
2020 *
21- * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.24 2001/05/07 19:57:24 petere Exp $
21+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.25 2001/05/31 17:32:33 tgl Exp $
2222 *
2323 * ----------
2424 */
@@ -3243,17 +3243,32 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
32433243if (!found )
32443244{
32453245HeapTuple opr_tup ;
3246- Form_pg_operator opr_struct ;
3246+ Oid opr_proc ;
3247+ MemoryContext oldcontext ;
3248+ FmgrInfo finfo ;
32473249
32483250opr_tup = SearchSysCache (OPERNAME ,
32493251PointerGetDatum ("=" ),
32503252ObjectIdGetDatum (typeid ),
32513253ObjectIdGetDatum (typeid ),
32523254CharGetDatum ('b' ));
32533255if (!HeapTupleIsValid (opr_tup ))
3254- elog (ERROR ,"ri_AttributesEqual(): cannot find '=' operator "
3255- "for type %u" ,typeid );
3256- opr_struct = (Form_pg_operator )GETSTRUCT (opr_tup );
3256+ elog (ERROR ,
3257+ "ri_AttributesEqual(): cannot find '=' operator for type %u" ,
3258+ typeid );
3259+ opr_proc = ((Form_pg_operator )GETSTRUCT (opr_tup ))-> oprcode ;
3260+ ReleaseSysCache (opr_tup );
3261+
3262+ /*
3263+ * Since fmgr_info could fail, call it *before* creating the
3264+ * hashtable entry --- otherwise we could elog leaving an incomplete
3265+ * entry in the hashtable. Also, because this will be a permanent
3266+ * table entry, we must make sure any subsidiary structures of the
3267+ * fmgr record are kept in TopMemoryContext.
3268+ */
3269+ oldcontext = MemoryContextSwitchTo (TopMemoryContext );
3270+ fmgr_info (opr_proc ,& finfo );
3271+ MemoryContextSwitchTo (oldcontext );
32573272
32583273entry = (RI_OpreqHashEntry * )hash_search (ri_opreq_cache ,
32593274 (char * )& typeid ,
@@ -3263,8 +3278,7 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
32633278elog (FATAL ,"can't insert into RI operator cache" );
32643279
32653280entry -> typeid = typeid ;
3266- fmgr_info (opr_struct -> oprcode ,& (entry -> oprfmgrinfo ));
3267- ReleaseSysCache (opr_tup );
3281+ memcpy (& (entry -> oprfmgrinfo ),& finfo ,sizeof (FmgrInfo ));
32683282}
32693283
32703284/*