diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c
index 64daefa02949e52f33f1a8298b94d554543442b1..2624c203f7c46c44fe093596d4aeca6158dafda0 100644
--- a/src/backend/utils/adt/network.c
+++ b/src/backend/utils/adt/network.c
@@ -1,7 +1,7 @@
 /*
  *	PostgreSQL type definitions for the INET and CIDR types.
  *
- *	$PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.64 2006/02/11 03:32:39 momjian Exp $
+ *	$PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.65 2006/02/11 20:39:58 tgl Exp $
  *
  *	Jon Postel RIP 16 Oct 1998
  */
@@ -27,7 +27,7 @@ static int32 network_cmp_internal(inet *a1, inet *a2);
 static int	bitncmp(void *l, void *r, int n);
 static bool addressOK(unsigned char *a, int bits, int family);
 static int	ip_addrsize(inet *inetptr);
-static Datum internal_inetpl(inet *ip, int64 iarg);
+static inet *internal_inetpl(inet *ip, int64 addend);
 
 /*
  *	Access macros.
@@ -1292,8 +1292,7 @@ inetand(PG_FUNCTION_ARGS)
 	if (ip_family(ip) != ip_family(ip2))
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("mismatch in address family (%d) != (%d)",
-						ip_family(ip), ip_family(ip2))));
+				 errmsg("cannot AND inet values of different sizes")));
 	else
 	{
 		int nb = ip_addrsize(ip);
@@ -1327,8 +1326,7 @@ inetor(PG_FUNCTION_ARGS)
 	if (ip_family(ip) != ip_family(ip2))
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("mismatch in address family (%d) != (%d)",
-						ip_family(ip), ip_family(ip2))));
+				 errmsg("cannot OR inet values of different sizes")));
 	else
 	{
 		int nb = ip_addrsize(ip);
@@ -1350,8 +1348,8 @@ inetor(PG_FUNCTION_ARGS)
 }
 
 
-static Datum
-internal_inetpl(inet *ip, int64 plus)
+static inet *
+internal_inetpl(inet *ip, int64 addend)
 {
 	inet	   *dst;
 
@@ -1365,15 +1363,31 @@ internal_inetpl(inet *ip, int64 plus)
 
 		while (nb-- > 0)
 		{
-			pdst[nb] = carry = pip[nb] + plus + carry;
-			plus /= 0x100;		/* process next byte */
-			carry /= 0x100;		/* remove low byte */
-			/* Overflow on high byte? */
-			if (nb == 0 && (plus != 0 || carry != 0))
-				ereport(ERROR,
-						(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-						 errmsg("result out of range")));
+			carry = pip[nb] + (int) (addend & 0xFF) + carry;
+			pdst[nb] = (unsigned char) (carry & 0xFF);
+			carry >>= 8;
+			/*
+			 * We have to be careful about right-shifting addend because
+			 * right-shift isn't portable for negative values, while
+			 * simply dividing by 256 doesn't work (the standard rounding
+			 * is in the wrong direction, besides which there may be machines
+			 * out there that round the wrong way).  So, explicitly clear
+			 * the low-order byte to remove any doubt about the correct
+			 * result of the division, and then divide rather than shift.
+			 */
+			addend &= ~((int64) 0xFF);
+			addend /= 0x100;
 		}
+		/*
+		 * At this point we should have addend and carry both zero if
+		 * original addend was >= 0, or addend -1 and carry 1 if original
+		 * addend was < 0.  Anything else means overflow.
+		 */
+		if (!((addend == 0 && carry == 0) ||
+			  (addend == -1 && carry == 1)))
+			ereport(ERROR,
+					(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+					 errmsg("result out of range")));
 	}
 	ip_bits(dst) = ip_bits(ip);
 
@@ -1382,7 +1396,7 @@ internal_inetpl(inet *ip, int64 plus)
 		((char *) ip_addr(dst) - (char *) VARDATA(dst)) +
 		ip_addrsize(dst);
 
-	PG_RETURN_INET_P(dst);
+	return dst;
 }
 
 
@@ -1390,9 +1404,9 @@ Datum
 inetpl(PG_FUNCTION_ARGS)
 {
 	inet   *ip = PG_GETARG_INET_P(0);
-	int64	plus = PG_GETARG_INT64(1);
+	int64	addend = PG_GETARG_INT64(1);
 
-	return internal_inetpl(ip, plus);
+	PG_RETURN_INET_P(internal_inetpl(ip, addend));
 }
 
 
@@ -1400,9 +1414,9 @@ Datum
 inetmi_int8(PG_FUNCTION_ARGS)
 {
 	inet   *ip = PG_GETARG_INET_P(0);
-	int64	plus = PG_GETARG_INT64(1);
+	int64	addend = PG_GETARG_INT64(1);
 
-	return internal_inetpl(ip, -plus);
+	PG_RETURN_INET_P(internal_inetpl(ip, -addend));
 }
 
 
