From a2100230087b702e42d30a1e6a95e3192ffb16ff Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 10 Nov 2000 20:13:27 +0000 Subject: [PATCH] Adjust INET/CIDR display conventions and reimplement some INET/CIDR functions, per recent discussions on pghackers. For now, I have called the verbose-display formatting function text(), but will reconsider if enough people object. initdb forced. --- doc/src/sgml/datatype.sgml | 86 ++++++++++------ doc/src/sgml/func.sgml | 74 ++++++++++---- doc/src/sgml/oper.sgml | 89 +++------------- src/backend/utils/adt/inet_net_ntop.c | 56 ++++------ src/backend/utils/adt/network.c | 142 ++++++++++++++++---------- src/include/catalog/catversion.h | 4 +- src/include/catalog/pg_proc.h | 18 ++-- src/include/utils/builtins.h | 3 +- src/test/regress/expected/inet.out | 52 +++++----- src/test/regress/sql/inet.sql | 2 +- 10 files changed, 272 insertions(+), 254 deletions(-) diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index f3e7aa83abf..11ccc2a9a60 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -1,5 +1,5 @@ @@ -65,7 +65,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.38 2000/10/04 15:47:45 pe cidr - IP version 4 network or host address + IP network address circle @@ -95,7 +95,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.38 2000/10/04 15:47:45 pe inet - IP version 4 network or host address + IP network or host address int2 @@ -1736,7 +1736,7 @@ January 8 04:05:06 1999 PST Postgres offers data types to store IP and MAC - addresses. It is preferrable to use these types over plain text + addresses. It is preferable to use these types over plain text types, because these types offer input error checking and several specialized operators and functions. @@ -1755,16 +1755,16 @@ January 8 04:05:06 1999 PST cidr - 11 bytes + 12 bytes IP networks valid IPv4 networks inet - 11 bytes + 12 bytes IP hosts and networks - valid IPv4 hosts + valid IPv4 hosts or networks @@ -1784,19 +1784,48 @@ January 8 04:05:06 1999 PST + + <type>inet</type> + + + The inet type holds an IP host address, and + optionally the identity of the subnet it is in, all in one field. + The subnet identity is represented by the number of bits in the + network part of the address (the "netmask"). If the netmask is 32, + then the value does not indicate a subnet, only a single host. + Note that if you want to accept networks only, you should use the + cidr type rather than inet. + + + + The input format for this type is x.x.x.x/y where x.x.x.x is an IP address and + y is the number of + bits in the netmask. If the y part is left off, then the + netmask is 32, and the value represents just a single host. + On display, the /y + portion is suppressed if the netmask is 32. + + + <type>cidr</> - The cidr type holds an IP network. The format for + The cidr type holds an IP network specification. + Input and output formats follow Classless Internet Domain Routing + conventions. + The format for specifying classless networks is x.x.x.x/y where x.x.x.x is the network and y is the number of bits in the netmask. If y omitted, it is calculated - using assumptions from the older classfull naming system except - that it is extended to include at least all of the octets in the - input. + using assumptions from the older classful numbering system, except + that it will be at least large enough to include all of the octets + written in the input. @@ -1816,6 +1845,10 @@ January 8 04:05:06 1999 PST 192.168.100.128/25 192.168.100.128/25 + + 192.168/24 + 192.168.0/24 + 192.168/25 192.168.0.0/25 @@ -1856,30 +1889,19 @@ January 8 04:05:06 1999 PST - - - - <type>inet</type> - The inet type holds an IP host address, and - optionally the identity of the subnet it is in, all in one field. - Note that if you want to store networks only, you should use the - cidr type. The inet type is similar to - the cidr type except that the bits in the host part - can be non-zero. Functions exist to extract the various elements - of the field. - + The essential difference between inet and cidr + data types is that inet accepts values with nonzero bits to + the right of the netmask, whereas cidr does not. - - The input format for this type is x.x.x.x/y where x.x.x.x is an internet host and - y is the number of - bits in the netmask. If the y part is left off, then the - netmask is 32 and you are effectively only storing the address of - a single host. + + + If you do not like the output format for inet or + cidr values, try the host() and + text() functions. + + diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index c51e8905e10..655c63a7931 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -1480,62 +1480,98 @@ Not defined by this name. Implements the intersection operator '#' <type>cidr</> and <type>inet</> Functions - + Function Returns Description Example + Result - - broadcast(cidr) - text - construct broadcast address as text - broadcast('192.168.1.5/24') - broadcast(inet) - text - construct broadcast address as text + inet + broadcast address for network broadcast('192.168.1.5/24') + 192.168.1.255/24 host(inet) text - extract host address as text + extract IP address as text host('192.168.1.5/24') - - - masklen(cidr) - integer - calculate netmask length - masklen('192.168.1.5/24') + 192.168.1.5 masklen(inet) integer - calculate netmask length + extract netmask length masklen('192.168.1.5/24') + 24 netmask(inet) - text - construct netmask as text + inet + construct netmask for network netmask('192.168.1.5/24') + 255.255.255.0 + + network(inet) + cidr + extract network part of address + network('192.168.1.5/24') + 192.168.1/24 + + + text(inet) + text + extract IP address and masklen as text + text(inet '192.168.1.5') + 192.168.1.5/32 + + + +
+
+ + + All of the functions for inet can be applied to + cidr values as well. The host() and + text() functions are primarily intended to offer + alternative display formats. + + + + + <type>macaddr</> Functions + + + + Function + Returns + Description + Example + Result + + + trunc(macaddr) macaddr set last 3 bytes to zero trunc(macaddr '12:34:56:78:90:ab') + 12:34:56:00:00:00
+
+ The function trunc(macaddr) returns a MAC address with the last 3 bytes set to 0. This can be used to associate the remaining prefix with a manufacturer. The directory diff --git a/doc/src/sgml/oper.sgml b/doc/src/sgml/oper.sgml index deb3d33cde8..8934323cd05 100644 --- a/doc/src/sgml/oper.sgml +++ b/doc/src/sgml/oper.sgml @@ -1,5 +1,5 @@ @@ -756,80 +756,11 @@ logical union Network Address Type Operators - - <type>cidr</> Operators + + <type>cidr</> and <type>inet</> Operators - - <type>cidr</> Operators - - - - Operator - Description - Usage - - - - - < - Less than - '192.168.1.5'::cidr < '192.168.1.6'::cidr - - - <= - Less than or equal - '192.168.1.5'::cidr <= '192.168.1.5'::cidr - - - = - Equals - '192.168.1.5'::cidr = '192.168.1.5'::cidr - - - >= - Greater or equal - '192.168.1.5'::cidr >= '192.168.1.5'::cidr - - - > - Greater - '192.168.1.5'::cidr > '192.168.1.4'::cidr - - - <> - Not equal - '192.168.1.5'::cidr <> '192.168.1.4'::cidr - - - << - is contained within - '192.168.1.5'::cidr << '192.168.1/24'::cidr - - - <<= - is contained within or equals - '192.168.1/24'::cidr <<= '192.168.1/24'::cidr - - - >> - contains - '192.168.1/24'::cidr >> '192.168.1.5'::cidr - - - >>= - contains or equals - '192.168.1/24'::cidr >>= '192.168.1/24'::cidr - - - -
-
- - - <type>inet</> Operators - - - <type>inet</> Operators +
+ <type>cidr</> and <type>inet</> Operators @@ -892,6 +823,16 @@ logical union
+ + + All of the operators for inet can be applied to + cidr values as well. The operators + << <<= + >> >>= + test for subnet inclusion: they consider only the network parts + of the two addresses, ignoring any host part, and determine whether + one network part is identical to or a subnet of the other. +
diff --git a/src/backend/utils/adt/inet_net_ntop.c b/src/backend/utils/adt/inet_net_ntop.c index c38ecc5a6f2..ecc83cab814 100644 --- a/src/backend/utils/adt/inet_net_ntop.c +++ b/src/backend/utils/adt/inet_net_ntop.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.8 1999/07/17 20:17:56 momjian Exp $"; +static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.9 2000/11/10 20:13:25 tgl Exp $"; #endif @@ -56,7 +56,7 @@ inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size) { switch (af) { - case AF_INET: + case AF_INET: return (inet_cidr_ntop_ipv4(src, bits, dst, size)); default: errno = EAFNOSUPPORT; @@ -102,15 +102,12 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) /* Format whole octets. */ for (b = bits / 8; b > 0; b--) { - if (size < sizeof "255.") + if (size < sizeof ".255") goto emsgsize; t = dst; - dst += SPRINTF((dst, "%u", *src++)); - if (b > 1) - { + if (dst != odst) *dst++ = '.'; - *dst = '\0'; - } + dst += SPRINTF((dst, "%u", *src++)); size -= (size_t) (dst - t); } @@ -132,6 +129,7 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) if (size < sizeof "/32") goto emsgsize; dst += SPRINTF((dst, "/%u", bits)); + return (odst); emsgsize: @@ -159,7 +157,7 @@ inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size) { switch (af) { - case AF_INET: + case AF_INET: return (inet_net_ntop_ipv4(src, bits, dst, size)); default: errno = EAFNOSUPPORT; @@ -185,48 +183,34 @@ inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) { char *odst = dst; char *t; - size_t len = 4; - int b, - tb; + int len = 4; + int b; if (bits < 0 || bits > 32) { errno = EINVAL; return (NULL); } - if (bits == 0) - { - if (size < sizeof "0") - goto emsgsize; - *dst++ = '0'; - size--; - *dst = '\0'; - } - /* Format whole octets plus nonzero trailing octets. */ - tb = (bits == 32) ? 31 : bits; - for (b = 0; bits != 0 && (b <= (tb / 8) || (b < len && *src != 0)); b++) + /* Always format all four octets, regardless of mask length. */ + for (b = len; b > 0; b--) { - if (size < sizeof "255.") + if (size < sizeof ".255") goto emsgsize; t = dst; - dst += SPRINTF((dst, "%u", *src++)); - if (b + 1 <= (tb / 8) || (b + 1 < len && *src != 0)) - { + if (dst != odst) *dst++ = '.'; - *dst = '\0'; - } + dst += SPRINTF((dst, "%u", *src++)); size -= (size_t) (dst - t); } /* don't print masklen if 32 bits */ - if (bits == 32) - return odst; - - /* Format CIDR /width. */ - if (size < sizeof "/32") - goto emsgsize; - dst += SPRINTF((dst, "/%u", bits)); + if (bits != 32) + { + if (size < sizeof "/32") + goto emsgsize; + dst += SPRINTF((dst, "/%u", bits)); + } return (odst); diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c index a3070f29e76..52f4e8ecd2f 100644 --- a/src/backend/utils/adt/network.c +++ b/src/backend/utils/adt/network.c @@ -3,7 +3,7 @@ * is for IP V4 CIDR notation, but prepared for V6: just * add the necessary bits where the comments indicate. * - * $Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.25 2000/10/27 01:52:15 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.26 2000/11/10 20:13:25 tgl Exp $ * * Jon Postel RIP 16 Oct 1998 */ @@ -67,12 +67,12 @@ network_in(char *src, int type) /* * Error check: CIDR values must not have any bits set beyond the masklen. - * XXX this code not IPV6 ready. + * XXX this code is not IPV6 ready. */ if (type) { if (! v4addressOK(ip_v4addr(dst), bits)) - elog(ERROR, "invalid CIDR value '%s': width too small", src); + elog(ERROR, "invalid CIDR value '%s': has bits set to right of mask", src); } VARATT_SIZEP(dst) = VARHDRSZ @@ -338,12 +338,10 @@ network_host(PG_FUNCTION_ARGS) char *ptr, tmp[sizeof("255.255.255.255/32")]; - if (ip_type(ip)) - elog(ERROR, "CIDR type has no host part"); - if (ip_family(ip) == AF_INET) { /* It's an IP V4 address: */ + /* force display of 32 bits, regardless of masklen... */ if (inet_net_ntop(AF_INET, &ip_v4addr(ip), 32, tmp, sizeof(tmp)) == NULL) elog(ERROR, "unable to print host (%s)", strerror(errno)); } @@ -351,7 +349,7 @@ network_host(PG_FUNCTION_ARGS) /* Go for an IPV6 address here, before faulting out: */ elog(ERROR, "unknown address family (%d)", ip_family(ip)); - /* Suppress /n if present */ + /* Suppress /n if present (shouldn't happen now) */ if ((ptr = strchr(tmp, '/')) != NULL) *ptr = '\0'; @@ -363,6 +361,40 @@ network_host(PG_FUNCTION_ARGS) PG_RETURN_TEXT_P(ret); } +Datum +network_show(PG_FUNCTION_ARGS) +{ + inet *ip = PG_GETARG_INET_P(0); + text *ret; + int len; + char tmp[sizeof("255.255.255.255/32")]; + + if (ip_family(ip) == AF_INET) + { + /* It's an IP V4 address: */ + /* force display of 32 bits, regardless of masklen... */ + if (inet_net_ntop(AF_INET, &ip_v4addr(ip), 32, tmp, sizeof(tmp)) == NULL) + elog(ERROR, "unable to print host (%s)", strerror(errno)); + } + else + /* Go for an IPV6 address here, before faulting out: */ + elog(ERROR, "unknown address family (%d)", ip_family(ip)); + + /* Add /n if not present */ + if (strchr(tmp, '/') == NULL) + { + len = strlen(tmp); + snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(ip)); + } + + /* 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) { @@ -375,100 +407,100 @@ Datum network_broadcast(PG_FUNCTION_ARGS) { inet *ip = PG_GETARG_INET_P(0); - text *ret; - int len; - char *ptr, - tmp[sizeof("255.255.255.255/32")]; + inet *dst; + + dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct)); + /* make sure any unused bits are zeroed */ + MemSet(dst, 0, VARHDRSZ + sizeof(inet_struct)); if (ip_family(ip) == AF_INET) { /* It's an IP V4 address: */ - int addr; unsigned long mask = 0xffffffff; - if (ip_bits(ip) < 32) - mask >>= ip_bits(ip); - addr = htonl(ntohl(ip_v4addr(ip)) | mask); + mask >>= ip_bits(ip); - if (inet_net_ntop(AF_INET, &addr, 32, tmp, sizeof(tmp)) == NULL) - elog(ERROR, "unable to print address (%s)", strerror(errno)); + ip_v4addr(dst) = htonl(ntohl(ip_v4addr(ip)) | mask); } else /* Go for an IPV6 address here, before faulting out: */ elog(ERROR, "unknown address family (%d)", ip_family(ip)); - /* Suppress /n if present */ - if ((ptr = strchr(tmp, '/')) != NULL) - *ptr = '\0'; + ip_family(dst) = ip_family(ip); + ip_bits(dst) = ip_bits(ip); + ip_type(dst) = 0; + VARATT_SIZEP(dst) = VARHDRSZ + + ((char *) &ip_v4addr(dst) - (char *) VARDATA(dst)) + + ip_addrsize(dst); - /* 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); + PG_RETURN_INET_P(dst); } Datum network_network(PG_FUNCTION_ARGS) { inet *ip = PG_GETARG_INET_P(0); - text *ret; - int len; - char tmp[sizeof("255.255.255.255/32")]; + inet *dst; + + dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct)); + /* make sure any unused bits are zeroed */ + MemSet(dst, 0, VARHDRSZ + sizeof(inet_struct)); if (ip_family(ip) == AF_INET) { /* It's an IP V4 address: */ - int addr = htonl(ntohl(ip_v4addr(ip)) & (0xffffffff << (32 - ip_bits(ip)))); + unsigned long mask = 0xffffffff; - if (inet_cidr_ntop(AF_INET, &addr, ip_bits(ip), tmp, sizeof(tmp)) == NULL) - elog(ERROR, "unable to print network (%s)", strerror(errno)); + mask <<= (32 - ip_bits(ip)); + + ip_v4addr(dst) = htonl(ntohl(ip_v4addr(ip)) & mask); } else /* Go for an IPV6 address here, before faulting out: */ elog(ERROR, "unknown address family (%d)", ip_family(ip)); - /* 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); + ip_family(dst) = ip_family(ip); + ip_bits(dst) = ip_bits(ip); + ip_type(dst) = 1; + VARATT_SIZEP(dst) = VARHDRSZ + + ((char *) &ip_v4addr(dst) - (char *) VARDATA(dst)) + + ip_addrsize(dst); + + PG_RETURN_INET_P(dst); } Datum network_netmask(PG_FUNCTION_ARGS) { inet *ip = PG_GETARG_INET_P(0); - text *ret; - int len; - char *ptr, - tmp[sizeof("255.255.255.255/32")]; + inet *dst; + + dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct)); + /* make sure any unused bits are zeroed */ + MemSet(dst, 0, VARHDRSZ + sizeof(inet_struct)); if (ip_family(ip) == AF_INET) { /* It's an IP V4 address: */ - int addr = htonl(ip_bits(ip) ? - (-1 << (32 - ip_bits(ip))) & 0xffffffff : 0x00000000); + unsigned long mask = 0xffffffff; - if (inet_net_ntop(AF_INET, &addr, 32, tmp, sizeof(tmp)) == NULL) - elog(ERROR, "unable to print netmask (%s)", strerror(errno)); + mask <<= (32 - ip_bits(ip)); + + ip_v4addr(dst) = htonl(mask); + + ip_bits(dst) = 32; } else /* Go for an IPV6 address here, before faulting out: */ elog(ERROR, "unknown address family (%d)", ip_family(ip)); - /* Suppress /n if present */ - if ((ptr = strchr(tmp, '/')) != NULL) - *ptr = '\0'; + ip_family(dst) = ip_family(ip); + ip_type(dst) = 0; + VARATT_SIZEP(dst) = VARHDRSZ + + ((char *) &ip_v4addr(dst) - (char *) VARDATA(dst)) + + ip_addrsize(dst); - /* 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); + PG_RETURN_INET_P(dst); } /* diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 01efe5efb98..bf66917aa7f 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: catversion.h,v 1.56 2000/11/08 16:59:50 petere Exp $ + * $Id: catversion.h,v 1.57 2000/11/10 20:13:26 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200011080 +#define CATALOG_VERSION_NO 200011101 #endif diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 30a7b2d9982..11f20071c7e 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_proc.h,v 1.172 2000/11/06 15:58:46 thomas Exp $ + * $Id: pg_proc.h,v 1.173 2000/11/10 20:13:26 tgl Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -2270,17 +2270,19 @@ DESCR("is-supernet"); DATA(insert OID = 930 ( network_supeq PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_supeq - )); DESCR("is-supernet-or-equal"); -/* inet/cidr versions */ -DATA(insert OID = 696 ( netmask PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_netmask - )); +/* inet/cidr functions */ +DATA(insert OID = 683 ( network PGUID 12 f t t t 1 f 650 "869" 100 0 0 100 network_network - )); +DESCR("network part of address"); +DATA(insert OID = 696 ( netmask PGUID 12 f t t t 1 f 869 "869" 100 0 0 100 network_netmask - )); DESCR("netmask of address"); DATA(insert OID = 697 ( masklen PGUID 12 f t t t 1 f 23 "869" 100 0 0 100 network_masklen - )); DESCR("netmask length"); -DATA(insert OID = 698 ( broadcast PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_broadcast - )); -DESCR("broadcast address"); +DATA(insert OID = 698 ( broadcast PGUID 12 f t t t 1 f 869 "869" 100 0 0 100 network_broadcast - )); +DESCR("broadcast address of network"); DATA(insert OID = 699 ( host PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_host - )); -DESCR("host address"); -DATA(insert OID = 683 ( network PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_network - )); -DESCR("network address"); +DESCR("show address octets only"); +DATA(insert OID = 730 ( text PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_show - )); +DESCR("show all parts of inet/cidr value"); DATA(insert OID = 1691 ( boolle PGUID 12 f t t t 2 f 16 "16 16" 100 0 0 100 boolle - )); DESCR("less-than-or-equal"); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 446c33cc420..f6a4055bb1d 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: builtins.h,v 1.140 2000/10/24 20:16:47 petere Exp $ + * $Id: builtins.h,v 1.141 2000/11/10 20:13:26 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -504,6 +504,7 @@ extern Datum network_netmask(PG_FUNCTION_ARGS); extern Datum network_masklen(PG_FUNCTION_ARGS); extern Datum network_broadcast(PG_FUNCTION_ARGS); extern Datum network_host(PG_FUNCTION_ARGS); +extern Datum network_show(PG_FUNCTION_ARGS); /* mac.c */ extern Datum macaddr_in(PG_FUNCTION_ARGS); diff --git a/src/test/regress/expected/inet.out b/src/test/regress/expected/inet.out index daa9cded133..6f86056c013 100644 --- a/src/test/regress/expected/inet.out +++ b/src/test/regress/expected/inet.out @@ -17,7 +17,7 @@ INSERT INTO INET_TBL (c, i) VALUES ('10', '11.1.2.3/8'); INSERT INTO INET_TBL (c, i) VALUES ('10', '9.1.2.3/8'); -- check that CIDR rejects invalid input: INSERT INTO INET_TBL (c, i) VALUES ('192.168.1.2/24', '192.168.1.226'); -ERROR: invalid CIDR value '192.168.1.2/24': width too small +ERROR: invalid CIDR value '192.168.1.2/24': has bits set to right of mask SELECT '' AS ten, c AS cidr, i AS inet FROM INET_TBL; ten | cidr | inet -----+--------------+------------------ @@ -34,35 +34,35 @@ SELECT '' AS ten, c AS cidr, i AS inet FROM INET_TBL; (10 rows) -- now test some support functions -SELECT '' AS ten, i AS inet, host(i) FROM INET_TBL; - ten | inet | host ------+------------------+--------------- - | 192.168.1.226/24 | 192.168.1.226 - | 192.168.1.226 | 192.168.1.226 - | 10.1.2.3/8 | 10.1.2.3 - | 10.1.2.3/8 | 10.1.2.3 - | 10.1.2.3 | 10.1.2.3 - | 10.1.2.3/24 | 10.1.2.3 - | 10.1.2.3/16 | 10.1.2.3 - | 10.1.2.3/8 | 10.1.2.3 - | 11.1.2.3/8 | 11.1.2.3 - | 9.1.2.3/8 | 9.1.2.3 +SELECT '' AS ten, i AS inet, host(i), text(i) FROM INET_TBL; + ten | inet | host | text +-----+------------------+---------------+------------------ + | 192.168.1.226/24 | 192.168.1.226 | 192.168.1.226/24 + | 192.168.1.226 | 192.168.1.226 | 192.168.1.226/32 + | 10.1.2.3/8 | 10.1.2.3 | 10.1.2.3/8 + | 10.1.2.3/8 | 10.1.2.3 | 10.1.2.3/8 + | 10.1.2.3 | 10.1.2.3 | 10.1.2.3/32 + | 10.1.2.3/24 | 10.1.2.3 | 10.1.2.3/24 + | 10.1.2.3/16 | 10.1.2.3 | 10.1.2.3/16 + | 10.1.2.3/8 | 10.1.2.3 | 10.1.2.3/8 + | 11.1.2.3/8 | 11.1.2.3 | 11.1.2.3/8 + | 9.1.2.3/8 | 9.1.2.3 | 9.1.2.3/8 (10 rows) SELECT '' AS ten, c AS cidr, broadcast(c), i AS inet, broadcast(i) FROM INET_TBL; - ten | cidr | broadcast | inet | broadcast ------+--------------+-----------------+------------------+----------------- - | 192.168.1/24 | 192.168.1.255 | 192.168.1.226/24 | 192.168.1.255 - | 192.168.1/24 | 192.168.1.255 | 192.168.1.226 | 255.255.255.255 - | 10/8 | 10.255.255.255 | 10.1.2.3/8 | 10.255.255.255 - | 10.0.0.0/32 | 255.255.255.255 | 10.1.2.3/8 | 10.255.255.255 - | 10.1.2.3/32 | 255.255.255.255 | 10.1.2.3 | 255.255.255.255 - | 10.1.2/24 | 10.1.2.255 | 10.1.2.3/24 | 10.1.2.255 - | 10.1/16 | 10.1.255.255 | 10.1.2.3/16 | 10.1.255.255 - | 10/8 | 10.255.255.255 | 10.1.2.3/8 | 10.255.255.255 - | 10/8 | 10.255.255.255 | 11.1.2.3/8 | 11.255.255.255 - | 10/8 | 10.255.255.255 | 9.1.2.3/8 | 9.255.255.255 + ten | cidr | broadcast | inet | broadcast +-----+--------------+------------------+------------------+------------------ + | 192.168.1/24 | 192.168.1.255/24 | 192.168.1.226/24 | 192.168.1.255/24 + | 192.168.1/24 | 192.168.1.255/24 | 192.168.1.226 | 255.255.255.255 + | 10/8 | 10.255.255.255/8 | 10.1.2.3/8 | 10.255.255.255/8 + | 10.0.0.0/32 | 255.255.255.255 | 10.1.2.3/8 | 10.255.255.255/8 + | 10.1.2.3/32 | 255.255.255.255 | 10.1.2.3 | 255.255.255.255 + | 10.1.2/24 | 10.1.2.255/24 | 10.1.2.3/24 | 10.1.2.255/24 + | 10.1/16 | 10.1.255.255/16 | 10.1.2.3/16 | 10.1.255.255/16 + | 10/8 | 10.255.255.255/8 | 10.1.2.3/8 | 10.255.255.255/8 + | 10/8 | 10.255.255.255/8 | 11.1.2.3/8 | 11.255.255.255/8 + | 10/8 | 10.255.255.255/8 | 9.1.2.3/8 | 9.255.255.255/8 (10 rows) SELECT '' AS ten, c AS cidr, network(c) AS "network(cidr)", diff --git a/src/test/regress/sql/inet.sql b/src/test/regress/sql/inet.sql index e225b2824f7..d91c3a0bbf0 100644 --- a/src/test/regress/sql/inet.sql +++ b/src/test/regress/sql/inet.sql @@ -23,7 +23,7 @@ SELECT '' AS ten, c AS cidr, i AS inet FROM INET_TBL; -- now test some support functions -SELECT '' AS ten, i AS inet, host(i) FROM INET_TBL; +SELECT '' AS ten, i AS inet, host(i), text(i) FROM INET_TBL; SELECT '' AS ten, c AS cidr, broadcast(c), i AS inet, broadcast(i) FROM INET_TBL; SELECT '' AS ten, c AS cidr, network(c) AS "network(cidr)",