From ed9ca687582caa88f31c4b273b9fd4eb5743cf41 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu, 3 Aug 2000 23:07:51 +0000
Subject: [PATCH] Convert inet-related functions to new fmgr style.  I have
 also taken it on myself to do something about the non-self-consistency of the
 inet comparison functions.  The results are probably still semantically wrong
 (inet and cidr should have different comparison semantics, I think) but at
 least the boolean operators now agree with each other and with the sort order
 of indexes on inet/cidr.

---
 src/backend/utils/adt/mac.c        | 146 ++++++++--------
 src/backend/utils/adt/network.c    | 272 ++++++++++++++---------------
 src/include/catalog/pg_proc.h      |  52 +++---
 src/include/utils/builtins.h       |  66 ++++---
 src/include/utils/inet.h           |  35 +++-
 src/test/regress/expected/inet.out |   2 +-
 6 files changed, 292 insertions(+), 281 deletions(-)

diff --git a/src/backend/utils/adt/mac.c b/src/backend/utils/adt/mac.c
index 5b542504643..e8d502b87d2 100644
--- a/src/backend/utils/adt/mac.c
+++ b/src/backend/utils/adt/mac.c
@@ -1,20 +1,18 @@
 /*
  *	PostgreSQL type definitions for MAC addresses.
  *
- *	$Header: /cvsroot/pgsql/src/backend/utils/adt/mac.c,v 1.16 2000/07/06 05:48:11 tgl Exp $
+ *	$Header: /cvsroot/pgsql/src/backend/utils/adt/mac.c,v 1.17 2000/08/03 23:07:46 tgl Exp $
  */
 
 #include "postgres.h"
 
 #include "utils/builtins.h"
-
+#include "utils/inet.h"
 
 /*
- * macaddr is a pass-by-reference datatype.
+ * XXX this table of manufacturers is long out of date, and should never
+ * have been wired into the code in the first place.
  */
-#define PG_GETARG_MACADDR_P(n)  ((macaddr *) PG_GETARG_POINTER(n))
-#define PG_RETURN_MACADDR_P(x)  return PointerGetDatum(x)
-
 
 typedef struct manufacturer
 {
@@ -145,18 +143,18 @@ static manufacturer manufacturers[] = {
  */
 
 #define hibits(addr) \
-  ((unsigned long)((addr->a<<16)|(addr->b<<8)|(addr->c)))
+  ((unsigned long)(((addr)->a<<16)|((addr)->b<<8)|((addr)->c)))
 
 #define lobits(addr) \
-  ((unsigned long)((addr->d<<16)|(addr->e<<8)|(addr->f)))
+  ((unsigned long)(((addr)->d<<16)|((addr)->e<<8)|((addr)->f)))
 
 /*
  *	MAC address reader.  Accepts several common notations.
  */
-
-macaddr    *
-macaddr_in(char *str)
+Datum
+macaddr_in(PG_FUNCTION_ARGS)
 {
+	char	   *str = PG_GETARG_CSTRING(0);
 	int			a,
 				b,
 				c,
@@ -201,21 +199,18 @@ macaddr_in(char *str)
 	result->e = e;
 	result->f = f;
 
-	return (result);
+	PG_RETURN_MACADDR_P(result);
 }
 
 /*
  *	MAC address output function.  Fixed format.
  */
-
-char *
-macaddr_out(macaddr *addr)
+Datum
+macaddr_out(PG_FUNCTION_ARGS)
 {
+	macaddr	   *addr = PG_GETARG_MACADDR_P(0);
 	char	   *result;
 
-	if (addr == NULL)
-		return (NULL);
-
 	result = (char *) palloc(32);
 
 	if ((hibits(addr) > 0) || (lobits(addr) > 0))
@@ -225,84 +220,95 @@ macaddr_out(macaddr *addr)
 	}
 	else
 	{
-		result[0] = 0;			/* special case for missing address */
+		result[0] = '\0';		/* special case for missing address */
 	}
-	return (result);
+
+	PG_RETURN_CSTRING(result);
 }
 
 /*
- *	Boolean tests.
+ *	Comparison function for sorting:
  */
 
-bool
-macaddr_lt(macaddr *a1, macaddr *a2)
+static int32
+macaddr_cmp_internal(macaddr *a1, macaddr *a2)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
-	return ((hibits(a1) < hibits(a2)) ||
-			((hibits(a1) == hibits(a2)) && lobits(a1) < lobits(a2)));
+	if (hibits(a1) < hibits(a2))
+		return -1;
+	else if (hibits(a1) > hibits(a2))
+		return 1;
+	else if (lobits(a1) < lobits(a2))
+		return -1;
+	else if (lobits(a1) > lobits(a2))
+		return 1;
+	else
+		return 0;
 }
 
