Commit 8d8bf127 authored by Tom Lane's avatar Tom Lane

Clean up the INET-vs-CIDR situation. Get rid of the internal is_cidr flag

and rely exclusively on the SQL type system to tell the difference between
the types.  Prevent creation of invalid CIDR values via casting from INET
or set_masklen() --- both of these operations now silently zero any bits
to the right of the netmask.  Remove duplicate CIDR comparison operators,
letting the type rely on the INET operators instead.
parent 5997386a
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.302 2006/01/11 20:12:38 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.303 2006/01/26 02:35:48 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -6797,9 +6797,7 @@ SELECT pg_sleep(1.5); ...@@ -6797,9 +6797,7 @@ SELECT pg_sleep(1.5);
types. The <function>host</function>, types. The <function>host</function>,
<function>text</function>, and <function>abbrev</function> <function>text</function>, and <function>abbrev</function>
functions are primarily intended to offer alternative display functions are primarily intended to offer alternative display
formats. You can cast a text value to <type>inet</> using normal casting formats.
syntax: <literal>inet(<replaceable>expression</>)</literal> or
<literal><replaceable>colname</>::inet</literal>.
</para> </para>
<table id="cidr-inet-functions-table"> <table id="cidr-inet-functions-table">
...@@ -6843,6 +6841,13 @@ SELECT pg_sleep(1.5); ...@@ -6843,6 +6841,13 @@ SELECT pg_sleep(1.5);
<entry><literal>set_masklen('192.168.1.5/24', 16)</literal></entry> <entry><literal>set_masklen('192.168.1.5/24', 16)</literal></entry>
<entry><literal>192.168.1.5/16</literal></entry> <entry><literal>192.168.1.5/16</literal></entry>
</row> </row>
<row>
<entry><literal><function>set_masklen</function>(<type>cidr</type>, <type>int</type>)</literal></entry>
<entry><type>cidr</type></entry>
<entry>set netmask length for <type>cidr</type> value</entry>
<entry><literal>set_masklen('192.168.1.0/24'::cidr, 16)</literal></entry>
<entry><literal>192.168.0.0/16</literal></entry>
</row>
<row> <row>
<entry><literal><function>netmask</function>(<type>inet</type>)</literal></entry> <entry><literal><function>netmask</function>(<type>inet</type>)</literal></entry>
<entry><type>inet</type></entry> <entry><type>inet</type></entry>
...@@ -6875,6 +6880,13 @@ SELECT pg_sleep(1.5); ...@@ -6875,6 +6880,13 @@ SELECT pg_sleep(1.5);
<entry><literal><function>abbrev</function>(<type>inet</type>)</literal></entry> <entry><literal><function>abbrev</function>(<type>inet</type>)</literal></entry>
<entry><type>text</type></entry> <entry><type>text</type></entry>
<entry>abbreviated display format as text</entry> <entry>abbreviated display format as text</entry>
<entry><literal>abbrev(inet '10.1.0.0/16')</literal></entry>
<entry><literal>10.1.0.0/16</literal></entry>
</row>
<row>
<entry><literal><function>abbrev</function>(<type>cidr</type>)</literal></entry>
<entry><type>text</type></entry>
<entry>abbreviated display format as text</entry>
<entry><literal>abbrev(cidr '10.1.0.0/16')</literal></entry> <entry><literal>abbrev(cidr '10.1.0.0/16')</literal></entry>
<entry><literal>10.1/16</literal></entry> <entry><literal>10.1/16</literal></entry>
</row> </row>
...@@ -6890,6 +6902,22 @@ SELECT pg_sleep(1.5); ...@@ -6890,6 +6902,22 @@ SELECT pg_sleep(1.5);
</tgroup> </tgroup>
</table> </table>
<para>
Any <type>cidr</> value can be cast to <type>inet</> implicitly
or explicitly; therefore, the functions shown above as operating on
<type>inet</> also work on <type>cidr</> values. (Where there are
separate functions for <type>inet</> and <type>cidr</>, it is because
the behavior should be different for the two cases.)
Also, it is permitted to cast an <type>inet</> value to <type>cidr</>.
When this is done, any bits to the right of the netmask are silently zeroed
to create a valid <type>cidr</> value.
In addition,
you can cast a text value to <type>inet</> or <type>cidr</>
using normal casting syntax: for example,
<literal>inet(<replaceable>expression</>)</literal> or
<literal><replaceable>colname</>::cidr</literal>.
</para>
<para> <para>
<xref linkend="macaddr-functions-table"> shows the functions <xref linkend="macaddr-functions-table"> shows the functions
available for use with the <type>macaddr</type> type. The function available for use with the <type>macaddr</type> type. The function
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -2024,8 +2024,6 @@ match_special_index_operator(Expr *clause, Oid opclass,
case OID_INET_SUB_OP: case OID_INET_SUB_OP:
case OID_INET_SUBEQ_OP: case OID_INET_SUBEQ_OP:
case OID_CIDR_SUB_OP:
case OID_CIDR_SUBEQ_OP:
isIndexable = true; isIndexable = true;
break; break;
} }
...@@ -2087,12 +2085,8 @@ match_special_index_operator(Expr *clause, Oid opclass, ...@@ -2087,12 +2085,8 @@ match_special_index_operator(Expr *clause, Oid opclass,
case OID_INET_SUB_OP: case OID_INET_SUB_OP:
case OID_INET_SUBEQ_OP: case OID_INET_SUBEQ_OP:
isIndexable = (opclass == INET_BTREE_OPS_OID); isIndexable = (opclass == INET_BTREE_OPS_OID ||
break; opclass == CIDR_BTREE_OPS_OID);
case OID_CIDR_SUB_OP:
case OID_CIDR_SUBEQ_OP:
isIndexable = (opclass == CIDR_BTREE_OPS_OID);
break; break;
} }
...@@ -2317,8 +2311,6 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass) ...@@ -2317,8 +2311,6 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass)
case OID_INET_SUB_OP: case OID_INET_SUB_OP:
case OID_INET_SUBEQ_OP: case OID_INET_SUBEQ_OP:
case OID_CIDR_SUB_OP:
case OID_CIDR_SUBEQ_OP:
result = network_prefix_quals(leftop, expr_op, opclass, result = network_prefix_quals(leftop, expr_op, opclass,
patt->constvalue); patt->constvalue);
break; break;
...@@ -2681,14 +2673,6 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, Datum rightop) ...@@ -2681,14 +2673,6 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, Datum rightop)
datatype = INETOID; datatype = INETOID;
is_eq = true; is_eq = true;
break; break;
case OID_CIDR_SUB_OP:
datatype = CIDROID;
is_eq = false;
break;
case OID_CIDR_SUBEQ_OP:
datatype = CIDROID;
is_eq = true;
break;
default: default:
elog(ERROR, "unexpected operator: %u", expr_op); elog(ERROR, "unexpected operator: %u", expr_op);
return NIL; return NIL;
......
/* /*
* PostgreSQL type definitions for the INET and CIDR types. * 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 * Jon Postel RIP 16 Oct 1998
*/ */
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "utils/inet.h" #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 int32 network_cmp_internal(inet *a1, inet *a2);
static int bitncmp(void *l, void *r, int n); static int bitncmp(void *l, void *r, int n);
static bool addressOK(unsigned char *a, int bits, int family); static bool addressOK(unsigned char *a, int bits, int family);
...@@ -38,9 +38,6 @@ static int ip_addrsize(inet *inetptr); ...@@ -38,9 +38,6 @@ static int ip_addrsize(inet *inetptr);
#define ip_bits(inetptr) \ #define ip_bits(inetptr) \
(((inet_struct *)VARDATA(inetptr))->bits) (((inet_struct *)VARDATA(inetptr))->bits)
#define ip_is_cidr(inetptr) \
(((inet_struct *)VARDATA(inetptr))->is_cidr)
#define ip_addr(inetptr) \ #define ip_addr(inetptr) \
(((inet_struct *)VARDATA(inetptr))->ipaddr) (((inet_struct *)VARDATA(inetptr))->ipaddr)
...@@ -64,7 +61,9 @@ ip_addrsize(inet *inetptr) ...@@ -64,7 +61,9 @@ ip_addrsize(inet *inetptr)
} }
} }
/* Common input routine */ /*
* Common INET/CIDR input routine
*/
static inet * static inet *
network_in(char *src, bool is_cidr) network_in(char *src, bool is_cidr)
{ {
...@@ -109,37 +108,33 @@ 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)) + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+ ip_addrsize(dst); + ip_addrsize(dst);
ip_bits(dst) = bits; ip_bits(dst) = bits;
ip_is_cidr(dst) = is_cidr;
return dst; return dst;
} }
/* INET address reader. */
Datum Datum
inet_in(PG_FUNCTION_ARGS) inet_in(PG_FUNCTION_ARGS)
{ {
char *src = PG_GETARG_CSTRING(0); 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 Datum
cidr_in(PG_FUNCTION_ARGS) cidr_in(PG_FUNCTION_ARGS)
{ {
char *src = PG_GETARG_CSTRING(0); 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 static char *
inet_out(PG_FUNCTION_ARGS) 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 tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
char *dst; char *dst;
int len; int len;
...@@ -152,34 +147,45 @@ inet_out(PG_FUNCTION_ARGS) ...@@ -152,34 +147,45 @@ inet_out(PG_FUNCTION_ARGS)
errmsg("could not format inet value: %m"))); errmsg("could not format inet value: %m")));
/* For CIDR, add /n if not present */ /* For CIDR, add /n if not present */
if (ip_is_cidr(src) && strchr(tmp, '/') == NULL) if (is_cidr && strchr(tmp, '/') == NULL)
{ {
len = strlen(tmp); len = strlen(tmp);
snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(src)); 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 Datum
cidr_out(PG_FUNCTION_ARGS) 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) * The external representation is (one byte apiece for)
* family, bits, is_cidr, address length, address in network byte order. * 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 static inet *
inet_recv(PG_FUNCTION_ARGS) network_recv(StringInfo buf, bool is_cidr)
{ {
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
inet *addr; inet *addr;
char *addrptr; char *addrptr;
int bits; int bits;
...@@ -194,23 +200,25 @@ inet_recv(PG_FUNCTION_ARGS) ...@@ -194,23 +200,25 @@ inet_recv(PG_FUNCTION_ARGS)
ip_family(addr) != PGSQL_AF_INET6) ip_family(addr) != PGSQL_AF_INET6)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), (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); bits = pq_getmsgbyte(buf);
if (bits < 0 || bits > ip_maxbits(addr)) if (bits < 0 || bits > ip_maxbits(addr))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), (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_bits(addr) = bits;
ip_is_cidr(addr) = pq_getmsgbyte(buf); i = pq_getmsgbyte(buf); /* ignore is_cidr */
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")));
nb = pq_getmsgbyte(buf); nb = pq_getmsgbyte(buf);
if (nb != ip_addrsize(addr)) if (nb != ip_addrsize(addr))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), (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 VARATT_SIZEP(addr) = VARHDRSZ
+ ((char *) ip_addr(addr) - (char *) VARDATA(addr)) + ((char *) ip_addr(addr) - (char *) VARDATA(addr))
+ ip_addrsize(addr); + ip_addrsize(addr);
...@@ -222,7 +230,7 @@ inet_recv(PG_FUNCTION_ARGS) ...@@ -222,7 +230,7 @@ inet_recv(PG_FUNCTION_ARGS)
/* /*
* Error check: CIDR values must not have any bits set beyond the masklen. * 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))) if (!addressOK(ip_addr(addr), bits, ip_family(addr)))
ereport(ERROR, ereport(ERROR,
...@@ -231,23 +239,32 @@ inet_recv(PG_FUNCTION_ARGS) ...@@ -231,23 +239,32 @@ inet_recv(PG_FUNCTION_ARGS)
errdetail("Value has bits set to right of mask."))); 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 Datum
cidr_recv(PG_FUNCTION_ARGS) 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 static bytea *
inet_send(PG_FUNCTION_ARGS) network_send(inet *addr, bool is_cidr)
{ {
inet *addr = PG_GETARG_INET_P(0);
StringInfoData buf; StringInfoData buf;
char *addrptr; char *addrptr;
int nb, int nb,
...@@ -256,7 +273,7 @@ inet_send(PG_FUNCTION_ARGS) ...@@ -256,7 +273,7 @@ inet_send(PG_FUNCTION_ARGS)
pq_begintypsend(&buf); pq_begintypsend(&buf);
pq_sendbyte(&buf, ip_family(addr)); pq_sendbyte(&buf, ip_family(addr));
pq_sendbyte(&buf, ip_bits(addr)); pq_sendbyte(&buf, ip_bits(addr));
pq_sendbyte(&buf, ip_is_cidr(addr)); pq_sendbyte(&buf, is_cidr);
nb = ip_addrsize(addr); nb = ip_addrsize(addr);
if (nb < 0) if (nb < 0)
nb = 0; nb = 0;
...@@ -264,41 +281,93 @@ inet_send(PG_FUNCTION_ARGS) ...@@ -264,41 +281,93 @@ inet_send(PG_FUNCTION_ARGS)
addrptr = (char *) ip_addr(addr); addrptr = (char *) ip_addr(addr);
for (i = 0; i < nb; i++) for (i = 0; i < nb; i++)
pq_sendbyte(&buf, addrptr[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 Datum
cidr_send(PG_FUNCTION_ARGS) 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) text_network(text *src, bool is_cidr)
{ {
int len = VARSIZE(src) - VARHDRSZ; int len = VARSIZE(src) - VARHDRSZ;
char *str = palloc(len + 1); char *str = palloc(len + 1);
memcpy(str, VARDATA(src), len); memcpy(str, VARDATA(src), len);
*(str + len) = '\0'; str[len] = '\0';
PG_RETURN_INET_P(network_in(str, is_cidr)); return network_in(str, is_cidr);
} }
Datum
text_inet(PG_FUNCTION_ARGS)
{
text *src = PG_GETARG_TEXT_P(0);
PG_RETURN_INET_P(text_network(src, false));
}
Datum Datum
text_cidr(PG_FUNCTION_ARGS) text_cidr(PG_FUNCTION_ARGS)
{ {
return text_network(PG_GETARG_TEXT_P(0), 1); text *src = PG_GETARG_TEXT_P(0);
PG_RETURN_INET_P(text_network(src, true));
} }
Datum Datum
text_inet(PG_FUNCTION_ARGS) inet_to_cidr(PG_FUNCTION_ARGS)
{ {
return text_network(PG_GETARG_TEXT_P(0), 0); 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 Datum
...@@ -325,6 +394,50 @@ inet_set_masklen(PG_FUNCTION_ARGS) ...@@ -325,6 +394,50 @@ inet_set_masklen(PG_FUNCTION_ARGS)
PG_RETURN_INET_P(dst); 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. * Basic comparison function for sorting and inet/cidr comparisons.
* *
...@@ -424,23 +537,15 @@ network_ne(PG_FUNCTION_ARGS) ...@@ -424,23 +537,15 @@ network_ne(PG_FUNCTION_ARGS)
/* /*
* Support function for hash indexes on inet/cidr. * 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 Datum
hashinet(PG_FUNCTION_ARGS) hashinet(PG_FUNCTION_ARGS)
{ {
inet *addr = PG_GETARG_INET_P(0); inet *addr = PG_GETARG_INET_P(0);
int addrsize = ip_addrsize(addr); 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) ...@@ -567,7 +672,7 @@ network_show(PG_FUNCTION_ARGS)
} }
Datum Datum
network_abbrev(PG_FUNCTION_ARGS) inet_abbrev(PG_FUNCTION_ARGS)
{ {
inet *ip = PG_GETARG_INET_P(0); inet *ip = PG_GETARG_INET_P(0);
text *ret; text *ret;
...@@ -575,10 +680,6 @@ network_abbrev(PG_FUNCTION_ARGS) ...@@ -575,10 +680,6 @@ network_abbrev(PG_FUNCTION_ARGS)
int len; int len;
char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; 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), dst = inet_net_ntop(ip_family(ip), ip_addr(ip),
ip_bits(ip), tmp, sizeof(tmp)); ip_bits(ip), tmp, sizeof(tmp));
...@@ -595,6 +696,31 @@ network_abbrev(PG_FUNCTION_ARGS) ...@@ -595,6 +696,31 @@ network_abbrev(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(ret); 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 Datum
network_masklen(PG_FUNCTION_ARGS) network_masklen(PG_FUNCTION_ARGS)
{ {
...@@ -666,7 +792,6 @@ network_broadcast(PG_FUNCTION_ARGS) ...@@ -666,7 +792,6 @@ network_broadcast(PG_FUNCTION_ARGS)
ip_family(dst) = ip_family(ip); ip_family(dst) = ip_family(ip);
ip_bits(dst) = ip_bits(ip); ip_bits(dst) = ip_bits(ip);
ip_is_cidr(dst) = false;
VARATT_SIZEP(dst) = VARHDRSZ VARATT_SIZEP(dst) = VARHDRSZ
+ ((char *) ip_addr(dst) - (char *) VARDATA(dst)) + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+ ip_addrsize(dst); + ip_addrsize(dst);
...@@ -712,7 +837,6 @@ network_network(PG_FUNCTION_ARGS) ...@@ -712,7 +837,6 @@ network_network(PG_FUNCTION_ARGS)
ip_family(dst) = ip_family(ip); ip_family(dst) = ip_family(ip);
ip_bits(dst) = ip_bits(ip); ip_bits(dst) = ip_bits(ip);
ip_is_cidr(dst) = true;
VARATT_SIZEP(dst) = VARHDRSZ VARATT_SIZEP(dst) = VARHDRSZ
+ ((char *) ip_addr(dst) - (char *) VARDATA(dst)) + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+ ip_addrsize(dst); + ip_addrsize(dst);
...@@ -756,7 +880,6 @@ network_netmask(PG_FUNCTION_ARGS) ...@@ -756,7 +880,6 @@ network_netmask(PG_FUNCTION_ARGS)
ip_family(dst) = ip_family(ip); ip_family(dst) = ip_family(ip);
ip_bits(dst) = ip_maxbits(ip); ip_bits(dst) = ip_maxbits(ip);
ip_is_cidr(dst) = false;
VARATT_SIZEP(dst) = VARHDRSZ VARATT_SIZEP(dst) = VARHDRSZ
+ ((char *) ip_addr(dst) - (char *) VARDATA(dst)) + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+ ip_addrsize(dst); + ip_addrsize(dst);
...@@ -806,7 +929,6 @@ network_hostmask(PG_FUNCTION_ARGS) ...@@ -806,7 +929,6 @@ network_hostmask(PG_FUNCTION_ARGS)
ip_family(dst) = ip_family(ip); ip_family(dst) = ip_family(ip);
ip_bits(dst) = ip_maxbits(ip); ip_bits(dst) = ip_maxbits(ip);
ip_is_cidr(dst) = false;
VARATT_SIZEP(dst) = VARHDRSZ VARATT_SIZEP(dst) = VARHDRSZ
+ ((char *) ip_addr(dst) - (char *) VARDATA(dst)) + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
+ ip_addrsize(dst); + ip_addrsize(dst);
...@@ -818,11 +940,6 @@ network_hostmask(PG_FUNCTION_ARGS) ...@@ -818,11 +940,6 @@ network_hostmask(PG_FUNCTION_ARGS)
* Convert a value of a network datatype to an approximate scalar value. * Convert a value of a network datatype to an approximate scalar value.
* This is used for estimating selectivities of inequality operators * This is used for estimating selectivities of inequality operators
* involving network types. * 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 double
convert_network_to_scalar(Datum value, Oid typid) convert_network_to_scalar(Datum value, Oid typid)
...@@ -838,7 +955,7 @@ convert_network_to_scalar(Datum value, Oid typid) ...@@ -838,7 +955,7 @@ convert_network_to_scalar(Datum value, Oid typid)
int i; 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) if (ip_family(ip) == PGSQL_AF_INET)
len = 4; len = 4;
...@@ -1020,7 +1137,7 @@ inet_client_addr(PG_FUNCTION_ARGS) ...@@ -1020,7 +1137,7 @@ inet_client_addr(PG_FUNCTION_ARGS)
if (ret) if (ret)
PG_RETURN_NULL(); 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) ...@@ -1094,7 +1211,7 @@ inet_server_addr(PG_FUNCTION_ARGS)
if (ret) if (ret)
PG_RETURN_NULL(); PG_RETURN_NULL();
PG_RETURN_INET_P(network_in(local_host, 0)); PG_RETURN_INET_P(network_in(local_host, false));
} }
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200601181 #define CATALOG_VERSION_NO 200601251
#endif #endif
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -388,11 +388,11 @@ DATA(insert ( 1974 0 5 f 1205 )); ...@@ -388,11 +388,11 @@ DATA(insert ( 1974 0 5 f 1205 ));
* btree cidr * btree cidr
*/ */
DATA(insert ( 432 0 1 f 822 )); DATA(insert ( 432 0 1 f 1203 ));
DATA(insert ( 432 0 2 f 823 )); DATA(insert ( 432 0 2 f 1204 ));
DATA(insert ( 432 0 3 f 820 )); DATA(insert ( 432 0 3 f 1201 ));
DATA(insert ( 432 0 4 f 825 )); DATA(insert ( 432 0 4 f 1206 ));
DATA(insert ( 432 0 5 f 824 )); DATA(insert ( 432 0 5 f 1205 ));
/* /*
* btree numeric * btree numeric
...@@ -523,7 +523,7 @@ DATA(insert ( 427 0 1 f 1054 )); ...@@ -523,7 +523,7 @@ DATA(insert ( 427 0 1 f 1054 ));
/* char_ops */ /* char_ops */
DATA(insert ( 431 0 1 f 92 )); DATA(insert ( 431 0 1 f 92 ));
/* cidr_ops */ /* cidr_ops */
DATA(insert ( 433 0 1 f 820 )); DATA(insert ( 433 0 1 f 1201 ));
/* date_ops */ /* date_ops */
DATA(insert ( 435 0 1 f 1093 )); DATA(insert ( 435 0 1 f 1093 ));
/* float4_ops */ /* float4_ops */
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* Copyright (c) 2002-2005, PostgreSQL Global Development Group * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -249,7 +249,7 @@ DATA(insert ( 718 604 1544 e )); ...@@ -249,7 +249,7 @@ DATA(insert ( 718 604 1544 e ));
* INET category * INET category
*/ */
DATA(insert ( 650 869 0 i )); DATA(insert ( 650 869 0 i ));
DATA(insert ( 869 650 0 i )); DATA(insert ( 869 650 1715 a ));
/* /*
* BitString category * BitString category
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * 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 ...@@ -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 = 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 )); 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 = 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 = 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 )); 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 ...@@ -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 - - )); 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 #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 */ /* case-insensitive LIKE hacks */
DATA(insert OID = 1625 ( "~~*" PGNSP PGUID b f 19 25 16 0 1626 0 0 0 0 nameiclike iclikesel iclikejoinsel )); 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 #define OID_NAME_ICLIKE_OP 1625
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* The script catalog/genbki.sh reads this file and generates .bki * 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" ...@@ -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"); DESCR("is-supernet-or-equal");
/* inet/cidr functions */ /* 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_ )); 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/cidr value"); 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_ )); 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_ )); 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"); 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_ )); 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 ...@@ -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"); 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_ )); 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"); 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_ )); DATA(insert OID = 1715 ( cidr PGNSP PGUID 12 f f t f i 1 650 "869" _null_ _null_ _null_ inet_to_cidr - _null_ ));
DESCR("change the netmask of an inet"); 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_ )); 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");
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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); ...@@ -720,11 +720,14 @@ extern Datum network_family(PG_FUNCTION_ARGS);
extern Datum network_broadcast(PG_FUNCTION_ARGS); extern Datum network_broadcast(PG_FUNCTION_ARGS);
extern Datum network_host(PG_FUNCTION_ARGS); extern Datum network_host(PG_FUNCTION_ARGS);
extern Datum network_show(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 double convert_network_to_scalar(Datum value, Oid typid);
extern Datum text_cidr(PG_FUNCTION_ARGS); extern Datum text_cidr(PG_FUNCTION_ARGS);
extern Datum text_inet(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 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_first(Datum in);
extern Datum network_scan_last(Datum in); extern Datum network_scan_last(Datum in);
extern Datum inet_client_addr(PG_FUNCTION_ARGS); extern Datum inet_client_addr(PG_FUNCTION_ARGS);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 ...@@ -22,7 +22,6 @@ typedef struct
{ {
unsigned char family; /* PGSQL_AF_INET or PGSQL_AF_INET6 */ unsigned char family; /* PGSQL_AF_INET or PGSQL_AF_INET6 */
unsigned char bits; /* number of bits in netmask */ unsigned char bits; /* number of bits in netmask */
bool is_cidr; /* is cidr? */
unsigned char ipaddr[16]; /* up to 128 bits of address */ unsigned char ipaddr[16]; /* up to 128 bits of address */
} inet_struct; } inet_struct;
......
...@@ -274,6 +274,8 @@ WHERE c.castfunc = p.oid AND ...@@ -274,6 +274,8 @@ WHERE c.castfunc = p.oid AND
-- also binary compatible. This is legal, but usually not intended. -- 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 -- 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(). -- 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 * SELECT *
FROM pg_cast c FROM pg_cast c
WHERE c.castfunc = 0 AND WHERE c.castfunc = 0 AND
...@@ -285,7 +287,8 @@ WHERE c.castfunc = 0 AND ...@@ -285,7 +287,8 @@ WHERE c.castfunc = 0 AND
------------+------------+----------+------------- ------------+------------+----------+-------------
25 | 1042 | 0 | i 25 | 1042 | 0 | i
1043 | 1042 | 0 | i 1043 | 1042 | 0 | i
(2 rows) 650 | 869 | 0 | i
(3 rows)
-- **************** pg_operator **************** -- **************** pg_operator ****************
-- Look for illegal values in pg_operator fields. -- Look for illegal values in pg_operator fields.
......
...@@ -223,6 +223,9 @@ WHERE c.castfunc = p.oid AND ...@@ -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 -- 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(). -- 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 * SELECT *
FROM pg_cast c FROM pg_cast c
WHERE c.castfunc = 0 AND WHERE c.castfunc = 0 AND
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment