mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-03-01 19:45:33 +08:00
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.
This commit is contained in:
parent
5997386a0a
commit
8d8bf12760
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$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
|
||||
-->
|
||||
|
||||
@ -6797,9 +6797,7 @@ SELECT pg_sleep(1.5);
|
||||
types. The <function>host</function>,
|
||||
<function>text</function>, and <function>abbrev</function>
|
||||
functions are primarily intended to offer alternative display
|
||||
formats. You can cast a text value to <type>inet</> using normal casting
|
||||
syntax: <literal>inet(<replaceable>expression</>)</literal> or
|
||||
<literal><replaceable>colname</>::inet</literal>.
|
||||
formats.
|
||||
</para>
|
||||
|
||||
<table id="cidr-inet-functions-table">
|
||||
@ -6843,6 +6841,13 @@ SELECT pg_sleep(1.5);
|
||||
<entry><literal>set_masklen('192.168.1.5/24', 16)</literal></entry>
|
||||
<entry><literal>192.168.1.5/16</literal></entry>
|
||||
</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>
|
||||
<entry><literal><function>netmask</function>(<type>inet</type>)</literal></entry>
|
||||
<entry><type>inet</type></entry>
|
||||
@ -6875,6 +6880,13 @@ SELECT pg_sleep(1.5);
|
||||
<entry><literal><function>abbrev</function>(<type>inet</type>)</literal></entry>
|
||||
<entry><type>text</type></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>10.1/16</literal></entry>
|
||||
</row>
|
||||
@ -6890,6 +6902,22 @@ SELECT pg_sleep(1.5);
|
||||
</tgroup>
|
||||
</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>
|
||||
<xref linkend="macaddr-functions-table"> shows the functions
|
||||
available for use with the <type>macaddr</type> type. The function
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user