Thread: Re: Re: postgres - development of inet/cidr
Jakub Bartosz Bielecki wrote: > > "select '10.0.0.1/27'::cidr << '10.0.0.2/27'::inet;" ERROR > > Currently it's not an error... There is no way (and no reason) to > distinguish between INET and CIDR. Yes, there is. CIDR is defined as the network 10.0.0.1 & /27, while INET is defined as host 10.0.0.1 within network 10.0.0.1 & /27. You can do almost every network and host calculation both in CIDR and INET, but you need implicit knowledge for it. Two columns are necessary to define a host and its network in CIDR, and a network cannot be specified without a host using INET - except for ugly in-band hacks like using 10.0.0.0/27 for the network which would prevent you from specifying a base address. > Above example is exactly > equivalent to: > select '10.0.0.0/27'::inet << '10.0.0.2/27'::inet; -- FALSE Nope. If the right hand side is automatically propagated to a network, it is true. If not, the above IMHO should better raise an error, as a host can never contain a host. > but: > select '10.0.0.0/27'::inet <<= '10.0.0.2/27'::inet; -- TRUE Well, you might argue that a host could contain-or-equal a host, but as only the equals part could ever be true, that is a redundant operator without any meaning beyond equals, and accordingly it should not be valid for that case. > > But we need to reach an agreement on the proper > > behaviour on greater/smaller comparisons. Should: > > > > "select '10.0.0.1/27'::inet > '10.0.0.2/27'::cidr;" > > > > be true or false? Casting to cidr prior to comparison would make it > > equivalent to "select '10.0.0.0/27'::cidr > '10.0.0.0/27'::cidr;", which > > is false, both networks being equal. > > It should be (and is!) true... Since second argument is > really '10.0.0.0/27'. Yes, but that does not make it any truer. CIDR 10.0.0.0/27 is definitively not 10.0.0.0 but [10.0.0.0 .. 10.0.0.31]. A CIDR address is never synonymous to a plain host address. You'll see the problem if you try to calculate the inverse - any zeroed CIDR address in the entire range from 10.0/8 to 10.0.0.0/32 would mask to 10.0.0.0. Accordingly, there is no simple answer to a "host bigger/smaller than network" question. For many applications, it may be useful to define that to mean that the host is smaller than the network bottom address respectively bigger than the top address, but any of the other possible views would be perfectly legal as well. Sevo -- sevo@ip23.net
On Wed, 5 Jul 2000, Sevo Stille wrote: > > > > "select '10.0.0.1/27'::cidr << '10.0.0.2/27'::inet;" ERROR > > > > Currently it's not an error... There is no way (and no reason) to > > distinguish between INET and CIDR. > > Yes, there is. CIDR is defined as the network 10.0.0.1 & /27, while INET > is defined as host 10.0.0.1 within network 10.0.0.1 & /27. You can do > almost every network and host calculation both in CIDR and INET, but > you need implicit knowledge for it. I was talking about *current* implementation of INET/CIDR (which IMHO is very ill). There is INET for users that want simply to store IP's and don't care about all the technical jargon. There is CIDR for advanced users who want to store network data. Currently these 2 types are handled by 1 implementation, moreover despite INET netmask and CIDR prefix-length are something completely different, both are stored in the same field of inet structure (yuck). At the moment it works fine. But that's only a hack. I guess the purpose was to prevent duplication of code... Blah... > > select '10.0.0.0/27'::inet << '10.0.0.2/27'::inet; -- FALSE > > Nope. If the right hand side is automatically propagated to a network, > it is true. If not, the above IMHO should better raise an error, as a > host can never contain a host. > > > select '10.0.0.0/27'::inet <<= '10.0.0.2/27'::inet; -- TRUE > > Well, you might argue that a host could contain-or-equal a host, but as > only the equals part could ever be true, that is a redundant operator > without any meaning beyond equals, and accordingly it should not be > valid for that case. > > > > "select '10.0.0.1/27'::inet > '10.0.0.2/27'::cidr;" > > It should be (and is!) true... Since second argument is > > really '10.0.0.0/27'. > > Yes, but that does not make it any truer. CIDR 10.0.0.0/27 is > definitively not 10.0.0.0 but [10.0.0.0 .. 10.0.0.31]. Same as above... You are perfectly right. Everything works until user starts messing with _both_ INET and CIDR at the same time. The possible solution is: - inhibit cidr-to-inet cast (and maybe also inet-to-cidr, because it would throw away netmask), - CIDR operators: > = < << >> - INET operators: > = < (and why not & | if it would be useful???) functions: cidr network(inet); // '10.0.0.0/27' text host(inet); // '10.0.0.1' int masklen(inet); // 27 - write an usable manual. Comments? I *might* work on it if I find some spare time. But it's unlikely :(