-bool
-macaddr_le(macaddr *a1, macaddr *a2)
+Datum
+macaddr_cmp(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
-	return ((hibits(a1) < hibits(a2)) ||
-			((hibits(a1) == hibits(a2)) && lobits(a1) <= lobits(a2)));
+	macaddr	   *a1 = PG_GETARG_MACADDR_P(0);
+	macaddr	   *a2 = PG_GETARG_MACADDR_P(1);
+
+	PG_RETURN_INT32(macaddr_cmp_internal(a1, a2));
 }
 
-bool
-macaddr_eq(macaddr *a1, macaddr *a2)
+/*
+ *	Boolean comparisons.
+ */
+Datum
+macaddr_lt(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
-	return ((hibits(a1) == hibits(a2)) && (lobits(a1) == lobits(a2)));
+	macaddr	   *a1 = PG_GETARG_MACADDR_P(0);
+	macaddr	   *a2 = PG_GETARG_MACADDR_P(1);
+
+	PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) < 0);
 }
 
-bool
-macaddr_ge(macaddr *a1, macaddr *a2)
+Datum
+macaddr_le(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
-	return ((hibits(a1) > hibits(a2)) ||
-			((hibits(a1) == hibits(a2)) && lobits(a1) >= lobits(a2)));
+	macaddr	   *a1 = PG_GETARG_MACADDR_P(0);
+	macaddr	   *a2 = PG_GETARG_MACADDR_P(1);
+
+	PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) <= 0);
 }
 
-bool
-macaddr_gt(macaddr *a1, macaddr *a2)
+Datum
+macaddr_eq(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
-	return ((hibits(a1) > hibits(a2)) ||
-			((hibits(a1) == hibits(a2)) && lobits(a1) > lobits(a2)));
+	macaddr	   *a1 = PG_GETARG_MACADDR_P(0);
+	macaddr	   *a2 = PG_GETARG_MACADDR_P(1);
+
+	PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) == 0);
 }
 
-bool
-macaddr_ne(macaddr *a1, macaddr *a2)
+Datum
+macaddr_ge(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
-	return ((hibits(a1) != hibits(a2)) || (lobits(a1) != lobits(a2)));
+	macaddr	   *a1 = PG_GETARG_MACADDR_P(0);
+	macaddr	   *a2 = PG_GETARG_MACADDR_P(1);
+
+	PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) >= 0);
 }
 
-/*
- *	Comparison function for sorting:
- */
+Datum
+macaddr_gt(PG_FUNCTION_ARGS)
+{
+	macaddr	   *a1 = PG_GETARG_MACADDR_P(0);
+	macaddr	   *a2 = PG_GETARG_MACADDR_P(1);
+
+	PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) > 0);
+}
 
-int4
-macaddr_cmp(macaddr *a1, macaddr *a2)
+Datum
+macaddr_ne(PG_FUNCTION_ARGS)
 {
-	if (hibits(a1) < hibits(a2))
-		return -1;
-	else if (hibits(a1) > hibits(a2))
-		return 1;
-	else if (lobits(a1) < lobits(a2))
-		return -1;
-	else if (lobits(a1) > lobits(a2))
-		return 1;
-	else
-		return 0;
+	macaddr	   *a1 = PG_GETARG_MACADDR_P(0);
+	macaddr	   *a2 = PG_GETARG_MACADDR_P(1);
+
+	PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) != 0);
 }
 
 /*
diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c
index eb489d9cd71..9765444eace 100644
--- a/src/backend/utils/adt/network.c
+++ b/src/backend/utils/adt/network.c
@@ -3,7 +3,7 @@
  *	is for IP V4 CIDR notation, but prepared for V6: just
  *	add the necessary bits where the comments indicate.
  *
- *	$Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.23 2000/07/06 05:48:11 tgl Exp $
+ *	$Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.24 2000/08/03 23:07:46 tgl Exp $
  *
  *	Jon Postel RIP 16 Oct 1998
  */
@@ -17,16 +17,11 @@
 #include <arpa/inet.h>
 
 #include "utils/builtins.h"
-
-/*
- * inet is a pass-by-reference datatype.  It's not toastable, and we
- * don't try to hide the pass-by-refness, so these macros are simple.
- */
-#define PG_GETARG_INET_P(n)  ((inet *) PG_GETARG_POINTER(n))
-#define PG_RETURN_INET_P(x)  return PointerGetDatum(x)
+#include "utils/inet.h"
 
 
 static int	v4bitncmp(unsigned int a1, unsigned int a2, int bits);
