diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index f3e7aa83abf..11ccc2a9a60 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.38 2000/10/04 15:47:45 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.39 2000/11/10 20:13:25 tgl Exp $
 -->
 
  <chapter id="datatype">
@@ -65,7 +65,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.38 2000/10/04 15:47:45 pe
       <row>
        <entry>cidr</entry>
        <entry></entry>
-       <entry>IP version 4 network or host address</entry>
+       <entry>IP network address</entry>
       </row>
       <row>
        <entry>circle</entry>
@@ -95,7 +95,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.38 2000/10/04 15:47:45 pe
       <row>
        <entry>inet</entry>
        <entry></entry>
-       <entry>IP version 4 network or host address</entry>
+       <entry>IP network or host address</entry>
       </row>
       <row>
        <entry>int2</entry>
@@ -1736,7 +1736,7 @@ January 8 04:05:06 1999 PST
 
    <para>
     <productname>Postgres</> offers data types to store IP and MAC
-    addresses.  It is preferrable to use these types over plain text
+    addresses.  It is preferable to use these types over plain text
     types, because these types offer input error checking and several
     specialized operators and functions.
 
@@ -1755,16 +1755,16 @@ January 8 04:05:06 1999 PST
 
        <row>
 	<entry>cidr</entry>
-	<entry>11 bytes</entry>
+	<entry>12 bytes</entry>
 	<entry>IP networks</entry>
 	<entry>valid IPv4 networks</entry>
        </row>
 
        <row>
 	<entry>inet</entry>
-	<entry>11 bytes</entry>
+	<entry>12 bytes</entry>
 	<entry>IP hosts and networks</entry>
-	<entry>valid IPv4 hosts</entry>
+	<entry>valid IPv4 hosts or networks</entry>
        </row>
 
        <row>
@@ -1784,19 +1784,48 @@ January 8 04:05:06 1999 PST
    </para>
 
 
+   <sect2 id="inet-type">
+    <title><type>inet</type></title>
+
+    <para>
+     The <type>inet</type> type holds an IP host address, and
+     optionally the identity of the subnet it is in, all in one field.
+     The subnet identity is represented by the number of bits in the
+     network part of the address (the "netmask").  If the netmask is 32,
+     then the value does not indicate a subnet, only a single host.
+     Note that if you want to accept networks only, you should use the
+     <type>cidr</type> type rather than <type>inet</type>.
+    </para>
+
+    <para>
+     The input format for this type is <replaceable
+     class="parameter">x.x.x.x/y</replaceable> where <replaceable
+     class="parameter">x.x.x.x</replaceable> is an IP address and
+     <replaceable class="parameter">y</replaceable> is the number of
+     bits in the netmask.  If the <replaceable
+     class="parameter">y</replaceable> part is left off, then the
+     netmask is 32, and the value represents just a single host.
+     On display, the <replaceable class="parameter">/y</replaceable>
+     portion is suppressed if the netmask is 32.
+    </para>
+   </sect2>
+
    <sect2 id="cidr-type">
     <title><type>cidr</></title>
 
     <para>
-     The <type>cidr</type> type holds an IP network.  The format for
+     The <type>cidr</type> type holds an IP network specification.
+     Input and output formats follow Classless Internet Domain Routing
+     conventions.
+     The format for
      specifying classless networks is <replaceable
      class="parameter">x.x.x.x/y</> where <replaceable
      class="parameter">x.x.x.x</> is the network and <replaceable
      class="parameter">y</> is the number of bits in the netmask.  If
      <replaceable class="parameter">y</> omitted, it is calculated
-     using assumptions from the older classfull naming system except
-     that it is extended to include at least all of the octets in the
-     input.
+     using assumptions from the older classful numbering system, except
+     that it will be at least large enough to include all of the octets
+     written in the input.
     </para>
 
     <para>
@@ -1816,6 +1845,10 @@ January 8 04:05:06 1999 PST
 	 <entry>192.168.100.128/25</entry>
 	 <entry>192.168.100.128/25</entry>
 	</row>
+	<row>
+	 <entry>192.168/24</entry>
+	 <entry>192.168.0/24</entry>
+	</row>
 	<row>
 	 <entry>192.168/25</entry>
 	 <entry>192.168.0.0/25</entry>
@@ -1856,30 +1889,19 @@ January 8 04:05:06 1999 PST
       </tgroup>
      </table>
     </para>
-   </sect2>
-
-   <sect2 id="inet-type">
-    <title><type>inet</type></title>
 
     <para>
