diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index a3eadb4bc4..8f6f1ba392 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -1,5 +1,5 @@
@@ -6797,9 +6797,7 @@ SELECT pg_sleep(1.5);
types. The host,
text, and abbrev
functions are primarily intended to offer alternative display
- formats. You can cast a text value to inet> using normal casting
- syntax: inet(expression>) or
- colname>::inet.
+ formats.
@@ -6843,6 +6841,13 @@ SELECT pg_sleep(1.5);
set_masklen('192.168.1.5/24', 16)
192.168.1.5/16
+
+ set_masklen(cidr, int)
+ cidr
+ set netmask length for cidr value
+ set_masklen('192.168.1.0/24'::cidr, 16)
+ 192.168.0.0/16
+
netmask(inet)
inet
@@ -6875,6 +6880,13 @@ SELECT pg_sleep(1.5);
abbrev(inet)
text
abbreviated display format as text
+ abbrev(inet '10.1.0.0/16')
+ 10.1.0.0/16
+
+
+ abbrev(cidr)
+ text
+ abbreviated display format as text
abbrev(cidr '10.1.0.0/16')
10.1/16
@@ -6890,6 +6902,22 @@ SELECT pg_sleep(1.5);
+
+ Any cidr> value can be cast to inet> implicitly
+ or explicitly; therefore, the functions shown above as operating on
+ inet> also work on cidr> values. (Where there are
+ separate functions for inet> and cidr>, it is because
+ the behavior should be different for the two cases.)
+ Also, it is permitted to cast an inet> value to cidr>.
+ When this is done, any bits to the right of the netmask are silently zeroed
+ to create a valid cidr> value.
+ In addition,
+ you can cast a text value to inet> or cidr>
+ using normal casting syntax: for example,
+ inet(expression>) or
+ colname>::cidr.
+
+
shows the functions
available for use with the macaddr type. The function
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 9ec5911403..a00ad764c7 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.197 2006/01/25 20:29:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.198 2006/01/26 02:35:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2024,8 +2024,6 @@ match_special_index_operator(Expr *clause, Oid opclass,
case OID_INET_SUB_OP:
case OID_INET_SUBEQ_OP:
- case OID_CIDR_SUB_OP:
- case OID_CIDR_SUBEQ_OP:
isIndexable = true;
break;
}
@@ -2087,12 +2085,8 @@ match_special_index_operator(Expr *clause, Oid opclass,
case OID_INET_SUB_OP:
case OID_INET_SUBEQ_OP:
- isIndexable = (opclass == INET_BTREE_OPS_OID);
- break;
-
- case OID_CIDR_SUB_OP:
- case OID_CIDR_SUBEQ_OP:
- isIndexable = (opclass == CIDR_BTREE_OPS_OID);
+ isIndexable = (opclass == INET_BTREE_OPS_OID ||
+ opclass == CIDR_BTREE_OPS_OID);
break;
}
@@ -2317,8 +2311,6 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass)
case OID_INET_SUB_OP:
case OID_INET_SUBEQ_OP:
- case OID_CIDR_SUB_OP:
- case OID_CIDR_SUBEQ_OP:
result = network_prefix_quals(leftop, expr_op, opclass,
patt->constvalue);
break;
@@ -2681,14 +2673,6 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, Datum rightop)
datatype = INETOID;
is_eq = true;
break;
- case OID_CIDR_SUB_OP:
- datatype = CIDROID;
- is_eq = false;
- break;
- case OID_CIDR_SUBEQ_OP:
- datatype = CIDROID;
- is_eq = true;
- break;
default:
elog(ERROR, "unexpected operator: %u", expr_op);
return NIL;
diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c
index 567a7cc2ee..c827dab696 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.60 2006/01/23 21:49:39 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.61 2006/01/26 02:35:49 tgl Exp $
*
* Jon Postel RIP 16 Oct 1998
*/
@@ -22,7 +22,7 @@
#include "utils/inet.h"
-static Datum text_network(text *src, bool is_cidr);
+static inet *text_network(text *src, bool is_cidr);
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);
@@ -38,9 +38,6 @@ static int ip_addrsize(inet *inetptr);
#define ip_bits(inetptr) \
(((inet_struct *)VARDATA(inetptr))->bits)
-#define ip_is_cidr(inetptr) \
- (((inet_struct *)VARDATA(inetptr))->is_cidr)
-
#define ip_addr(inetptr) \
(((inet_struct *)VARDATA(inetptr))->ipaddr)
@@ -64,7 +61,9 @@ ip_addrsize(inet *inetptr)
}
}
-/* Common input routine */
+/*
+ * Common INET/CIDR input routine
+ */
static inet *
network_in(char *src, bool is_cidr)
{
@@ -109,37 +108,33 @@ network_in(char *src, bool is_cidr)
+ ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+ ip_addrsize(dst);
ip_bits(dst) = bits;
- ip_is_cidr(dst) = is_cidr;
return dst;
}
-/* INET address reader. */
Datum
inet_in(PG_FUNCTION_ARGS)
{
char *src = PG_GETARG_CSTRING(0);
- PG_RETURN_INET_P(network_in(src, 0));
+ PG_RETURN_INET_P(network_in(src, false));
}
-/* CIDR address reader. */
Datum
cidr_in(PG_FUNCTION_ARGS)
{
char *src = PG_GETARG_CSTRING(0);
- PG_RETURN_INET_P(network_in(src, 1));
+ PG_RETURN_INET_P(network_in(src, true));
}
/*
- * INET address output function.
+ * Common INET/CIDR output routine
*/
-Datum
-inet_out(PG_FUNCTION_ARGS)
+static char *
+network_out(inet *src, bool is_cidr)
{
- inet *src = PG_GETARG_INET_P(0);
char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
char *dst;
int len;
@@ -152,34 +147,45 @@ inet_out(PG_FUNCTION_ARGS)
errmsg("could not format inet value: %m")));
/* For CIDR, add /n if not present */
- if (ip_is_cidr(src) && strchr(tmp, '/') == NULL)
+ if (is_cidr && strchr(tmp, '/') == NULL)
{
len = strlen(tmp);
snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(src));
}
- PG_RETURN_CSTRING(pstrdup(tmp));
+ return pstrdup(tmp);
}
+Datum
+inet_out(PG_FUNCTION_ARGS)
+{
+ inet *src = PG_GETARG_INET_P(0);
+
+ PG_RETURN_CSTRING(network_out(src, false));
+}
-/* share code with INET case */
Datum
cidr_out(PG_FUNCTION_ARGS)
{
- return inet_out(fcinfo);
+ inet *src = PG_GETARG_INET_P(0);
+
+ PG_RETURN_CSTRING(network_out(src, true));
}
/*
- * inet_recv - converts external binary format to inet
+ * network_recv - converts external binary format to inet
*
* The external representation is (one byte apiece for)
* family, bits, is_cidr, address length, address in network byte order.
+ *
+ * Presence of is_cidr is largely for historical reasons, though it might
+ * allow some code-sharing on the client side. We send it correctly on
+ * output, but ignore the value on input.
*/
-Datum
-inet_recv(PG_FUNCTION_ARGS)
+static inet *
+network_recv(StringInfo buf, bool is_cidr)
{
- StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
inet *addr;
char *addrptr;
int bits;
@@ -194,23 +200,25 @@ inet_recv(PG_FUNCTION_ARGS)
ip_family(addr) != PGSQL_AF_INET6)
ereport(ERROR,
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
- errmsg("invalid address family in external \"inet\" value")));
+ /* translator: %s is inet or cidr */
+ errmsg("invalid address family in external \"%s\" value",
+ is_cidr ? "cidr" : "inet")));
bits = pq_getmsgbyte(buf);
if (bits < 0 || bits > ip_maxbits(addr))
ereport(ERROR,
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
- errmsg("invalid bits in external \"inet\" value")));
+ /* translator: %s is inet or cidr */
+ errmsg("invalid bits in external \"%s\" value",
+ is_cidr ? "cidr" : "inet")));
ip_bits(addr) = bits;
- ip_is_cidr(addr) = pq_getmsgbyte(buf);
- if (ip_is_cidr(addr) != false && ip_is_cidr(addr) != true)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
- errmsg("invalid type in external \"inet\" value")));
+ i = pq_getmsgbyte(buf); /* ignore is_cidr */
nb = pq_getmsgbyte(buf);
if (nb != ip_addrsize(addr))
ereport(ERROR,
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
- errmsg("invalid length in external \"inet\" value")));
+ /* translator: %s is inet or cidr */
+ errmsg("invalid length in external \"%s\" value",
+ is_cidr ? "cidr" : "inet")));
VARATT_SIZEP(addr) = VARHDRSZ
+ ((char *) ip_addr(addr) - (char *) VARDATA(addr))
+ ip_addrsize(addr);
@@ -222,7 +230,7 @@ inet_recv(PG_FUNCTION_ARGS)
/*
* Error check: CIDR values must not have any bits set beyond the masklen.
*/
- if (ip_is_cidr(addr))
+ if (is_cidr)
{
if (!addressOK(ip_addr(addr), bits, ip_family(addr)))
ereport(ERROR,
@@ -231,23 +239,32 @@ inet_recv(PG_FUNCTION_ARGS)
errdetail("Value has bits set to right of mask.")));
}
- PG_RETURN_INET_P(addr);
+ return addr;
+}
+
+Datum
+inet_recv(PG_FUNCTION_ARGS)
+{
+ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
+
+ PG_RETURN_INET_P(network_recv(buf, false));
}
-/* share code with INET case */
Datum
cidr_recv(PG_FUNCTION_ARGS)
{
- return inet_recv(fcinfo);
+ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
+
+ PG_RETURN_INET_P(network_recv(buf, true));
}
+
/*
- * inet_send - converts inet to binary format
+ * network_send - converts inet to binary format
*/
-Datum
-inet_send(PG_FUNCTION_ARGS)
+static bytea *
+network_send(inet *addr, bool is_cidr)
{
- inet *addr = PG_GETARG_INET_P(0);
StringInfoData buf;
char *addrptr;
int nb,
@@ -256,7 +273,7 @@ inet_send(PG_FUNCTION_ARGS)
pq_begintypsend(&buf);
pq_sendbyte(&buf, ip_family(addr));
pq_sendbyte(&buf, ip_bits(addr));
- pq_sendbyte(&buf, ip_is_cidr(addr));
+ pq_sendbyte(&buf, is_cidr);
nb = ip_addrsize(addr);
if (nb < 0)
nb = 0;
@@ -264,41 +281,93 @@ inet_send(PG_FUNCTION_ARGS)
addrptr = (char *) ip_addr(addr);
for (i = 0; i < nb; i++)
pq_sendbyte(&buf, addrptr[i]);
- PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
+ return pq_endtypsend(&buf);
+}
+
+Datum
+inet_send(PG_FUNCTION_ARGS)
+{
+ inet *addr = PG_GETARG_INET_P(0);
+
+ PG_RETURN_BYTEA_P(network_send(addr, false));
}
-/* share code with INET case */
Datum
cidr_send(PG_FUNCTION_ARGS)
{
- return inet_send(fcinfo);
+ inet *addr = PG_GETARG_INET_P(0);
+
+ PG_RETURN_BYTEA_P(network_send(addr, true));
}
-static Datum
+static inet *
text_network(text *src, bool is_cidr)
{
int len = VARSIZE(src) - VARHDRSZ;
-
char *str = palloc(len + 1);
memcpy(str, VARDATA(src), len);
- *(str + len) = '\0';
+ str[len] = '\0';
- PG_RETURN_INET_P(network_in(str, is_cidr));
-}
-
-
-Datum
-text_cidr(PG_FUNCTION_ARGS)
-{
- return text_network(PG_GETARG_TEXT_P(0), 1);
+ return network_in(str, is_cidr);
}
Datum
text_inet(PG_FUNCTION_ARGS)
{
- return text_network(PG_GETARG_TEXT_P(0), 0);
+ text *src = PG_GETARG_TEXT_P(0);
+
+ PG_RETURN_INET_P(text_network(src, false));
+}
+
+Datum
+text_cidr(PG_FUNCTION_ARGS)
+{
+ text *src = PG_GETARG_TEXT_P(0);
+
+ PG_RETURN_INET_P(text_network(src, true));
+}
+
+
+Datum
+inet_to_cidr(PG_FUNCTION_ARGS)
+{
+ inet *src = PG_GETARG_INET_P(0);
+ inet *dst;
+ int bits;
+ int byte;
+ int nbits;
+ int maxbytes;
+
+ bits = ip_bits(src);
+
+ /* safety check */
+ if ((bits < 0) || (bits > ip_maxbits(src)))
+ elog(ERROR, "invalid inet bit length: %d", bits);
+
+ /* clone the original data */
+ dst = (inet *) palloc(VARSIZE(src));
+ memcpy(dst, src, VARSIZE(src));
+
+ /* zero out any bits to the right of the netmask */
+ byte = bits / 8;
+ nbits = bits % 8;
+ /* clear the first byte, this might be a partial byte */
+ if (nbits != 0)
+ {
+ ip_addr(dst)[byte] &= ~(0xFF >> nbits);
+ byte++;
+ }
+ /* clear remaining bytes */
+ maxbytes = ip_addrsize(dst);
+ while (byte < maxbytes)
+ {
+ ip_addr(dst)[byte] = 0;
+ byte++;
+ }
+
+ PG_RETURN_INET_P(dst);
}
Datum
@@ -325,6 +394,50 @@ inet_set_masklen(PG_FUNCTION_ARGS)
PG_RETURN_INET_P(dst);
}
+Datum
+cidr_set_masklen(PG_FUNCTION_ARGS)
+{
+ inet *src = PG_GETARG_INET_P(0);
+ int bits = PG_GETARG_INT32(1);
+ inet *dst;
+ int byte;
+ int nbits;
+ int maxbytes;
+
+ if (bits == -1)
+ bits = ip_maxbits(src);
+
+ if ((bits < 0) || (bits > ip_maxbits(src)))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid mask length: %d", bits)));
+
+ /* clone the original data */
+ dst = (inet *) palloc(VARSIZE(src));
+ memcpy(dst, src, VARSIZE(src));
+
+ ip_bits(dst) = bits;
+
+ /* zero out any bits to the right of the new netmask */
+ byte = bits / 8;
+ nbits = bits % 8;
+ /* clear the first byte, this might be a partial byte */
+ if (nbits != 0)
+ {
+ ip_addr(dst)[byte] &= ~(0xFF >> nbits);
+ byte++;
+ }
+ /* clear remaining bytes */
+ maxbytes = ip_addrsize(dst);
+ while (byte < maxbytes)
+ {
+ ip_addr(dst)[byte] = 0;
+ byte++;
+ }
+
+ PG_RETURN_INET_P(dst);
+}
+
/*
* Basic comparison function for sorting and inet/cidr comparisons.
*
@@ -424,23 +537,15 @@ network_ne(PG_FUNCTION_ARGS)
/*
* Support function for hash indexes on inet/cidr.
- *
- * Since network_cmp considers only ip_family, ip_bits, and ip_addr, only
- * these fields may be used in the hash; in particular don't use is_cidr.
*/
Datum
hashinet(PG_FUNCTION_ARGS)
{
inet *addr = PG_GETARG_INET_P(0);
int addrsize = ip_addrsize(addr);
- unsigned char key[sizeof(inet_struct)];
- Assert(addrsize + 2 <= sizeof(key));
- key[0] = ip_family(addr);
- key[1] = ip_bits(addr);
- memcpy(key + 2, ip_addr(addr), addrsize);
-
- return hash_any(key, addrsize + 2);
+ /* XXX this assumes there are no pad bytes in the data structure */
+ return hash_any(VARDATA(addr), addrsize + 2);
}
/*
@@ -567,7 +672,7 @@ network_show(PG_FUNCTION_ARGS)
}
Datum
-network_abbrev(PG_FUNCTION_ARGS)
+inet_abbrev(PG_FUNCTION_ARGS)
{
inet *ip = PG_GETARG_INET_P(0);
text *ret;
@@ -575,12 +680,8 @@ network_abbrev(PG_FUNCTION_ARGS)
int len;
char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
- if (ip_is_cidr(ip))
- dst = inet_cidr_ntop(ip_family(ip), ip_addr(ip),
- ip_bits(ip), tmp, sizeof(tmp));
- else
- dst = inet_net_ntop(ip_family(ip), ip_addr(ip),
- ip_bits(ip), tmp, sizeof(tmp));
+ dst = inet_net_ntop(ip_family(ip), ip_addr(ip),
+ ip_bits(ip), tmp, sizeof(tmp));
if (dst == NULL)
ereport(ERROR,
@@ -595,6 +696,31 @@ network_abbrev(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(ret);
}
+Datum
+cidr_abbrev(PG_FUNCTION_ARGS)
+{
+ inet *ip = PG_GETARG_INET_P(0);
+ text *ret;
+ char *dst;
+ int len;
+ char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
+
+ dst = inet_cidr_ntop(ip_family(ip), ip_addr(ip),
+ ip_bits(ip), tmp, sizeof(tmp));
+
+ if (dst == NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
+ errmsg("could not format cidr value: %m")));
+
+ /* 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)
{
@@ -666,7 +792,6 @@ network_broadcast(PG_FUNCTION_ARGS)
ip_family(dst) = ip_family(ip);
ip_bits(dst) = ip_bits(ip);
- ip_is_cidr(dst) = false;
VARATT_SIZEP(dst) = VARHDRSZ
+ ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+ ip_addrsize(dst);
@@ -712,7 +837,6 @@ network_network(PG_FUNCTION_ARGS)
ip_family(dst) = ip_family(ip);
ip_bits(dst) = ip_bits(ip);
- ip_is_cidr(dst) = true;
VARATT_SIZEP(dst) = VARHDRSZ
+ ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+ ip_addrsize(dst);
@@ -756,7 +880,6 @@ network_netmask(PG_FUNCTION_ARGS)
ip_family(dst) = ip_family(ip);
ip_bits(dst) = ip_maxbits(ip);
- ip_is_cidr(dst) = false;
VARATT_SIZEP(dst) = VARHDRSZ
+ ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+ ip_addrsize(dst);
@@ -806,7 +929,6 @@ network_hostmask(PG_FUNCTION_ARGS)
ip_family(dst) = ip_family(ip);
ip_bits(dst) = ip_maxbits(ip);
- ip_is_cidr(dst) = false;
VARATT_SIZEP(dst) = VARHDRSZ
+ ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+ ip_addrsize(dst);
@@ -818,11 +940,6 @@ network_hostmask(PG_FUNCTION_ARGS)
* Convert a value of a network datatype to an approximate scalar value.
* This is used for estimating selectivities of inequality operators
* involving network types.
- *
- * Currently, inet/cidr values are simply converted to the IPv4 address;
- * this will need more thought when IPv6 is supported too. MAC addresses
- * are converted to their numeric equivalent as well (OK since we have a
- * double to play in).
*/
double
convert_network_to_scalar(Datum value, Oid typid)
@@ -838,7 +955,7 @@ convert_network_to_scalar(Datum value, Oid typid)
int i;
/*
- * Note that we don't use the full address here.
+ * Note that we don't use the full address for IPv6.
*/
if (ip_family(ip) == PGSQL_AF_INET)
len = 4;
@@ -1020,7 +1137,7 @@ inet_client_addr(PG_FUNCTION_ARGS)
if (ret)
PG_RETURN_NULL();
- PG_RETURN_INET_P(network_in(remote_host, 0));
+ PG_RETURN_INET_P(network_in(remote_host, false));
}
@@ -1094,7 +1211,7 @@ inet_server_addr(PG_FUNCTION_ARGS)
if (ret)
PG_RETURN_NULL();
- PG_RETURN_INET_P(network_in(local_host, 0));
+ PG_RETURN_INET_P(network_in(local_host, false));
}
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 2742b70027..7887bdb8aa 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,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/catversion.h,v 1.312 2006/01/18 06:49:27 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.313 2006/01/26 02:35:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200601181
+#define CATALOG_VERSION_NO 200601251
#endif
diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h
index 55b289212d..d4932ed89c 100644
--- a/src/include/catalog/pg_amop.h
+++ b/src/include/catalog/pg_amop.h
@@ -23,7 +23,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_amop.h,v 1.67 2005/11/07 17:36:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_amop.h,v 1.68 2006/01/26 02:35:49 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -388,11 +388,11 @@ DATA(insert ( 1974 0 5 f 1205 ));
* btree cidr
*/
-DATA(insert ( 432 0 1 f 822 ));
-DATA(insert ( 432 0 2 f 823 ));
-DATA(insert ( 432 0 3 f 820 ));
-DATA(insert ( 432 0 4 f 825 ));
-DATA(insert ( 432 0 5 f 824 ));
+DATA(insert ( 432 0 1 f 1203 ));
+DATA(insert ( 432 0 2 f 1204 ));
+DATA(insert ( 432 0 3 f 1201 ));
+DATA(insert ( 432 0 4 f 1206 ));
+DATA(insert ( 432 0 5 f 1205 ));
/*
* btree numeric
@@ -523,7 +523,7 @@ DATA(insert ( 427 0 1 f 1054 ));
/* char_ops */
DATA(insert ( 431 0 1 f 92 ));
/* cidr_ops */
-DATA(insert ( 433 0 1 f 820 ));
+DATA(insert ( 433 0 1 f 1201 ));
/* date_ops */
DATA(insert ( 435 0 1 f 1093 ));
/* float4_ops */
diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h
index d0dfbecd62..db52b892fd 100644
--- a/src/include/catalog/pg_cast.h
+++ b/src/include/catalog/pg_cast.h
@@ -10,7 +10,7 @@
*
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_cast.h,v 1.24 2005/10/21 15:45:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_cast.h,v 1.25 2006/01/26 02:35:49 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -249,7 +249,7 @@ DATA(insert ( 718 604 1544 e ));
* INET category
*/
DATA(insert ( 650 869 0 i ));
-DATA(insert ( 869 650 0 i ));
+DATA(insert ( 869 650 1715 a ));
/*
* BitString category
diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h
index 678ed306f2..9b426f6c59 100644
--- a/src/include/catalog/pg_operator.h
+++ b/src/include/catalog/pg_operator.h
@@ -8,7 +8,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_operator.h,v 1.137 2005/10/15 02:49:42 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.138 2006/01/26 02:35:49 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -637,7 +637,7 @@ DATA(insert OID = 1223 ( "<=" PGNSP PGUID b f 829 829 16 1225 1224 0 0
DATA(insert OID = 1224 ( ">" PGNSP PGUID b f 829 829 16 1222 1223 0 0 0 0 macaddr_gt scalargtsel scalargtjoinsel ));
DATA(insert OID = 1225 ( ">=" PGNSP PGUID b f 829 829 16 1223 1222 0 0 0 0 macaddr_ge scalargtsel scalargtjoinsel ));
-/* INET type */
+/* INET type (these also support CIDR via implicit cast) */
DATA(insert OID = 1201 ( "=" PGNSP PGUID b t 869 869 16 1201 1202 1203 1203 1203 1205 network_eq eqsel eqjoinsel ));
DATA(insert OID = 1202 ( "<>" PGNSP PGUID b f 869 869 16 1202 1201 0 0 0 0 network_ne neqsel neqjoinsel ));
DATA(insert OID = 1203 ( "<" PGNSP PGUID b f 869 869 16 1205 1206 0 0 0 0 network_lt scalarltsel scalarltjoinsel ));
@@ -653,22 +653,6 @@ DATA(insert OID = 933 ( ">>" PGNSP PGUID b f 869 869 16 931 0 0 0 0
DATA(insert OID = 934 ( ">>=" PGNSP PGUID b f 869 869 16 932 0 0 0 0 0 network_supeq - - ));
#define OID_INET_SUPEQ_OP 934
-/* CIDR type */
-DATA(insert OID = 820 ( "=" PGNSP PGUID b t 650 650 16 820 821 822 822 822 824 network_eq eqsel eqjoinsel ));
-DATA(insert OID = 821 ( "<>" PGNSP PGUID b f 650 650 16 821 820 0 0 0 0 network_ne neqsel neqjoinsel ));
-DATA(insert OID = 822 ( "<" PGNSP PGUID b f 650 650 16 824 825 0 0 0 0 network_lt scalarltsel scalarltjoinsel ));
-DATA(insert OID = 823 ( "<=" PGNSP PGUID b f 650 650 16 825 824 0 0 0 0 network_le scalarltsel scalarltjoinsel ));
-DATA(insert OID = 824 ( ">" PGNSP PGUID b f 650 650 16 822 823 0 0 0 0 network_gt scalargtsel scalargtjoinsel ));
-DATA(insert OID = 825 ( ">=" PGNSP PGUID b f 650 650 16 823 822 0 0 0 0 network_ge scalargtsel scalargtjoinsel ));
-DATA(insert OID = 826 ( "<<" PGNSP PGUID b f 650 650 16 828 0 0 0 0 0 network_sub - - ));
-#define OID_CIDR_SUB_OP 826
-DATA(insert OID = 827 ( "<<=" PGNSP PGUID b f 650 650 16 1004 0 0 0 0 0 network_subeq - - ));
-#define OID_CIDR_SUBEQ_OP 827
-DATA(insert OID = 828 ( ">>" PGNSP PGUID b f 650 650 16 826 0 0 0 0 0 network_sup - - ));
-#define OID_CIDR_SUP_OP 828
-DATA(insert OID = 1004 ( ">>=" PGNSP PGUID b f 650 650 16 827 0 0 0 0 0 network_supeq - - ));
-#define OID_CIDR_SUPEQ_OP 1004
-
/* case-insensitive LIKE hacks */
DATA(insert OID = 1625 ( "~~*" PGNSP PGUID b f 19 25 16 0 1626 0 0 0 0 nameiclike iclikesel iclikejoinsel ));
#define OID_NAME_ICLIKE_OP 1625
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 5c54d831cd..a79a58c2e9 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.392 2006/01/18 06:49:28 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.393 2006/01/26 02:35:49 tgl Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
@@ -2391,10 +2391,16 @@ DATA(insert OID = 930 ( network_supeq PGNSP PGUID 12 f f t f i 2 16 "869 869"
DESCR("is-supernet-or-equal");
/* inet/cidr functions */
-DATA(insert OID = 605 ( abbrev PGNSP PGUID 12 f f t f i 1 25 "869" _null_ _null_ _null_ network_abbrev - _null_ ));
-DESCR("abbreviated display of inet/cidr value");
+DATA(insert OID = 598 ( abbrev PGNSP PGUID 12 f f t f i 1 25 "869" _null_ _null_ _null_ inet_abbrev - _null_ ));
+DESCR("abbreviated display of inet value");
+DATA(insert OID = 599 ( abbrev PGNSP PGUID 12 f f t f i 1 25 "650" _null_ _null_ _null_ cidr_abbrev - _null_ ));
+DESCR("abbreviated display of cidr value");
+DATA(insert OID = 605 ( set_masklen PGNSP PGUID 12 f f t f i 2 869 "869 23" _null_ _null_ _null_ inet_set_masklen - _null_ ));
+DESCR("change netmask of inet");
+DATA(insert OID = 635 ( set_masklen PGNSP PGUID 12 f f t f i 2 650 "650 23" _null_ _null_ _null_ cidr_set_masklen - _null_ ));
+DESCR("change netmask of cidr");
DATA(insert OID = 711 ( family PGNSP PGUID 12 f f t f i 1 23 "869" _null_ _null_ _null_ network_family - _null_ ));
-DESCR("return address family (4 for IPv4, 6 for IPv6)");
+DESCR("address family (4 for IPv4, 6 for IPv6)");
DATA(insert OID = 683 ( network PGNSP PGUID 12 f f t f i 1 650 "869" _null_ _null_ _null_ network_network - _null_ ));
DESCR("network part of address");
DATA(insert OID = 696 ( netmask PGNSP PGUID 12 f f t f i 1 869 "869" _null_ _null_ _null_ network_netmask - _null_ ));
@@ -2413,8 +2419,8 @@ DATA(insert OID = 1713 ( inet PGNSP PGUID 12 f f t f i 1 869 "25" _null_ _nu
DESCR("text to inet");
DATA(insert OID = 1714 ( cidr PGNSP PGUID 12 f f t f i 1 650 "25" _null_ _null_ _null_ text_cidr - _null_ ));
DESCR("text to cidr");
-DATA(insert OID = 1715 ( set_masklen PGNSP PGUID 12 f f t f i 2 869 "869 23" _null_ _null_ _null_ inet_set_masklen - _null_ ));
-DESCR("change the netmask of an inet");
+DATA(insert OID = 1715 ( cidr PGNSP PGUID 12 f f t f i 1 650 "869" _null_ _null_ _null_ inet_to_cidr - _null_ ));
+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");
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index e8ad4bd0e2..527d5ce8e8 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.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/utils/builtins.h,v 1.271 2006/01/18 06:49:29 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.272 2006/01/26 02:35:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -720,11 +720,14 @@ extern Datum network_family(PG_FUNCTION_ARGS);
extern Datum network_broadcast(PG_FUNCTION_ARGS);
extern Datum network_host(PG_FUNCTION_ARGS);
extern Datum network_show(PG_FUNCTION_ARGS);
-extern Datum network_abbrev(PG_FUNCTION_ARGS);
+extern Datum inet_abbrev(PG_FUNCTION_ARGS);
+extern Datum cidr_abbrev(PG_FUNCTION_ARGS);
extern double convert_network_to_scalar(Datum value, Oid typid);
extern Datum text_cidr(PG_FUNCTION_ARGS);
extern Datum text_inet(PG_FUNCTION_ARGS);
+extern Datum inet_to_cidr(PG_FUNCTION_ARGS);
extern Datum inet_set_masklen(PG_FUNCTION_ARGS);
+extern Datum cidr_set_masklen(PG_FUNCTION_ARGS);
extern Datum network_scan_first(Datum in);
extern Datum network_scan_last(Datum in);
extern Datum inet_client_addr(PG_FUNCTION_ARGS);
diff --git a/src/include/utils/inet.h b/src/include/utils/inet.h
index 03b8ee4b7e..ad6215d772 100644
--- a/src/include/utils/inet.h
+++ b/src/include/utils/inet.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/utils/inet.h,v 1.21 2006/01/23 21:45:47 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/inet.h,v 1.22 2006/01/26 02:35:51 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,7 +22,6 @@ typedef struct
{
unsigned char family; /* PGSQL_AF_INET or PGSQL_AF_INET6 */
unsigned char bits; /* number of bits in netmask */
- bool is_cidr; /* is cidr? */
unsigned char ipaddr[16]; /* up to 128 bits of address */
} inet_struct;
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index aad7a10ed0..f367d0a552 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -274,6 +274,8 @@ WHERE c.castfunc = p.oid AND
-- also binary compatible. This is legal, but usually not intended.
-- As of 7.4, this finds the casts from text and varchar to bpchar, because
-- those are binary-compatible while the reverse way goes through rtrim().
+-- As of 8.2, this finds the cast from cidr to inet, because that is a
+-- trivial binary coercion while the other way goes through inet_to_cidr().
SELECT *
FROM pg_cast c
WHERE c.castfunc = 0 AND
@@ -285,7 +287,8 @@ WHERE c.castfunc = 0 AND
------------+------------+----------+-------------
25 | 1042 | 0 | i
1043 | 1042 | 0 | i
-(2 rows)
+ 650 | 869 | 0 | i
+(3 rows)
-- **************** pg_operator ****************
-- Look for illegal values in pg_operator fields.
diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql
index ea5bc5b436..0528e3657c 100644
--- a/src/test/regress/sql/opr_sanity.sql
+++ b/src/test/regress/sql/opr_sanity.sql
@@ -223,6 +223,9 @@ WHERE c.castfunc = p.oid AND
-- As of 7.4, this finds the casts from text and varchar to bpchar, because
-- those are binary-compatible while the reverse way goes through rtrim().
+-- As of 8.2, this finds the cast from cidr to inet, because that is a
+-- trivial binary coercion while the other way goes through inet_to_cidr().
+
SELECT *
FROM pg_cast c
WHERE c.castfunc = 0 AND