+static int32 network_cmp_internal(inet *a1, inet *a2);
 
 /*
  *	Access macros.	Add IPV6 support.
@@ -54,12 +49,7 @@ network_in(char *src, int type)
 	int			bits;
 	inet	   *dst;
 
-	if (!src)
-		return NULL;
-
-	dst = palloc(VARHDRSZ + sizeof(inet_struct));
-	if (dst == NULL)
-		elog(ERROR, "unable to allocate memory in network_in()");
+	dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct));
 
 	/* First, try for an IP V4 address: */
 	ip_family(dst) = AF_INET;
@@ -74,32 +64,37 @@ network_in(char *src, int type)
 		+ ip_addrsize(dst);
 	ip_bits(dst) = bits;
 	ip_type(dst) = type;
+
 	return dst;
 }
 
 /* INET address reader.  */
-inet *
-inet_in(char *src)
+Datum
+inet_in(PG_FUNCTION_ARGS)
 {
-	return network_in(src, 0);
+	char	   *src = PG_GETARG_CSTRING(0);
+
+	PG_RETURN_INET_P(network_in(src, 0));
 }
 
 /* CIDR address reader.  */
-inet *
-cidr_in(char *src)
+Datum
+cidr_in(PG_FUNCTION_ARGS)
 {
-	return network_in(src, 1);
+	char	   *src = PG_GETARG_CSTRING(0);
+
+	PG_RETURN_INET_P(network_in(src, 1));
 }
 
 /*
  *	INET address output function.
  */
-
-char *
-inet_out(inet *src)
+Datum
+inet_out(PG_FUNCTION_ARGS)
 {
-	char	   *dst,
-				tmp[sizeof("255.255.255.255/32")];
+	inet	   *src = PG_GETARG_INET_P(0);
+	char		tmp[sizeof("255.255.255.255/32")];
+	char	   *dst;
 
 	if (ip_family(src) == AF_INET)
 	{
@@ -118,211 +113,201 @@ inet_out(inet *src)
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "unknown address family (%d)", ip_family(src));
 
-	dst = palloc(strlen(tmp) + 1);
-	if (dst == NULL)
-		elog(ERROR, "unable to allocate memory in inet_out()");
-
-	strcpy(dst, tmp);
-	return dst;
+	PG_RETURN_CSTRING(pstrdup(tmp));
 }
 
 
-/* just a stub */
-char *
-cidr_out(inet *src)
+/* share code with INET case */
+Datum
+cidr_out(PG_FUNCTION_ARGS)
 {
-	return inet_out(src);
+	return inet_out(fcinfo);
 }
 
+
 /*
- *	Boolean tests for magnitude.  Add V4/V6 testing!
+ *	Basic comparison function for sorting and inet/cidr comparisons.
+ *
+ * XXX this ignores bits to the right of the mask.  That's probably
+ * correct for CIDR, almost certainly wrong for INET.  We need to have
+ * two sets of comparator routines, not just one.  Note that suggests
+ * that CIDR and INET should not be considered binary-equivalent by
+ * the parser?
  */
 
-bool
-network_lt(inet *a1, inet *a2)
+static int32
+network_cmp_internal(inet *a1, inet *a2)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
-	if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
+	if (ip_family(a1) == AF_INET && ip_family(a2) == AF_INET)
 	{
-		int			order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2));
+		int		order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2),
+								  Min(ip_bits(a1), ip_bits(a2)));
 
-		return ((order < 0) || ((order == 0) && (ip_bits(a1) < ip_bits(a2))));
+		if (order != 0)
+			return order;
+		return ((int32) ip_bits(a1)) - ((int32) ip_bits(a2));
 	}
 	else
 	{
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "cannot compare address families %d and %d",
 			 ip_family(a1), ip_family(a2));
-		return FALSE;
+		return 0;				/* keep compiler quiet */
 	}
 }
 
-bool
-network_le(inet *a1, inet *a2)
+Datum
+network_cmp(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
-	return (network_lt(a1, a2) || network_eq(a1, a2));
+	inet	   *a1 = PG_GETARG_INET_P(0);
+	inet	   *a2 = PG_GETARG_INET_P(1);
+
+	PG_RETURN_INT32(network_cmp_internal(a1, a2));
 }
 
-bool
-network_eq(inet *a1, inet *a2)
+/*
+ *	Boolean ordering tests.
+ */
+Datum
+network_lt(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
-	if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
-	{
-		return ((ip_bits(a1) == ip_bits(a2))
-		 && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0));
-	}
-	else
-	{
-		/* Go for an IPV6 address here, before faulting out: */
-		elog(ERROR, "cannot compare address families %d and %d",
-			 ip_family(a1), ip_family(a2));
-		return FALSE;
-	}
+	inet	   *a1 = PG_GETARG_INET_P(0);
+	inet	   *a2 = PG_GETARG_INET_P(1);
+
+	PG_RETURN_BOOL(network_cmp_internal(a1, a2) < 0);
 }
 