-     The <type>inet</type> type holds an IP host address, and
-     optionally the identity of the subnet it is in, all in one field.
-     Note that if you want to store networks only, you should use the
-     <type>cidr</type> type.  The <type>inet</type> type is similar to
-     the <type>cidr</type> type except that the bits in the host part
-     can be non-zero.  Functions exist to extract the various elements
-     of the field.
-    </para>
+    The essential difference between <type>inet</type> and <type>cidr</type>
+    data types is that <type>inet</type> accepts values with nonzero bits to
+    the right of the netmask, whereas <type>cidr</type> does not.
 
-    <para>
-     The input format for this type is <replaceable
-     class="parameter">x.x.x.x/y</replaceable> where <replaceable
-     class="parameter">x.x.x.x</replaceable> is an internet host and
-     <replaceable class="parameter">y</replaceable> is the number of
-     bits in the netmask.  If the <replaceable
-     class="parameter">y</replaceable> part is left off, then the
-     netmask is 32 and you are effectively only storing the address of
-     a single host.
+      <tip>
+        <para>
+	If you do not like the output format for <type>inet</type> or
+	<type>cidr</type> values, try the <function>host</>() and
+	<function>text</>() functions.
+	</para>
+      </tip>
     </para>
    </sect2>
 
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index c51e8905e10..655c63a7931 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -1480,62 +1480,98 @@ Not defined by this name. Implements the intersection operator '#'
    <para>
     <table tocentry="1" id="cidr-inet-functions">
      <title><type>cidr</> and <type>inet</> Functions</title>
-     <tgroup cols="4">
+     <tgroup cols="5">
       <thead>
        <row>
 	<entry>Function</entry>
 	<entry>Returns</entry>
 	<entry>Description</entry>
 	<entry>Example</entry>
+	<entry>Result</entry>
        </row>
       </thead>
       <tbody>
-       <row>
-	<entry>broadcast(cidr)</entry>
-	<entry>text</entry>
-	<entry>construct broadcast address as text</entry>
-	<entry>broadcast('192.168.1.5/24')</entry>
-       </row>
        <row>
 	<entry>broadcast(inet)</entry>
-	<entry>text</entry>
-	<entry>construct broadcast address as text</entry>
+	<entry>inet</entry>
+	<entry>broadcast address for network</entry>
 	<entry>broadcast('192.168.1.5/24')</entry>
+	<entry>192.168.1.255/24</entry>
        </row>
        <row>
 	<entry>host(inet)</entry>
 	<entry>text</entry>
-	<entry>extract host address as text</entry>
+	<entry>extract IP address as text</entry>
 	<entry>host('192.168.1.5/24')</entry>
-       </row>
-       <row>
-	<entry>masklen(cidr)</entry>
-	<entry>integer</entry>
-	<entry>calculate netmask length</entry>
-	<entry>masklen('192.168.1.5/24')</entry>
+	<entry>192.168.1.5</entry>
        </row>
        <row>
 	<entry>masklen(inet)</entry>
 	<entry>integer</entry>
-	<entry>calculate netmask length</entry>
+	<entry>extract netmask length</entry>
 	<entry>masklen('192.168.1.5/24')</entry>
+	<entry>24</entry>
        </row>
        <row>
 	<entry>netmask(inet)</entry>
-	<entry>text</entry>
-	<entry>construct netmask as text</entry>
+	<entry>inet</entry>
+	<entry>construct netmask for network</entry>
 	<entry>netmask('192.168.1.5/24')</entry>
+	<entry>255.255.255.0</entry>
        </row>
+       <row>
+	<entry>network(inet)</entry>
+	<entry>cidr</entry>
+	<entry>extract network part of address</entry>
+	<entry>network('192.168.1.5/24')</entry>
+	<entry>192.168.1/24</entry>
+       </row>
+       <row>
+	<entry>text(inet)</entry>
+	<entry>text</entry>
+	<entry>extract IP address and masklen as text</entry>
+	<entry>text(inet '192.168.1.5')</entry>
+	<entry>192.168.1.5/32</entry>
+       </row>
+      </tbody>
+     </tgroup>
+    </table>
+   </para>
+
+   <para>
+    All of the functions for <type>inet</type> can be applied to
+    <type>cidr</type> values as well.  The <function>host</>() and
+    <function>text</>() functions are primarily intended to offer
+    alternative display formats.
+   </para>
+
+   <para>
+    <table tocentry="1" id="macaddr-functions">
+     <title><type>macaddr</> Functions</title>
+     <tgroup cols="5">
+      <thead>
+       <row>
+	<entry>Function</entry>
+	<entry>Returns</entry>
+	<entry>Description</entry>
+	<entry>Example</entry>
+	<entry>Result</entry>
+       </row>
+      </thead>
+      <tbody>
        <row>
 	<entry>trunc(macaddr)</entry>
 	<entry>macaddr</entry>
 	<entry>set last 3 bytes to zero</entry>
 	<entry>trunc(macaddr '12:34:56:78:90:ab')</entry>
