New cast between inet/cidr and bytea

Started by Zoltan Boszormenyiover 18 years ago8 messages
#1Zoltan Boszormenyi
zb@cybertec.at

Hi,

we at Cybertec have developed cast functions in C between
inet/cidr <-> bytea for a client and we would like to submit it.

This is how it works:
- IPv4 inet/cidr value will return 4 bytes if the netmask covers all 32
bits.
It returns 5 bytes if the netmask is shorter than 32 bits.
- Similarly for IPv6, 12[+1] bytes is returned.
- 4, 5, 12 or 13 bytes long bytea values are converted
to an inet/cidr value, the 5th or 13th byte is range-checked
to be a valid netmask value.

What are the requirements for it to be accepted
as a core cast function or as a contrib module?

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Geschwinde & Sch�nig GmbH
http://www.postgresql.at/

#2Bruce Momjian
bruce@momjian.us
In reply to: Zoltan Boszormenyi (#1)
Re: New cast between inet/cidr and bytea

Zoltan Boszormenyi wrote:

Hi,

we at Cybertec have developed cast functions in C between
inet/cidr <-> bytea for a client and we would like to submit it.

This is how it works:
- IPv4 inet/cidr value will return 4 bytes if the netmask covers all 32
bits.
It returns 5 bytes if the netmask is shorter than 32 bits.
- Similarly for IPv6, 12[+1] bytes is returned.
- 4, 5, 12 or 13 bytes long bytea values are converted
to an inet/cidr value, the 5th or 13th byte is range-checked
to be a valid netmask value.

What are the requirements for it to be accepted
as a core cast function or as a contrib module?

You discuss it on the hackers list. Have you read the developer's FAQ?
What is the use case for such a cast?

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://www.enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Zoltan Boszormenyi (#1)
Re: New cast between inet/cidr and bytea

Zoltan Boszormenyi <zb@cybertec.at> writes:

we at Cybertec have developed cast functions in C between
inet/cidr <-> bytea for a client and we would like to submit it.

Why is this a good idea? Exposing the internal representation of a
datatype is usually bad. What will you do when we add support for
scoped IPv6 addressing, to take one obvious example?

regards, tom lane

#4Zoltan Boszormenyi
zb@cybertec.at
In reply to: Bruce Momjian (#2)
Re: New cast between inet/cidr and bytea

Bruce Momjian �rta:

Zoltan Boszormenyi wrote:

Hi,

we at Cybertec have developed cast functions in C between
inet/cidr <-> bytea for a client and we would like to submit it.

This is how it works:
- IPv4 inet/cidr value will return 4 bytes if the netmask covers all 32
bits.
It returns 5 bytes if the netmask is shorter than 32 bits.
- Similarly for IPv6, 12[+1] bytes is returned.
- 4, 5, 12 or 13 bytes long bytea values are converted
to an inet/cidr value, the 5th or 13th byte is range-checked
to be a valid netmask value.

What are the requirements for it to be accepted
as a core cast function or as a contrib module?

You discuss it on the hackers list.

That's what I am trying to.

Have you read the developer's FAQ?

Not yet in its entireness.

What is the use case for such a cast?

e.g.:
# select '192.168.0.1'::inet::bytea;
bytea
------------------
\300\250\000\001
(1 row)

# select '192.168.0.0/24'::inet::bytea;
bytea
----------------------
\300\250\000\000\030
(1 row)

# select decode('\\300\\250\\000\\001', 'escape')::inet;
decode
-------------
192.168.0.1
(1 row)

# select decode('\\300\\250\\000\\000\\030', 'escape')::inet;
decode
----------------
192.168.0.2/24
(1 row)

Similarly for IPv6 addresses.
The application doesn't want to parse the textual IP address
when all the parsing and checking intelligence is already there
in the inet/cidr type checks. The reverse when you pass in bytes
is only a logical extension.

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Geschwinde & Sch�nig GmbH
http://www.postgresql.at/

#5Zoltan Boszormenyi
zb@cybertec.at
In reply to: Tom Lane (#3)
Re: New cast between inet/cidr and bytea

Tom Lane �rta:

Zoltan Boszormenyi <zb@cybertec.at> writes:

we at Cybertec have developed cast functions in C between
inet/cidr <-> bytea for a client and we would like to submit it.

Why is this a good idea? Exposing the internal representation of a
datatype is usually bad.

I didn't expose the inet/cidr internals.

An IP address is an IP address whether you represent it
textually or as a series of bytes. Since the rise of the CIDR
type netmask usage, there is not much support for netmasks
with holes in the middle of the bits, like 255.255.192.128
on the 'net. And there is no support for this kind of netmask
in PostgreSQL either. So, to don't lose data (the netmask _is_
an important data) we decided to go this way.
A single IP address without the netmask means the netmask
covers the whole 32 or 128 bits in real life, too.

What will you do when we add support for
scoped IPv6 addressing, to take one obvious example?

It can still be represented as a series of bytes, won't it?
Just as in an actual IP packet header.
When the support arrives, I can fix the cast, too, if needed.

regards, tom lane

Best regards

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Geschwinde & Sch�nig GmbH
http://www.postgresql.at/

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Zoltan Boszormenyi (#4)
Re: New cast between inet/cidr and bytea

Zoltan Boszormenyi <zb@cybertec.at> writes:

Bruce Momjian �rta:

What is the use case for such a cast?

The application doesn't want to parse the textual IP address
when all the parsing and checking intelligence is already there
in the inet/cidr type checks.

This presumes exactly the assumption we are questioning, namely that
there's a universal binary representation for these things. There might
be such for bare IP addresses (ignoring endianness) but the argument
doesn't scale to CIDR. You've also failed to make the case that this
application designer has made a sane judgment about whether avoiding
parsing is a good tradeoff here.

Also: to the extent that the application is willing to deal with a
Postgres-specific inet/cidr representation (which, in the end, is
what this would be) it can do that *today* using binary output format.
So I'm still not seeing an argument for exposing a cast to bytea.

regards, tom lane

#7Zoltan Boszormenyi
zb@cybertec.at
In reply to: Tom Lane (#6)
Re: New cast between inet/cidr and bytea

Tom Lane �rta:

Zoltan Boszormenyi <zb@cybertec.at> writes:

Bruce Momjian �rta:

What is the use case for such a cast?

The application doesn't want to parse the textual IP address
when all the parsing and checking intelligence is already there
in the inet/cidr type checks.

This presumes exactly the assumption we are questioning, namely that
there's a universal binary representation for these things.

But there is: network order.

There might
be such for bare IP addresses (ignoring endianness) but the argument
doesn't scale to CIDR.

Would you enlighten me why not?

You've also failed to make the case that this
application designer has made a sane judgment about whether avoiding
parsing is a good tradeoff here.

So, reinventing the wheel is always the way to go?
Even when the app is actually storing those IP addresses
with the type and features PostgreSQL provides?

Also: to the extent that the application is willing to deal with a
Postgres-specific inet/cidr representation (which, in the end, is
what this would be) it can do that *today* using binary output format.
So I'm still not seeing an argument for exposing a cast to bytea.

regards, tom lane

But the binary output of inet/cidr needs another round of parsing
which requires using internal server headers.

Would you like a 4/8/16/32 byte output using IP only
or IP + fully represented netmask better?

Best regards,

--
----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Geschwinde & Sch�nig GmbH
http://www.postgresql.at/

#8Andrew Dunstan
andrew@dunslane.net
In reply to: Zoltan Boszormenyi (#7)
Re: New cast between inet/cidr and bytea

Zoltan Boszormenyi wrote:

Also: to the extent that the application is willing to deal with a
Postgres-specific inet/cidr representation (which, in the end, is
what this would be) it can do that *today* using binary output format.
So I'm still not seeing an argument for exposing a cast to bytea.

regards, tom lane

But the binary output of inet/cidr needs another round of parsing
which requires using internal server headers.

Would you like a 4/8/16/32 byte output using IP only
or IP + fully represented netmask better?

How are you getting the bytea output? If as text then you're going to be
doing parsing anyway; if as binary, why not just get the binary of the
base type directly? It is not clear to me why we should provide this
facility just for inet/cidr - if it is justified in that case it should
be required for all types.

cheers

andrew