-bool
-network_ge(inet *a1, inet *a2)
+Datum
+network_le(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
-	return (network_gt(a1, a2) || network_eq(a1, a2));
+	inet	   *a1 = PG_GETARG_INET_P(0);
+	inet	   *a2 = PG_GETARG_INET_P(1);
+
+	PG_RETURN_BOOL(network_cmp_internal(a1, a2) <= 0);
 }
 
-bool
-network_gt(inet *a1, inet *a2)
+Datum
+network_eq(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
-	if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
-	{
-		int			order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2));
+	inet	   *a1 = PG_GETARG_INET_P(0);
+	inet	   *a2 = PG_GETARG_INET_P(1);
 
-		return ((order > 0) || ((order == 0) && (ip_bits(a1) > ip_bits(a2))));
-	}
-	else
-	{
-		/* Go for an IPV6 address here, before faulting out: */
-		elog(ERROR, "cannot compare address families %d and %d",
-			 ip_family(a1), ip_family(a2));
-		return FALSE;
-	}
+	PG_RETURN_BOOL(network_cmp_internal(a1, a2) == 0);
+}
+
+Datum
+network_ge(PG_FUNCTION_ARGS)
+{
+	inet	   *a1 = PG_GETARG_INET_P(0);
+	inet	   *a2 = PG_GETARG_INET_P(1);
+
+	PG_RETURN_BOOL(network_cmp_internal(a1, a2) >= 0);
 }
 
-bool
-network_ne(inet *a1, inet *a2)
+Datum
+network_gt(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
-	return (!network_eq(a1, a2));
+	inet	   *a1 = PG_GETARG_INET_P(0);
+	inet	   *a2 = PG_GETARG_INET_P(1);
+
+	PG_RETURN_BOOL(network_cmp_internal(a1, a2) > 0);
 }
 
-bool
-network_sub(inet *a1, inet *a2)
+Datum
+network_ne(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
+	inet	   *a1 = PG_GETARG_INET_P(0);
+	inet	   *a2 = PG_GETARG_INET_P(1);
+
+	PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0);
+}
+
+/*
+ *	Boolean network-inclusion tests.
+ */
+Datum
+network_sub(PG_FUNCTION_ARGS)
+{
+	inet	   *a1 = PG_GETARG_INET_P(0);
+	inet	   *a2 = PG_GETARG_INET_P(1);
 
 	if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
 	{
-		return ((ip_bits(a1) > ip_bits(a2))
-		 && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0));
+		PG_RETURN_BOOL(ip_bits(a1) > ip_bits(a2)
+			&& v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0);
 	}
 	else
 	{
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "cannot compare address families %d and %d",
 			 ip_family(a1), ip_family(a2));
-		return FALSE;
+		PG_RETURN_BOOL(false);
 	}
 }
 
-bool
-network_subeq(inet *a1, inet *a2)
+Datum
+network_subeq(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
+	inet	   *a1 = PG_GETARG_INET_P(0);
+	inet	   *a2 = PG_GETARG_INET_P(1);
 
 	if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
 	{
-		return ((ip_bits(a1) >= ip_bits(a2))
-		 && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0));
+		PG_RETURN_BOOL(ip_bits(a1) >= ip_bits(a2)
+			&& v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0);
 	}
 	else
 	{
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "cannot compare address families %d and %d",
 			 ip_family(a1), ip_family(a2));
-		return FALSE;
+		PG_RETURN_BOOL(false);
 	}
 }
 
-bool
-network_sup(inet *a1, inet *a2)
+Datum
+network_sup(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
+	inet	   *a1 = PG_GETARG_INET_P(0);
+	inet	   *a2 = PG_GETARG_INET_P(1);
 
 	if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
 	{
-		return ((ip_bits(a1) < ip_bits(a2))
-		 && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0));
+		PG_RETURN_BOOL(ip_bits(a1) < ip_bits(a2)
+			&& v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0);
 	}
 	else
 	{
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "cannot compare address families %d and %d",
 			 ip_family(a1), ip_family(a2));
-		return FALSE;
+		PG_RETURN_BOOL(false);
 	}
 }
 
-bool
-network_supeq(inet *a1, inet *a2)
+Datum
+network_supeq(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
+	inet	   *a1 = PG_GETARG_INET_P(0);
+	inet	   *a2 = PG_GETARG_INET_P(1);
 
 	if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
 	{
-		return ((ip_bits(a1) <= ip_bits(a2))
-		 && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0));
+		PG_RETURN_BOOL(ip_bits(a1) <= ip_bits(a2)
+			&& v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0);
 	}
 	else
 	{
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "cannot compare address families %d and %d",
 			 ip_family(a1), ip_family(a2));
