Summary: what to do about INET/CIDR
After reviewing a number of past threads about the INET/CIDR mess,
I have concluded that we should adopt the following behavior:
1. A data value like '10.1.2.3/16' is a legal INET value (it implies
the host 10.1.2.3 in the network 10.1/16) but not a legal CIDR value.
Hence, cidr_in should reject such a value. Up to now it hasn't.
2. We do not have a datatype corresponding strictly to a host address
alone --- to store a plain address, use INET and let the mask width
default to 32. inet_out suppresses display of a "/32" netmask (whereas
cidr_out does not).
3. Given that CIDRs never have invalid bits set, we can use the same
ordering rules for both datatypes: sort by address part, then by
number of bits. This is compatible with what 7.0 did when sorting.
It is *not* quite the same as what current sources do, but I will revert
that change.
I didn't see anyone objecting to this scheme in past discussions, but
I also didn't see any clear statement that all the interested parties
had agreed to it. Last chance to complain...
regards, tom lane
* Tom Lane <tgl@sss.pgh.pa.us> [001026 18:46]:
After reviewing a number of past threads about the INET/CIDR mess,
I have concluded that we should adopt the following behavior:1. A data value like '10.1.2.3/16' is a legal INET value (it implies
the host 10.1.2.3 in the network 10.1/16) but not a legal CIDR value.
Hence, cidr_in should reject such a value. Up to now it hasn't.2. We do not have a datatype corresponding strictly to a host address
alone --- to store a plain address, use INET and let the mask width
default to 32. inet_out suppresses display of a "/32" netmask (whereas
cidr_out does not).3. Given that CIDRs never have invalid bits set, we can use the same
ordering rules for both datatypes: sort by address part, then by
number of bits. This is compatible with what 7.0 did when sorting.
It is *not* quite the same as what current sources do, but I will revert
that change.I didn't see anyone objecting to this scheme in past discussions, but
I also didn't see any clear statement that all the interested parties
had agreed to it. Last chance to complain...
I'd like to see a way to get all 4 octets of a CIDR printed out...
Also a way to get network (.0) and broadcast (all ones) for a cidr
block out of our stuff.
Larry
regards, tom lane
--
Larry Rosenman http://www.lerctr.org/~ler
Phone: +1 972-414-9812 (voice) Internet: ler@lerctr.org
US Mail: 1905 Steamboat Springs Drive, Garland, TX 75044-6749
makes sense to me
On Thu, 26 Oct 2000, Tom Lane wrote:
After reviewing a number of past threads about the INET/CIDR mess,
I have concluded that we should adopt the following behavior:1. A data value like '10.1.2.3/16' is a legal INET value (it implies
the host 10.1.2.3 in the network 10.1/16) but not a legal CIDR value.
Hence, cidr_in should reject such a value. Up to now it hasn't.2. We do not have a datatype corresponding strictly to a host address
alone --- to store a plain address, use INET and let the mask width
default to 32. inet_out suppresses display of a "/32" netmask (whereas
cidr_out does not).3. Given that CIDRs never have invalid bits set, we can use the same
ordering rules for both datatypes: sort by address part, then by
number of bits. This is compatible with what 7.0 did when sorting.
It is *not* quite the same as what current sources do, but I will revert
that change.I didn't see anyone objecting to this scheme in past discussions, but
I also didn't see any clear statement that all the interested parties
had agreed to it. Last chance to complain...regards, tom lane
Marc G. Fournier ICQ#7615664 IRC Nick: Scrappy
Systems Administrator @ hub.org
primary: scrappy@hub.org secondary: scrappy@{freebsd|postgresql}.org
Larry Rosenman <ler@lerctr.org> writes:
Also a way to get network (.0) and broadcast (all ones) for a cidr
block out of our stuff.
network() and broadcast() have been there all along ...
regards, tom lane
* Tom Lane <tgl@sss.pgh.pa.us> [001027 09:49]:
Larry Rosenman <ler@lerctr.org> writes:
Also a way to get network (.0) and broadcast (all ones) for a cidr
block out of our stuff.network() and broadcast() have been there all along ...
but don't work on CIDR types.....
LER
regards, tom lane
--
Larry Rosenman http://www.lerctr.org/~ler
Phone: +1 972-414-9812 (voice) Internet: ler@lerctr.org
US Mail: 1905 Steamboat Springs Drive, Garland, TX 75044-6749
* Larry Rosenman <ler@lerctr.org> [001027 09:51]:
* Tom Lane <tgl@sss.pgh.pa.us> [001027 09:49]:
Larry Rosenman <ler@lerctr.org> writes:
Also a way to get network (.0) and broadcast (all ones) for a cidr
block out of our stuff.network() and broadcast() have been there all along ...
but don't work on CIDR types.....
And I get to be wrong.
Sorry about that.
But, it would still be nice if we can force all 4 octets to be printed
for the network funcs..
LER
LER
regards, tom lane
--
Larry Rosenman http://www.lerctr.org/~ler
Phone: +1 972-414-9812 (voice) Internet: ler@lerctr.org
US Mail: 1905 Steamboat Springs Drive, Garland, TX 75044-6749
--
Larry Rosenman http://www.lerctr.org/~ler
Phone: +1 972-414-9812 (voice) Internet: ler@lerctr.org
US Mail: 1905 Steamboat Springs Drive, Garland, TX 75044-6749
* Tom Lane <tgl@sss.pgh.pa.us> [001027 09:49]:
Larry Rosenman <ler@lerctr.org> writes:
Also a way to get network (.0) and broadcast (all ones) for a cidr
block out of our stuff.network() and broadcast() have been there all along ...
OK, what I really meant was a way to coerce a CIDR entity to INET so
that host() can work with a CIDR type to print all 4 octets.
Does this help with what I want?
Currently you can't coerce a CIDR type to INET.
regards, tom lane
--
Larry Rosenman http://www.lerctr.org/~ler
Phone: +1 972-414-9812 (voice) Internet: ler@lerctr.org
US Mail: 1905 Steamboat Springs Drive, Garland, TX 75044-6749
* Larry Rosenman <ler@lerctr.org> [001027 11:08]:
* Tom Lane <tgl@sss.pgh.pa.us> [001027 09:49]:
Larry Rosenman <ler@lerctr.org> writes:
Also a way to get network (.0) and broadcast (all ones) for a cidr
block out of our stuff.network() and broadcast() have been there all along ...
OK, what I really meant was a way to coerce a CIDR entity to INET so
that host() can work with a CIDR type to print all 4 octets.Does this help with what I want?
Currently you can't coerce a CIDR type to INET.
For example, I feel the following should work:
ler=# \d ler_test
Table "ler_test"
Attribute | Type | Modifier
-----------+------+----------
net | cidr |
host | inet |
ler=# select * from ler_test;
net | host
---------------+------------------
207.158.72/24 | 207.158.72.11/24
(1 row)
ler=# select host(net::inet) from ler_test;
ERROR: CIDR type has no host part
ERROR: CIDR type has no host part
ler=#
regards, tom lane
--
Larry Rosenman http://www.lerctr.org/~ler
Phone: +1 972-414-9812 (voice) Internet: ler@lerctr.org
US Mail: 1905 Steamboat Springs Drive, Garland, TX 75044-6749
--
Larry Rosenman http://www.lerctr.org/~ler
Phone: +1 972-414-9812 (voice) Internet: ler@lerctr.org
US Mail: 1905 Steamboat Springs Drive, Garland, TX 75044-6749
Tom Lane writes:
1. A data value like '10.1.2.3/16' is a legal INET value (it implies
the host 10.1.2.3 in the network 10.1/16) but not a legal CIDR value.
Hence, cidr_in should reject such a value. Up to now it hasn't.
Nod.
2. We do not have a datatype corresponding strictly to a host address
alone --- to store a plain address, use INET and let the mask width
default to 32. inet_out suppresses display of a "/32" netmask (whereas
cidr_out does not).
Inet is supposed to be host address, with optional network specification.
I also have in my notes (some might have been fixed since):
* inet output is broken => 127.0.0.1/8
* no cast function to "text" available (what about host()?)
* equality/distinctness is broken in certain cases => select
'10.0.0.1/27'::inet='10.0.0.2/27'::inet; returns true
* operator commutators and negators are incorrect
* ouput functions apparently null-terminate their result => select
host('10.0.0.1')='10.0.0.1'; returns false
* comparing inet and cidr is not well defined
* should '127.0.0.1/24'::cidr fail?
--
Peter Eisentraut peter_e@gmx.net http://yi.org/peter-e/
Peter Eisentraut <peter_e@gmx.net> writes:
Inet is supposed to be host address, with optional network specification.
Agreed. As such, it probably should always display all 4 octets
regardless of the maskwidth. It doesn't do that at the moment:
regression=# select '127.0.0.1/8'::inet;
?column?
----------
127.0/8
(1 row)
This is clearly bad. I will change it to produce '127.0.0.1/8',
unless someone has a better idea.
I also have in my notes (some might have been fixed since):
* inet output is broken => 127.0.0.1/8
See above.
* no cast function to "text" available
I don't see much point in solving that issue on a one-datatype-at-a-time
basis. Sooner or later we should fix things so that the datatype I/O
conversion functions can be invoked safely in expressions.
* equality/distinctness is broken in certain cases => select
'10.0.0.1/27'::inet='10.0.0.2/27'::inet; returns true
This is now fixed.
* operator commutators and negators are incorrect
Fixed.
* ouput functions apparently null-terminate their result => select
host('10.0.0.1')='10.0.0.1'; returns false
Not sure what that has to do with output functions, but I get 'true'
now.
* comparing inet and cidr is not well defined
Perhaps not. There was a whole lot of argument about that point,
and it didn't seem to me that we came to any real agreement.
* should '127.0.0.1/24'::cidr fail?
Looks like we've resolved that as "yes".
There are still unresolved issues about whether inet and cidr should be
considered binary-equivalent, what network_sup/sub mean when comparing
inet and cidr, whether we are missing any important functions, etc.
I'm not hoping to get these resolved for 7.1, considering we are nearly
at beta stage and don't even have a complete proposal for what to do.
I'm satisfied for the moment with having eliminated the failure to
compare all bits of the values, which led to bogus equality results
and consequent malfunction of indexes.
regards, tom lane
On Fri, 27 Oct 2000, Larry Rosenman wrote:
ler=# select * from ler_test;
net | host
---------------+------------------
207.158.72/24 | 207.158.72.11/24
(1 row)ler=# select host(net::inet) from ler_test;
ERROR: CIDR type has no host part
ERROR: CIDR type has no host part
I agree. There should be a coercion function, but it should never be
automatic...But since now there aren't any automatic coercions, that's not
a problem ;)
Also, I agree with Larry that cidr _must_ be printed with 4 octets in
them, whether they are 0 or not. (i.e. it should print 207.158.72.0/24)
This is the standard way of specifying addresses in all network equipment.
RFC specifies that, just the library that we use doesn't (yes, it is from
Vixie, but it doesn't make it RFC-compliant)
I'll submit patches in a week or so, when I start straightening out my
network equipment tables...;)
-alex
* Alex Pilosov <alex@pilosoft.com> [001027 14:43]:
On Fri, 27 Oct 2000, Larry Rosenman wrote:
ler=# select * from ler_test;
net | host
---------------+------------------
207.158.72/24 | 207.158.72.11/24
(1 row)ler=# select host(net::inet) from ler_test;
ERROR: CIDR type has no host part
ERROR: CIDR type has no host partI agree. There should be a coercion function, but it should never be
automatic...But since now there aren't any automatic coercions, that's not
a problem ;)Also, I agree with Larry that cidr _must_ be printed with 4 octets in
them, whether they are 0 or not. (i.e. it should print 207.158.72.0/24)This is the standard way of specifying addresses in all network equipment.
RFC specifies that, just the library that we use doesn't (yes, it is from
Vixie, but it doesn't make it RFC-compliant)
and network(cidr) should print ONLY the octets, not the mask...
LER
I'll submit patches in a week or so, when I start straightening out my
network equipment tables...;)-alex
--
Larry Rosenman http://www.lerctr.org/~ler
Phone: +1 972-414-9812 (voice) Internet: ler@lerctr.org
US Mail: 1905 Steamboat Springs Drive, Garland, TX 75044-6749
On Fri, 27 Oct 2000, Larry Rosenman wrote:
and network(cidr) should print ONLY the octets, not the mask...
Agreed. There's a function to get the mask size, and the network should
just return the network. Otherwise, it is impossible to use.
-alex
Larry Rosenman <ler@lerctr.org> writes:
OK, what I really meant was a way to coerce a CIDR entity to INET so
that host() can work with a CIDR type to print all 4 octets.
Hm. I don't see any really good reason why host() rejects CIDR input
in the first place. What's wrong with producing the host address
that corresponds to extending the CIDR network address with zeroes?
Currently you can't coerce a CIDR type to INET.
Well you can, but it doesn't *do* anything. One of the peculiarities
of these two types is that the cidr-vs-inet flag is actually stored
in the data value. The type-system differentiation between CIDR and
INET is a complete no-op for everything except initial entry of a value
(ie, conversion of a text string to CIDR or INET); all the operators
that care (which is darn few ... in fact it looks like host() is the
only one!) look right at the value to see which type they've been given.
So applying a type coercion may make the type system happy, but it
doesn't do a darn thing to the bits, and thus not to the behavior of
subsequent operators either. I have not yet figured out if that's a
good thing or a bad thing ...
regards, tom lane
Alex Pilosov <alex@pilosoft.com> writes:
Also, I agree with Larry that cidr _must_ be printed with 4 octets in
them, whether they are 0 or not. (i.e. it should print 207.158.72.0/24)
This is the standard way of specifying addresses in all network equipment.
RFC specifies that, just the library that we use doesn't (yes, it is from
Vixie, but it doesn't make it RFC-compliant)
Somehow, I am more inclined to believe Vixie's opinion on this than
either yours or Larry's ;-)
If you think there is an RFC that demands the above behavior and not
what Vixie recommended to us, let's see chapter and verse.
FWIW, the direction we seem to be converging in is that INET will always
print all four octets. Maybe the answer for you is to use INET, rather
than to try to persuade us that you understand CIDR notation better than
Vixie does...
regards, tom lane
* Tom Lane <tgl@sss.pgh.pa.us> [001027 15:14]:
Alex Pilosov <alex@pilosoft.com> writes:
Also, I agree with Larry that cidr _must_ be printed with 4 octets in
them, whether they are 0 or not. (i.e. it should print 207.158.72.0/24)This is the standard way of specifying addresses in all network equipment.
RFC specifies that, just the library that we use doesn't (yes, it is from
Vixie, but it doesn't make it RFC-compliant)Somehow, I am more inclined to believe Vixie's opinion on this than
either yours or Larry's ;-)If you think there is an RFC that demands the above behavior and not
what Vixie recommended to us, let's see chapter and verse.FWIW, the direction we seem to be converging in is that INET will always
print all four octets. Maybe the answer for you is to use INET, rather
than to try to persuade us that you understand CIDR notation better than
Vixie does...
What I need is a way to convince PG to print all 4 octets from a CIDR
type. I *WANT* the safety of the CIDR type for blocks of addresses,
but need to be able to print all 4 octets out for NON-TECHIES.
LER
regards, tom lane
--
Larry Rosenman http://www.lerctr.org/~ler
Phone: +1 972-414-9812 (voice) Internet: ler@lerctr.org
US Mail: 1905 Steamboat Springs Drive, Garland, TX 75044-6749
On Fri, 27 Oct 2000, Tom Lane wrote:
Larry Rosenman <ler@lerctr.org> writes:
OK, what I really meant was a way to coerce a CIDR entity to INET so
that host() can work with a CIDR type to print all 4 octets.Hm. I don't see any really good reason why host() rejects CIDR input
in the first place. What's wrong with producing the host address
that corresponds to extending the CIDR network address with zeroes?
_maybe_ cuz this is an invalid address. (an address cannot have all-zeros
or all-ones host part). On other hand, postgres doesn't enforce that in
inet_in, so its inconsistent to enforce it there...
Currently you can't coerce a CIDR type to INET.
Well you can, but it doesn't *do* anything. One of the peculiarities
of these two types is that the cidr-vs-inet flag is actually stored
in the data value. The type-system differentiation between CIDR and
INET is a complete no-op for everything except initial entry of a value
(ie, conversion of a text string to CIDR or INET); all the operators
that care (which is darn few ... in fact it looks like host() is the
only one!) look right at the value to see which type they've been given.
So applying a type coercion may make the type system happy, but it
doesn't do a darn thing to the bits, and thus not to the behavior of
subsequent operators either. I have not yet figured out if that's a
good thing or a bad thing ...
Probably cidr_inet should make a copy instead of just "blessing" the
original value?
-alex
BTW, does it strike anyone else as peculiar that the host(),
broadcast(), network(), and netmask() functions yield results
of type text, rather than type inet? Seems like it'd be considerably
more useful if they returned values of type inet with masklen = 32
(except for network(), which would keep the original masklen while
coercing bits to its right to 0).
Given the current proposal that inet_out should always display all 4
octets, and the existing fact that inet_out suppresses display of
a /32 netmask, the textual display of SELECT host(...) etc would
remain the same as it is now. But AFAICS you could do more with
an inet-type result value, like say compare it to other inet or cidr
values ...
Comments? Why was it done this way, anyway?
regards, tom lane
* Tom Lane <tgl@sss.pgh.pa.us> [001027 17:04]:
BTW, does it strike anyone else as peculiar that the host(),
broadcast(), network(), and netmask() functions yield results
of type text, rather than type inet? Seems like it'd be considerably
more useful if they returned values of type inet with masklen = 32
(except for network(), which would keep the original masklen while
coercing bits to its right to 0).Given the current proposal that inet_out should always display all 4
octets, and the existing fact that inet_out suppresses display of
a /32 netmask, the textual display of SELECT host(...) etc would
remain the same as it is now. But AFAICS you could do more with
an inet-type result value, like say compare it to other inet or cidr
values ...Comments? Why was it done this way, anyway?
It doesn't bother me, as long as there is someway for me to get from a
CIDR type to 4 octets output with no mask indicated, and print the
broadcast and netmask and bits out separately from ONE column in the
table.
I.E. for select
network('207.158.72.0/24'),broadcast('207.158.72.0/24'),netmask('207.158.72.0/24')
I get
207.158.72.0 207.158.72.255 255.255.255.0
as output.
Aside from that, I'm not picky.
Larry
regards, tom lane
--
Larry Rosenman http://www.lerctr.org/~ler
Phone: +1 972-414-9812 (voice) Internet: ler@lerctr.org
US Mail: 1905 Steamboat Springs Drive, Garland, TX 75044-6749
Larry Rosenman <ler@lerctr.org> writes:
I.E. for select network('207.158.72.0/24')
I get
207.158.72.0
To my mind that should be done with host(), not network(). If you strip
the masklen information then what you have is no longer a network
specification, so expecting a function named network() to behave that
way strikes me as bizarre.
regards, tom lane