+	<entry>12:34:56:00:00:00</entry>
        </row>
       </tbody>
      </tgroup>
     </table>
+   </para>
 
+   <para>
     The function <function>trunc</>(<type>macaddr</>) returns a MAC
     address with the last 3 bytes set to 0.  This can be used to
     associate the remaining prefix with a manufacturer.  The directory
diff --git a/doc/src/sgml/oper.sgml b/doc/src/sgml/oper.sgml
index deb3d33cde8..8934323cd05 100644
--- a/doc/src/sgml/oper.sgml
+++ b/doc/src/sgml/oper.sgml
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/Attic/oper.sgml,v 1.21 2000/10/24 20:13:31 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/Attic/oper.sgml,v 1.22 2000/11/10 20:13:25 tgl Exp $
 -->
 
  <Chapter Id="operators">
@@ -756,80 +756,11 @@ logical union
   <sect1 id="net-operators">
    <title>Network Address Type Operators</title>
 
-   <sect2 id="cidr-operators">
-    <title><type>cidr</> Operators</title>
+   <sect2 id="cidr-inet-operators">
+    <title><type>cidr</> and <type>inet</> Operators</title>
 
-    <table tocentry="1" id="cidr-operators-table">
-     <title><type>cidr</> Operators</title>
-     <TGROUP COLS="3">
-      <THEAD>
-       <ROW>
-	<ENTRY>Operator</ENTRY>
-	<ENTRY>Description</ENTRY>
-	<ENTRY>Usage</ENTRY>
-       </ROW>
-      </THEAD>
-      <TBODY>
-       <ROW>
-	<ENTRY> &lt; </ENTRY>
-	<ENTRY>Less than</ENTRY>
-	<ENTRY>'192.168.1.5'::cidr &lt; '192.168.1.6'::cidr</ENTRY>
-       </ROW>
-       <ROW>
-	<ENTRY> &lt;= </ENTRY>
-	<ENTRY>Less than or equal</ENTRY>
-	<ENTRY>'192.168.1.5'::cidr &lt;= '192.168.1.5'::cidr</ENTRY>
-       </ROW>
-       <ROW>
-	<ENTRY> = </ENTRY>
-	<ENTRY>Equals</ENTRY>
-	<ENTRY>'192.168.1.5'::cidr = '192.168.1.5'::cidr</ENTRY>
-       </ROW>
-       <ROW>
-	<ENTRY> &gt;= </ENTRY>
-	<ENTRY>Greater or equal</ENTRY>
-	<ENTRY>'192.168.1.5'::cidr &gt;= '192.168.1.5'::cidr</ENTRY>
-       </ROW>
-       <ROW>
-	<ENTRY> &gt; </ENTRY>
-	<ENTRY>Greater</ENTRY>
-	<ENTRY>'192.168.1.5'::cidr &gt; '192.168.1.4'::cidr</ENTRY>
-       </ROW>
-       <ROW>
-	<ENTRY> &lt;&gt; </ENTRY>
-	<ENTRY>Not equal</ENTRY>
-	<ENTRY>'192.168.1.5'::cidr &lt;&gt; '192.168.1.4'::cidr</ENTRY>
-       </ROW>
-       <ROW>
-	<ENTRY> &lt;&lt; </ENTRY>
-	<ENTRY>is contained within</ENTRY>
-	<ENTRY>'192.168.1.5'::cidr &lt;&lt; '192.168.1/24'::cidr</ENTRY>
-       </ROW>
-       <ROW>
-	<ENTRY> &lt;&lt;= </ENTRY>
-	<ENTRY>is contained within or equals</ENTRY>
-	<ENTRY>'192.168.1/24'::cidr &lt;&lt;= '192.168.1/24'::cidr</ENTRY>
-       </ROW>
-       <ROW>
-	<ENTRY> &gt;&gt; </ENTRY>
-	<ENTRY>contains</ENTRY>
-	<ENTRY>'192.168.1/24'::cidr &gt;&gt; '192.168.1.5'::cidr</ENTRY>
-       </ROW>
-       <ROW>
-	<ENTRY> &gt;&gt;= </ENTRY>
-	<ENTRY>contains or equals</ENTRY>
-	<ENTRY>'192.168.1/24'::cidr &gt;&gt;= '192.168.1/24'::cidr</ENTRY>
-       </ROW>
-      </TBODY>
-     </TGROUP>
-    </TABLE>
-   </sect2>
-
-   <sect2 id="inet-operators">
-   <title><type>inet</> Operators</title>
-   
-    <table tocentry="1" id="inet-operators-table">
-     <title><type>inet</> Operators</title>
+    <table tocentry="1" id="cidr-inet-operators-table">
+     <title><type>cidr</> and <type>inet</> Operators</title>
      <TGROUP COLS="3">
       <THEAD>
        <ROW>
