Re: Range Types, constructors, and the type system

From: Jeff Davis <pgsql(at)j-davis(dot)com>
To: Florian Pflug <fgp(at)phlo(dot)org>
Cc: Robert Haas <robertmhaas(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: Range Types, constructors, and the type system
Date: 2011-06-29 15:41:49
Message-ID: 1309362109.10707.129.camel@jdavis
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Wed, 2011-06-29 at 13:35 +0200, Florian Pflug wrote:
> What I'm concerned about is how elegantly we'd be able to tie up all
> the loose ends. What'd be the result of
> select range(1,2)
> for example? Or
> create table (r rangeinput)
> for that matter.
>
> I think we'd want to forbid both of these, and more or less every other
> use except
> range(1,2)::<some range type>
> but that seems to require special-casing RANGEINPUT in a lot of places.

We could make it a pseudo-type and make the IO functions generate
exceptions. That should prevent most mistakes and effectively hide it
from the user (sure, they could probably use it somewhere if they really
want to, but I wouldn't be worried about breaking backwards
compatibility with undocumented usage like that). There are plenty of
types that are hidden from users in one way or another -- trigger, void,
internal, fdw_handler, etc., so I don't see this as special-casing at
all.

That might make it slightly harder to document, but I think it can be
done. All we have to do is document the range constructors saying "you
must cast the result to a valid range type; trying to use the result of
these functions directly raises an exception". In fact, I think I'll
take back the "hard to document" claim from before: it will be pretty
easy to document, and if someone gets it wrong, we can throw a helpful
error and hint.

Robert didn't really seem to like the idea of throwing an error though
-- Robert, can you expand on your reasoning here?

I tend to lean toward throwing an error as well, but I don't really have
much of an opinion.

> If we don't restrict RANGEINPUT that way, I think we ought to provide
> at least a basic set of operators and functions for it - e.g.
> input, output, lower(), upper(), ...
>
> *Pondering this*
>
> But we can't do that easily, since RANGEINPUT would actually be a kind of
> VARIANT type (i.e. can hold values of arbitrary types). That's something
> that our type system doesn't really support. We do have RECORD, which is
> similar in a way, but its implementation is about as intrusive as it
> gets...

I don't want to go down the road of making this a fully supported type.
I don't see any use case for it at all, and I think it's a bad idea to
design something with no idea how people might want to use it.

> Is it? That's actually too bad, since I kinda like it. But anyway,
> if that's a concern it could also be
> range_bounds(ARRAY[1,2]::int8range, '(]')

What type would the result of that be? What value?

> > * It still suffers similar problems as casting back and forth to text:
> > ANYARRAY is too general, doesn't really take advantage of the type
> > system, and not a great fit anyway.
>
> I believe it alleviates the gravest problems of casting back and forth
> to text. It doesn't have quoting issues and it doesn't potentially lose
> information.

I think it still circumvents the type system to a degree. We're just
putting stuff in an array with no intention of really using it that way.

> In any case, I wouldn't expect this to *stay* the only way to construct
> a range forever. But I does have it's virtues for a first incarnation of
> range type, I believe, mostly because it's completely unintrusive and
> won't cause any backwards-compatbility headaches in the future

I'm not sure that your overloading of arrays is completely immune from
backwards-compatibility problems, should we decide to change it later.

But regardless, we have quite a lot of time to make a decision before
9.2 is released; so let's do it once and do it right.

> I fear that the intermediate type will turn out to be quite intrusive,
> at least if we try to handle all the corner cases and loose ends. And if
> we don't, I'm concerned that we're painting ourselves into a corner here...

Can you expand on some of the corner-cases and loose ends you're
concerned about? Does marking it as a pseudotype and making the IO
functions throw exceptions handle them?

Regards,
Jeff Davis

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Jeff Davis 2011-06-29 15:42:48 Re: Range Types, constructors, and the type system
Previous Message Andrew Dunstan 2011-06-29 15:21:12 default privileges wording