Thread: Proposal: stand-alone composite types

Proposal: stand-alone composite types

From
Joe Conway
Date:
We've discussed at least a couple of times before that it would be nice
to be able to create stand-alone composite types. Tom mentioned that
ideally this would be done as part of a refactoring of system tables so
that attributes belonged to pg_type, instead of belonging to pg_class.
But it wasn't clear that this approach was worth the effort,
particularly due to backwards compatability breakage.

Recently Tom mentioned another alternative (see:
http://archives.postgresql.org/pgsql-hackers/2002-07/msg00788.php for
more). The basic idea was to "create a new 'dummy' relkind for a
pg_class entry that isn't a real relation, but merely a front for a
composite type in pg_type."

Based on Tom's suggestion, I propose the following:

1. Define a new pg_class relkind as 'c' for composite. Currently relkind   can be: 'S' sequence, 'i' index, 'r'
relation,'s' special, 't'   toast, and 'v' view.
 

2. Borrow the needed parts from CREATE and DROP VIEW to implement a new   form of the CREATE TYPE command, with syntax
somethinglike:
 
   CREATE TYPE typename AS ( column_name data_type [, ... ] )
   This would add a pg_class entry of relkind 'c', and add a new   pg_type entry of typtype 'c', with typrelid pointing
tothe   pg_class entry. Essentially, this new stand-alone composite type   looks a lot like a view without any rules.
 

3. Modify CREATE FUNCTION to allow the implicit creation of a dependent   composite type, e.g.:
   CREATE [ OR REPLACE ] FUNCTION name ( [ argtype [, ...] ] )   RETURNS [setof] { data_type | (column_name data_type
[,... ]) }...
 
   This would automatically create a stand-alone composite type with a   system generated name for the function. Thanks
tothe new dependency   tracking, the implicit composite type would go away if the function   is dropped.
 


Comments, objections, or thoughts?

Thanks,

Joe




Re: Proposal: stand-alone composite types

From
"Christopher Kings-Lynne"
Date:
> 3. Modify CREATE FUNCTION to allow the implicit creation of a dependent
>     composite type, e.g.:
>
>     CREATE [ OR REPLACE ] FUNCTION name ( [ argtype [, ...] ] )
>     RETURNS [setof] { data_type | (column_name data_type [, ... ]) }...
>
>     This would automatically create a stand-alone composite type with a
>     system generated name for the function. Thanks to the new dependency
>     tracking, the implicit composite type would go away if the function
>     is dropped.
>
>
> Comments, objections, or thoughts?

I'm just licking my lips in anticipation of converting my entire website to
SRFs ;)

Chris



Re: Proposal: stand-alone composite types

From
Joe Conway
Date:
Joe Conway wrote:
> 2. Borrow the needed parts from CREATE and DROP VIEW to implement a new
>    form of the CREATE TYPE command, with syntax something like:
> 
>    CREATE TYPE typename AS ( column_name data_type [, ... ] )
> 
>    This would add a pg_class entry of relkind 'c', and add a new
>    pg_type entry of typtype 'c', with typrelid pointing to the
>    pg_class entry. Essentially, this new stand-alone composite type
>    looks a lot like a view without any rules.

I'm working on stand-alone composite types and running into a 
reduce/reduce problem with the grammer. Any suggestions would be 
appreciated. Here's what I have:

DefineStmt:  CREATE AGGREGATE func_name definition  {    . . .  }  | CREATE TYPE_P qualified_name AS    '('
TableFuncElementList')'  {    CompositeTypeStmt *n = makeNode(CompositeTypeStmt);    n->typevar = $3;    n->coldeflist
=$6;    $$ = (Node *)n;  }
 

Thanks,

Joe



Re: Proposal: stand-alone composite types

From
Tom Lane
Date:
Joe Conway <mail@joeconway.com> writes:
> I'm working on stand-alone composite types and running into a 
> reduce/reduce problem with the grammer. Any suggestions would be 
> appreciated. Here's what I have:

> DefineStmt:
>    | CREATE TYPE_P qualified_name AS
>      '(' TableFuncElementList ')'

Use any_name, not qualified_name.  As-is, you're forcing the parser
to try to distinguish the two forms of CREATE TYPE before it can
see anything that would tell the difference.

In hindsight I think it was a mistake to set up RangeVar/qualified_name
as a distinct reduction path from non-relation qualified names ---
we'd have been better off using a single production and a uniform
intermediate representation.  But I haven't had time to investigate
simplifying the grammar that way.
        regards, tom lane


Re: Proposal: stand-alone composite types

From
Peter Eisentraut
Date:
Joe Conway writes:

> 3. Modify CREATE FUNCTION to allow the implicit creation of a dependent
>     composite type, e.g.:

Forgive this blunt question, but:  Why?

Of course I can see the answer, it's convenient, but wouldn't the system
be more consistent overall if all functions and types are declared
explicitly?

-- 
Peter Eisentraut   peter_e@gmx.net



Re: Proposal: stand-alone composite types

From
Joe Conway
Date:
Peter Eisentraut wrote:
> Joe Conway writes:
>>3. Modify CREATE FUNCTION to allow the implicit creation of a dependent
>>    composite type, e.g.:
> 
> Forgive this blunt question, but:  Why?