@@ -892,6 +823,16 @@ logical union
       </TBODY>
      </TGROUP>
     </TABLE>
+
+    <para>
+     All of the operators for <type>inet</type> can be applied to
+     <type>cidr</type> values as well.  The operators
+     <literal>&lt;&lt;</> <literal>&lt;&lt;=</>
+     <literal>&gt;&gt;</> <literal>&gt;&gt;=</>
+     test for subnet inclusion: they consider only the network parts
+     of the two addresses, ignoring any host part, and determine whether
+     one network part is identical to or a subnet of the other.
+    </para>
    </sect2>
 
    <sect2 id="macaddr-operators">
diff --git a/src/backend/utils/adt/inet_net_ntop.c b/src/backend/utils/adt/inet_net_ntop.c
index c38ecc5a6f2..ecc83cab814 100644
--- a/src/backend/utils/adt/inet_net_ntop.c
+++ b/src/backend/utils/adt/inet_net_ntop.c
@@ -16,7 +16,7 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.8 1999/07/17 20:17:56 momjian Exp $";
+static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.9 2000/11/10 20:13:25 tgl Exp $";
 
 #endif
 
@@ -56,7 +56,7 @@ inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size)
 {
 	switch (af)
 	{
-			case AF_INET:
+		case AF_INET:
 			return (inet_cidr_ntop_ipv4(src, bits, dst, size));
 		default:
 			errno = EAFNOSUPPORT;
@@ -102,15 +102,12 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
 	/* Format whole octets. */
 	for (b = bits / 8; b > 0; b--)
 	{
-		if (size < sizeof "255.")
+		if (size < sizeof ".255")
 			goto emsgsize;
 		t = dst;
-		dst += SPRINTF((dst, "%u", *src++));
-		if (b > 1)
-		{
+		if (dst != odst)
 			*dst++ = '.';
-			*dst = '\0';
-		}
+		dst += SPRINTF((dst, "%u", *src++));
 		size -= (size_t) (dst - t);
 	}
 
@@ -132,6 +129,7 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
 	if (size < sizeof "/32")
 		goto emsgsize;
 	dst += SPRINTF((dst, "/%u", bits));
+
 	return (odst);
 
 emsgsize:
@@ -159,7 +157,7 @@ inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
 {
 	switch (af)
 	{
-			case AF_INET:
+		case AF_INET:
 			return (inet_net_ntop_ipv4(src, bits, dst, size));
 		default:
 			errno = EAFNOSUPPORT;
@@ -185,48 +183,34 @@ inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
 {
 	char	   *odst = dst;
 	char	   *t;
-	size_t		len = 4;
-	int			b,
-				tb;
+	int			len = 4;
+	int			b;
 
 	if (bits < 0 || bits > 32)
 	{
 		errno = EINVAL;
 		return (NULL);
 	}
-	if (bits == 0)
-	{
-		if (size < sizeof "0")
-			goto emsgsize;
-		*dst++ = '0';
-		size--;
-		*dst = '\0';
-	}
 
-	/* Format whole octets plus nonzero trailing octets. */
-	tb = (bits == 32) ? 31 : bits;
-	for (b = 0; bits != 0 && (b <= (tb / 8) || (b < len && *src != 0)); b++)
+	/* Always format all four octets, regardless of mask length. */
+	for (b = len; b > 0; b--)
 	{
-		if (size < sizeof "255.")
+		if (size < sizeof ".255")
 			goto emsgsize;
 		t = dst;
-		dst += SPRINTF((dst, "%u", *src++));
-		if (b + 1 <= (tb / 8) || (b + 1 < len && *src != 0))
-		{
+		if (dst != odst)
 			*dst++ = '.';
-			*dst = '\0';
-		}
+		dst += SPRINTF((dst, "%u", *src++));
 		size -= (size_t) (dst - t);
 	}
 
 	/* don't print masklen if 32 bits */
-	if (bits == 32)
-		return odst;
-
-	/* Format CIDR /width. */
-	if (size < sizeof "/32")
-		goto emsgsize;
-	dst += SPRINTF((dst, "/%u", bits));
+	if (bits != 32)
+	{
+		if (size < sizeof "/32")
+			goto emsgsize;
+		dst += SPRINTF((dst, "/%u", bits));
+	}
 
 	return (odst);
 
diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c
index a3070f29e76..52f4e8ecd2f 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.25 2000/10/27 01:52:15 tgl Exp $
+ *	$Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.26 2000/11/10 20:13:25 tgl Exp $
  *
  *	Jon Postel RIP 16 Oct 1998
  */
@@ -67,12 +67,12 @@ network_in(char *src, int type)
 
 	/*
 	 * Error check: CIDR values must not have any bits set beyond the masklen.
-	 * XXX this code not IPV6 ready.
+	 * XXX this code is not IPV6 ready.
 	 */
 	if (type)
 	{
 		if (! v4addressOK(ip_v4addr(dst), bits))
-			elog(ERROR, "invalid CIDR value '%s': width too small", src);
+			elog(ERROR, "invalid CIDR value '%s': has bits set to right of mask", src);
 	}
 
 	VARATT_SIZEP(dst) = VARHDRSZ
@@ -338,12 +338,10 @@ network_host(PG_FUNCTION_ARGS)
 	char	   *ptr,
 				tmp[sizeof("255.255.255.255/32")];
 
-	if (ip_type(ip))
-		elog(ERROR, "CIDR type has no host part");
-
 	if (ip_family(ip) == AF_INET)
 	{
 		/* It's an IP V4 address: */
+		/* force display of 32 bits, regardless of masklen... */
 		if (inet_net_ntop(AF_INET, &ip_v4addr(ip), 32, tmp, sizeof(tmp)) == NULL)
 			elog(ERROR, "unable to print host (%s)", strerror(errno));
 	}
@@ -351,7 +349,7 @@ network_host(PG_FUNCTION_ARGS)
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "unknown address family (%d)", ip_family(ip));
 
-	/* Suppress /n if present */
+	/* Suppress /n if present (shouldn't happen now) */
 	if ((ptr = strchr(tmp, '/')) != NULL)
 		*ptr = '\0';
 
@@ -363,6 +361,40 @@ network_host(PG_FUNCTION_ARGS)
 	PG_RETURN_TEXT_P(ret);
 }
 
+Datum
+network_show(PG_FUNCTION_ARGS)
+{
+	inet	   *ip = PG_GETARG_INET_P(0);
+	text	   *ret;
+	int			len;
+	char		tmp[sizeof("255.255.255.255/32")];
+
+	if (ip_family(ip) == AF_INET)
+	{
+		/* It's an IP V4 address: */
+		/* force display of 32 bits, regardless of masklen... */
+		if (inet_net_ntop(AF_INET, &ip_v4addr(ip), 32, tmp, sizeof(tmp)) == NULL)
+			elog(ERROR, "unable to print host (%s)", strerror(errno));
+	}
+	else
+		/* Go for an IPV6 address here, before faulting out: */
+		elog(ERROR, "unknown address family (%d)", ip_family(ip));
+
+	/* Add /n if not present */
+	if (strchr(tmp, '/') == NULL)
+	{
+		len = strlen(tmp);
+		snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(ip));
+	}
+
+	/* Return string as a text datum */
+	len = strlen(tmp);
+	ret = (text *) palloc(len + VARHDRSZ);
+	VARATT_SIZEP(ret) = len + VARHDRSZ;
+	memcpy(VARDATA(ret), tmp, len);
+	PG_RETURN_TEXT_P(ret);
+}
+
 Datum
 network_masklen(PG_FUNCTION_ARGS)
 {
@@ -375,100 +407,100 @@ Datum
 network_broadcast(PG_FUNCTION_ARGS)
 {
 	inet	   *ip = PG_GETARG_INET_P(0);
-	text	   *ret;
-	int			len;
-	char	   *ptr,
-				tmp[sizeof("255.255.255.255/32")];
+	inet	   *dst;
+
+	dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct));
+	/* make sure any unused bits are zeroed */
+	MemSet(dst, 0, VARHDRSZ + sizeof(inet_struct));
 
 	if (ip_family(ip) == AF_INET)
 	{
 		/* It's an IP V4 address: */
-		int			addr;
 		unsigned long mask = 0xffffffff;
 
-		if (ip_bits(ip) < 32)
-			mask >>= ip_bits(ip);
-		addr = htonl(ntohl(ip_v4addr(ip)) | mask);
+		mask >>= ip_bits(ip);
 
-		if (inet_net_ntop(AF_INET, &addr, 32, tmp, sizeof(tmp)) == NULL)
-			elog(ERROR, "unable to print address (%s)", strerror(errno));
+		ip_v4addr(dst) = htonl(ntohl(ip_v4addr(ip)) | mask);
 	}
 	else
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "unknown address family (%d)", ip_family(ip));
 
-	/* Suppress /n if present */
-	if ((ptr = strchr(tmp, '/')) != NULL)
-		*ptr = '\0';
+	ip_family(dst) = ip_family(ip);
+	ip_bits(dst) = ip_bits(ip);
+	ip_type(dst) = 0;
+	VARATT_SIZEP(dst) = VARHDRSZ
+		+ ((char *) &ip_v4addr(dst) - (char *) VARDATA(dst))
+		+ ip_addrsize(dst);
 
-	/* Return string as a text datum */
-	len = strlen(tmp);
-	ret = (text *) palloc(len + VARHDRSZ);
-	VARATT_SIZEP(ret) = len + VARHDRSZ;
-	memcpy(VARDATA(ret), tmp, len);
-	PG_RETURN_TEXT_P(ret);
+	PG_RETURN_INET_P(dst);
 }
 
 Datum
 network_network(PG_FUNCTION_ARGS)
 {
 	inet	   *ip = PG_GETARG_INET_P(0);
-	text	   *ret;
-	int			len;
-	char		tmp[sizeof("255.255.255.255/32")];
+	inet	   *dst;
+
+	dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct));
+	/* make sure any unused bits are zeroed */
+	MemSet(dst, 0, VARHDRSZ + sizeof(inet_struct));
 
 	if (ip_family(ip) == AF_INET)
 	{
 		/* It's an IP V4 address: */
-		int			addr = htonl(ntohl(ip_v4addr(ip)) & (0xffffffff << (32 - ip_bits(ip))));
+		unsigned long mask = 0xffffffff;
 
-		if (inet_cidr_ntop(AF_INET, &addr, ip_bits(ip), tmp, sizeof(tmp)) == NULL)
-			elog(ERROR, "unable to print network (%s)", strerror(errno));
+		mask <<= (32 - ip_bits(ip));
+
+		ip_v4addr(dst) = htonl(ntohl(ip_v4addr(ip)) & mask);
 	}
 	else
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "unknown address family (%d)", ip_family(ip));
 