@@ -1416,42 +1430,53 @@ inetmi(PG_FUNCTION_ARGS)
 	if (ip_family(ip) != ip_family(ip2))
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("mismatch in address family (%d) != (%d)",
-						ip_family(ip), ip_family(ip2))));
+				 errmsg("cannot subtract inet values of different sizes")));
 	else
 	{
+		/*
+		 * We form the difference using the traditional complement,
+		 * increment, and add rule, with the increment part being handled
+		 * by starting the carry off at 1.  If you don't think integer
+		 * arithmetic is done in two's complement, too bad.
+		 */
 		int nb = ip_addrsize(ip);
 		int	byte = 0;
 		unsigned char	*pip = ip_addr(ip);
 		unsigned char	*pip2 = ip_addr(ip2);
+		int carry = 1;
 
 		while (nb-- > 0)
 		{
-			/*
-			 *	Error if overflow on last byte.  This test is tricky
-			 *	because if the subtraction == 128 and res is negative, or
-			 *	if subtraction == -128 and res is positive, the result
-			 *	would still fit in int64.
-			 */
-			if (byte + 1 == sizeof(int64) &&
-				(pip[nb] - pip2[nb] >= 128 + (res < 0) ||
-				 pip[nb] - pip2[nb] <= -128 - (res > 0)))
-				ereport(ERROR,
-						(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-						 errmsg("result out of range")));
-			if (byte >= sizeof(int64))
+			int		lobyte;
+
+			carry = pip[nb] + (~pip2[nb] & 0xFF) + carry;
+			lobyte = carry & 0xFF;
+			if (byte < sizeof(int64))
 			{
-				/* Error if bytes beyond int64 length differ. */
-				if (pip[nb] != pip2[nb])
+				res |= ((int64) lobyte) << (byte * 8);
+			}
+			else
+			{
+				/*
+				 * Input wider than int64: check for overflow.  All bytes
+				 * to the left of what will fit should be 0 or 0xFF,
+				 * depending on sign of the now-complete result.
+				 */
+				if ((res < 0) ? (lobyte != 0xFF) : (lobyte != 0))
 					ereport(ERROR,
 							(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
 							 errmsg("result out of range")));
 			}
-			else
-				res += (int64)(pip[nb] - pip2[nb]) << (byte * 8);
-
+			carry >>= 8;
 			byte++;
 		}
+
+		/*
+		 * If input is narrower than int64, overflow is not possible, but
+		 * we have to do proper sign extension.
+		 */
+		if (carry == 0 && byte < sizeof(int64))
+			res |= ((int64) -1) << (byte * 8);
 	}
 
 	PG_RETURN_INT64(res);
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 0a76b86aee32a4eb57b6d0ac4885dd89791c9ad1..93e186d5b12c811d05ba5cba054d1a5f1bf9c9de 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.395 2006/02/11 03:32:39 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.396 2006/02/11 20:39:58 tgl Exp $
  *
  * NOTES
  *	  The script catalog/genbki.sh reads this file and generates .bki
@@ -2297,7 +2297,7 @@ DESCR("bitwise or");
 DATA(insert OID = 1675 (  bitxor			PGNSP PGUID 12 f f t f i 2 1560 "1560 1560" _null_ _null_ _null_	bitxor - _null_ ));
 DESCR("bitwise exclusive or");
 DATA(insert OID = 1676 (  bitnot			PGNSP PGUID 12 f f t f i 1 1560 "1560" _null_ _null_ _null_ bitnot - _null_ ));
-DESCR("bitwise negation");
+DESCR("bitwise not");
 DATA(insert OID = 1677 (  bitshiftleft		PGNSP PGUID 12 f f t f i 2 1560 "1560 23" _null_ _null_ _null_	bitshiftleft - _null_ ));
 DESCR("bitwise left shift");
 DATA(insert OID = 1678 (  bitshiftright		PGNSP PGUID 12 f f t f i 2 1560 "1560 23" _null_ _null_ _null_	bitshiftright - _null_ ));