-		return FALSE;
+		PG_RETURN_BOOL(false);
 	}
 }
 
 /*
- *	Comparison function for sorting.  Add V4/V6 testing!
+ * Extract data from a network datatype.
  */
-
-int4
-network_cmp(inet *a1, inet *a2)
-{
-	if (ntohl(ip_v4addr(a1)) < ntohl(ip_v4addr(a2)))
-		return (-1);
-
-	if (ntohl(ip_v4addr(a1)) > ntohl(ip_v4addr(a2)))
-		return (1);
-
-	if (ip_bits(a1) < ip_bits(a2))
-		return (-1);
-
-	if (ip_bits(a1) > ip_bits(a2))
-		return (1);
-
-	return 0;
-}
-
 Datum
 network_host(PG_FUNCTION_ARGS)
 {
@@ -357,13 +342,12 @@ network_host(PG_FUNCTION_ARGS)
 	PG_RETURN_TEXT_P(ret);
 }
 
-int4
-network_masklen(inet *ip)
+Datum
+network_masklen(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(ip))
-		return 0;
+	inet	   *ip = PG_GETARG_INET_P(0);
 
-	return ip_bits(ip);
+	PG_RETURN_INT32(ip_bits(ip));
 }
 
 Datum
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 8556c83f53e..9919f1509be 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_proc.h,v 1.156 2000/08/03 16:34:31 tgl Exp $
+ * $Id: pg_proc.h,v 1.157 2000/08/03 23:07:46 tgl Exp $
  *
  * NOTES
  *	  The script catalog/genbki.sh reads this file and generates .bki