-	/* Return string as a text datum */
-	len = strlen(tmp);
-	ret = (text *) palloc(len + VARHDRSZ);
-	VARATT_SIZEP(ret) = len + VARHDRSZ;
-	memcpy(VARDATA(ret), tmp, len);
-	PG_RETURN_TEXT_P(ret);
+	ip_family(dst) = ip_family(ip);
+	ip_bits(dst) = ip_bits(ip);
+	ip_type(dst) = 1;
+	VARATT_SIZEP(dst) = VARHDRSZ
+		+ ((char *) &ip_v4addr(dst) - (char *) VARDATA(dst))
+		+ ip_addrsize(dst);
+
+	PG_RETURN_INET_P(dst);
 }
 
 Datum
 network_netmask(PG_FUNCTION_ARGS)
 {
 	inet	   *ip = PG_GETARG_INET_P(0);
-	text	   *ret;
-	int			len;
-	char	   *ptr,
-				tmp[sizeof("255.255.255.255/32")];
+	inet	   *dst;
+
+	dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct));
+	/* make sure any unused bits are zeroed */
+	MemSet(dst, 0, VARHDRSZ + sizeof(inet_struct));
 
 	if (ip_family(ip) == AF_INET)
 	{
 		/* It's an IP V4 address: */
-		int			addr = htonl(ip_bits(ip) ?
-				   (-1 << (32 - ip_bits(ip))) & 0xffffffff : 0x00000000);
+		unsigned long mask = 0xffffffff;
 
-		if (inet_net_ntop(AF_INET, &addr, 32, tmp, sizeof(tmp)) == NULL)
-			elog(ERROR, "unable to print netmask (%s)", strerror(errno));
+		mask <<= (32 - ip_bits(ip));
+
+		ip_v4addr(dst) = htonl(mask);
+
+		ip_bits(dst) = 32;
 	}
 	else
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "unknown address family (%d)", ip_family(ip));
 
