Re: Repair plan for inet and cidr types

From: Peter Eisentraut <peter_e(at)gmx(dot)net>
To: "D'Arcy J(dot)M(dot) Cain" <darcy(at)druid(dot)net>
Cc: PostgreSQL Development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Repair plan for inet and cidr types
Date: 2000-07-07 16:16:26
Message-ID: Pine.LNX.4.21.0007070156410.4191-100000@localhost.localdomain
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

D'Arcy J.M. Cain writes:

> > Automatic casts should not lose information. How would you feel if floats
> > were automatically rounded when you store them into int fields? I think
> > this is an important principle in any type system.
>
> If it was defined well I would have no problem with it.

That is certainly not how type systems operate anywhere.

> I guess what I was really getting at was this.
>
> host OP cidr
>
> where inet would cast to host on one side and cidr on the other. What
> we have now is
>
> cidr OP cidr
>
> with both sides casting to cidr. Of course there is no such thing as a host
> type so I don't know how we would cast such a thing.

I think that while the implicit casting could sometimes be convenient,
it's also a source of confusion. Consider the statement

select '10.0.0.3'::cidr < '10.0.0.2'::inet; => f

This cannot possibly make sense on closer inspection. Firstly, it's
semantic nonsense, you cannot order a network and a host. Secondly, it's
also wrong. According to the documentation, the '10.0.0.3'::cidr should be
converted to '10/8' internally. Then one of two things could have happened
here: 1) cidr was implicitly converted to inet and '10.0.0.3' is taken to
be a host, which is completely wrong. Or 2) inet was converted to cidr.
But then we're looking at '10/8' < '10.0.0.2/32', which should be true.

See also

select '10.0.0.2'::cidr = '10.0.0.2'::inet; => t

which is wrong for similar reasons.

Then let's look at the << family of operators.

select '10.0.0.2'::cidr >> '10.0.0.2'::inet; => f

Again, there are two ways this could currently be resolved:

'10/8'::cidr >> '10.0.0.2/32'::cidr which does return true
or
'10.0.0.2'::inet >> '10.0.0.2'::inet
which doesn't make any sense.

On closer inspection, the inet << cidr case is completely misbehaving:

select '10.0.0.5/8'::inet << '10.0.0.0/16'::cidr; => f
select '10.0.0.5/24'::inet << '10.0.0.0/16'::cidr; => t

This is not what I'd expect.

Concretely, the cases
inet << cidr
cidr << cidr
are not the same:

'10.0.0.5/8'::inet << '10.0.0.0/16'::cidr
should be true

'10.0.0.5/8'::cidr << '10.0.0.0/16'::cidr
should be false, if you allow the left-side value in at all, which I
wouldn't.

What this tells me is that the cast from inet to cidr is not well-defined
in the mathematical sense, and therefore no implicit casting should be
allowed.

So the bottom line here is that these two types are, while from a related
domain, different, and the user should be the one that controls when and
how they are mixed together.

--
Peter Eisentraut Sernanders väg 10:115
peter_e(at)gmx(dot)net 75262 Uppsala
http://yi.org/peter-e/ Sweden

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Peter Eisentraut 2000-07-07 16:16:41 Re: zlib for pg_dump
Previous Message Peter Eisentraut 2000-07-07 16:15:54 Re: Re: pg_dump and LOs (another proposal)