Now's a *great* time for a blunt question because I haven't started 
actively working on this yet. Much better than after I'm done.  ;-)


> Of course I can see the answer, it's convenient, but wouldn't the system
> be more consistent overall if all functions and types are declared
> explicitly?
> 

And of couse you are correct. It is almost purely convenience. My 
reasoning was this: if I am creating a function which returns a 
composite type, then the fact that a named composite type exists is 
superfluous to me. It would be more natural for me to do:
   CREATE FUNCTION foo() RETURNS SETOF (f1 int, f2 text);

than to do:
   CREATE TYPE some_arbitrary_name AS (f1 int, f2 text);   CREATE FUNCTION foo() RETURNS SETOF some_arbitrary_name;

But I admit it is only a "nice-to-have", not a "need-to-have".

How do others feel? Do we want to be able to implicitly create a 
composite type during function creation? Or is it unneeded bloat?

I prefer the former, but don't have a strong argument against the latter.

Joe




Re: Proposal: stand-alone composite types

From
Rod Taylor
Date:
I think it buys the same as SERIAL does for sequences.

Is it likely to have more than one function using a complex type like
that?  If not, then allowing it's creation (not enforcing) could be
useful.


On Fri, 2002-08-09 at 19:03, Joe Conway wrote:
> Peter Eisentraut wrote:
> > Joe Conway writes:
> >>3. Modify CREATE FUNCTION to allow the implicit creation of a dependent
> >>    composite type, e.g.:
> > 
> > Forgive this blunt question, but:  Why?
> 
> Now's a *great* time for a blunt question because I haven't started 
> actively working on this yet. Much better than after I'm done.  ;-)
> 
> 
> > Of course I can see the answer, it's convenient, but wouldn't the system
> > be more consistent overall if all functions and types are declared
> > explicitly?
> > 
> 
> And of couse you are correct. It is almost purely convenience. My 
> reasoning was this: if I am creating a function which returns a 
> composite type, then the fact that a named composite type exists is 
> superfluous to me. It would be more natural for me to do:
> 
>     CREATE FUNCTION foo() RETURNS SETOF (f1 int, f2 text);
> 
> than to do:
> 
>     CREATE TYPE some_arbitrary_name AS (f1 int, f2 text);
>     CREATE FUNCTION foo() RETURNS SETOF some_arbitrary_name;
> 
> But I admit it is only a "nice-to-have", not a "need-to-have".
> 
> How do others feel? Do we want to be able to implicitly create a 
> composite type during function creation? Or is it unneeded bloat?
> 
> I prefer the former, but don't have a strong argument against the latter.
> 
> Joe
> 
> 
> 
> ---------------------------(end of broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
>     (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)
> 




Re: Proposal: stand-alone composite types

From
Joe Conway
Date:
Rod Taylor wrote:
> I think it buys the same as SERIAL does for sequences.

That's a great analogy.

> Is it likely to have more than one function using a complex type like
> that?  If not, then allowing it's creation (not enforcing) could be
> useful.

That's what I was thinking. In cases where you want to use the type for 
several functions, use CREATE TYPE. If you only need the type for one 
function, let the function creation process manage it for you.

Joe



Re: Proposal: stand-alone composite types

From
"Dann Corbit"
Date:
> -----Original Message-----
> From: Joe Conway [mailto:mail@joeconway.com]
> Sent: Friday, August 09, 2002 4:04 PM
> To: Peter Eisentraut
> Cc: pgsql-hackers
> Subject: Re: [HACKERS] Proposal: stand-alone composite types
>
>
> Peter Eisentraut wrote:
> > Joe Conway writes:
> >>3. Modify CREATE FUNCTION to allow the implicit creation of
> a dependent
> >>    composite type, e.g.:
> >
> > Forgive this blunt question, but:  Why?
>
> Now's a *great* time for a blunt question because I haven't started
> actively working on this yet. Much better than after I'm done.  ;-)
>
>
> > Of course I can see the answer, it's convenient, but wouldn't the
> > system be more consistent overall if all functions and types are
> > declared explicitly?
> >
>
> And of couse you are correct. It is almost purely convenience. My
> reasoning was this: if I am creating a function which returns a
> composite type, then the fact that a named composite type exists is
> superfluous to me. It would be more natural for me to do:
>
>     CREATE FUNCTION foo() RETURNS SETOF (f1 int, f2 text);
>
> than to do:
>
>     CREATE TYPE some_arbitrary_name AS (f1 int, f2 text);
>     CREATE FUNCTION foo() RETURNS SETOF some_arbitrary_name;

Actually, the second looks a lot more natural to me.  As in most
programming languages, you define the type/class first, and then you can
use the type/class as an object.

Further, I don't want to have to remember the implementation details,
unless I need to dig into them.
So:

CREATE TYPE locator AS (First_Name varchar, Last_Name varchar, City
varchar, State_Province char(2), Country varchar);

CREATE FUNCTION CustomerList(varchar specification) RETURNS SETOF
locator;

Seems far more natural and convenient to me.


Re: Proposal: stand-alone composite types

From
Rod Taylor
Date:
> > Is it likely to have more than one function using a complex type like
> > that?  If not, then allowing it's creation (not enforcing) could be
> > useful.
> 
> That's what I was thinking. In cases where you want to use the type for 
> several functions, use CREATE TYPE. If you only need the type for one 
> function, let the function creation process manage it for you.

So long as the type dissapears with the drop of the function.  But don't
make stuff you don't clean up :)




Re: Proposal: stand-alone composite types

From
Thomas Lockhart
Date:
> That's what I was thinking. In cases where you want to use the type for
> several functions, use CREATE TYPE. If you only need the type for one
> function, let the function creation process manage it for you.

It would be nice then to have some mechanism for converting the
"automatic type" to a named type which could be used elsewhere.
Otherwise one would need to garbage collect the separate stuff later,
which would probably go into the "not so convenient" category of
features...
                  - Thomas


Re: Proposal: stand-alone composite types

From
Joe Conway
Date:
Thomas Lockhart wrote:
>>That's what I was thinking. In cases where you want to use the type for
>>several functions, use CREATE TYPE. If you only need the type for one
>>function, let the function creation process manage it for you.
> 
> It would be nice then to have some mechanism for converting the
> "automatic type" to a named type which could be used elsewhere.
> Otherwise one would need to garbage collect the separate stuff later,
> which would probably go into the "not so convenient" category of
> features...

Well I think that could be handled with the new dependency tracking 
system. Same as the SERIAL/sequence analogy -- when you drop the 
function, the type would automatically and transparently also get dropped.

Joe




Re: Proposal: stand-alone composite types

From
Bruce Momjian
Date:
Joe Conway wrote:
> Thomas Lockhart wrote:
> >>That's what I was thinking. In cases where you want to use the type for
> >>several functions, use CREATE TYPE. If you only need the type for one
> >>function, let the function creation process manage it for you.
> > 
> > It would be nice then to have some mechanism for converting the
> > "automatic type" to a named type which could be used elsewhere.
> > Otherwise one would need to garbage collect the separate stuff later,
> > which would probably go into the "not so convenient" category of
> > features...
> 
> Well I think that could be handled with the new dependency tracking 
> system. Same as the SERIAL/sequence analogy -- when you drop the 
> function, the type would automatically and transparently also get dropped.

All this type extension stuff is complex.  If we can make it easier for
people to get started with it, we should.

--  Bruce Momjian                        |  http://candle.pha.pa.us pgman@candle.pha.pa.us               |  (610)
359-1001+  If your life is a hard drive,     |  13 Roberts Road +  Christ can be your backup.        |  Newtown Square,
Pennsylvania19073
 


Re: Proposal: stand-alone composite types

From
Tom Lane
Date:
Peter Eisentraut <peter_e@gmx.net> writes:
> Joe Conway writes:
>> 3. Modify CREATE FUNCTION to allow the implicit creation of a dependent
>> composite type, e.g.:

> Forgive this blunt question, but:  Why?

> Of course I can see the answer, it's convenient, but wouldn't the system
> be more consistent overall if all functions and types are declared
> explicitly?

I was wondering about that too, in particular: what name are you going
to give to the implicit type, and what if it conflicts?

The already-accepted mechanism for anonymous function-result types for
RECORD functions doesn't have that problem, because it has no need to
create a catalog entry for the anonymous type.  But I'm not sure what
to do for record types that need to be present in the catalogs.
        regards, tom lane


Re: Proposal: stand-alone composite types

From
Joe Conway
Date:
Tom Lane wrote:
> I was wondering about that too, in particular: what name are you going
> to give to the implicit type, and what if it conflicts?
> 
> The already-accepted mechanism for anonymous function-result types for
> RECORD functions doesn't have that problem, because it has no need to
> create a catalog entry for the anonymous type.  But I'm not sure what
> to do for record types that need to be present in the catalogs.

I was intending to use the same naming method used for SERIAL sequences.

But since the poll from this afternoon only showed weak support and 
relatively strong objections, I'm OK with putting this aside for now. If 
enough people seem interested once they start using table functions in 
7.3, we can always resurrect this idea.

The most important changes (IMHO) were the "anonymous type" and "CREATE 
TYPE x AS()" pieces anyway, so I'm happy where we are (at least once the 
stand-alone composite type patch is applied ;) ). Onward and upward...

Joe





Re: Proposal: stand-alone composite types

From
"Christopher Kings-Lynne"
Date:
> than to do:
>
>     CREATE TYPE some_arbitrary_name AS (f1 int, f2 text);
>     CREATE FUNCTION foo() RETURNS SETOF some_arbitrary_name;
>
> But I admit it is only a "nice-to-have", not a "need-to-have".
>
> How do others feel? Do we want to be able to implicitly create a
> composite type during function creation? Or is it unneeded bloat?
>
> I prefer the former, but don't have a strong argument against the latter.

The former is super sweet, but does require some extra catalog entries for
every procedure - but that's the DBA's problem.  They can always use the
latter syntax.  The format syntax is cool and easy and it Should Just Work
for newbies...

Chris