-	/* Suppress /n if present */
-	if ((ptr = strchr(tmp, '/')) != NULL)
-		*ptr = '\0';
+	ip_family(dst) = ip_family(ip);
+	ip_type(dst) = 0;
+	VARATT_SIZEP(dst) = VARHDRSZ
+		+ ((char *) &ip_v4addr(dst) - (char *) VARDATA(dst))
+		+ ip_addrsize(dst);
 
-	/* Return string as a text datum */
-	len = strlen(tmp);
-	ret = (text *) palloc(len + VARHDRSZ);
-	VARATT_SIZEP(ret) = len + VARHDRSZ;
-	memcpy(VARDATA(ret), tmp, len);
-	PG_RETURN_TEXT_P(ret);
+	PG_RETURN_INET_P(dst);
 }
 
 /*
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 01efe5efb98..bf66917aa7f 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: catversion.h,v 1.56 2000/11/08 16:59:50 petere Exp $
+ * $Id: catversion.h,v 1.57 2000/11/10 20:13:26 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	200011080
+#define CATALOG_VERSION_NO	200011101
 
 #endif
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 30a7b2d9982..11f20071c7e 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.172 2000/11/06 15:58:46 thomas Exp $
+ * $Id: pg_proc.h,v 1.173 2000/11/10 20:13:26 tgl Exp $
  *
  * NOTES
  *	  The script catalog/genbki.sh reads this file and generates .bki
@@ -2270,17 +2270,19 @@ DESCR("is-supernet");
 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 - ));
+/* inet/cidr functions */
+DATA(insert OID = 683 (  network			PGUID 12 f t t t 1 f 650 "869" 100 0 0 100  network_network - ));
+DESCR("network part of address");
+DATA(insert OID = 696 (  netmask			PGUID 12 f t t t 1 f 869 "869" 100 0 0 100  network_netmask - ));
 DESCR("netmask of address");
 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");