@@ -2174,68 +2174,68 @@ DATA(insert OID = 1688 (  varbitsubstr		PGUID 11 f t t t 2 f 1562 "1562 1562" 10
 DESCR("bitwise field");
 
 /* for mac type support */
-DATA(insert OID = 436 (  macaddr_in			PGUID 11 f t t t 1 f 829 "0" 100 0 0 100	macaddr_in - ));
+DATA(insert OID = 436 (  macaddr_in			PGUID 12 f t t t 1 f 829 "0" 100 0 0 100	macaddr_in - ));
 DESCR("(internal)");
-DATA(insert OID = 437 (  macaddr_out		PGUID 11 f t t t 1 f 23 "0" 100 0 0 100  macaddr_out - ));
+DATA(insert OID = 437 (  macaddr_out		PGUID 12 f t t t 1 f 23 "0" 100 0 0 100  macaddr_out - ));
 DESCR("(internal)");
 
-DATA(insert OID = 830 (  macaddr_eq		   PGUID 11 f t t t 2 f 16 "829 829" 100 0 0 100	macaddr_eq - ));
+DATA(insert OID = 830 (  macaddr_eq		   PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100	macaddr_eq - ));
 DESCR("equal");
-DATA(insert OID = 831 (  macaddr_lt		   PGUID 11 f t t t 2 f 16 "829 829" 100 0 0 100	macaddr_lt - ));
+DATA(insert OID = 831 (  macaddr_lt		   PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100	macaddr_lt - ));
 DESCR("less-than");
-DATA(insert OID = 832 (  macaddr_le		   PGUID 11 f t t t 2 f 16 "829 829" 100 0 0 100	macaddr_le - ));
+DATA(insert OID = 832 (  macaddr_le		   PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100	macaddr_le - ));
 DESCR("less-than-or-equal");
-DATA(insert OID = 833 (  macaddr_gt		   PGUID 11 f t t t 2 f 16 "829 829" 100 0 0 100	macaddr_gt - ));
+DATA(insert OID = 833 (  macaddr_gt		   PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100	macaddr_gt - ));
 DESCR("greater-than");
-DATA(insert OID = 834 (  macaddr_ge		   PGUID 11 f t t t 2 f 16 "829 829" 100 0 0 100	macaddr_ge - ));
+DATA(insert OID = 834 (  macaddr_ge		   PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100	macaddr_ge - ));
 DESCR("greater-than-or-equal");
-DATA(insert OID = 835 (  macaddr_ne		   PGUID 11 f t t t 2 f 16 "829 829" 100 0 0 100	macaddr_ne - ));
+DATA(insert OID = 835 (  macaddr_ne		   PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100	macaddr_ne - ));
 DESCR("not equal");
-DATA(insert OID = 836 (  macaddr_cmp	   PGUID 11 f t t t 2 f 23 "829 829" 100 0 0 100	macaddr_cmp - ));
+DATA(insert OID = 836 (  macaddr_cmp	   PGUID 12 f t t t 2 f 23 "829 829" 100 0 0 100	macaddr_cmp - ));
 DESCR("less-equal-greater");
 DATA(insert OID = 837 (  macaddr_manuf	   PGUID 12 f t t t 1 f 25 "829" 100 0 0 100	macaddr_manuf - ));
 DESCR("MAC manufacturer");
 
 /* for inet type support */
-DATA(insert OID = 910 (  inet_in			PGUID 11 f t t t 1 f 869 "0" 100 0 0 100	inet_in - ));
+DATA(insert OID = 910 (  inet_in			PGUID 12 f t t t 1 f 869 "0" 100 0 0 100	inet_in - ));
 DESCR("(internal)");
-DATA(insert OID = 911 (  inet_out			PGUID 11 f t t t 1 f 23 "0" 100 0 0 100  inet_out - ));
+DATA(insert OID = 911 (  inet_out			PGUID 12 f t t t 1 f 23 "0" 100 0 0 100  inet_out - ));
 DESCR("(internal)");
 
 /* for cidr type support */
-DATA(insert OID = 1267 (  cidr_in			PGUID 11 f t t t 1 f 650 "0" 100 0 0 100	cidr_in - ));
+DATA(insert OID = 1267 (  cidr_in			PGUID 12 f t t t 1 f 650 "0" 100 0 0 100	cidr_in - ));
 DESCR("(internal)");
-DATA(insert OID = 1427 (  cidr_out			PGUID 11 f t t t 1 f 23 "0" 100 0 0 100  cidr_out - ));
+DATA(insert OID = 1427 (  cidr_out			PGUID 12 f t t t 1 f 23 "0" 100 0 0 100  cidr_out - ));
 DESCR("(internal)");
 
 /* these are used for both inet and cidr */
-DATA(insert OID = 920 (  network_eq		   PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100	network_eq - ));
+DATA(insert OID = 920 (  network_eq		   PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100	network_eq - ));
 DESCR("equal");
-DATA(insert OID = 921 (  network_lt		   PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100	network_lt - ));
+DATA(insert OID = 921 (  network_lt		   PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100	network_lt - ));
 DESCR("less-than");
-DATA(insert OID = 922 (  network_le		   PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100	network_le - ));
+DATA(insert OID = 922 (  network_le		   PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100	network_le - ));
 DESCR("less-than-or-equal");
-DATA(insert OID = 923 (  network_gt		   PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100	network_gt - ));
+DATA(insert OID = 923 (  network_gt		   PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100	network_gt - ));
 DESCR("greater-than");
-DATA(insert OID = 924 (  network_ge		   PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100	network_ge - ));
+DATA(insert OID = 924 (  network_ge		   PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100	network_ge - ));
 DESCR("greater-than-or-equal");
-DATA(insert OID = 925 (  network_ne		   PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100	network_ne - ));
+DATA(insert OID = 925 (  network_ne		   PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100	network_ne - ));
 DESCR("not equal");
-DATA(insert OID = 926 (  network_cmp		   PGUID 11 f t t t 2 f 23 "869 869" 100 0 0 100	network_cmp - ));
+DATA(insert OID = 926 (  network_cmp		   PGUID 12 f t t t 2 f 23 "869 869" 100 0 0 100	network_cmp - ));
 DESCR("less-equal-greater");
-DATA(insert OID = 927 (  network_sub		   PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100	network_sub - ));
+DATA(insert OID = 927 (  network_sub		   PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100	network_sub - ));
 DESCR("is-subnet");
-DATA(insert OID = 928 (  network_subeq		   PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100	network_subeq - ));
+DATA(insert OID = 928 (  network_subeq		   PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100	network_subeq - ));
 DESCR("is-subnet-or-equal");
-DATA(insert OID = 929 (  network_sup		   PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100	network_sup - ));
+DATA(insert OID = 929 (  network_sup		   PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100	network_sup - ));
 DESCR("is-supernet");
-DATA(insert OID = 930 (  network_supeq		   PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100	network_supeq - ));
+DATA(insert OID = 930 (  network_supeq		   PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100	network_supeq - ));
 DESCR("is-supernet-or-equal");
 
 /* inet/cidr versions */
 DATA(insert OID = 696 (  netmask				PGUID 12 f t t t 1 f 25 "869" 100 0 0 100  network_netmask - ));
 DESCR("netmask of address");
-DATA(insert OID = 697 (  masklen				PGUID 11 f t t t 1 f 23 "869" 100 0 0 100  network_masklen - ));
+DATA(insert OID = 697 (  masklen				PGUID 12 f t t t 1 f 23 "869" 100 0 0 100  network_masklen - ));
 DESCR("netmask length");
 DATA(insert OID = 698 (  broadcast				PGUID 12 f t t t 1 f 25 "869" 100 0 0 100  network_broadcast - ));
 DESCR("broadcast address");
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index bb483164130..4fa7481f042 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: builtins.h,v 1.129 2000/08/03 16:34:50 tgl Exp $
+ * $Id: builtins.h,v 1.130 2000/08/03 23:07:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -16,7 +16,6 @@
 
 #include "nodes/relation.h"		/* for amcostestimate parameters */
 #include "storage/itemptr.h"
-#include "utils/inet.h"
 #include "utils/numeric.h"
 
 /*
@@ -436,7 +435,6 @@ extern Datum textlike(PG_FUNCTION_ARGS);
 extern Datum textnlike(PG_FUNCTION_ARGS);
 
 /* oracle_compat.c */
-
 extern Datum lower(PG_FUNCTION_ARGS);
 extern Datum upper(PG_FUNCTION_ARGS);
 extern Datum initcap(PG_FUNCTION_ARGS);
@@ -450,48 +448,48 @@ extern Datum ichar(PG_FUNCTION_ARGS);
 extern Datum repeat(PG_FUNCTION_ARGS);
 extern Datum ascii(PG_FUNCTION_ARGS);
 
-/* acl.c */
-
 /* inet_net_ntop.c */
-extern char *inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size);
-extern char *inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size);
+extern char *inet_net_ntop(int af, const void *src, int bits,
+						   char *dst, size_t size);
+extern char *inet_cidr_ntop(int af, const void *src, int bits,
+							char *dst, size_t size);
 
 /* inet_net_pton.c */
