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.23.2.1 2001/05/09 16:28:31 petere Exp $
21+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.23.2.2 2001/05/31 17:33:03 tgl Exp $
2222 *
2323 * ----------
2424 */
@@ -3243,17 +3243,32 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
32433243 if (!found )
32443244 {
32453245 HeapTuple opr_tup ;
3246- Form_pg_operator opr_struct ;
3246+ Oid opr_proc ;
3247+ MemoryContext oldcontext ;
3248+ FmgrInfo finfo ;
32473249
32483250 opr_tup = SearchSysCache (OPERNAME ,
32493251 PointerGetDatum ("=" ),
32503252 ObjectIdGetDatum (typeid ),
32513253 ObjectIdGetDatum (typeid ),
32523254 CharGetDatum ('b' ));
32533255 if (!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
32583273 entry = (RI_OpreqHashEntry * ) hash_search (ri_opreq_cache ,
32593274 (char * ) & typeid ,
@@ -3263,8 +3278,7 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
32633278 elog (FATAL , "can't insert into RI operator cache" );
32643279
32653280 entry -> typeid = typeid ;
3266- fmgr_info (opr_struct -> oprcode , & (entry -> oprfmgrinfo ));
3267- ReleaseSysCache (opr_tup );
3281+ memcpy (& (entry -> oprfmgrinfo ), & finfo , sizeof (FmgrInfo ));
32683282 }
32693283
32703284 /*
0 commit comments