+DATA(insert OID = 698 (  broadcast			PGUID 12 f t t t 1 f 869 "869" 100 0 0 100  network_broadcast - ));
+DESCR("broadcast address of network");
 DATA(insert OID = 699 (  host				PGUID 12 f t t t 1 f 25 "869" 100 0 0 100  network_host - ));
-DESCR("host address");
-DATA(insert OID = 683 (  network			PGUID 12 f t t t 1 f 25 "869" 100 0 0 100  network_network - ));
-DESCR("network address");
+DESCR("show address octets only");
+DATA(insert OID = 730 (  text				PGUID 12 f t t t 1 f 25 "869" 100 0 0 100  network_show - ));
+DESCR("show all parts of inet/cidr value");
 
 DATA(insert OID =  1691 (  boolle			PGUID 12 f t t t 2 f 16 "16 16" 100 0 0 100  boolle - ));
 DESCR("less-than-or-equal");
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 446c33cc420..f6a4055bb1d 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.140 2000/10/24 20:16:47 petere Exp $
+ * $Id: builtins.h,v 1.141 2000/11/10 20:13:26 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -504,6 +504,7 @@ extern Datum network_netmask(PG_FUNCTION_ARGS);
 extern Datum network_masklen(PG_FUNCTION_ARGS);
 extern Datum network_broadcast(PG_FUNCTION_ARGS);
 extern Datum network_host(PG_FUNCTION_ARGS);
+extern Datum network_show(PG_FUNCTION_ARGS);
 
 /* mac.c */
 extern Datum macaddr_in(PG_FUNCTION_ARGS);
diff --git a/src/test/regress/expected/inet.out b/src/test/regress/expected/inet.out
index daa9cded133..6f86056c013 100644
--- a/src/test/regress/expected/inet.out
+++ b/src/test/regress/expected/inet.out
@@ -17,7 +17,7 @@ INSERT INTO INET_TBL (c, i) VALUES ('10', '11.1.2.3/8');
 INSERT INTO INET_TBL (c, i) VALUES ('10', '9.1.2.3/8');
 -- check that CIDR rejects invalid input:
 INSERT INTO INET_TBL (c, i) VALUES ('192.168.1.2/24', '192.168.1.226');
-ERROR:  invalid CIDR value '192.168.1.2/24': width too small
+ERROR:  invalid CIDR value '192.168.1.2/24': has bits set to right of mask
 SELECT '' AS ten, c AS cidr, i AS inet FROM INET_TBL;
  ten |     cidr     |       inet       
 -----+--------------+------------------
@@ -34,35 +34,35 @@ SELECT '' AS ten, c AS cidr, i AS inet FROM INET_TBL;
 (10 rows)
 
 -- now test some support functions