-extern int	inet_net_pton(int af, const char *src, void *dst, size_t size);
+extern int	inet_net_pton(int af, const char *src,
+						  void *dst, size_t size);
 
 /* network.c */
-extern inet *inet_in(char *str);
-extern char *inet_out(inet *addr);
-extern inet *cidr_in(char *str);
-extern char *cidr_out(inet *addr);
-extern bool network_lt(inet *a1, inet *a2);
-extern bool network_le(inet *a1, inet *a2);
-extern bool network_eq(inet *a1, inet *a2);
-extern bool network_ge(inet *a1, inet *a2);
-extern bool network_gt(inet *a1, inet *a2);
-extern bool network_ne(inet *a1, inet *a2);
-extern bool network_sub(inet *a1, inet *a2);
-extern bool network_subeq(inet *a1, inet *a2);
-extern bool network_sup(inet *a1, inet *a2);
-extern bool network_supeq(inet *a1, inet *a2);
-extern int4 network_cmp(inet *a1, inet *a2);
-
+extern Datum inet_in(PG_FUNCTION_ARGS);
+extern Datum inet_out(PG_FUNCTION_ARGS);
+extern Datum cidr_in(PG_FUNCTION_ARGS);
+extern Datum cidr_out(PG_FUNCTION_ARGS);
+extern Datum network_cmp(PG_FUNCTION_ARGS);
+extern Datum network_lt(PG_FUNCTION_ARGS);
+extern Datum network_le(PG_FUNCTION_ARGS);
+extern Datum network_eq(PG_FUNCTION_ARGS);
+extern Datum network_ge(PG_FUNCTION_ARGS);
+extern Datum network_gt(PG_FUNCTION_ARGS);
+extern Datum network_ne(PG_FUNCTION_ARGS);
+extern Datum network_sub(PG_FUNCTION_ARGS);
+extern Datum network_subeq(PG_FUNCTION_ARGS);
+extern Datum network_sup(PG_FUNCTION_ARGS);
+extern Datum network_supeq(PG_FUNCTION_ARGS);
 extern Datum network_network(PG_FUNCTION_ARGS);
 extern Datum network_netmask(PG_FUNCTION_ARGS);
-extern int4 network_masklen(inet *addr);
+extern Datum network_masklen(PG_FUNCTION_ARGS);
 extern Datum network_broadcast(PG_FUNCTION_ARGS);
 extern Datum network_host(PG_FUNCTION_ARGS);
 
 /* mac.c */
