/*
* 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
*/
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.
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);
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);
}
-static Datum
-internal_inetpl(inet *ip, int64 plus)
+static inet *
+internal_inetpl(inet *ip, int64 addend)
{
inet *dst;
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);
((char *) ip_addr(dst) - (char *) VARDATA(dst)) +
ip_addrsize(dst);
- PG_RETURN_INET_P(dst);
+ return dst;
}
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));
}
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));
}
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);
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
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)
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)",
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,
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
-----+------------------
| 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
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;