-SELECT '' AS ten, i AS inet, host(i) FROM INET_TBL;
- ten |       inet       |     host      
------+------------------+---------------
-     | 192.168.1.226/24 | 192.168.1.226
-     | 192.168.1.226    | 192.168.1.226
-     | 10.1.2.3/8       | 10.1.2.3
-     | 10.1.2.3/8       | 10.1.2.3
-     | 10.1.2.3         | 10.1.2.3
-     | 10.1.2.3/24      | 10.1.2.3
-     | 10.1.2.3/16      | 10.1.2.3
-     | 10.1.2.3/8       | 10.1.2.3
-     | 11.1.2.3/8       | 11.1.2.3
-     | 9.1.2.3/8        | 9.1.2.3
+SELECT '' AS ten, i AS inet, host(i), text(i) FROM INET_TBL;
+ ten |       inet       |     host      |       text       
+-----+------------------+---------------+------------------
+     | 192.168.1.226/24 | 192.168.1.226 | 192.168.1.226/24
+     | 192.168.1.226    | 192.168.1.226 | 192.168.1.226/32
+     | 10.1.2.3/8       | 10.1.2.3      | 10.1.2.3/8
+     | 10.1.2.3/8       | 10.1.2.3      | 10.1.2.3/8
+     | 10.1.2.3         | 10.1.2.3      | 10.1.2.3/32
+     | 10.1.2.3/24      | 10.1.2.3      | 10.1.2.3/24
+     | 10.1.2.3/16      | 10.1.2.3      | 10.1.2.3/16
+     | 10.1.2.3/8       | 10.1.2.3      | 10.1.2.3/8
+     | 11.1.2.3/8       | 11.1.2.3      | 11.1.2.3/8
+     | 9.1.2.3/8        | 9.1.2.3       | 9.1.2.3/8
 (10 rows)
 
 SELECT '' AS ten, c AS cidr, broadcast(c),
   i AS inet, broadcast(i) FROM INET_TBL;
- ten |     cidr     |    broadcast    |       inet       |    broadcast    
------+--------------+-----------------+------------------+-----------------
-     | 192.168.1/24 | 192.168.1.255   | 192.168.1.226/24 | 192.168.1.255
-     | 192.168.1/24 | 192.168.1.255   | 192.168.1.226    | 255.255.255.255
-     | 10/8         | 10.255.255.255  | 10.1.2.3/8       | 10.255.255.255
-     | 10.0.0.0/32  | 255.255.255.255 | 10.1.2.3/8       | 10.255.255.255
-     | 10.1.2.3/32  | 255.255.255.255 | 10.1.2.3         | 255.255.255.255
-     | 10.1.2/24    | 10.1.2.255      | 10.1.2.3/24      | 10.1.2.255
-     | 10.1/16      | 10.1.255.255    | 10.1.2.3/16      | 10.1.255.255
-     | 10/8         | 10.255.255.255  | 10.1.2.3/8       | 10.255.255.255
-     | 10/8         | 10.255.255.255  | 11.1.2.3/8       | 11.255.255.255
-     | 10/8         | 10.255.255.255  | 9.1.2.3/8        | 9.255.255.255
+ ten |     cidr     |    broadcast     |       inet       |    broadcast     
+-----+--------------+------------------+------------------+------------------
+     | 192.168.1/24 | 192.168.1.255/24 | 192.168.1.226/24 | 192.168.1.255/24
+     | 192.168.1/24 | 192.168.1.255/24 | 192.168.1.226    | 255.255.255.255
+     | 10/8         | 10.255.255.255/8 | 10.1.2.3/8       | 10.255.255.255/8
+     | 10.0.0.0/32  | 255.255.255.255  | 10.1.2.3/8       | 10.255.255.255/8
+     | 10.1.2.3/32  | 255.255.255.255  | 10.1.2.3         | 255.255.255.255
+     | 10.1.2/24    | 10.1.2.255/24    | 10.1.2.3/24      | 10.1.2.255/24
+     | 10.1/16      | 10.1.255.255/16  | 10.1.2.3/16      | 10.1.255.255/16
+     | 10/8         | 10.255.255.255/8 | 10.1.2.3/8       | 10.255.255.255/8
+     | 10/8         | 10.255.255.255/8 | 11.1.2.3/8       | 11.255.255.255/8
+     | 10/8         | 10.255.255.255/8 | 9.1.2.3/8        | 9.255.255.255/8
 (10 rows)
 
 SELECT '' AS ten, c AS cidr, network(c) AS "network(cidr)",
diff --git a/src/test/regress/sql/inet.sql b/src/test/regress/sql/inet.sql
index e225b2824f7..d91c3a0bbf0 100644
--- a/src/test/regress/sql/inet.sql
+++ b/src/test/regress/sql/inet.sql
@@ -23,7 +23,7 @@ SELECT '' AS ten, c AS cidr, i AS inet FROM INET_TBL;
 
 -- now test some support functions
 
-SELECT '' AS ten, i AS inet, host(i) FROM INET_TBL;
+SELECT '' AS ten, i AS inet, host(i), text(i) FROM INET_TBL;
 SELECT '' AS ten, c AS cidr, broadcast(c),
   i AS inet, broadcast(i) FROM INET_TBL;
 SELECT '' AS ten, c AS cidr, network(c) AS "network(cidr)",