-extern macaddr *macaddr_in(char *str);
-extern char *macaddr_out(macaddr *addr);
-extern bool macaddr_lt(macaddr *a1, macaddr *a2);
-extern bool macaddr_le(macaddr *a1, macaddr *a2);
-extern bool macaddr_eq(macaddr *a1, macaddr *a2);
-extern bool macaddr_ge(macaddr *a1, macaddr *a2);
-extern bool macaddr_gt(macaddr *a1, macaddr *a2);
-extern bool macaddr_ne(macaddr *a1, macaddr *a2);
-extern int4 macaddr_cmp(macaddr *a1, macaddr *a2);
+extern Datum macaddr_in(PG_FUNCTION_ARGS);
+extern Datum macaddr_out(PG_FUNCTION_ARGS);
+extern Datum macaddr_cmp(PG_FUNCTION_ARGS);
+extern Datum macaddr_lt(PG_FUNCTION_ARGS);
+extern Datum macaddr_le(PG_FUNCTION_ARGS);
+extern Datum macaddr_eq(PG_FUNCTION_ARGS);
+extern Datum macaddr_ge(PG_FUNCTION_ARGS);
+extern Datum macaddr_gt(PG_FUNCTION_ARGS);
+extern Datum macaddr_ne(PG_FUNCTION_ARGS);
 extern Datum macaddr_manuf(PG_FUNCTION_ARGS);
 
 /* numeric.c */
diff --git a/src/include/utils/inet.h b/src/include/utils/inet.h
index 075d66aa6b3..5b39801f9c1 100644
--- a/src/include/utils/inet.h
+++ b/src/include/utils/inet.h
@@ -7,17 +7,17 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: inet.h,v 1.7 2000/07/06 05:48:31 tgl Exp $
+ * $Id: inet.h,v 1.8 2000/08/03 23:07:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
-#ifndef MAC_H
-#define MAC_H
+#ifndef INET_H
+#define INET_H
 
 /*
- *	This is the internal storage format for IP addresses:
+ *	This is the internal storage format for IP addresses
+ *	(both INET and CIDR datatypes):
  */
-
 typedef struct
 {
 	unsigned char family;
@@ -30,8 +30,17 @@ typedef struct
 	}			addr;
 } inet_struct;
 
+/*
+ * Both INET and CIDR addresses are represented within Postgres as varlena
+ * objects, ie, there is a varlena header (basically a length word) in front
+ * of the struct type depicted above.
+ *
+ * Although these types are variable-length, the maximum length
+ * is pretty short, so we make no provision for TOASTing them.
+ */
 typedef struct varlena inet;
 
+
 /*
  *	This is the internal storage format for MAC addresses:
  */
@@ -45,4 +54,18 @@ typedef struct macaddr
 	unsigned char f;
 } macaddr;
 
-#endif	 /* MAC_H */
+/*
+ * fmgr interface macros
+ */
+#define DatumGetInetP(X)    ((inet *) DatumGetPointer(X))
+#define InetPGetDatum(X)    PointerGetDatum(X)
+#define PG_GETARG_INET_P(n) DatumGetInetP(PG_GETARG_DATUM(n))
+#define PG_RETURN_INET_P(x) return InetPGetDatum(x)
+/* macaddr is a fixed-length pass-by-reference datatype */
+#define DatumGetMacaddrP(X)    ((macaddr *) DatumGetPointer(X))
+#define MacaddrPGetDatum(X)    PointerGetDatum(X)
+#define PG_GETARG_MACADDR_P(n) DatumGetMacaddrP(PG_GETARG_DATUM(n))
+#define PG_RETURN_MACADDR_P(x) return MacaddrPGetDatum(x)
+
+
+#endif	 /* INET_H */
diff --git a/src/test/regress/expected/inet.out b/src/test/regress/expected/inet.out
index 35bfd77809d..6822ae38954 100644
--- a/src/test/regress/expected/inet.out
+++ b/src/test/regress/expected/inet.out
@@ -128,7 +128,7 @@ SELECT '' AS ten, i, c,
      | 192.168.1.226/24 | 192.168.1/24 | f  | t  | t  | t  | f  | f  | f  | t   | f   | t
      | 192.168.1.226    | 192.168.1/24 | f  | f  | f  | t  | t  | t  | t  | t   | f   | f
      | 10.1.2.3/8       | 10/8         | f  | t  | t  | t  | f  | f  | f  | t   | f   | t
-     | 10.1.2.3/8       | 10.0.0.0/32  | f  | f  | f  | t  | t  | t  | f  | f   | t   | t
+     | 10.1.2.3/8       | 10.0.0.0/32  | t  | t  | f  | f  | f  | t  | f  | f   | t   | t
      | 10.1.2.3         | 10.1.2.3/32  | f  | t  | t  | t  | f  | f  | f  | t   | f   | t
      | 10.1.2.3/24      | 10.1.2/24    | f  | t  | t  | t  | f  | f  | f  | t   | f   | t
      | 10.1.2.3/16      | 10.1/16      | f  | t  | t  | t  | f  | f  | f  | t   | f   | t
-- 
GitLab