@@ -2423,28 +2423,28 @@ DATA(insert OID = 1715 (  cidr				PGNSP PGUID 12 f f t f i 1 650 "869" _null_ _n
 DESCR("coerce inet to cidr");
 
 DATA(insert OID = 2196 (  inet_client_addr		PGNSP PGUID 12 f f f f s 0 869 "" _null_ _null_ _null_	inet_client_addr - _null_ ));
-DESCR("INET address of the client");
+DESCR("inet address of the client");
 DATA(insert OID = 2197 (  inet_client_port		PGNSP PGUID 12 f f f f s 0 23 "" _null_ _null_ _null_  inet_client_port - _null_ ));
 DESCR("client's port number for this connection");
 DATA(insert OID = 2198 (  inet_server_addr		PGNSP PGUID 12 f f f f s 0 869 "" _null_ _null_ _null_	inet_server_addr - _null_ ));
-DESCR("INET address of the server");
+DESCR("inet address of the server");
 DATA(insert OID = 2199 (  inet_server_port		PGNSP PGUID 12 f f f f s 0 23 "" _null_ _null_ _null_  inet_server_port - _null_ ));
 DESCR("server's port number for this connection");
 
 DATA(insert OID = 2627 (  inetnot			PGNSP PGUID 12 f f t f i 1 869 "869" _null_ _null_ _null_	inetnot - _null_ ));
-DESCR("binary NOT");
+DESCR("bitwise not");
 DATA(insert OID = 2628 (  inetand			PGNSP PGUID 12 f f t f i 2 869 "869 869" _null_ _null_ _null_	inetand - _null_ ));
-DESCR("binary AND");
+DESCR("bitwise and");
 DATA(insert OID = 2629 (  inetor			PGNSP PGUID 12 f f t f i 2 869 "869 869" _null_ _null_ _null_	inetor - _null_ ));
-DESCR("binary OR");
+DESCR("bitwise or");
 DATA(insert OID = 2630 (  inetpl			PGNSP PGUID 12 f f t f i 2 869 "869 20" _null_ _null_ _null_	inetpl - _null_ ));
-DESCR("add integer to INET value");
-DATA(insert OID = 2631 ( int8pl_inet		PGNSP PGUID 14 f f t f i 2 869 "20 869" _null_ _null_ _null_	"select $2 + $1" - _null_ ));
-DESCR("add integer to INET value");
+DESCR("add integer to inet value");
+DATA(insert OID = 2631 (  int8pl_inet		PGNSP PGUID 14 f f t f i 2 869 "20 869" _null_ _null_ _null_	"select $2 + $1" - _null_ ));
+DESCR("add integer to inet value");
 DATA(insert OID = 2632 (  inetmi_int8		PGNSP PGUID 12 f f t f i 2 869 "869 20" _null_ _null_ _null_	inetmi_int8 - _null_ ));
-DESCR("subtract integer from INET value");
+DESCR("subtract integer from inet value");
 DATA(insert OID = 2633 (  inetmi			PGNSP PGUID 12 f f t f i 2 20 "869 869" _null_ _null_ _null_	inetmi - _null_ ));
-DESCR("subtract INET values");
+DESCR("subtract inet values");
 
 DATA(insert OID = 1686 ( numeric			PGNSP PGUID 12 f f t f i 1 1700 "25" _null_ _null_ _null_ text_numeric - _null_ ));
 DESCR("(internal)");
diff --git a/src/test/regress/expected/inet.out b/src/test/regress/expected/inet.out
index 6c96f7d71b367baf143d6c85a1c8e828f4c86cd5..52a5a8c89bd86d44aa18050bf2c17c1ef2f177f2 100644
--- a/src/test/regress/expected/inet.out
+++ b/src/test/regress/expected/inet.out
@@ -39,22 +39,22 @@ SELECT '' AS ten, c AS cidr, i AS inet FROM INET_TBL;
  ten |        cidr        |       inet       
 -----+--------------------+------------------
      | 192.168.1.0/24     | 192.168.1.226/24
-     | 192.168.1.0/26     | 192.168.1.226
-     | 192.168.1.0/24     | 192.168.1.0/24
-     | 192.168.1.0/24     | 192.168.1.0/25
+     | 192.168.1.0/26     | 192.168.1.226   
+     | 192.168.1.0/24     | 192.168.1.0/24  
+     | 192.168.1.0/24     | 192.168.1.0/25  
      | 192.168.1.0/24     | 192.168.1.255/24
      | 192.168.1.0/24     | 192.168.1.255/25
-     | 10.0.0.0/8         | 10.1.2.3/8
-     | 10.0.0.0/32        | 10.1.2.3/8
-     | 10.1.2.3/32        | 10.1.2.3
-     | 10.1.2.0/24        | 10.1.2.3/24
-     | 10.1.0.0/16        | 10.1.2.3/16
-     | 10.0.0.0/8         | 10.1.2.3/8
-     | 10.0.0.0/8         | 11.1.2.3/8
-     | 10.0.0.0/8         | 9.1.2.3/8
-     | 10:23::f1/128      | 10:23::f1/64
-     | 10:23::8000/113    | 10:23::ffff
-     | ::ffff:1.2.3.4/128 | ::4.3.2.1/24
+     | 10.0.0.0/8         | 10.1.2.3/8      
+     | 10.0.0.0/32        | 10.1.2.3/8      
+     | 10.1.2.3/32        | 10.1.2.3        
+     | 10.1.2.0/24        | 10.1.2.3/24     
+     | 10.1.0.0/16        | 10.1.2.3/16     
+     | 10.0.0.0/8         | 10.1.2.3/8      
+     | 10.0.0.0/8         | 11.1.2.3/8      
+     | 10.0.0.0/8         | 9.1.2.3/8       
+     | 10:23::f1/128      | 10:23::f1/64    
+     | 10:23::8000/113    | 10:23::ffff     
+     | ::ffff:1.2.3.4/128 | ::4.3.2.1/24    
 (17 rows)
 
 -- now test some support functions
@@ -84,22 +84,22 @@ SELECT '' AS ten, c AS cidr, broadcast(c),
   i AS inet, broadcast(i) FROM INET_TBL;
  ten |        cidr        |    broadcast     |       inet       |               broadcast               
 -----+--------------------+------------------+------------------+---------------------------------------
-     | 192.168.1.0/24     | 192.168.1.255/24 | 192.168.1.226/24 | 192.168.1.255/24
-     | 192.168.1.0/26     | 192.168.1.63/26  | 192.168.1.226    | 192.168.1.226
-     | 192.168.1.0/24     | 192.168.1.255/24 | 192.168.1.0/24   | 192.168.1.255/24
-     | 192.168.1.0/24     | 192.168.1.255/24 | 192.168.1.0/25   | 192.168.1.127/25
-     | 192.168.1.0/24     | 192.168.1.255/24 | 192.168.1.255/24 | 192.168.1.255/24
-     | 192.168.1.0/24     | 192.168.1.255/24 | 192.168.1.255/25 | 192.168.1.255/25
-     | 10.0.0.0/8         | 10.255.255.255/8 | 10.1.2.3/8       | 10.255.255.255/8
-     | 10.0.0.0/32        | 10.0.0.0         | 10.1.2.3/8       | 10.255.255.255/8
-     | 10.1.2.3/32        | 10.1.2.3         | 10.1.2.3         | 10.1.2.3
-     | 10.1.2.0/24        | 10.1.2.255/24    | 10.1.2.3/24      | 10.1.2.255/24
-     | 10.1.0.0/16        | 10.1.255.255/16  | 10.1.2.3/16      | 10.1.255.255/16
-     | 10.0.0.0/8         | 10.255.255.255/8 | 10.1.2.3/8       | 10.255.255.255/8
-     | 10.0.0.0/8         | 10.255.255.255/8 | 11.1.2.3/8       | 11.255.255.255/8
-     | 10.0.0.0/8         | 10.255.255.255/8 | 9.1.2.3/8        | 9.255.255.255/8
-     | 10:23::f1/128      | 10:23::f1        | 10:23::f1/64     | 10:23::ffff:ffff:ffff:ffff/64
-     | 10:23::8000/113    | 10:23::ffff/113  | 10:23::ffff      | 10:23::ffff
+     | 192.168.1.0/24     | 192.168.1.255/24 | 192.168.1.226/24 | 192.168.1.255/24                     
+     | 192.168.1.0/26     | 192.168.1.63/26  | 192.168.1.226    | 192.168.1.226                        
+     | 192.168.1.0/24     | 192.168.1.255/24 | 192.168.1.0/24   | 192.168.1.255/24                     
+     | 192.168.1.0/24     | 192.168.1.255/24 | 192.168.1.0/25   | 192.168.1.127/25                     
+     | 192.168.1.0/24     | 192.168.1.255/24 | 192.168.1.255/24 | 192.168.1.255/24                     
+     | 192.168.1.0/24     | 192.168.1.255/24 | 192.168.1.255/25 | 192.168.1.255/25                     
+     | 10.0.0.0/8         | 10.255.255.255/8 | 10.1.2.3/8       | 10.255.255.255/8                     
+     | 10.0.0.0/32        | 10.0.0.0         | 10.1.2.3/8       | 10.255.255.255/8                     
+     | 10.1.2.3/32        | 10.1.2.3         | 10.1.2.3         | 10.1.2.3                             
+     | 10.1.2.0/24        | 10.1.2.255/24    | 10.1.2.3/24      | 10.1.2.255/24                        
+     | 10.1.0.0/16        | 10.1.255.255/16  | 10.1.2.3/16      | 10.1.255.255/16                      
+     | 10.0.0.0/8         | 10.255.255.255/8 | 10.1.2.3/8       | 10.255.255.255/8                     
+     | 10.0.0.0/8         | 10.255.255.255/8 | 11.1.2.3/8       | 11.255.255.255/8                     
+     | 10.0.0.0/8         | 10.255.255.255/8 | 9.1.2.3/8        | 9.255.255.255/8                      
+     | 10:23::f1/128      | 10:23::f1        | 10:23::f1/64     | 10:23::ffff:ffff:ffff:ffff/64        
+     | 10:23::8000/113    | 10:23::ffff/113  | 10:23::ffff      | 10:23::ffff                          
      | ::ffff:1.2.3.4/128 | ::ffff:1.2.3.4   | ::4.3.2.1/24     | 0:ff:ffff:ffff:ffff:ffff:ffff:ffff/24
 (17 rows)
 
@@ -107,23 +107,23 @@ SELECT '' AS ten, c AS cidr, network(c) AS "network(cidr)",
   i AS inet, network(i) AS "network(inet)" FROM INET_TBL;
  ten |        cidr        |   network(cidr)    |       inet       |  network(inet)   
 -----+--------------------+--------------------+------------------+------------------
-     | 192.168.1.0/24     | 192.168.1.0/24     | 192.168.1.226/24 | 192.168.1.0/24
+     | 192.168.1.0/24     | 192.168.1.0/24     | 192.168.1.226/24 | 192.168.1.0/24  
      | 192.168.1.0/26     | 192.168.1.0/26     | 192.168.1.226    | 192.168.1.226/32
-     | 192.168.1.0/24     | 192.168.1.0/24     | 192.168.1.0/24   | 192.168.1.0/24
-     | 192.168.1.0/24     | 192.168.1.0/24     | 192.168.1.0/25   | 192.168.1.0/25
-     | 192.168.1.0/24     | 192.168.1.0/24     | 192.168.1.255/24 | 192.168.1.0/24
+     | 192.168.1.0/24     | 192.168.1.0/24     | 192.168.1.0/24   | 192.168.1.0/24  
+     | 192.168.1.0/24     | 192.168.1.0/24     | 192.168.1.0/25   | 192.168.1.0/25  
+     | 192.168.1.0/24     | 192.168.1.0/24     | 192.168.1.255/24 | 192.168.1.0/24  
      | 192.168.1.0/24     | 192.168.1.0/24     | 192.168.1.255/25 | 192.168.1.128/25
-     | 10.0.0.0/8         | 10.0.0.0/8         | 10.1.2.3/8       | 10.0.0.0/8
-     | 10.0.0.0/32        | 10.0.0.0/32        | 10.1.2.3/8       | 10.0.0.0/8
-     | 10.1.2.3/32        | 10.1.2.3/32        | 10.1.2.3         | 10.1.2.3/32
-     | 10.1.2.0/24        | 10.1.2.0/24        | 10.1.2.3/24      | 10.1.2.0/24
-     | 10.1.0.0/16        | 10.1.0.0/16        | 10.1.2.3/16      | 10.1.0.0/16
-     | 10.0.0.0/8         | 10.0.0.0/8         | 10.1.2.3/8       | 10.0.0.0/8
-     | 10.0.0.0/8         | 10.0.0.0/8         | 11.1.2.3/8       | 11.0.0.0/8
-     | 10.0.0.0/8         | 10.0.0.0/8         | 9.1.2.3/8        | 9.0.0.0/8
-     | 10:23::f1/128      | 10:23::f1/128      | 10:23::f1/64     | 10:23::/64
-     | 10:23::8000/113    | 10:23::8000/113    | 10:23::ffff      | 10:23::ffff/128
-     | ::ffff:1.2.3.4/128 | ::ffff:1.2.3.4/128 | ::4.3.2.1/24     | ::/24
+     | 10.0.0.0/8         | 10.0.0.0/8         | 10.1.2.3/8       | 10.0.0.0/8      
+     | 10.0.0.0/32        | 10.0.0.0/32        | 10.1.2.3/8       | 10.0.0.0/8      
+     | 10.1.2.3/32        | 10.1.2.3/32        | 10.1.2.3         | 10.1.2.3/32     
+     | 10.1.2.0/24        | 10.1.2.0/24        | 10.1.2.3/24      | 10.1.2.0/24     
+     | 10.1.0.0/16        | 10.1.0.0/16        | 10.1.2.3/16      | 10.1.0.0/16     
+     | 10.0.0.0/8         | 10.0.0.0/8         | 10.1.2.3/8       | 10.0.0.0/8      
+     | 10.0.0.0/8         | 10.0.0.0/8         | 11.1.2.3/8       | 11.0.0.0/8      
+     | 10.0.0.0/8         | 10.0.0.0/8         | 9.1.2.3/8        | 9.0.0.0/8       
+     | 10:23::f1/128      | 10:23::f1/128      | 10:23::f1/64     | 10:23::/64      
+     | 10:23::8000/113    | 10:23::8000/113    | 10:23::ffff      | 10:23::ffff/128 
+     | ::ffff:1.2.3.4/128 | ::ffff:1.2.3.4/128 | ::4.3.2.1/24     | ::/24           
 (17 rows)
 
 SELECT '' AS ten, c AS cidr, masklen(c) AS "masklen(cidr)",
@@ -165,7 +165,7 @@ SELECT '' AS six, c AS cidr, i AS inet FROM INET_TBL
  six |      cidr      |      inet      
 -----+----------------+----------------
      | 192.168.1.0/24 | 192.168.1.0/24
-     | 10.1.2.3/32    | 10.1.2.3
+     | 10.1.2.3/32    | 10.1.2.3      
 (2 rows)
 
 SELECT '' AS ten, i, c,
@@ -176,23 +176,23 @@ SELECT '' AS ten, i, c,
   FROM INET_TBL;
  ten |        i         |         c          | lt | le | eq | ge | gt | ne | sb | sbe | sup | spe 
 -----+------------------+--------------------+----+----+----+----+----+----+----+-----+-----+-----
-     | 192.168.1.226/24 | 192.168.1.0/24     | f  | f  | f  | t  | t  | t  | f  | t   | f   | t
-     | 192.168.1.226    | 192.168.1.0/26     | f  | f  | f  | t  | t  | t  | f  | f   | f   | f
-     | 192.168.1.0/24   | 192.168.1.0/24     | f  | t  | t  | t  | f  | f  | f  | t   | f   | t
-     | 192.168.1.0/25   | 192.168.1.0/24     | f  | f  | f  | t  | t  | t  | t  | t   | f   | f
-     | 192.168.1.255/24 | 192.168.1.0/24     | f  | f  | f  | t  | t  | t  | f  | t   | f   | t
-     | 192.168.1.255/25 | 192.168.1.0/24     | f  | f  | f  | t  | t  | t  | t  | t   | f   | f
-     | 10.1.2.3/8       | 10.0.0.0/8         | f  | f  | f  | t  | t  | t  | f  | t   | f   | 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.0/24        | f  | f  | f  | t  | t  | t  | f  | t   | f   | t
-     | 10.1.2.3/16      | 10.1.0.0/16        | f  | f  | f  | t  | t  | t  | f  | t   | f   | t
-     | 10.1.2.3/8       | 10.0.0.0/8         | f  | f  | f  | t  | t  | t  | f  | t   | f   | t
-     | 11.1.2.3/8       | 10.0.0.0/8         | f  | f  | f  | t  | t  | t  | f  | f   | f   | f
-     | 9.1.2.3/8        | 10.0.0.0/8         | t  | t  | f  | f  | f  | t  | f  | f   | f   | f
-     | 10:23::f1/64     | 10:23::f1/128      | t  | t  | f  | f  | f  | t  | f  | f   | t   | t
-     | 10:23::ffff      | 10:23::8000/113    | f  | f  | f  | t  | t  | t  | t  | t   | f   | f
-     | ::4.3.2.1/24     | ::ffff:1.2.3.4/128 | t  | t  | f  | f  | f  | t  | f  | f   | t   | t
+     | 192.168.1.226/24 | 192.168.1.0/24     | f  | f  | f  | t  | t  | t  | f  | t   | f   | t  
+     | 192.168.1.226    | 192.168.1.0/26     | f  | f  | f  | t  | t  | t  | f  | f   | f   | f  
+     | 192.168.1.0/24   | 192.168.1.0/24     | f  | t  | t  | t  | f  | f  | f  | t   | f   | t  
+     | 192.168.1.0/25   | 192.168.1.0/24     | f  | f  | f  | t  | t  | t  | t  | t   | f   | f  
+     | 192.168.1.255/24 | 192.168.1.0/24     | f  | f  | f  | t  | t  | t  | f  | t   | f   | t  
+     | 192.168.1.255/25 | 192.168.1.0/24     | f  | f  | f  | t  | t  | t  | t  | t   | f   | f  
+     | 10.1.2.3/8       | 10.0.0.0/8         | f  | f  | f  | t  | t  | t  | f  | t   | f   | 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.0/24        | f  | f  | f  | t  | t  | t  | f  | t   | f   | t  
+     | 10.1.2.3/16      | 10.1.0.0/16        | f  | f  | f  | t  | t  | t  | f  | t   | f   | t  
+     | 10.1.2.3/8       | 10.0.0.0/8         | f  | f  | f  | t  | t  | t  | f  | t   | f   | t  
+     | 11.1.2.3/8       | 10.0.0.0/8         | f  | f  | f  | t  | t  | t  | f  | f   | f   | f  
+     | 9.1.2.3/8        | 10.0.0.0/8         | t  | t  | f  | f  | f  | t  | f  | f   | f   | f  
+     | 10:23::f1/64     | 10:23::f1/128      | t  | t  | f  | f  | f  | t  | f  | f   | t   | t  
+     | 10:23::ffff      | 10:23::8000/113    | f  | f  | f  | t  | t  | t  | t  | t   | f   | f  
+     | ::4.3.2.1/24     | ::ffff:1.2.3.4/128 | t  | t  | f  | f  | f  | t  | f  | f   | t   | t  
 (17 rows)
 
 -- check the conversion to/from text and set_netmask
@@ -201,21 +201,21 @@ SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL;
 -----+------------------
      | 192.168.1.226/24
      | 192.168.1.226/24
-     | 192.168.1.0/24
-     | 192.168.1.0/24
+     | 192.168.1.0/24  
+     | 192.168.1.0/24  
      | 192.168.1.255/24
      | 192.168.1.255/24
-     | 10.1.2.3/24
-     | 10.1.2.3/24
-     | 10.1.2.3/24
-     | 10.1.2.3/24
-     | 10.1.2.3/24
-     | 10.1.2.3/24
-     | 11.1.2.3/24
-     | 9.1.2.3/24
-     | 10:23::f1/24
-     | 10:23::ffff/24
-     | ::4.3.2.1/24
+     | 10.1.2.3/24     
+     | 10.1.2.3/24     
+     | 10.1.2.3/24     
+     | 10.1.2.3/24     
+     | 10.1.2.3/24     
+     | 10.1.2.3/24     
+     | 11.1.2.3/24     
+     | 9.1.2.3/24      
+     | 10:23::f1/24    
+     | 10:23::ffff/24  
+     | ::4.3.2.1/24    
 (17 rows)
 
 -- check that index works correctly
@@ -224,153 +224,224 @@ SET enable_seqscan TO off;
 SELECT * FROM inet_tbl WHERE i<<'192.168.1.0/24'::cidr;
        c        |        i         
 ----------------+------------------
- 192.168.1.0/24 | 192.168.1.0/25
+ 192.168.1.0/24 | 192.168.1.0/25  
  192.168.1.0/24 | 192.168.1.255/25
- 192.168.1.0/26 | 192.168.1.226
+ 192.168.1.0/26 | 192.168.1.226   
 (3 rows)
 
 SELECT * FROM inet_tbl WHERE i<<='192.168.1.0/24'::cidr;
        c        |        i         
 ----------------+------------------
- 192.168.1.0/24 | 192.168.1.0/24
+ 192.168.1.0/24 | 192.168.1.0/24  
  192.168.1.0/24 | 192.168.1.226/24
  192.168.1.0/24 | 192.168.1.255/24
- 192.168.1.0/24 | 192.168.1.0/25
+ 192.168.1.0/24 | 192.168.1.0/25  
  192.168.1.0/24 | 192.168.1.255/25
- 192.168.1.0/26 | 192.168.1.226
+ 192.168.1.0/26 | 192.168.1.226   
 (6 rows)
 
-SELECT ~i FROM inet_tbl;
-                  ?column?                  
---------------------------------------------
- 63.87.254.29/24
- 63.87.254.29
- 63.87.254.255/24
- 63.87.254.255/25
- 63.87.254.0/24
- 63.87.254.0/25
- 245.254.253.252/8
- 245.254.253.252/8
- 245.254.253.252
- 245.254.253.252/24
- 245.254.253.252/16
- 245.254.253.252/8
- 244.254.253.252/8
- 246.254.253.252/8
- ffef:ffdc:ffff:ffff:ffff:ffff:ffff:ff0e/64
- ffef:ffdc:ffff:ffff:ffff:ffff:ffff:0
- ffff:ffff:ffff:ffff:ffff:ffff:fbfc:fdfe/24
+SET enable_seqscan TO on;
+DROP INDEX inet_idx1;
+-- simple tests of inet boolean and arithmetic operators
+SELECT i, ~i AS "~i" FROM inet_tbl;
+        i         |                     ~i                     
+------------------+--------------------------------------------
+ 192.168.1.226/24 | 63.87.254.29/24                           
+ 192.168.1.226    | 63.87.254.29                              
+ 192.168.1.0/24   | 63.87.254.255/24                          
+ 192.168.1.0/25   | 63.87.254.255/25                          
+ 192.168.1.255/24 | 63.87.254.0/24                            
+ 192.168.1.255/25 | 63.87.254.0/25                            
+ 10.1.2.3/8       | 245.254.253.252/8                         
+ 10.1.2.3/8       | 245.254.253.252/8                         
+ 10.1.2.3         | 245.254.253.252                           
+ 10.1.2.3/24      | 245.254.253.252/24                        
+ 10.1.2.3/16      | 245.254.253.252/16                        
+ 10.1.2.3/8       | 245.254.253.252/8                         
+ 11.1.2.3/8       | 244.254.253.252/8                         
+ 9.1.2.3/8        | 246.254.253.252/8                         
+ 10:23::f1/64     | ffef:ffdc:ffff:ffff:ffff:ffff:ffff:ff0e/64
+ 10:23::ffff      | ffef:ffdc:ffff:ffff:ffff:ffff:ffff:0      
+ ::4.3.2.1/24     | ffff:ffff:ffff:ffff:ffff:ffff:fbfc:fdfe/24
 (17 rows)
 
-SELECT i & c FROM inet_tbl;
-    ?column?    
-----------------
- 192.168.1.0/24
- 192.168.1.0
- 192.168.1.0/24
- 192.168.1.0/25
- 192.168.1.0/24
- 192.168.1.0/25
- 10.0.0.0/8
- 10.0.0.0
- 10.1.2.3
- 10.1.2.0/24
- 10.1.0.0/16
- 10.0.0.0/8
- 10.0.0.0/8
- 8.0.0.0/8
- 10:23::f1
- 10:23::8000
- ::0.2.2.0
+SELECT i, c, i & c AS "and" FROM inet_tbl;
+        i         |         c          |      and       
+------------------+--------------------+----------------
+ 192.168.1.226/24 | 192.168.1.0/24     | 192.168.1.0/24
+ 192.168.1.226    | 192.168.1.0/26     | 192.168.1.0   
+ 192.168.1.0/24   | 192.168.1.0/24     | 192.168.1.0/24
+ 192.168.1.0/25   | 192.168.1.0/24     | 192.168.1.0/25
+ 192.168.1.255/24 | 192.168.1.0/24     | 192.168.1.0/24
+ 192.168.1.255/25 | 192.168.1.0/24     | 192.168.1.0/25
+ 10.1.2.3/8       | 10.0.0.0/8         | 10.0.0.0/8    
+ 10.1.2.3/8       | 10.0.0.0/32        | 10.0.0.0      
+ 10.1.2.3         | 10.1.2.3/32        | 10.1.2.3      
+ 10.1.2.3/24      | 10.1.2.0/24        | 10.1.2.0/24   
+ 10.1.2.3/16      | 10.1.0.0/16        | 10.1.0.0/16   
+ 10.1.2.3/8       | 10.0.0.0/8         | 10.0.0.0/8    
+ 11.1.2.3/8       | 10.0.0.0/8         | 10.0.0.0/8    
+ 9.1.2.3/8        | 10.0.0.0/8         | 8.0.0.0/8     
+ 10:23::f1/64     | 10:23::f1/128      | 10:23::f1     
+ 10:23::ffff      | 10:23::8000/113    | 10:23::8000   
+ ::4.3.2.1/24     | ::ffff:1.2.3.4/128 | ::0.2.2.0     
 (17 rows)
 
-SELECT i | c FROM inet_tbl;
-     ?column?     
-------------------
- 192.168.1.226/24
- 192.168.1.226
- 192.168.1.0/24
- 192.168.1.0/25
- 192.168.1.255/24
- 192.168.1.255/25
- 10.1.2.3/8
- 10.1.2.3
- 10.1.2.3
- 10.1.2.3/24
- 10.1.2.3/16
- 10.1.2.3/8
- 11.1.2.3/8
- 11.1.2.3/8
- 10:23::f1
- 10:23::ffff
- ::ffff:5.3.3.5
+SELECT i, c, i | c AS "or" FROM inet_tbl;
+        i         |         c          |        or        
+------------------+--------------------+------------------
+ 192.168.1.226/24 | 192.168.1.0/24     | 192.168.1.226/24
+ 192.168.1.226    | 192.168.1.0/26     | 192.168.1.226   
+ 192.168.1.0/24   | 192.168.1.0/24     | 192.168.1.0/24  
+ 192.168.1.0/25   | 192.168.1.0/24     | 192.168.1.0/25  
+ 192.168.1.255/24 | 192.168.1.0/24     | 192.168.1.255/24
+ 192.168.1.255/25 | 192.168.1.0/24     | 192.168.1.255/25
+ 10.1.2.3/8       | 10.0.0.0/8         | 10.1.2.3/8      
+ 10.1.2.3/8       | 10.0.0.0/32        | 10.1.2.3        
+ 10.1.2.3         | 10.1.2.3/32        | 10.1.2.3        
+ 10.1.2.3/24      | 10.1.2.0/24        | 10.1.2.3/24     
+ 10.1.2.3/16      | 10.1.0.0/16        | 10.1.2.3/16     
+ 10.1.2.3/8       | 10.0.0.0/8         | 10.1.2.3/8      
+ 11.1.2.3/8       | 10.0.0.0/8         | 11.1.2.3/8      
+ 9.1.2.3/8        | 10.0.0.0/8         | 11.1.2.3/8      
+ 10:23::f1/64     | 10:23::f1/128      | 10:23::f1       
+ 10:23::ffff      | 10:23::8000/113    | 10:23::ffff     
+ ::4.3.2.1/24     | ::ffff:1.2.3.4/128 | ::ffff:5.3.3.5  
 (17 rows)
 
-SELECT i + 500 FROM inet_tbl;
-     ?column?      
-------------------
- 192.168.4.214/24
- 192.168.4.214   
- 192.168.3.244/24
- 192.168.3.244/25
- 192.168.4.243/24
- 192.168.4.243/25
- 10.1.4.247/8    
- 10.1.4.247/8    
- 10.1.4.247      
- 10.1.4.247/24   
- 10.1.4.247/16   
- 10.1.4.247/8    
- 11.1.4.247/8    
- 9.1.4.247/8     
- 10:23::3e5/64   
- 10:23::1:2f3    
- ::4.3.4.245/24  
+SELECT i, i + 500 AS "i+500" FROM inet_tbl;
+        i         |      i+500       
+------------------+------------------
+ 192.168.1.226/24 | 192.168.3.214/24
+ 192.168.1.226    | 192.168.3.214   
+ 192.168.1.0/24   | 192.168.2.244/24
+ 192.168.1.0/25   | 192.168.2.244/25
+ 192.168.1.255/24 | 192.168.3.243/24
+ 192.168.1.255/25 | 192.168.3.243/25
+ 10.1.2.3/8       | 10.1.3.247/8    
+ 10.1.2.3/8       | 10.1.3.247/8    
+ 10.1.2.3         | 10.1.3.247      
+ 10.1.2.3/24      | 10.1.3.247/24   
+ 10.1.2.3/16      | 10.1.3.247/16   
+ 10.1.2.3/8       | 10.1.3.247/8    
+ 11.1.2.3/8       | 11.1.3.247/8    
+ 9.1.2.3/8        | 9.1.3.247/8     
+ 10:23::f1/64     | 10:23::2e5/64   
+ 10:23::ffff      | 10:23::1:1f3    
+ ::4.3.2.1/24     | ::4.3.3.245/24  
 (17 rows)
 
-SELECT i - 500 FROM inet_tbl;
-                ?column?                
---------------------
- 192.168.255.238/24
- 192.168.255.238   
- 192.168.255.12/24 
- 192.168.255.12/25 
- 192.168.0.11/24   
- 192.168.0.11/25   
- 10.1.0.15/8       
- 10.1.0.15/8       
- 10.1.0.15         
- 10.1.0.15/24      
- 10.1.0.15/16      
- 10.1.0.15/8       
- 11.1.0.15/8       
- 9.1.0.15/8        
- 10:23::fefd/64    
- 10:23::fe0b       
- ::4.3.0.13/24     
+SELECT i, i - 500 AS "i-500" FROM inet_tbl;
+        i         |                 i-500                  
+------------------+----------------------------------------
+ 192.168.1.226/24 | 192.167.255.238/24                    
+ 192.168.1.226    | 192.167.255.238                       
+ 192.168.1.0/24   | 192.167.255.12/24                     
+ 192.168.1.0/25   | 192.167.255.12/25                     
+ 192.168.1.255/24 | 192.168.0.11/24                       
+ 192.168.1.255/25 | 192.168.0.11/25                       
+ 10.1.2.3/8       | 10.1.0.15/8                           
+ 10.1.2.3/8       | 10.1.0.15/8                           
+ 10.1.2.3         | 10.1.0.15                             
+ 10.1.2.3/24      | 10.1.0.15/24                          
+ 10.1.2.3/16      | 10.1.0.15/16                          
+ 10.1.2.3/8       | 10.1.0.15/8                           
+ 11.1.2.3/8       | 11.1.0.15/8                           
+ 9.1.2.3/8        | 9.1.0.15/8                            
+ 10:23::f1/64     | 10:22:ffff:ffff:ffff:ffff:ffff:fefd/64
+ 10:23::ffff      | 10:23::fe0b                           
+ ::4.3.2.1/24     | ::4.3.0.13/24                         
 (17 rows)
 
-SELECT i - c FROM inet_tbl;
+SELECT i, c, i - c AS "minus" FROM inet_tbl;
+        i         |         c          |      minus       
+------------------+--------------------+------------------
+ 192.168.1.226/24 | 192.168.1.0/24     |              226
+ 192.168.1.226    | 192.168.1.0/26     |              226
+ 192.168.1.0/24   | 192.168.1.0/24     |                0
+ 192.168.1.0/25   | 192.168.1.0/24     |                0
+ 192.168.1.255/24 | 192.168.1.0/24     |              255
+ 192.168.1.255/25 | 192.168.1.0/24     |              255
+ 10.1.2.3/8       | 10.0.0.0/8         |            66051
+ 10.1.2.3/8       | 10.0.0.0/32        |            66051
+ 10.1.2.3         | 10.1.2.3/32        |                0
+ 10.1.2.3/24      | 10.1.2.0/24        |                3
+ 10.1.2.3/16      | 10.1.0.0/16        |              515
+ 10.1.2.3/8       | 10.0.0.0/8         |            66051
+ 11.1.2.3/8       | 10.0.0.0/8         |         16843267
+ 9.1.2.3/8        | 10.0.0.0/8         |        -16711165
+ 10:23::f1/64     | 10:23::f1/128      |                0
+ 10:23::ffff      | 10:23::8000/113    |            32767
+ ::4.3.2.1/24     | ::ffff:1.2.3.4/128 | -281470631346435
+(17 rows)
+
+SELECT '127.0.0.1'::inet + 257;
+ ?column?  
+-----------
+ 127.0.1.2
+(1 row)
+
+SELECT ('127.0.0.1'::inet + 257) - 257;
  ?column?  
+-----------
+ 127.0.0.1
+(1 row)
+
+SELECT '127::1'::inet + 257;
+ ?column? 
+----------
+ 127::102
+(1 row)
+
+SELECT ('127::1'::inet + 257) - 257;
+ ?column? 
+----------
+ 127::1  
+(1 row)
+
+SELECT '127.0.0.2'::inet  - ('127.0.0.2'::inet + 500);
+ ?column? 
+----------
+     -500
+(1 row)
+
+SELECT '127.0.0.2'::inet  - ('127.0.0.2'::inet - 500);
+ ?column? 
+----------
+      500
+(1 row)
+
+SELECT '127::2'::inet  - ('127::2'::inet + 500);
+ ?column? 
+----------
+     -500
+(1 row)
+
+SELECT '127::2'::inet  - ('127::2'::inet - 500);
+ ?column? 
+----------
+      500
+(1 row)
+
+-- these should give overflow errors:
+SELECT '127.0.0.1'::inet + 10000000000;
+ERROR:  result out of range
+SELECT '127.0.0.1'::inet - 10000000000;
+ERROR:  result out of range
+SELECT '126::1'::inet - '127::2'::inet;
+ERROR:  result out of range
+SELECT '127::1'::inet - '126::2'::inet;
+ERROR:  result out of range
+-- but not these
+SELECT '127::1'::inet + 10000000000;
+     ?column?     
 ------------------
-       226
-       226
-         0
-         0
-       255
-       255
-     66051
-     66051
-         0
-         3
-       515
-     66051
-  16843267
- -16711165
-                0
-            32767
- -281470631346435
-(17 rows)
+ 127::2:540b:e401
+(1 row)
+
+SELECT '127::1'::inet - '127::2'::inet;
+ ?column? 
+----------
+       -1
+(1 row)
 
-SET enable_seqscan TO on;
-DROP INDEX inet_idx1;
diff --git a/src/test/regress/sql/inet.sql b/src/test/regress/sql/inet.sql
index f44caf5006b4feb37aacc8bcf134773c24399344..f88a17eabc7814835cd2df458fc908c5355a1dfa 100644
--- a/src/test/regress/sql/inet.sql
+++ b/src/test/regress/sql/inet.sql
@@ -62,14 +62,29 @@ CREATE INDEX inet_idx1 ON inet_tbl(i);
 SET enable_seqscan TO off;
 SELECT * FROM inet_tbl WHERE i<<'192.168.1.0/24'::cidr;
 SELECT * FROM inet_tbl WHERE i<<='192.168.1.0/24'::cidr;
-
-SELECT ~i FROM inet_tbl;
-SELECT i & c FROM inet_tbl;
-SELECT i | c FROM inet_tbl;
-SELECT i + 500 FROM inet_tbl;
-SELECT i - 500 FROM inet_tbl;
-SELECT i - c FROM inet_tbl;
-
 SET enable_seqscan TO on;
 DROP INDEX inet_idx1;
 
+-- simple tests of inet boolean and arithmetic operators
+SELECT i, ~i AS "~i" FROM inet_tbl;
+SELECT i, c, i & c AS "and" FROM inet_tbl;
+SELECT i, c, i | c AS "or" FROM inet_tbl;
+SELECT i, i + 500 AS "i+500" FROM inet_tbl;
+SELECT i, i - 500 AS "i-500" FROM inet_tbl;
+SELECT i, c, i - c AS "minus" FROM inet_tbl;
+SELECT '127.0.0.1'::inet + 257;
+SELECT ('127.0.0.1'::inet + 257) - 257;
+SELECT '127::1'::inet + 257;
+SELECT ('127::1'::inet + 257) - 257;
+SELECT '127.0.0.2'::inet  - ('127.0.0.2'::inet + 500);
+SELECT '127.0.0.2'::inet  - ('127.0.0.2'::inet - 500);
+SELECT '127::2'::inet  - ('127::2'::inet + 500);
+SELECT '127::2'::inet  - ('127::2'::inet - 500);
+-- these should give overflow errors:
+SELECT '127.0.0.1'::inet + 10000000000;
+SELECT '127.0.0.1'::inet - 10000000000;
+SELECT '126::1'::inet - '127::2'::inet;
+SELECT '127::1'::inet - '126::2'::inet;
+-- but not these
+SELECT '127::1'::inet + 10000000000;
+SELECT '127::1'::inet - '127::2'::inet;