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