diff --git a/src/backend/access/common/indexvalid.c b/src/backend/access/common/indexvalid.c
index 91d873e446b47ab39b986ec39a6c3d4f90199184..d2f4d5ee83f50e6cf8226f3b96a7ac2d05d1a6dd 100644
--- a/src/backend/access/common/indexvalid.c
+++ b/src/backend/access/common/indexvalid.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/common/Attic/indexvalid.c,v 1.24 2000/01/26 05:55:53 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/common/Attic/indexvalid.c,v 1.25 2000/05/30 04:24:27 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -40,7 +40,7 @@ index_keytest(IndexTuple tuple,
 {
 	bool		isNull;
 	Datum		datum;
-	int			test;
+	Datum		test;
 
 	IncrIndexProcessed();
 
@@ -62,18 +62,16 @@ index_keytest(IndexTuple tuple,
 
 		if (key[0].sk_flags & SK_COMMUTE)
 		{
-			test = (*(fmgr_faddr(&key[0].sk_func)))
-				(DatumGetPointer(key[0].sk_argument),
-				 datum) ? 1 : 0;
+			test = FunctionCall2(&key[0].sk_func,
+								 key[0].sk_argument, datum);
 		}
 		else
 		{
-			test = (*(fmgr_faddr(&key[0].sk_func)))
-				(datum,
-				 DatumGetPointer(key[0].sk_argument)) ? 1 : 0;
+			test = FunctionCall2(&key[0].sk_func,
+								 datum, key[0].sk_argument);
 		}
 
-		if (!test == !(key[0].sk_flags & SK_NEGATE))
+		if (DatumGetBool(test) == !!(key[0].sk_flags & SK_NEGATE))
 			return false;
 
 		scanKeySize -= 1;
diff --git a/src/backend/access/common/printtup.c b/src/backend/access/common/printtup.c
index 6e71b084ef1cbace6257df230900f890b9b95a59..6fe0e9652c21272a1eb10615a30915dda9b8e4cb 100644
--- a/src/backend/access/common/printtup.c
+++ b/src/backend/access/common/printtup.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.52 2000/01/26 05:55:53 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.53 2000/05/30 04:24:27 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -206,8 +206,10 @@ printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
 			continue;
 		if (OidIsValid(thisState->typoutput))
 		{
-			outputstr = (char *) (*fmgr_faddr(&thisState->finfo))
-				(attr, thisState->typelem, typeinfo->attrs[i]->atttypmod);
+			outputstr = DatumGetCString(FunctionCall3(&thisState->finfo,
+										attr,
+										ObjectIdGetDatum(thisState->typelem),
+										Int32GetDatum(typeinfo->attrs[i]->atttypmod)));
 			pq_sendcountedtext(&buf, outputstr, strlen(outputstr));
 			pfree(outputstr);
 		}
@@ -295,8 +297,10 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
 		if (getTypeOutAndElem((Oid) typeinfo->attrs[i]->atttypid,
 							  &typoutput, &typelem))
 		{
-			value = fmgr(typoutput, attr, typelem,
-						 typeinfo->attrs[i]->atttypmod);
+			value = DatumGetCString(OidFunctionCall3(typoutput,
+									attr,
+									ObjectIdGetDatum(typelem),
+									Int32GetDatum(typeinfo->attrs[i]->atttypmod)));
 			printatt((unsigned) i + 1, typeinfo->attrs[i], value);
 			pfree(value);
 		}
diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c
index 685390c67a77ac0ab6014e06a3e2ca19218f22b1..7c3bb452cce89bb3cd5b4fd3cf76bf54560d3ae0 100644
--- a/src/backend/access/gist/gist.c
+++ b/src/backend/access/gist/gist.c
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.54 2000/05/30 00:49:39 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.55 2000/05/30 04:24:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -551,10 +551,16 @@ gistAdjustKeys(Relation r,
 	ev1p = &((GISTENTRY *) VARDATA(evec))[1];
 
 	/* form union of decompressed entries */
-	datum = (*fmgr_faddr(&giststate->unionFn)) (evec, &datumsize);
+	datum = (char *)
+		DatumGetPointer(FunctionCall2(&giststate->unionFn,
+									  PointerGetDatum(evec),
+									  PointerGetDatum(&datumsize)));
 
 	/* did union leave decompressed version of oldud unchanged? */
-	(*fmgr_faddr(&giststate->equalFn)) (ev0p->pred, datum, &result);
+	FunctionCall3(&giststate->equalFn,
+				  PointerGetDatum(ev0p->pred),
+				  PointerGetDatum(datum),
+				  PointerGetDatum(&result));
 	if (!result)
 	{
 		TupleDesc	td = RelationGetDescr(r);
@@ -727,7 +733,9 @@ gistSplit(Relation r,
 	VARSIZE(entryvec) = (maxoff + 2) * sizeof(GISTENTRY) + VARHDRSZ;
 
 	/* now let the user-defined picksplit function set up the split vector */
-	(*fmgr_faddr(&giststate->picksplitFn)) (entryvec, &v);
+	FunctionCall2(&giststate->picksplitFn,
+				  PointerGetDatum(entryvec),
+				  PointerGetDatum(&v));
 
 	/* compress ldatum and rdatum */
 	gistcentryinit(giststate, &tmpentry, v.spl_ldatum, (Relation) NULL,
@@ -1054,7 +1062,10 @@ gistchoose(Relation r, Page p, IndexTuple it,	/* it has compressed entry */
 		size = IndexTupleSize(datum) - sizeof(IndexTupleData);
 		datum += sizeof(IndexTupleData);
 		gistdentryinit(giststate, &entry, datum, r, p, i, size, FALSE);
-		(*fmgr_faddr(&giststate->penaltyFn)) (&entry, &identry, &usize);
+		FunctionCall3(&giststate->penaltyFn,
+					  PointerGetDatum(&entry),
+					  PointerGetDatum(&identry),
+					  PointerGetDatum(&usize));
 		if (which_grow < 0 || usize < which_grow)
 		{
 			which = i;
@@ -1237,7 +1248,9 @@ gistdentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, Relation r,
 	gistentryinit(*e, pr, r, pg, o, b, l);
 	if (giststate->haskeytype)
 	{
-		dep = (GISTENTRY *) ((*fmgr_faddr(&giststate->decompressFn)) (e));
+		dep = (GISTENTRY *)
+			DatumGetPointer(FunctionCall1(&giststate->decompressFn,
+										  PointerGetDatum(e)));
 		gistentryinit(*e, dep->pred, dep->rel, dep->page, dep->offset, dep->bytes,
 					  dep->leafkey);
 		if (dep != e)
@@ -1258,7 +1271,9 @@ gistcentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, Relation r,
 	gistentryinit(*e, pr, r, pg, o, b, l);
 	if (giststate->haskeytype)
 	{
-		cep = (GISTENTRY *) ((*fmgr_faddr(&giststate->compressFn)) (e));
+		cep = (GISTENTRY *)
+			DatumGetPointer(FunctionCall1(&giststate->compressFn,
+										  PointerGetDatum(e)));
 		gistentryinit(*e, cep->pred, cep->rel, cep->page, cep->offset, cep->bytes,
 					  cep->leafkey);
 		if (cep != e)
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index fc18377a94a27dba6da8c7e983ac3b10d8defbc5..c08a5cc2fea35d710878ba72d4b7c91fc6f416b4 100644
--- a/src/backend/access/gist/gistget.c
+++ b/src/backend/access/gist/gistget.c
@@ -227,7 +227,7 @@ gistindex_keytest(IndexTuple tuple,
 {
 	bool		isNull;
 	Datum		datum;
-	int			test;
+	Datum		test;
 	GISTENTRY	de;
 
 	IncrIndexProcessed();
@@ -251,19 +251,20 @@ gistindex_keytest(IndexTuple tuple,
 
 		if (key[0].sk_flags & SK_COMMUTE)
 		{
-			test = (*fmgr_faddr(&key[0].sk_func))
-				(DatumGetPointer(key[0].sk_argument),
-				 &de, key[0].sk_procedure) ? 1 : 0;
+			test = FunctionCall3(&key[0].sk_func,
+								 key[0].sk_argument,
+								 PointerGetDatum(&de),
+								 ObjectIdGetDatum(key[0].sk_procedure));
 		}
 		else
 		{
-			test = (*fmgr_faddr(&key[0].sk_func))
-				(&de,
-				 DatumGetPointer(key[0].sk_argument),
-				 key[0].sk_procedure) ? 1 : 0;
+			test = FunctionCall3(&key[0].sk_func,
+								 PointerGetDatum(&de),
+								 key[0].sk_argument,
+								 ObjectIdGetDatum(key[0].sk_procedure));
 		}
 
-		if (!test == !(key[0].sk_flags & SK_NEGATE))
+		if (DatumGetBool(test) == !!(key[0].sk_flags & SK_NEGATE))
 			return false;
 
 		scanKeySize -= 1;
diff --git a/src/backend/access/hash/hashutil.c b/src/backend/access/hash/hashutil.c
index 9a89427521b269570a92c80c04d02dd2ce4e12bb..6685c6eea91103bfd7ced265a7182e1074103d4e 100644
--- a/src/backend/access/hash/hashutil.c
+++ b/src/backend/access/hash/hashutil.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v 1.23 2000/01/26 05:55:55 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v 1.24 2000/05/30 04:24:31 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -91,10 +91,8 @@ _hash_call(Relation rel, HashMetaPage metap, Datum key)
 {
 	uint32		n;
 	Bucket		bucket;
-	RegProcedure proc;
 
-	proc = metap->hashm_procid;
-	n = (uint32) fmgr(proc, key);
+	n = DatumGetUInt32(OidFunctionCall1(metap->hashm_procid, key));
 	bucket = n & metap->hashm_highmask;
 	if (bucket > metap->hashm_maxbucket)
 		bucket = bucket & metap->hashm_lowmask;
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index 43d8a3850f54631c73a8fdc1a0be78f2a8568f74..7f402a33e37e5e39475b45e1d1bc94d872f7f8aa 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.43 2000/05/28 17:55:52 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.44 2000/05/30 04:24:32 tgl Exp $
  *
  * INTERFACE ROUTINES
  *		index_open		- open an index relation by relationId
@@ -195,7 +195,13 @@ index_insert(Relation relation,
 	 * ----------------
 	 */
 	specificResult = (InsertIndexResult)
-		fmgr(procedure, relation, datum, nulls, heap_t_ctid, heapRel, NULL);
+		DatumGetPointer(OidFunctionCall6(procedure,
+										 PointerGetDatum(relation),
+										 PointerGetDatum(datum),
+										 PointerGetDatum(nulls),
+										 PointerGetDatum(heap_t_ctid),
+										 PointerGetDatum(heapRel),
+										 PointerGetDatum(NULL)));
 
 	/* must be pfree'ed */
 	return specificResult;
@@ -213,7 +219,9 @@ index_delete(Relation relation, ItemPointer indexItem)
 	RELATION_CHECKS;
 	GET_REL_PROCEDURE(delete, amdelete);
 
-	fmgr(procedure, relation, indexItem);
+	OidFunctionCall2(procedure,
+					 PointerGetDatum(relation),
+					 PointerGetDatum(indexItem));
 }
 
 /* ----------------
@@ -245,7 +253,11 @@ index_beginscan(Relation relation,
 	LockRelation(relation, AccessShareLock);
 
 	scandesc = (IndexScanDesc)
-		fmgr(procedure, relation, scanFromEnd, numberOfKeys, key);
+		DatumGetPointer(OidFunctionCall4(procedure,
+										 PointerGetDatum(relation),
+										 BoolGetDatum(scanFromEnd),
+										 UInt16GetDatum(numberOfKeys),
+										 PointerGetDatum(key)));
 
 	return scandesc;
 }
@@ -262,7 +274,10 @@ index_rescan(IndexScanDesc scan, bool scanFromEnd, ScanKey key)
 	SCAN_CHECKS;
 	GET_SCAN_PROCEDURE(rescan, amrescan);
 
-	fmgr(procedure, scan, scanFromEnd, key);
+	OidFunctionCall3(procedure,
+					 PointerGetDatum(scan),
+					 BoolGetDatum(scanFromEnd),
+					 PointerGetDatum(key));
 }
 
 /* ----------------
@@ -277,7 +292,7 @@ index_endscan(IndexScanDesc scan)
 	SCAN_CHECKS;
 	GET_SCAN_PROCEDURE(endscan, amendscan);
 
-	fmgr(procedure, scan);
+	OidFunctionCall1(procedure, PointerGetDatum(scan));
 
 	/* Release lock and refcount acquired by index_beginscan */
 
@@ -301,7 +316,7 @@ index_markpos(IndexScanDesc scan)
 	SCAN_CHECKS;
 	GET_SCAN_PROCEDURE(markpos, ammarkpos);
 
-	fmgr(procedure, scan);
+	OidFunctionCall1(procedure, PointerGetDatum(scan));
 }
 
 /* ----------------
@@ -316,7 +331,7 @@ index_restrpos(IndexScanDesc scan)
 	SCAN_CHECKS;
 	GET_SCAN_PROCEDURE(restrpos, amrestrpos);
 
-	fmgr(procedure, scan);
+	OidFunctionCall1(procedure, PointerGetDatum(scan));
 }
 
 /* ----------------
@@ -350,7 +365,9 @@ index_getnext(IndexScanDesc scan,
 	 * ----------------
 	 */
 	result = (RetrieveIndexResult)
-		(*fmgr_faddr(&scan->fn_getnext)) (scan, direction);
+		DatumGetPointer(FunctionCall2(&scan->fn_getnext,
+									  PointerGetDatum(scan),
+									  Int32GetDatum(direction)));
 
 	return result;
 }
diff --git a/src/backend/access/index/istrat.c b/src/backend/access/index/istrat.c
index 5116b622dd1741847eb496782c54e6c35e574ac6..48872cdf680353ce49bf0c403074fffa4b34e460 100644
--- a/src/backend/access/index/istrat.c
+++ b/src/backend/access/index/istrat.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.43 2000/05/28 17:55:52 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.44 2000/05/30 04:24:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -217,15 +217,14 @@ StrategyTermEvaluate(StrategyTerm term,
 					 Datum left,
 					 Datum right)
 {
+	bool		result = false;
 	Index		index;
-	long		tmpres = 0;
-	bool		result = 0;
 	StrategyOperator operator;
-	ScanKey		entry;
 
 	for (index = 0, operator = &term->operatorData[0];
 		 index < term->degree; index += 1, operator += 1)
 	{
+		ScanKey		entry;
 
 		entry = &map->entry[operator->strategy - 1];
 
@@ -234,31 +233,29 @@ StrategyTermEvaluate(StrategyTerm term,
 		switch (operator->flags ^ entry->sk_flags)
 		{
 			case 0x0:
-				tmpres = (long) FMGR_PTR2(&entry->sk_func,
-										  left, right);
+				result = DatumGetBool(FunctionCall2(&entry->sk_func,
+													left, right));
 				break;
 
 			case SK_NEGATE:
-				tmpres = (long) !FMGR_PTR2(&entry->sk_func,
-										   left, right);
+				result = ! DatumGetBool(FunctionCall2(&entry->sk_func,
+													  left, right));
 				break;
 
 			case SK_COMMUTE:
-				tmpres = (long) FMGR_PTR2(&entry->sk_func,
-										  right, left);
+				result = DatumGetBool(FunctionCall2(&entry->sk_func,
+													right, left));
 				break;
 
 			case SK_NEGATE | SK_COMMUTE:
-				tmpres = (long) !FMGR_PTR2(&entry->sk_func,
-										   right, left);
+				result = ! DatumGetBool(FunctionCall2(&entry->sk_func,
+													  right, left));
 				break;
 
 			default:
-				elog(FATAL, "StrategyTermEvaluate: impossible case %d",
+				elog(ERROR, "StrategyTermEvaluate: impossible case %d",
 					 operator->flags ^ entry->sk_flags);
 		}
-
-		result = (bool) tmpres;
 		if (!result)
 			return result;
 	}
diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
index 975b53d658ac0a803bbe713722b8afa283be7fdc..0ec7af2cf962f2112038ef4977ca96d92b8d60f8 100644
--- a/src/backend/access/nbtree/nbtinsert.c
+++ b/src/backend/access/nbtree/nbtinsert.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.57 2000/04/12 17:14:49 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.58 2000/05/30 04:24:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1398,8 +1398,8 @@ _bt_tuplecompare(Relation rel,
 		}
 		else
 		{
-			compare = (int32) FMGR_PTR2(&entry->sk_func,
-										attrDatum1, attrDatum2);
+			compare = DatumGetInt32(FunctionCall2(&entry->sk_func,
+												  attrDatum1, attrDatum2));
 		}
 
 		if (compare != 0)
@@ -1520,7 +1520,7 @@ _bt_isequal(TupleDesc itupdesc, Page page, OffsetNumber offnum,
 	IndexTuple	itup;
 	ScanKey		entry;
 	AttrNumber	attno;
-	long		result;
+	int32		result;
 	int			i;
 	bool		null;
 
@@ -1538,7 +1538,8 @@ _bt_isequal(TupleDesc itupdesc, Page page, OffsetNumber offnum,
 		if (entry->sk_flags & SK_ISNULL || null)
 			return false;
 
-		result = (long) FMGR_PTR2(&entry->sk_func, entry->sk_argument, datum);
+		result = DatumGetInt32(FunctionCall2(&entry->sk_func,
+											 entry->sk_argument, datum));
 		if (result != 0)
 			return false;
 	}
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index cad117e5e6174f239764079d3679ef90c2b61157..54c15b2f6a9b57272c5057e91c18b8c0ae315a03 100644
--- a/src/backend/access/nbtree/nbtsearch.c
+++ b/src/backend/access/nbtree/nbtsearch.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.59 2000/04/12 17:14:49 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.60 2000/05/30 04:24:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,8 +22,8 @@
 
 static BTStack _bt_searchr(Relation rel, int keysz, ScanKey scankey,
 			Buffer *bufP, BTStack stack_in);
-static int _bt_compare(Relation rel, TupleDesc itupdesc, Page page,
-			int keysz, ScanKey scankey, OffsetNumber offnum);
+static int32 _bt_compare(Relation rel, TupleDesc itupdesc, Page page,
+						 int keysz, ScanKey scankey, OffsetNumber offnum);
 static bool
 			_bt_twostep(IndexScanDesc scan, Buffer *bufP, ScanDirection dir);
 static RetrieveIndexResult
@@ -277,14 +277,12 @@ _bt_skeycmp(Relation rel,
 		ScanKey		entry = &scankey[i - 1];
 		Datum		attrDatum;
 		bool		isNull;
-		Datum		keyDatum;
 
 		Assert(entry->sk_attno == i);
 		attrDatum = index_getattr(indexTuple,
 								  entry->sk_attno,
 								  tupDes,
 								  &isNull);
-		keyDatum = entry->sk_argument;
 
 		/* see comments about NULLs handling in btbuild */
 		if (entry->sk_flags & SK_ISNULL)		/* key is NULL */
@@ -299,7 +297,9 @@ _bt_skeycmp(Relation rel,
 			compare = -1;		/* not-NULL key "<" NULL datum */
 		}
 		else
-			compare = (int32) FMGR_PTR2(&entry->sk_func, keyDatum, attrDatum);
+			compare = DatumGetInt32(FunctionCall2(&entry->sk_func,
+												  entry->sk_argument,
+												  attrDatum));
 
 		if (compare != 0)
 			break;				/* done when we find unequal attributes */
@@ -353,7 +353,7 @@ _bt_binsrch(Relation rel,
 				high;
 	bool		haveEq;
 	int			natts = rel->rd_rel->relnatts;
-	int			result;
+	int32		result;
 
 	itupdesc = RelationGetDescr(rel);
 	page = BufferGetPage(buf);
@@ -474,9 +474,9 @@ _bt_binsrch(Relation rel,
  *	_bt_compare() -- Compare scankey to a particular tuple on the page.
  *
  *		This routine returns:
- *			-1 if scankey < tuple at offnum;
+ *			<0 if scankey < tuple at offnum;
  *			 0 if scankey == tuple at offnum;
- *			+1 if scankey > tuple at offnum.
+ *			>0 if scankey > tuple at offnum.
  *
  *		-- Old comments:
  *		In order to avoid having to propagate changes up the tree any time
@@ -492,7 +492,7 @@ _bt_binsrch(Relation rel,
  *		but not "any time a new min key is inserted" (see _bt_insertonpg).
  *				- vadim 12/05/96
  */
-static int
+static int32
 _bt_compare(Relation rel,
 			TupleDesc itupdesc,
 			Page page,
@@ -506,7 +506,7 @@ _bt_compare(Relation rel,
 	BTPageOpaque opaque;
 	ScanKey		entry;
 	AttrNumber	attno;
-	int			result;
+	int32		result;
 	int			i;
 	bool		null;
 
@@ -573,8 +573,6 @@ _bt_compare(Relation rel,
 
 	for (i = 1; i <= keysz; i++)
 	{
-		long		tmpres;
-
 		entry = &scankey[i - 1];
 		attno = entry->sk_attno;
 		datum = index_getattr(itup, attno, itupdesc, &null);
@@ -583,17 +581,17 @@ _bt_compare(Relation rel,
 		if (entry->sk_flags & SK_ISNULL)		/* key is NULL */
 		{
 			if (null)
-				tmpres = (long) 0;		/* NULL "=" NULL */
+				result = 0;		/* NULL "=" NULL */
 			else
-				tmpres = (long) 1;		/* NULL ">" NOT_NULL */
+				result = 1;		/* NULL ">" NOT_NULL */
 		}
 		else if (null)			/* key is NOT_NULL and item is NULL */
 		{
-			tmpres = (long) -1; /* NOT_NULL "<" NULL */
+			result = -1;		/* NOT_NULL "<" NULL */
 		}
 		else
-			tmpres = (long) FMGR_PTR2(&entry->sk_func, entry->sk_argument, datum);
-		result = tmpres;
+			result = DatumGetInt32(FunctionCall2(&entry->sk_func,
+												 entry->sk_argument, datum));
 
 		/* if the keys are unequal, return the difference */
 		if (result != 0)
@@ -697,7 +695,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
 	StrategyNumber strat;
 	RetrieveIndexResult res;
 	RegProcedure proc;
-	int			result;
+	int32		result;
 	BTScanOpaque so;
 	Size		keysok;
 
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index 38b152e61b28b214fa6c3a2afd848bf94fdfc7a7..5853267670fe4f103b6e81d80ceb6703e0a21ae5 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.36 2000/04/12 17:14:50 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.37 2000/05/30 04:24:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -133,7 +133,7 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
 	ScanKeyData *cur;
 	StrategyMap map;
 	int			nbytes;
-	long		test;
+	Datum		test;
 	int			i,
 				j;
 	int			init[BTMaxStrategyNumber + 1];
@@ -212,8 +212,9 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
 					if (j == (BTEqualStrategyNumber - 1) || init[j] == 0)
 						continue;
 					chk = &xform[j];
-					test = (long) fmgr(chk->sk_procedure, eq->sk_argument, chk->sk_argument);
-					if (!test)
+					test = OidFunctionCall2(chk->sk_procedure,
+											eq->sk_argument, chk->sk_argument);
+					if (!DatumGetBool(test))
 						so->qual_ok = 0;
 				}
 				init[BTLessStrategyNumber - 1] = 0;
@@ -241,8 +242,9 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
 				 * anyway.	The transform maps are hard-coded, and can't
 				 * be initialized in the correct way.
 				 */
-				test = (long) fmgr(le->sk_procedure, lt->sk_argument, le->sk_argument);
-				if (test)
+				test = OidFunctionCall2(le->sk_procedure,
+										lt->sk_argument, le->sk_argument);
+				if (DatumGetBool(test))
 					init[BTLessEqualStrategyNumber - 1] = 0;
 				else
 					init[BTLessStrategyNumber - 1] = 0;
@@ -259,8 +261,9 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
 				ge = &xform[BTGreaterEqualStrategyNumber - 1];
 
 				/* see note above on function cache */
-				test = (long) fmgr(ge->sk_procedure, gt->sk_argument, ge->sk_argument);
-				if (test)
+				test = OidFunctionCall2(ge->sk_procedure,
+										gt->sk_argument, ge->sk_argument);
+				if (DatumGetBool(test))
 					init[BTGreaterEqualStrategyNumber - 1] = 0;
 				else
 					init[BTGreaterStrategyNumber - 1] = 0;
@@ -298,8 +301,9 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
 		if (init[j])
 		{
 			/* yup, use the appropriate value */
-			test = (long) FMGR_PTR2(&cur->sk_func, cur->sk_argument, xform[j].sk_argument);
-			if (test)
+			test = FunctionCall2(&cur->sk_func,
+								 cur->sk_argument, xform[j].sk_argument);
+			if (DatumGetBool(test))
 				xform[j].sk_argument = cur->sk_argument;
 			else if (j == (BTEqualStrategyNumber - 1))
 				so->qual_ok = 0;/* key == a && key == b, but a != b */
@@ -385,7 +389,7 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, Size *keysok)
 	ScanKey		key;
 	Datum		datum;
 	bool		isNull;
-	int			test;
+	Datum		test;
 
 	*keysok = 0;
 	if (keysz == 0)
@@ -415,18 +419,16 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, Size *keysok)
 
 		if (key[0].sk_flags & SK_COMMUTE)
 		{
-			test = (int) (*fmgr_faddr(&key[0].sk_func))
-				(DatumGetPointer(key[0].sk_argument),
-				 datum);
+			test = FunctionCall2(&key[0].sk_func,
+								 key[0].sk_argument, datum);
 		}
 		else
 		{
-			test = (int) (*fmgr_faddr(&key[0].sk_func))
-				(datum,
-				 DatumGetPointer(key[0].sk_argument));
+			test = FunctionCall2(&key[0].sk_func,
+								 datum, key[0].sk_argument);
 		}
 
-		if (!test == !(key[0].sk_flags & SK_NEGATE))
+		if (DatumGetBool(test) == !!(key[0].sk_flags & SK_NEGATE))
 			return false;
 
 		keysz -= 1;
diff --git a/src/backend/access/rtree/rtree.c b/src/backend/access/rtree/rtree.c
index 2de19275771b2d45d569a2529116aaae682f1491..020f6bdff821041b12281dee5f225444d188427f 100644
--- a/src/backend/access/rtree/rtree.c
+++ b/src/backend/access/rtree/rtree.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.46 2000/05/30 00:49:41 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.47 2000/05/30 04:24:34 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -415,10 +415,18 @@ rttighten(Relation r,
 	oldud = (char *) PageGetItem(p, PageGetItemId(p, stk->rts_child));
 	oldud += sizeof(IndexTupleData);
 
-	(*fmgr_faddr(&rtstate->sizeFn)) (oldud, &old_size);
-	datum = (char *) (*fmgr_faddr(&rtstate->unionFn)) (oldud, datum);
+	FunctionCall2(&rtstate->sizeFn,
+				  PointerGetDatum(oldud),
+				  PointerGetDatum(&old_size));
 
-	(*fmgr_faddr(&rtstate->sizeFn)) (datum, &newd_size);
+	datum = (char *)
+		DatumGetPointer(FunctionCall2(&rtstate->unionFn,
+									  PointerGetDatum(oldud),
+									  PointerGetDatum(datum)));
+
+	FunctionCall2(&rtstate->sizeFn,
+				  PointerGetDatum(datum),
+				  PointerGetDatum(&newd_size));
 
 	if (newd_size != old_size)
 	{
@@ -445,7 +453,10 @@ rttighten(Relation r,
 		 * union proc, which is guaranteed to return a rectangle.
 		 */
 
-		tdatum = (char *) (*fmgr_faddr(&rtstate->unionFn)) (datum, datum);
+		tdatum = (char *)
+			DatumGetPointer(FunctionCall2(&rtstate->unionFn,
+										  PointerGetDatum(datum),
+										  PointerGetDatum(datum)));
 		rttighten(r, stk->rts_parent, tdatum, att_size, rtstate);
 		pfree(tdatum);
 	}
@@ -665,7 +676,10 @@ rtintinsert(Relation r,
 		WriteBuffer(b);
 		ldatum = (((char *) ltup) + sizeof(IndexTupleData));
 		rdatum = (((char *) rtup) + sizeof(IndexTupleData));
-		newdatum = (char *) (*fmgr_faddr(&rtstate->unionFn)) (ldatum, rdatum);
+		newdatum = (char *)
+			DatumGetPointer(FunctionCall2(&rtstate->unionFn,
+										  PointerGetDatum(ldatum),
+										  PointerGetDatum(rdatum)));
 
 		rttighten(r, stk->rts_parent, newdatum,
 			   (IndexTupleSize(rtup) - sizeof(IndexTupleData)), rtstate);
@@ -744,10 +758,20 @@ picksplit(Relation r,
 			datum_beta = ((char *) item_2) + sizeof(IndexTupleData);
 
 			/* compute the wasted space by unioning these guys */
-			union_d = (char *) (*fmgr_faddr(&rtstate->unionFn)) (datum_alpha, datum_beta);
-			(*fmgr_faddr(&rtstate->sizeFn)) (union_d, &size_union);
-			inter_d = (char *) (*fmgr_faddr(&rtstate->interFn)) (datum_alpha, datum_beta);
-			(*fmgr_faddr(&rtstate->sizeFn)) (inter_d, &size_inter);
+			union_d = (char *)
+				DatumGetPointer(FunctionCall2(&rtstate->unionFn,
+											  PointerGetDatum(datum_alpha),
+											  PointerGetDatum(datum_beta)));
+			FunctionCall2(&rtstate->sizeFn,
+						  PointerGetDatum(union_d),
+						  PointerGetDatum(&size_union));
+			inter_d = (char *)
+				DatumGetPointer(FunctionCall2(&rtstate->interFn,
+											  PointerGetDatum(datum_alpha),
+											  PointerGetDatum(datum_beta)));
+			FunctionCall2(&rtstate->sizeFn,
+						  PointerGetDatum(inter_d),
+						  PointerGetDatum(&size_inter));
 			size_waste = size_union - size_inter;
 
 			pfree(union_d);
@@ -777,12 +801,22 @@ picksplit(Relation r,
 
 	item_1 = (IndexTuple) PageGetItem(page, PageGetItemId(page, seed_1));
 	datum_alpha = ((char *) item_1) + sizeof(IndexTupleData);
-	datum_l = (char *) (*fmgr_faddr(&rtstate->unionFn)) (datum_alpha, datum_alpha);
-	(*fmgr_faddr(&rtstate->sizeFn)) (datum_l, &size_l);
+	datum_l = (char *)
+		DatumGetPointer(FunctionCall2(&rtstate->unionFn,
+									  PointerGetDatum(datum_alpha),
+									  PointerGetDatum(datum_alpha)));
+	FunctionCall2(&rtstate->sizeFn,
+				  PointerGetDatum(datum_l),
+				  PointerGetDatum(&size_l));
 	item_2 = (IndexTuple) PageGetItem(page, PageGetItemId(page, seed_2));
 	datum_beta = ((char *) item_2) + sizeof(IndexTupleData);
-	datum_r = (char *) (*fmgr_faddr(&rtstate->unionFn)) (datum_beta, datum_beta);
-	(*fmgr_faddr(&rtstate->sizeFn)) (datum_r, &size_r);
+	datum_r = (char *)
+		DatumGetPointer(FunctionCall2(&rtstate->unionFn,
+									  PointerGetDatum(datum_beta),
+									  PointerGetDatum(datum_beta)));
+	FunctionCall2(&rtstate->sizeFn,
+				  PointerGetDatum(datum_r),
+				  PointerGetDatum(&size_r));
 
 	/*
 	 * Now split up the regions between the two seeds.	An important
@@ -826,10 +860,20 @@ picksplit(Relation r,
 			item_1 = (IndexTuple) PageGetItem(page, PageGetItemId(page, i));
 
 		datum_alpha = ((char *) item_1) + sizeof(IndexTupleData);
-		union_dl = (char *) (*fmgr_faddr(&rtstate->unionFn)) (datum_l, datum_alpha);
-		union_dr = (char *) (*fmgr_faddr(&rtstate->unionFn)) (datum_r, datum_alpha);
-		(*fmgr_faddr(&rtstate->sizeFn)) (union_dl, &size_alpha);
-		(*fmgr_faddr(&rtstate->sizeFn)) (union_dr, &size_beta);
+		union_dl = (char *)
+			DatumGetPointer(FunctionCall2(&rtstate->unionFn,
+										  PointerGetDatum(datum_l),
+										  PointerGetDatum(datum_alpha)));
+		union_dr = (char *)
+			DatumGetPointer(FunctionCall2(&rtstate->unionFn,
+										  PointerGetDatum(datum_r),
+										  PointerGetDatum(datum_alpha)));
+		FunctionCall2(&rtstate->sizeFn,
+					  PointerGetDatum(union_dl),
+					  PointerGetDatum(&size_alpha));
+		FunctionCall2(&rtstate->sizeFn,
+					  PointerGetDatum(union_dr),
+					  PointerGetDatum(&size_beta));
 
 		/* pick which page to add it to */
 		if (size_alpha - size_l < size_beta - size_r)
@@ -896,9 +940,16 @@ choose(Relation r, Page p, IndexTuple it, RTSTATE *rtstate)
 	{
 		datum = (char *) PageGetItem(p, PageGetItemId(p, i));
 		datum += sizeof(IndexTupleData);
-		(*fmgr_faddr(&rtstate->sizeFn)) (datum, &dsize);
-		ud = (char *) (*fmgr_faddr(&rtstate->unionFn)) (datum, id);
-		(*fmgr_faddr(&rtstate->sizeFn)) (ud, &usize);
+		FunctionCall2(&rtstate->sizeFn,
+					  PointerGetDatum(datum),
+					  PointerGetDatum(&dsize));
+		ud = (char *)
+			DatumGetPointer(FunctionCall2(&rtstate->unionFn,
+										  PointerGetDatum(datum),
+										  PointerGetDatum(id)));
+		FunctionCall2(&rtstate->sizeFn,
+					  PointerGetDatum(ud),
+					  PointerGetDatum(&usize));
 		pfree(ud);
 		if (which_grow < 0 || usize - dsize < which_grow)
 		{
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index beb4b079045f4ca7c14b2107309693df87e95e60..1d38ab1fb4b6a54f6fde9233cff954a057f13131 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.82 2000/05/28 17:55:53 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.83 2000/05/30 04:24:35 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -139,7 +139,7 @@ static char Blanks[MAXATTR];
 static char *relname;			/* current relation name */
 
 Form_pg_attribute attrtypes[MAXATTR];	/* points to attribute info */
-static char *values[MAXATTR];	/* cooresponding attribute values */
+static Datum values[MAXATTR];	/* corresponding attribute values */
 int			numattr;			/* number of attributes for cur. rel */
 
 int			DebugMode;
@@ -622,7 +622,7 @@ InsertOneTuple(Oid objectid)
 	}
 
 	tupDesc = CreateTupleDesc(numattr, attrtypes);
-	tuple = heap_formtuple(tupDesc, (Datum *) values, Blanks);
+	tuple = heap_formtuple(tupDesc, values, Blanks);
 	pfree(tupDesc);				/* just free's tupDesc, not the attrtypes */
 
 	if (objectid != (Oid) 0)
@@ -678,13 +678,14 @@ InsertOneValue(Oid objectid, char *value, int i)
 				);
 			Assert(0);
 		}
-		values[i] = fmgr(ap->am_typ.typinput,
-						 value,
-						 ap->am_typ.typelem,
-						 -1);
-		prt = fmgr(ap->am_typ.typoutput, values[i],
-				   ap->am_typ.typelem,
-				   -1);
+		values[i] = OidFunctionCall3(ap->am_typ.typinput,
+									 CStringGetDatum(value),
+									 ObjectIdGetDatum(ap->am_typ.typelem),
+									 Int32GetDatum(-1));
+		prt = DatumGetCString(OidFunctionCall3(ap->am_typ.typoutput,
+							  values[i],
+							  ObjectIdGetDatum(ap->am_typ.typelem),
+							  Int32GetDatum(-1)));
 		if (!Quiet)
 			printf("%s ", prt);
 		pfree(prt);
@@ -700,10 +701,14 @@ InsertOneValue(Oid objectid, char *value, int i)
 			elog(ERROR, "can't find type OID %u", attrtypes[i]->atttypid);
 		if (DebugMode)
 			printf("Typ == NULL, typeindex = %u idx = %d\n", typeindex, i);
-		values[i] = fmgr(Procid[typeindex].inproc, value,
-						 Procid[typeindex].elem, -1);
-		prt = fmgr(Procid[typeindex].outproc, values[i],
-				   Procid[typeindex].elem);
+		values[i] = OidFunctionCall3(Procid[typeindex].inproc,
+									 CStringGetDatum(value),
+									 ObjectIdGetDatum(Procid[typeindex].elem),
+									 Int32GetDatum(-1));
+		prt = DatumGetCString(OidFunctionCall3(Procid[typeindex].outproc,
+							  values[i],
+							  ObjectIdGetDatum(Procid[typeindex].elem),
+							  Int32GetDatum(-1)));
 		if (!Quiet)
 			printf("%s ", prt);
 		pfree(prt);
@@ -726,7 +731,7 @@ InsertOneNull(int i)
 		printf("Inserting null\n");
 	if (i < 0 || i >= MAXATTR)
 		elog(FATAL, "i out of range (too many attrs): %d\n", i);
-	values[i] = (char *) NULL;
+	values[i] = PointerGetDatum(NULL);
 	Blanks[i] = 'n';
 }
 
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index f64902f6cb43b716e06826173f30dfe00ea1fd3d..445f1caf2a5187b2021a09b263619f8a157333bb 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.112 2000/05/30 00:49:42 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.113 2000/05/30 04:24:35 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1922,16 +1922,16 @@ index_build(Relation heapRelation,
 	 * ----------------
 	 */
 	if (RegProcedureIsValid(procedure))
-		fmgr(procedure,
-			 heapRelation,
-			 indexRelation,
-			 numberOfAttributes,
-			 attributeNumber,
-			 RelationGetIndexStrategy(indexRelation),
-			 parameterCount,
-			 parameter,
-			 funcInfo,
-			 predInfo);
+		OidFunctionCall9(procedure,
+						 PointerGetDatum(heapRelation),
+						 PointerGetDatum(indexRelation),
+						 Int32GetDatum(numberOfAttributes),
+						 PointerGetDatum(attributeNumber),
+						 PointerGetDatum(RelationGetIndexStrategy(indexRelation)),
+						 UInt16GetDatum(parameterCount),
+						 PointerGetDatum(parameter),
+						 PointerGetDatum(funcInfo),
+						 PointerGetDatum(predInfo));
 	else
 		DefaultBuild(heapRelation,
 					 indexRelation,
diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index 03db7bf7d7f56802b2bf012ad854e649c67b39bc..37c6a8cb41d87bbf50d47a570936e65fcec88108 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.32 2000/04/16 04:16:09 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.33 2000/05/30 04:24:36 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -268,7 +268,7 @@ AggregateCreate(char *aggName,
 	heap_close(aggdesc, RowExclusiveLock);
 }
 
-char *
+Datum
 AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull)
 {
 	HeapTuple	tup;
@@ -278,8 +278,8 @@ AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull)
 				typinput,
 				typelem;
 	text	   *textInitVal;
-	char	   *strInitVal,
-			   *initVal;
+	char	   *strInitVal;
+	Datum		initVal;
 
 	Assert(PointerIsValid(aggName));
 	Assert(PointerIsValid(isNull));
@@ -320,7 +320,7 @@ AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull)
 	if (*isNull)
 	{
 		heap_close(aggRel, AccessShareLock);
-		return (char *) NULL;
+		return PointerGetDatum(NULL);
 	}
 	strInitVal = textout(textInitVal);
 
@@ -337,7 +337,10 @@ AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull)
 	typinput = ((Form_pg_type) GETSTRUCT(tup))->typinput;
 	typelem = ((Form_pg_type) GETSTRUCT(tup))->typelem;
 
-	initVal = fmgr(typinput, strInitVal, typelem, -1);
+	initVal = OidFunctionCall3(typinput,
+							   CStringGetDatum(strInitVal),
+							   ObjectIdGetDatum(typelem),
+							   Int32GetDatum(-1));
 
 	pfree(strInitVal);
 	return initVal;
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 9428ba1ee5f05d55cab33bc71a0c3f6d68e6b8a4..719e20a4161f23508392bc9f4c3400ddb370be47 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.1 2000/05/29 17:44:17 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.2 2000/05/30 04:25:00 tgl Exp $
  *
 
  *-------------------------------------------------------------------------
@@ -236,7 +236,7 @@ analyze_rel(Oid relid, List *anal_cols2, int MESSAGE_LEVEL)
  *	frequently in each column.	These figures are used to compute
  *	the selectivity of the column.
  *
- *	We use a three-bucked cache to get the most frequent item.
+ *	We use a three-bucket cache to get the most frequent item.
  *	The 'guess' buckets count hits.  A cache miss causes guess1
  *	to get the most hit 'guess' item in the most recent cycle, and
  *	the new item goes into guess2.	Whenever the total count of hits
@@ -254,101 +254,114 @@ attr_stats(Relation onerel, int attr_cnt, VacAttrStats *vacattrstats, HeapTuple
 {
 	int			i;
 	TupleDesc	tupDesc = onerel->rd_att;
-	Datum		value;
-	bool		isnull;
 
 	for (i = 0; i < attr_cnt; i++)
 	{
 		VacAttrStats *stats = &vacattrstats[i];
-		bool		value_hit = true;
+		Datum		value;
+		bool		isnull;
+		bool		value_hit;
+
+		if (!VacAttrStatsEqValid(stats))
+			continue;
 
 #ifdef	_DROP_COLUMN_HACK__
 		if (COLUMN_IS_DROPPED(stats->attr))
 			continue;
 #endif	 /* _DROP_COLUMN_HACK__ */
+
 		value = heap_getattr(tuple,
 							 stats->attr->attnum, tupDesc, &isnull);
 
-		if (!VacAttrStatsEqValid(stats))
-			continue;
-
 		if (isnull)
+		{
 			stats->null_cnt++;
-		else
+			continue;
+		}
+
+		stats->nonnull_cnt++;
+		if (! stats->initialized)
 		{
-			stats->nonnull_cnt++;
-			if (stats->initialized == false)
-			{
-				bucketcpy(stats->attr, value, &stats->best, &stats->best_len);
-				/* best_cnt gets incremented later */
-				bucketcpy(stats->attr, value, &stats->guess1, &stats->guess1_len);
-				stats->guess1_cnt = stats->guess1_hits = 1;
-				bucketcpy(stats->attr, value, &stats->guess2, &stats->guess2_len);
-				stats->guess2_hits = 1;
-				if (VacAttrStatsLtGtValid(stats))
-				{
-					bucketcpy(stats->attr, value, &stats->max, &stats->max_len);
-					bucketcpy(stats->attr, value, &stats->min, &stats->min_len);
-				}
-				stats->initialized = true;
-			}
+			bucketcpy(stats->attr, value, &stats->best, &stats->best_len);
+			/* best_cnt gets incremented below */
+			bucketcpy(stats->attr, value, &stats->guess1, &stats->guess1_len);
+			stats->guess1_cnt = stats->guess1_hits = 1;
+			bucketcpy(stats->attr, value, &stats->guess2, &stats->guess2_len);
+			stats->guess2_hits = 1;
 			if (VacAttrStatsLtGtValid(stats))
 			{
-				if ((*fmgr_faddr(&stats->f_cmplt)) (value, stats->min))
-				{
-					bucketcpy(stats->attr, value, &stats->min, &stats->min_len);
-					stats->min_cnt = 0;
-				}
-				if ((*fmgr_faddr(&stats->f_cmpgt)) (value, stats->max))
-				{
-					bucketcpy(stats->attr, value, &stats->max, &stats->max_len);
-					stats->max_cnt = 0;
-				}
-				if ((*fmgr_faddr(&stats->f_cmpeq)) (value, stats->min))
-					stats->min_cnt++;
-				else if ((*fmgr_faddr(&stats->f_cmpeq)) (value, stats->max))
-					stats->max_cnt++;
+				bucketcpy(stats->attr, value, &stats->max, &stats->max_len);
+				bucketcpy(stats->attr, value, &stats->min, &stats->min_len);
+				/* min_cnt, max_cnt get incremented below */
 			}
-			if ((*fmgr_faddr(&stats->f_cmpeq)) (value, stats->best))
-				stats->best_cnt++;
-			else if ((*fmgr_faddr(&stats->f_cmpeq)) (value, stats->guess1))
-			{
-				stats->guess1_cnt++;
-				stats->guess1_hits++;
-			}
-			else if ((*fmgr_faddr(&stats->f_cmpeq)) (value, stats->guess2))
-				stats->guess2_hits++;
-			else
-				value_hit = false;
+			stats->initialized = true;
+		}
 
-			if (stats->guess2_hits > stats->guess1_hits)
-			{
-				swapDatum(stats->guess1, stats->guess2);
-				swapInt(stats->guess1_len, stats->guess2_len);
-				swapLong(stats->guess1_hits, stats->guess2_hits);
-				stats->guess1_cnt = stats->guess1_hits;
-			}
-			if (stats->guess1_cnt > stats->best_cnt)
+		if (VacAttrStatsLtGtValid(stats))
+		{
+			if (DatumGetBool(FunctionCall2(&stats->f_cmplt,
+										   value, stats->min)))
 			{
-				swapDatum(stats->best, stats->guess1);
-				swapInt(stats->best_len, stats->guess1_len);
-				swapLong(stats->best_cnt, stats->guess1_cnt);
-				stats->guess1_hits = 1;
-				stats->guess2_hits = 1;
+				bucketcpy(stats->attr, value, &stats->min, &stats->min_len);
+				stats->min_cnt = 1;
 			}
-			if (!value_hit)
+			else if (DatumGetBool(FunctionCall2(&stats->f_cmpeq,
+												value, stats->min)))
+				stats->min_cnt++;
+
+			if (DatumGetBool(FunctionCall2(&stats->f_cmpgt,
+										   value, stats->max)))
 			{
-				bucketcpy(stats->attr, value, &stats->guess2, &stats->guess2_len);
-				stats->guess1_hits = 1;
-				stats->guess2_hits = 1;
+				bucketcpy(stats->attr, value, &stats->max, &stats->max_len);
+				stats->max_cnt = 1;
 			}
+			else if (DatumGetBool(FunctionCall2(&stats->f_cmpeq,
+												value, stats->max)))
+				stats->max_cnt++;
+		}
+
+		value_hit = true;
+		if (DatumGetBool(FunctionCall2(&stats->f_cmpeq,
+									   value, stats->best)))
+			stats->best_cnt++;
+		else if (DatumGetBool(FunctionCall2(&stats->f_cmpeq,
+											value, stats->guess1)))
+		{
+			stats->guess1_cnt++;
+			stats->guess1_hits++;
+		}
+		else if (DatumGetBool(FunctionCall2(&stats->f_cmpeq,
+											value, stats->guess2)))
+			stats->guess2_hits++;
+		else
+			value_hit = false;
+
+		if (stats->guess2_hits > stats->guess1_hits)
+		{
+			swapDatum(stats->guess1, stats->guess2);
+			swapInt(stats->guess1_len, stats->guess2_len);
+			swapLong(stats->guess1_hits, stats->guess2_hits);
+			stats->guess1_cnt = stats->guess1_hits;
+		}
+		if (stats->guess1_cnt > stats->best_cnt)
+		{
+			swapDatum(stats->best, stats->guess1);
+			swapInt(stats->best_len, stats->guess1_len);
+			swapLong(stats->best_cnt, stats->guess1_cnt);
+			stats->guess1_hits = 1;
+			stats->guess2_hits = 1;
+		}
+		if (!value_hit)
+		{
+			bucketcpy(stats->attr, value, &stats->guess2, &stats->guess2_len);
+			stats->guess1_hits = 1;
+			stats->guess2_hits = 1;
 		}
 	}
-	return;
 }
 
 /*
- *	bucketcpy() -- update pg_class statistics for one relation
+ *	bucketcpy() -- copy a new value into one of the statistics buckets
  *
  */
 static void
@@ -367,7 +380,7 @@ bucketcpy(Form_pg_attribute attr, Datum value, Datum *bucket, int *bucket_len)
 			*bucket = PointerGetDatum(palloc(len));
 			*bucket_len = len;
 		}
-		memmove(DatumGetPointer(*bucket), DatumGetPointer(value), len);
+		memcpy(DatumGetPointer(*bucket), DatumGetPointer(value), len);
 	}
 }
 
@@ -525,19 +538,28 @@ update_attstats(Oid relid, int natts, VacAttrStats *vacattrstats)
 				 * ----------------
 				 */
 				i = 0;
-				values[i++] = (Datum) relid;		/* starelid */
-				values[i++] = (Datum) attp->attnum; /* staattnum */
-				values[i++] = (Datum) stats->op_cmplt;		/* staop */
+				values[i++] = ObjectIdGetDatum(relid);		/* starelid */
+				values[i++] = Int16GetDatum(attp->attnum);	/* staattnum */
+				values[i++] = ObjectIdGetDatum(stats->op_cmplt); /* staop */
 				/* hack: this code knows float4 is pass-by-ref */
-				values[i++] = PointerGetDatum(&nullratio);	/* stanullfrac */
-				values[i++] = PointerGetDatum(&bestratio);	/* stacommonfrac */
-				out_string = (*fmgr_faddr(&out_function)) (stats->best, stats->typelem, stats->attr->atttypmod);
+				values[i++] = Float32GetDatum(&nullratio);	/* stanullfrac */
+				values[i++] = Float32GetDatum(&bestratio);	/* stacommonfrac */
+				out_string = DatumGetCString(FunctionCall3(&out_function,
+											 stats->best,
+											 ObjectIdGetDatum(stats->typelem),
+											 Int32GetDatum(stats->attr->atttypmod)));
 				values[i++] = PointerGetDatum(textin(out_string));	/* stacommonval */
 				pfree(out_string);
-				out_string = (*fmgr_faddr(&out_function)) (stats->min, stats->typelem, stats->attr->atttypmod);
+				out_string = DatumGetCString(FunctionCall3(&out_function,
+											 stats->min,
+											 ObjectIdGetDatum(stats->typelem),
+											 Int32GetDatum(stats->attr->atttypmod)));
 				values[i++] = PointerGetDatum(textin(out_string));	/* staloval */
 				pfree(out_string);
-				out_string = (char *) (*fmgr_faddr(&out_function)) (stats->max, stats->typelem, stats->attr->atttypmod);
+				out_string = DatumGetCString(FunctionCall3(&out_function,
+											 stats->max,
+											 ObjectIdGetDatum(stats->typelem),
+											 Int32GetDatum(stats->attr->atttypmod)));
 				values[i++] = PointerGetDatum(textin(out_string));	/* stahival */
 				pfree(out_string);
 
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 5382effb198a2cd6357cd3c879a7b82101a5d175..fe8a3223c1dc02d8863745e9572808bdf0ea53d9 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.108 2000/05/30 00:49:43 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.109 2000/05/30 04:25:00 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -501,8 +501,10 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
 #endif	 /* _DROP_COLUMN_HACK__ */
 				if (!isnull)
 				{
-					string = (char *) (*fmgr_faddr(&out_functions[i]))
-						(value, elements[i], typmod[i]);
+					string = DatumGetCString(FunctionCall3(&out_functions[i],
+												value,
+												ObjectIdGetDatum(elements[i]),
+												Int32GetDatum(typmod[i])));
 					CopyAttributeOut(fp, string, delim);
 					pfree(string);
 				}
@@ -814,17 +816,10 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
 					done = 1;
 				else
 				{
-					values[i] = (Datum) (*fmgr_faddr(&in_functions[i])) (string,
-															 elements[i],
-															  typmod[i]);
-
-					/*
-					 * Sanity check - by reference attributes cannot
-					 * return NULL
-					 */
-					if (!PointerIsValid(values[i]) &&
-						!(rel->rd_att->attrs[i]->attbyval))
-						elog(ERROR, "COPY: Bad file format");
+					values[i] = FunctionCall3(&in_functions[i],
+											  CStringGetDatum(string),
+											  ObjectIdGetDatum(elements[i]),
+											  Int32GetDatum(typmod[i]));
 				}
 			}
 			if (!done)
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 61bfb3c6d31ca82b1f91f7e12d82c7288291e084..1999acedc12561e3186f9dcc7aa95351546d16de 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -32,7 +32,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.65 2000/05/30 00:49:44 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.66 2000/05/30 04:24:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -327,12 +327,10 @@ finalize_aggregate(AggStatePerAgg peraggstate,
 				continue;
 			if (haveOldVal)
 			{
-				Datum		equal;
-
-				equal = (Datum) (*fmgr_faddr(&peraggstate->equalfn)) (oldVal,
-																 newVal);
-				if (DatumGetInt32(equal) != 0)
+				if (DatumGetBool(FunctionCall2(&peraggstate->equalfn,
+											   oldVal, newVal)))
 				{
+					/* equal to prior, so forget this one */
 					if (!peraggstate->inputtypeByVal)
 						pfree(DatumGetPointer(newVal));
 					continue;
@@ -780,13 +778,13 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
 				 typeidTypeName(aggref->basetype));
 		aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple);
 
-		peraggstate->initValue1 = (Datum)
+		peraggstate->initValue1 =
 			AggNameGetInitVal(aggname,
 							  aggform->aggbasetype,
 							  1,
 							  &peraggstate->initValue1IsNull);
 
-		peraggstate->initValue2 = (Datum)
+		peraggstate->initValue2 =
 			AggNameGetInitVal(aggname,
 							  aggform->aggbasetype,
 							  2,
diff --git a/src/backend/executor/nodeGroup.c b/src/backend/executor/nodeGroup.c
index eead721dacbae8b4f8572d69698757c6fbbb6929..d1ae02616c1440493c9ab0eeca2f63c9504a83ab 100644
--- a/src/backend/executor/nodeGroup.c
+++ b/src/backend/executor/nodeGroup.c
@@ -15,7 +15,7 @@
  *	  locate group boundaries.
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.35 2000/05/30 00:49:44 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.36 2000/05/30 04:24:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -430,7 +430,6 @@ execTuplesMatch(HeapTuple tuple1,
 					attr2;
 		bool		isNull1,
 					isNull2;
-		Datum		equal;
 
 		attr1 = heap_getattr(tuple1,
 							 att,
@@ -450,9 +449,8 @@ execTuplesMatch(HeapTuple tuple1,
 
 		/* Apply the type-specific equality function */
 
-		equal = (Datum) (*fmgr_faddr(&eqfunctions[i])) (attr1, attr2);
-
-		if (DatumGetInt32(equal) == 0)
+		if (! DatumGetBool(FunctionCall2(&eqfunctions[i],
+										 attr1, attr2)))
 			return FALSE;
 	}
 
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 016d15ae8ac56a0c6a4b38aeda401240ed7160d2..ac86695ee1b44f35bcbecc6a325a3a2bc6ab0708 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -3,7 +3,7 @@
  * spi.c
  *				Server Programming Interface
  *
- * $Id: spi.c,v 1.45 2000/04/04 21:44:39 tgl Exp $
+ * $Id: spi.c,v 1.46 2000/05/30 04:24:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -415,8 +415,10 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
 		return NULL;
 	}
 
-	return (fmgr(foutoid, val, typelem,
-				 tupdesc->attrs[fnumber - 1]->atttypmod));
+	return DatumGetCString(OidFunctionCall3(foutoid,
+						   val,
+						   ObjectIdGetDatum(typelem),
+						   Int32GetDatum(tupdesc->attrs[fnumber - 1]->atttypmod)));
 }
 
 Datum
diff --git a/src/backend/libpq/be-dumpdata.c b/src/backend/libpq/be-dumpdata.c
index fcc63e1e2a0e0179cb50a844d2e2cf14c361059c..8bcb77f98e04cb945b747fa9580095c940daa182 100644
--- a/src/backend/libpq/be-dumpdata.c
+++ b/src/backend/libpq/be-dumpdata.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *	$Id: be-dumpdata.c,v 1.33 2000/04/12 17:15:14 momjian Exp $
+ *	$Id: be-dumpdata.c,v 1.34 2000/05/30 04:24:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -306,8 +306,10 @@ be_printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
 		}
 
 		if (!isnull && OidIsValid(typoutput))
-			values[i] = fmgr(typoutput, attr, typelem,
-							 typeinfo->attrs[i]->atttypmod);
+			values[i] = DatumGetCString(OidFunctionCall3(typoutput,
+										attr,
+										ObjectIdGetDatum(typelem),
+										Int32GetDatum(typeinfo->attrs[i]->atttypmod)));
 		else
 			values[i] = NULL;
 
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index e1c66c105f81480f33ed71ab5c1ee40d6810e1e1..dd710ca2f761ea168d79ea80c60ed635861df0d2 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -42,7 +42,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.59 2000/05/30 00:49:46 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.60 2000/05/30 04:24:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -240,8 +240,14 @@ cost_index(Path *path, Query *root,
 	 * index (ie, the fraction of main-table tuples we will have to
 	 * retrieve).
 	 */
-	fmgr(index->amcostestimate, root, baserel, index, indexQuals,
-		 &indexStartupCost, &indexTotalCost, &indexSelectivity);
+	OidFunctionCall7(index->amcostestimate,
+					 PointerGetDatum(root),
+					 PointerGetDatum(baserel),
+					 PointerGetDatum(index),
+					 PointerGetDatum(indexQuals),
+					 PointerGetDatum(&indexStartupCost),
+					 PointerGetDatum(&indexTotalCost),
+					 PointerGetDatum(&indexSelectivity));
 
 	/* all costs for touching index itself included here */
 	startup_cost += indexStartupCost;
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 91f57dc14134347e8df2847bd37137831fa2e853..34f687809f148772d4c19c94fd326a1db2d55992 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.52 2000/05/30 00:49:49 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.53 2000/05/30 04:24:48 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -195,22 +195,19 @@ restriction_selectivity(Oid functionObjectId,
 						Datum constValue,
 						int constFlag)
 {
-	float64		result;
-
-	result = (float64) fmgr(functionObjectId,
-							(char *) operatorObjectId,
-							(char *) relationObjectId,
-							(char *) (int) attributeNumber,
-							(char *) constValue,
-							(char *) constFlag,
-							NULL);
-	if (!PointerIsValid(result))
-		elog(ERROR, "restriction_selectivity: bad pointer");
-
-	if (*result < 0.0 || *result > 1.0)
-		elog(ERROR, "restriction_selectivity: bad value %f", *result);
-
-	return (Selectivity) *result;
+	float8		result;
+
+	result = DatumGetFloat8(OidFunctionCall5(functionObjectId,
+							ObjectIdGetDatum(operatorObjectId),
+							ObjectIdGetDatum(relationObjectId),
+							Int16GetDatum(attributeNumber),
+							constValue,
+							Int32GetDatum(constFlag)));
+
+	if (result < 0.0 || result > 1.0)
+		elog(ERROR, "restriction_selectivity: bad value %f", result);
+
+	return (Selectivity) result;
 }
 
 /*
@@ -231,22 +228,19 @@ join_selectivity(Oid functionObjectId,
 				 Oid relationObjectId2,
 				 AttrNumber attributeNumber2)
 {
-	float64		result;
-
-	result = (float64) fmgr(functionObjectId,
-							(char *) operatorObjectId,
-							(char *) relationObjectId1,
-							(char *) (int) attributeNumber1,
-							(char *) relationObjectId2,
-							(char *) (int) attributeNumber2,
-							NULL);
-	if (!PointerIsValid(result))
-		elog(ERROR, "join_selectivity: bad pointer");
-
-	if (*result < 0.0 || *result > 1.0)
-		elog(ERROR, "join_selectivity: bad value %f", *result);
-
-	return (Selectivity) *result;
+	float8		result;
+
+	result = DatumGetFloat8(OidFunctionCall5(functionObjectId,
+							ObjectIdGetDatum(operatorObjectId),
+							ObjectIdGetDatum(relationObjectId1),
+							Int16GetDatum(attributeNumber1),
+							ObjectIdGetDatum(relationObjectId2),
+							Int16GetDatum(attributeNumber2)));
+
+	if (result < 0.0 || result > 1.0)
+		elog(ERROR, "join_selectivity: bad value %f", result);
+
+	return (Selectivity) result;
 }
 
 /*
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
index 3fc2c623fd5b903a7aa5aada732bf4484d71276f..ac4f94ec957bdab72e8473237f304c3e271c9221 100644
--- a/src/backend/parser/parse_type.c
+++ b/src/backend/parser/parse_type.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.29 2000/01/26 05:56:42 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.30 2000/05/30 04:24:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -143,7 +143,10 @@ stringTypeDatum(Type tp, char *string, int32 atttypmod)
 	op = ((Form_pg_type) GETSTRUCT(tp))->typinput;
 	typelem = ((Form_pg_type) GETSTRUCT(tp))->typelem;	/* XXX - used for
 														 * array_in */
-	return (Datum) fmgr(op, string, typelem, atttypmod);
+	return OidFunctionCall3(op,
+							CStringGetDatum(string),
+							ObjectIdGetDatum(typelem),
+							Int32GetDatum(atttypmod));
 }
 
 /* Given a type id, returns the out-conversion function of the type */
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index bd9ab6c60e75ec206f829262f5f0f243fa577168..6e6d32e08dab4b035012ab4a8365884b147a604d 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.53 2000/05/29 21:02:32 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.54 2000/05/30 04:24:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -441,7 +441,10 @@ _ReadArrayStr(char *arrayStr,
 		*q = '\0';
 		if (i >= nitems)
 			elog(ERROR, "array_in: illformed array constant");
-		values[i] = (*fmgr_faddr(inputproc)) (p, typelem, typmod);
+		values[i] = (char *) FunctionCall3(inputproc,
+										   CStringGetDatum(p),
+										   ObjectIdGetDatum(typelem),
+										   Int32GetDatum(typmod));
 		p = ++q;
 		if (!eoArray)
 
@@ -669,21 +672,33 @@ array_out(ArrayType *v, Oid element_type)
 			switch (typlen)
 			{
 				case 1:
-					values[i] = (*fmgr_faddr(&outputproc)) (*p, typelem, -1);
+					values[i] = DatumGetCString(FunctionCall3(&outputproc,
+												CharGetDatum(*p),
+												ObjectIdGetDatum(typelem),
+												Int32GetDatum(-1)));
 					break;
 				case 2:
-					values[i] = (*fmgr_faddr(&outputproc)) (*(int16 *) p, typelem, -1);
+					values[i] = DatumGetCString(FunctionCall3(&outputproc,
+												Int16GetDatum(*(int16 *) p),
+												ObjectIdGetDatum(typelem),
+												Int32GetDatum(-1)));
 					break;
 				case 3:
 				case 4:
-					values[i] = (*fmgr_faddr(&outputproc)) (*(int32 *) p, typelem, -1);
+					values[i] = DatumGetCString(FunctionCall3(&outputproc,
+												Int32GetDatum(*(int32 *) p),
+												ObjectIdGetDatum(typelem),
+												Int32GetDatum(-1)));
 					break;
 			}
 			p += typlen;
 		}
 		else
 		{
-			values[i] = (*fmgr_faddr(&outputproc)) (p, typelem, -1);
+			values[i] = DatumGetCString(FunctionCall3(&outputproc,
+												PointerGetDatum(p),
+												ObjectIdGetDatum(typelem),
+												Int32GetDatum(-1)));
 			if (typlen > 0)
 				p += typlen;
 			else
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index f8f23c44c8bb9b18866723acda488da4c51e93b2..a147b15ceb1540c8d241929ffa2bf67970b7b247 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -3,7 +3,7 @@
  *			  out of its tuple
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.49 2000/05/30 00:49:53 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.50 2000/05/30 04:24:51 tgl Exp $
  *
  *	  This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -1647,7 +1647,6 @@ get_const_expr(Const *constval, deparse_context *context)
 	StringInfo	buf = context->buf;
 	HeapTuple	typetup;
 	Form_pg_type typeStruct;
-	FmgrInfo	finfo_output;
 	char	   *extval;
 	char	   *valptr;
 
@@ -1673,10 +1672,10 @@ get_const_expr(Const *constval, deparse_context *context)
 		return;
 	}
 
-	fmgr_info(typeStruct->typoutput, &finfo_output);
-	extval = (char *) (*fmgr_faddr(&finfo_output)) (constval->constvalue,
-													typeStruct->typelem,
-													-1);
+	extval = DatumGetCString(OidFunctionCall3(typeStruct->typoutput,
+							 constval->constvalue,
+							 ObjectIdGetDatum(typeStruct->typelem),
+							 Int32GetDatum(-1)));
 
 	switch (constval->consttype)
 	{
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index c93ef767d8e2f6eaa45fa7c646d4cb4e87223640..611f57f9acb596ff9e197067987116e444d78d2b 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.67 2000/05/28 17:56:06 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.68 2000/05/30 04:24:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -32,6 +32,7 @@
 #include "catalog/pg_statistic.h"
 #include "catalog/pg_type.h"
 #include "mb/pg_wchar.h"
+#include "optimizer/clauses.h"
 #include "optimizer/cost.h"
 #include "parser/parse_func.h"
 #include "parser/parse_oper.h"
@@ -157,11 +158,13 @@ eqsel(Oid opid,
 
 				/* be careful to apply operator right way 'round */
 				if (flag & SEL_RIGHT)
-					mostcommon = (bool)
-						DatumGetUInt8(fmgr(eqproc, commonval, value));
+					mostcommon = DatumGetBool(OidFunctionCall2(eqproc,
+															   commonval,
+															   value));
 				else
-					mostcommon = (bool)
-						DatumGetUInt8(fmgr(eqproc, value, commonval));
+					mostcommon = DatumGetBool(OidFunctionCall2(eqproc,
+															   value,
+															   commonval));
 
 				if (mostcommon)
 				{
@@ -1278,8 +1281,10 @@ getattstatistics(Oid relid,
 		{
 			char	   *strval = textout(val);
 
-			*commonval = (Datum)
-				(*fmgr_faddr(&inputproc)) (strval, typelem, typmod);
+			*commonval = FunctionCall3(&inputproc,
+									   CStringGetDatum(strval),
+									   ObjectIdGetDatum(typelem),
+									   Int32GetDatum(typmod));
 			pfree(strval);
 		}
 	}
@@ -1287,7 +1292,7 @@ getattstatistics(Oid relid,
 	if (loval)
 	{
 		text	   *val = (text *) SysCacheGetAttr(STATRELID, tuple,
-											  Anum_pg_statistic_staloval,
+												   Anum_pg_statistic_staloval,
 												   &isnull);
 
 		if (isnull)
@@ -1299,8 +1304,10 @@ getattstatistics(Oid relid,
 		{
 			char	   *strval = textout(val);
 
-			*loval = (Datum)
-				(*fmgr_faddr(&inputproc)) (strval, typelem, typmod);
+			*loval = FunctionCall3(&inputproc,
+								   CStringGetDatum(strval),
+								   ObjectIdGetDatum(typelem),
+								   Int32GetDatum(typmod));
 			pfree(strval);
 		}
 	}
@@ -1320,8 +1327,10 @@ getattstatistics(Oid relid,
 		{
 			char	   *strval = textout(val);
 
-			*hival = (Datum)
-				(*fmgr_faddr(&inputproc)) (strval, typelem, typmod);
+			*hival = FunctionCall3(&inputproc,
+								   CStringGetDatum(strval),
+								   ObjectIdGetDatum(typelem),
+								   Int32GetDatum(typmod));
 			pfree(strval);
 		}
 	}
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 414837922579dd83172f6353760fe3015ab94cf5..713d714bb7e1f57eea29c9c6db6a1e8d845aff47 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.41 2000/05/29 01:59:09 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.42 2000/05/30 04:24:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -420,6 +420,8 @@ fmgr_sql(PG_FUNCTION_ARGS)
 	return 0;					/* keep compiler happy */
 }
 
+#if 0
+
 /*
  * Interface routine for functions using fmgr_faddr
  */
@@ -510,6 +512,8 @@ fmgr(Oid procedureId,...)
 	return (char *) result;
 }
 
+#endif
+
 
 /*-------------------------------------------------------------------------
  *		Support routines for callers of fmgr-compatible functions
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index 154efd1080e4ff1fe85f38eacc55e0875456b779..1a0781dd9217015d0dc9f6184c8e6ca3ec7bf9cf 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -78,7 +78,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.9 2000/04/12 17:16:12 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.10 2000/05/30 04:24:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1694,7 +1694,6 @@ comparetup_heap(Tuplesortstate *state, const void *a, const void *b)
 					rattr;
 		bool		isnull1,
 					isnull2;
-		int			result;
 
 		lattr = heap_getattr(ltup, attno, tupDesc, &isnull1);
 		rattr = heap_getattr(rtup, attno, tupDesc, &isnull2);
@@ -1708,17 +1707,21 @@ comparetup_heap(Tuplesortstate *state, const void *a, const void *b)
 			return -1;
 		else if (scanKey->sk_flags & SK_COMMUTE)
 		{
-			if (!(result = -(int) (*fmgr_faddr(&scanKey->sk_func)) (rattr, lattr)))
-				result = (int) (*fmgr_faddr(&scanKey->sk_func)) (lattr, rattr);
-			if (result)
-				return result;
+			if (DatumGetBool(FunctionCall2(&scanKey->sk_func,
+										   rattr, lattr)))
+				return -1;		/* a < b after commute */
+			if (DatumGetBool(FunctionCall2(&scanKey->sk_func,
+										   lattr, rattr)))
+				return 1;		/* a > b after commute */
 		}
 		else
 		{
-			if (!(result = -(int) (*fmgr_faddr(&scanKey->sk_func)) (lattr, rattr)))
-				result = (int) (*fmgr_faddr(&scanKey->sk_func)) (rattr, lattr);
-			if (result)
-				return result;
+			if (DatumGetBool(FunctionCall2(&scanKey->sk_func,
+										   lattr, rattr)))
+				return -1;		/* a < b */
+			if (DatumGetBool(FunctionCall2(&scanKey->sk_func,
+										   rattr, lattr)))
+				return 1;		/* a > b */
 		}
 	}
 
@@ -1846,8 +1849,8 @@ comparetup_index(Tuplesortstate *state, const void *a, const void *b)
 		}
 		else
 		{
-			compare = (int32) FMGR_PTR2(&entry->sk_func,
-										attrDatum1, attrDatum2);
+			compare = DatumGetInt32(FunctionCall2(&entry->sk_func,
+												  attrDatum1, attrDatum2));
 		}
 
 		if (compare != 0)
@@ -1950,13 +1953,13 @@ comparetup_datum(Tuplesortstate *state, const void *a, const void *b)
 		return -1;
 	else
 	{
-		int			result;
-
-		if (!(result = -(int) (*fmgr_faddr(&state->sortOpFn)) (ltup->val,
-															 rtup->val)))
-			result = (int) (*fmgr_faddr(&state->sortOpFn)) (rtup->val,
-															ltup->val);
-		return result;
+		if (DatumGetBool(FunctionCall2(&state->sortOpFn,
+									   ltup->val, rtup->val)))
+			return -1;			/* a < b */
+		if (DatumGetBool(FunctionCall2(&state->sortOpFn,
+									   rtup->val, ltup->val)))
+			return 1;			/* a > b */
+		return 0;
 	}
 }
 
diff --git a/src/include/access/valid.h b/src/include/access/valid.h
index e710ff415af472a38626f3d3cff77ee350e0c742..d89b3fce1873380a48941d1752cbb5f0bb770d6e 100644
--- a/src/include/access/valid.h
+++ b/src/include/access/valid.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: valid.h,v 1.21 2000/05/28 17:56:14 tgl Exp $
+ * $Id: valid.h,v 1.22 2000/05/30 04:24:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -33,7 +33,7 @@ do \
    macro below */ \
 	bool		__isnull; \
 	Datum		__atp; \
-	int			__test; \
+	Datum		__test; \
 	int			__cur_nkeys = (nkeys); \
 	ScanKey		__cur_keys = (keys); \
  \
@@ -41,9 +41,9 @@ do \
 	for (; __cur_nkeys--; __cur_keys++) \
 	{ \
 		__atp = heap_getattr((tuple), \
-						   __cur_keys->sk_attno, \
-						   (tupdesc), \
-						   &__isnull); \
+							 __cur_keys->sk_attno, \
+							 (tupdesc), \
+							 &__isnull); \
  \
 		if (__isnull) \
 		{ \
@@ -58,16 +58,14 @@ do \
 			break; \
 		} \
  \
-		if (__cur_keys->sk_func.fn_addr == (PGFunction) oideq)	/* optimization */ \
-			__test = (__cur_keys->sk_argument == __atp); \
-		else if (__cur_keys->sk_flags & SK_COMMUTE) \
-			__test = (long) FMGR_PTR2(&__cur_keys->sk_func, \
-									__cur_keys->sk_argument, __atp); \
+		if (__cur_keys->sk_flags & SK_COMMUTE) \
+			__test = FunctionCall2(&__cur_keys->sk_func, \
+								   __cur_keys->sk_argument, __atp); \
 		else \
-			__test = (long) FMGR_PTR2(&__cur_keys->sk_func, \
-									__atp, __cur_keys->sk_argument); \
+			__test = FunctionCall2(&__cur_keys->sk_func, \
+								   __atp, __cur_keys->sk_argument); \
  \
-		if (!__test == !(__cur_keys->sk_flags & SK_NEGATE)) \
+		if (DatumGetBool(__test) == !!(__cur_keys->sk_flags & SK_NEGATE)) \
 		{ \
 			/* XXX eventually should check if SK_ISNULL */ \
 			(result) = false; \
diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h
index 0cae51dec647c8f371dd287d20282c3fa0033210..2350d7385655c55d8366fb0f5acf58893f8dfc57 100644
--- a/src/include/catalog/pg_aggregate.h
+++ b/src/include/catalog/pg_aggregate.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_aggregate.h,v 1.25 2000/04/12 17:16:27 momjian Exp $
+ * $Id: pg_aggregate.h,v 1.26 2000/05/30 04:24:55 tgl Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -151,7 +151,8 @@ extern void AggregateCreate(char *aggName,
 				char *aggtransfn2typeName,
 				char *agginitval1,
 				char *agginitval2);
-extern char *AggNameGetInitVal(char *aggName, Oid basetype,
-				  int xfuncno, bool *isNull);
+
+extern Datum AggNameGetInitVal(char *aggName, Oid basetype,
+							   int xfuncno, bool *isNull);
 
 #endif	 /* PG_AGGREGATE_H */
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index ce6b06bf8d4d98e25c7bfc91f94fe82fc3620c02..fadb09d24e1ff27e0d7c6a8a5a1fc8091a6ba2c6 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -11,7 +11,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: fmgr.h,v 1.2 2000/05/29 01:59:09 tgl Exp $
+ * $Id: fmgr.h,v 1.3 2000/05/30 04:24:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -272,6 +272,8 @@ typedef int32 ((*func_ptr) ());
 typedef char *((*func_ptr) ());
 #endif
 
+#if 0
+
 typedef struct {
     char *data[FUNC_MAX_ARGS];
 } FmgrValues;
@@ -286,18 +288,11 @@ extern char *fmgr_faddr_link(char *arg0, ...);
  *	Macros for calling through the result of fmgr_info.
  */
 
-/* We don't make this static so fmgr_faddr() macros can access it */
+/* We don't make this static so fmgr_faddr() macro can access it */
 extern FmgrInfo        *fmgr_pl_finfo;
 
 #define fmgr_faddr(finfo) (fmgr_pl_finfo = (finfo), (func_ptr) fmgr_faddr_link)
 
-#define	FMGR_PTR2(FINFO, ARG1, ARG2)  ((*(fmgr_faddr(FINFO))) (ARG1, ARG2))
-
-/*
- *	Flags for the builtin oprrest selectivity routines.
- *  XXX These do not belong here ... put 'em in some planner/optimizer header.
- */
-#define	SEL_CONSTANT 	1		/* operator's non-var arg is a constant */
-#define	SEL_RIGHT	2			/* operator's non-var arg is on the right */
+#endif
 
 #endif	/* FMGR_H */
diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h
index 9cccc65454ee5a793c393136b8f31a0d7a4964f8..946a9b0586ff39c1fd2e76f131b9dc34ba6b7978 100644
--- a/src/include/optimizer/clauses.h
+++ b/src/include/optimizer/clauses.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: clauses.h,v 1.36 2000/04/12 17:16:41 momjian Exp $
+ * $Id: clauses.h,v 1.37 2000/05/30 04:24:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -16,6 +16,14 @@
 
 #include "nodes/relation.h"
 
+/*
+ *	Flag bits returned by get_relattval().
+ *	These are used in selectivity-estimation routines, too.
+ */
+#define	SEL_CONSTANT 	1		/* operator's non-var arg is a constant */
+#define	SEL_RIGHT		2		/* operator's non-var arg is on the right */
+
+
 extern Expr *make_clause(int type, Node *oper, List *args);
 
 extern bool is_opclause(Node *clause);
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index ed8d1672db95d4f49604e1943a82721b0d342e33..e51c950ef673f6e670bf93f2938d5e3100b9e057 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -33,7 +33,7 @@
  *	  ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.9 2000/05/29 21:25:06 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.10 2000/05/30 04:24:57 tgl Exp $
  *
  **********************************************************************/
 
@@ -427,10 +427,10 @@ plperl_call_perl_func(plperl_proc_desc * desc, FunctionCallInfo fcinfo)
 			{
 				char	   *tmp;
 
-				tmp = (*fmgr_faddr(&(desc->arg_out_func[i])))
-					(fcinfo->arg[i],
-					 desc->arg_out_elem[i],
-					 desc->arg_out_len[i]);
+				tmp = DatumGetCString(FunctionCall3(&(desc->arg_out_func[i]),
+									  fcinfo->arg[i],
+									  ObjectIdGetDatum(desc->arg_out_elem[i]),
+									  Int32GetDatum(desc->arg_out_len[i])));
 				XPUSHs(sv_2mortal(newSVpv(tmp, 0)));
 				pfree(tmp);
 			}
@@ -1081,13 +1081,11 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
 		 ************************************************************/
 		modnulls[attnum - 1] = ' ';
 		fmgr_info(typinput, &finfo);
-		modvalues[attnum - 1] = (Datum) (*fmgr_faddr(&finfo))
-			(ret_values[i++],
-			 typelem,
-			 (!VARLENA_FIXED_SIZE(tupdesc->attrs[attnum - 1]))
-			 ? tupdesc->attrs[attnum - 1]->attlen
-			 : tupdesc->attrs[attnum - 1]->atttypmod
-			);
+		modvalues[attnum - 1] =
+			FunctionCall3(&finfo,
+						  CStringGetDatum(ret_values[i++]),
+						  ObjectIdGetDatum(typelem),
+						  Int32GetDatum(tupdesc->attrs[attnum-1]->atttypmod));
 	}
 
 
@@ -1825,10 +1823,11 @@ plperl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
 		 ************************************************************/
 		for (j = 0; j < callnargs; j++)
 		{
-			qdesc->argvalues[j] = (Datum) (*fmgr_faddr(&qdesc->arginfuncs[j]))
-				(callargs[j],
-				 qdesc->argtypelems[j],
-				 qdesc->arglen[j]);
+			qdesc->argvalues[j] =
+				FunctionCall3(&qdesc->arginfuncs[j],
+							  CStringGetDatum(callargs[j]),
+							  ObjectIdGetDatum(qdesc->argtypelems[j]),
+							  Int32GetDatum(qdesc->arglen[j]));
 		}
 
 		/************************************************************
@@ -2103,14 +2102,10 @@ plperl_set_tuple_values(Tcl_Interp *interp, char *arrayname,
 		 ************************************************************/
 		if (!isnull && OidIsValid(typoutput))
 		{
-			FmgrInfo	finfo;
-
-			fmgr_info(typoutput, &finfo);
-
-			outputstr = (*fmgr_faddr(&finfo))
-				(attr, typelem,
-				 tupdesc->attrs[i]->attlen);
-
+			outputstr = DatumGetCString(OidFunctionCall3(typoutput,
+										attr,
+										ObjectIdGetDatum(typelem),
+										Int32GetDatum(tupdesc->attrs[i]->attlen)));
 			Tcl_SetVar2(interp, *arrptr, *nameptr, outputstr, 0);
 			pfree(outputstr);
 		}
@@ -2176,14 +2171,10 @@ plperl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc)
 		 ************************************************************/
 		if (!isnull && OidIsValid(typoutput))
 		{
-			FmgrInfo	finfo;
-
-			fmgr_info(typoutput, &finfo);
-
-			outputstr = (*fmgr_faddr(&finfo))
-				(attr, typelem,
-				 tupdesc->attrs[i]->attlen);
-
+			outputstr = DatumGetCString(OidFunctionCall3(typoutput,
+										attr,
+										ObjectIdGetDatum(typelem),
+										Int32GetDatum(tupdesc->attrs[i]->attlen)));
 			sv_catpvf(output, "'%s' => '%s',", attname, outputstr);
 			pfree(outputstr);
 		}
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index e587aecba6045eb9ac349f35fbd15fbb15197478..77370801c9c4c51e3fed4aa0ab7e73b96dc29100 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -3,7 +3,7 @@
  *			  procedural language
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.22 2000/05/28 17:56:28 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.23 2000/05/30 04:24:58 tgl Exp $
  *
  *	  This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -1566,10 +1566,10 @@ exec_stmt_raise(PLpgSQL_execstate * estate, PLpgSQL_stmt_raise * stmt)
 						typeStruct = (Form_pg_type) GETSTRUCT(typetup);
 
 						fmgr_info(typeStruct->typoutput, &finfo_output);
-						extval = (char *) (*fmgr_faddr(&finfo_output))
-							(var->value,
-							 typeStruct->typelem,
-							 var->datatype->atttypmod);
+						extval = DatumGetCString(FunctionCall3(&finfo_output,
+									var->value,
+									ObjectIdGetDatum(typeStruct->typelem),
+									Int32GetDatum(var->datatype->atttypmod)));
 					}
 					plpgsql_dstring_append(&ds, extval);
 					break;
@@ -2414,13 +2414,14 @@ exec_cast_value(Datum value, Oid valtype,
 			typeStruct = (Form_pg_type) GETSTRUCT(typetup);
 
 			fmgr_info(typeStruct->typoutput, &finfo_output);
-			extval = (char *) (*fmgr_faddr(&finfo_output))
-				(value,
-				 typeStruct->typelem,
-				 -1);
-			value = (Datum) (*fmgr_faddr(reqinput)) (extval,
-													 reqtypelem,
-													 reqtypmod);
+			extval = DatumGetCString(FunctionCall3(&finfo_output,
+									 value,
+									 ObjectIdGetDatum(typeStruct->typelem),
+									 Int32GetDatum(-1)));
+			value = FunctionCall3(reqinput,
+								  CStringGetDatum(extval),
+								  ObjectIdGetDatum(reqtypelem),
+								  Int32GetDatum(reqtypmod));
 			pfree(extval);
 		}
 	}
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index 201bbdf092d20be9bda3bc3b033f07b4150a9832..b2bceb9218433ebe4f3f3d88d1d2b1b277daab04 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -31,7 +31,7 @@
  *	  ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.24 2000/05/29 01:59:15 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.25 2000/05/30 04:24:59 tgl Exp $
  *
  **********************************************************************/
 
@@ -655,10 +655,10 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
 			{
 				char	   *tmp;
 
-				tmp = (*fmgr_faddr(&(prodesc->arg_out_func[i])))
-					(fcinfo->arg[i],
-					 prodesc->arg_out_elem[i],
-					 prodesc->arg_out_len[i]);
+				tmp = DatumGetCString(FunctionCall3(&prodesc->arg_out_func[i],
+									  fcinfo->arg[i],
+									  ObjectIdGetDatum(prodesc->arg_out_elem[i]),
+									  Int32GetDatum(prodesc->arg_out_len[i])));
 				Tcl_DStringAppendElement(&tcl_cmd, tmp);
 				pfree(tmp);
 			}
@@ -696,7 +696,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
 	/************************************************************
 	 * Convert the result value from the safe interpreter
 	 * into its PostgreSQL data format and return it.
-	 * Again, the call to fmgr() could fire an elog and we
+	 * Again, the function call could fire an elog and we
 	 * have to count for the current interpreter level we are
 	 * on. The save_restart from above is still good.
 	 ************************************************************/
@@ -1129,13 +1129,13 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
 		 ************************************************************/
 		modnulls[attnum - 1] = ' ';
 		fmgr_info(typinput, &finfo);
-		modvalues[attnum - 1] = (Datum) (*fmgr_faddr(&finfo))
-			(ret_values[i++],
-			 typelem,
-			 tupdesc->attrs[attnum - 1]->atttypmod);
+		modvalues[attnum - 1] =
+			FunctionCall3(&finfo,
+						  CStringGetDatum(ret_values[i++]),
+						  ObjectIdGetDatum(typelem),
+						  Int32GetDatum(tupdesc->attrs[attnum-1]->atttypmod));
 	}
 
-
 	rettup = SPI_modifytuple(trigdata->tg_relation, rettup, tupdesc->natts,
 							 modattrs, modvalues, modnulls);
 
@@ -1870,10 +1870,11 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
 		 ************************************************************/
 		for (j = 0; j < callnargs; j++)
 		{
-			qdesc->argvalues[j] = (Datum) (*fmgr_faddr(&qdesc->arginfuncs[j]))
-				(callargs[j],
-				 qdesc->argtypelems[j],
-				 qdesc->arglen[j]);
+			qdesc->argvalues[j] =
+				FunctionCall3(&qdesc->arginfuncs[j],
+							  CStringGetDatum(callargs[j]),
+							  ObjectIdGetDatum(qdesc->argtypelems[j]),
+							  Int32GetDatum(qdesc->arglen[j]));
 		}
 
 		/************************************************************
@@ -2148,14 +2149,10 @@ pltcl_set_tuple_values(Tcl_Interp *interp, char *arrayname,
 		 ************************************************************/
 		if (!isnull && OidIsValid(typoutput))
 		{
-			FmgrInfo	finfo;
-
-			fmgr_info(typoutput, &finfo);
-
-			outputstr = (*fmgr_faddr(&finfo))
-				(attr, typelem,
-				 tupdesc->attrs[i]->attlen);
-
+			outputstr = DatumGetCString(OidFunctionCall3(typoutput,
+										attr,
+										ObjectIdGetDatum(typelem),
+										Int32GetDatum(tupdesc->attrs[i]->attlen)));
 			Tcl_SetVar2(interp, *arrptr, *nameptr, outputstr, 0);
 			pfree(outputstr);
 		}
@@ -2221,14 +2218,10 @@ pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc,
 		 ************************************************************/
 		if (!isnull && OidIsValid(typoutput))
 		{
-			FmgrInfo	finfo;
-
-			fmgr_info(typoutput, &finfo);
-
-			outputstr = (*fmgr_faddr(&finfo))
-				(attr, typelem,
-				 tupdesc->attrs[i]->attlen);
-
+			outputstr = DatumGetCString(OidFunctionCall3(typoutput,
+										attr,
+										ObjectIdGetDatum(typelem),
+										Int32GetDatum(tupdesc->attrs[i]->attlen)));
 			Tcl_DStringAppendElement(retval, attname);
 			Tcl_DStringAppendElement(retval, outputstr);
 			pfree(outputstr);