Re: [BUGS] [GENERAL] Altering a table with a rowtype column

2012-03-21 Thread Robert Haas
On Tue, Mar 20, 2012 at 2:48 PM, Tom Lane t...@sss.pgh.pa.us wrote:
 I think Tom's correct about what the right behavior would be if
 composite types supported defaults, but they don't, never have, and
 maybe never will.  I had a previous argument about this with Tom, and
 lost, though I am not sure that anyone other than Tom thinks that the
 current behavior is for the best.

 Um, did I say I thought it was for the best?  I thought I said we don't
 have support for doing better.

 If we are willing to legislate that column defaults are not and never
 will be applied to composite types, then I think Merlin might be right
 that we could just let an ALTER ADD with DEFAULT ignore the existence of
 composite columns.

I tend to think that's exactly what we should do, and it's what that
patch did, although as you point out my commit message was the product
of confused thinking.

 I'd always figured that we'd want to try to fix that
 omission eventually, though.

It's mildly tempting, but as Merlin points out, it's hard to know
exactly when you'd apply those rules.  We talked a while back about
domains with NOT NULL constraints; if someone does a left join with a
domain-typed column on the outer side, what are you going to put there
if you don't put NULL?  This case seems somewhat similar.  Defaults
make sense when applied to table columns, because the semantics are
clear: columns not explicitly mentioned get their default value if
any, else NULL.  But if we rule that a composite type with no default
gets the composite type's default values for each column, then we're
overriding the general SQL presumption that unspecified columns are
NULL.  And similarly for temps created by uninitialized variables or,
worse, LEFT JOINs.  In languages like C++ or even Perl, there's always
a very clear notion of when an object gets created, and constructors
and so on run at that time.  Defaults logically should run at the same
time that a constructor would, but that concept doesn't really exist
in SQL, which is seemingly deliberately quite murky about when values
spring into existence.

Does the SQL standard say anything on this topic?

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

-- 
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [BUGS] [GENERAL] Altering a table with a rowtype column

2012-03-20 Thread Robert Haas
On Wed, Mar 7, 2012 at 3:49 PM, Merlin Moncure mmonc...@gmail.com wrote:
 On Wed, Mar 7, 2012 at 2:31 PM, Tom Lane t...@sss.pgh.pa.us wrote:
 Merlin Moncure mmonc...@gmail.com writes:
 On Wed, Mar 7, 2012 at 11:45 AM, Mike Blackwell mike.blackw...@rrd.com 
 wrote:
 alter table a add column even_more_stuff boolean not null default false;

 aha! that's not what you posted last time.  you appended 'not null
 default false'; which inexplicably breaks the ALTER.

 try this:
 ALTER TABLE a ADD COLUMN even_more_stuff text not null;
 ALTER TABLE a ALTER even_more_stuff set default false;
 ALTER TABLE a DROP COLUMN even_more_stuff;
 ALTER TABLE a ADD COLUMN even_more_stuff boolean not null default false;

 (this really looks like a bug in postgres, cc-ing to bugs)

 It is not a bug.  The ALTER ADD ... DEFAULT ... form implies rewriting
 every existing tuple of the rowtype to insert a non-null value in the
 added column, and we don't have support for doing that to rowtype
 columns, only to the target table and descendants.

 I'm not buying that..it implies no such thing.  In particular, for
 table-as-rowtype columns, there's no way that I can see to have
 default values be generated.  So why does it follow that the dependent
 table has to be rewritten?  Column constraints are not enforced on the
 rowtype, so it follows that default shouldn't be either considering
 there's no way to get the default to fire.  Composite type (or table
 based composite) defaults are applied to the composite as a whole, not
 to specific fields.

I think Tom's correct about what the right behavior would be if
composite types supported defaults, but they don't, never have, and
maybe never will.  I had a previous argument about this with Tom, and
lost, though I am not sure that anyone other than Tom thinks that the
current behavior is for the best.  But see commits
a06e41deebdf74b8b5109329dc75b2e9d9057962 and
a40b1e0bf32b1da46c1baa9bc7da87f207cd37d8.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

-- 
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [BUGS] [GENERAL] Altering a table with a rowtype column

2012-03-20 Thread Tom Lane
Robert Haas robertmh...@gmail.com writes:
 On Wed, Mar 7, 2012 at 3:49 PM, Merlin Moncure mmonc...@gmail.com wrote:
 On Wed, Mar 7, 2012 at 2:31 PM, Tom Lane t...@sss.pgh.pa.us wrote:
 It is not a bug.  The ALTER ADD ... DEFAULT ... form implies rewriting
 every existing tuple of the rowtype to insert a non-null value in the
 added column, and we don't have support for doing that to rowtype
 columns, only to the target table and descendants.

 I'm not buying that..it implies no such thing.  In particular, for
 table-as-rowtype columns, there's no way that I can see to have
 default values be generated.  So why does it follow that the dependent
 table has to be rewritten?  Column constraints are not enforced on the
 rowtype, so it follows that default shouldn't be either considering
 there's no way to get the default to fire.  Composite type (or table
 based composite) defaults are applied to the composite as a whole, not
 to specific fields.

 I think Tom's correct about what the right behavior would be if
 composite types supported defaults, but they don't, never have, and
 maybe never will.  I had a previous argument about this with Tom, and
 lost, though I am not sure that anyone other than Tom thinks that the
 current behavior is for the best.

Um, did I say I thought it was for the best?  I thought I said we don't
have support for doing better.

If we are willing to legislate that column defaults are not and never
will be applied to composite types, then I think Merlin might be right
that we could just let an ALTER ADD with DEFAULT ignore the existence of
composite columns.  I'd always figured that we'd want to try to fix that
omission eventually, though.

 But see commits
 a06e41deebdf74b8b5109329dc75b2e9d9057962 and
 a40b1e0bf32b1da46c1baa9bc7da87f207cd37d8.

Note that the actual problem with the original commit was that it
depended on a misreading of the SQL standard.  Per spec, ALTER ADD with
DEFAULT is *not* the same thing as ALTER ADD followed by ALTER SET
DEFAULT; the contents of the table end up different.

regards, tom lane

-- 
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [BUGS] [GENERAL] Altering a table with a rowtype column

2012-03-20 Thread Merlin Moncure
On Tue, Mar 20, 2012 at 12:16 PM, Robert Haas robertmh...@gmail.com wrote:
 I think Tom's correct about what the right behavior would be if
 composite types supported defaults, but they don't, never have, and
 maybe never will.  I had a previous argument about this with Tom, and
 lost, though I am not sure that anyone other than Tom thinks that the
 current behavior is for the best.  But see commits
 a06e41deebdf74b8b5109329dc75b2e9d9057962 and
 a40b1e0bf32b1da46c1baa9bc7da87f207cd37d8.

I'll go further than that -- given the current infrastructure I'd say
that composite type defaults are not very well defined or useful
besides not being implemented. The way things work now:

create type foo as(a int, b int);
create table bar(f foo default row(1,2));

works perfectly ok.  how would you proxy the default from one of those
two columns?  does it make sense to do so?  defaults are applied to
table columns, not to types (you could argue that domains violate that
rule but IMO it's not the same thing).

type constraints are another matter.  this would be useful and
valuable but may end up being impossible to add for a lot of reasons
such as backwards compatibility and dealing with the standard's lack
(implemented nowhere in postgres except for the very special case of
IS NULL) of distinguishing between the type itself being null and it's
fields being null (making type constraints smack into plpgsql variable
declarations).

merlin

-- 
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [BUGS] [GENERAL] Altering a table with a rowtype column

2012-03-08 Thread Merlin Moncure
On Wed, Mar 7, 2012 at 2:49 PM, Merlin Moncure mmonc...@gmail.com wrote:
 On a practical level, the error blocks nothing -- you can bypass it
 trivially.   It's just an annoyance that prevents things that users
 would like to be able to do with table row types.  So I'd argue to
 remove the check, although I can kinda see the argument that it's not
 a bug unless the check was recently introduced so that it broke older
 code.

The behavior hasn't changed since at least as far back as 8.1, so
you're correct (once again) -- not a bug.  I'm really surprised I
haven't already bumped into this.  I usually don't mix
tables-as-storage with tables-as-composites though.

Mike, on 9.1, you'll probably get more mileage out of using the hstore
type for row storage if you want to do auditing in that style.

merlin

-- 
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [BUGS] [GENERAL] Altering a table with a rowtype column

2012-03-08 Thread Mike Blackwell
Not a bad idea.  I'd need to convert existing data, but it'd be an excuse
to try out hstore. ^_^

Mike
* mike.blackw...@rrd.com*


On Thu, Mar 8, 2012 at 11:08, Merlin Moncure mmonc...@gmail.com wrote:

 On Wed, Mar 7, 2012 at 2:49 PM, Merlin Moncure mmonc...@gmail.com wrote:
  On a practical level, the error blocks nothing -- you can bypass it
  trivially.   It's just an annoyance that prevents things that users
  would like to be able to do with table row types.  So I'd argue to
  remove the check, although I can kinda see the argument that it's not
  a bug unless the check was recently introduced so that it broke older
  code.

 The behavior hasn't changed since at least as far back as 8.1, so
 you're correct (once again) -- not a bug.  I'm really surprised I
 haven't already bumped into this.  I usually don't mix
 tables-as-storage with tables-as-composites though.

 Mike, on 9.1, you'll probably get more mileage out of using the hstore
 type for row storage if you want to do auditing in that style.

 merlin



Re: [BUGS] [GENERAL] Altering a table with a rowtype column

2012-03-07 Thread Tom Lane
Merlin Moncure mmonc...@gmail.com writes:
 On Wed, Mar 7, 2012 at 11:45 AM, Mike Blackwell mike.blackw...@rrd.com 
 wrote:
 alter table a add column even_more_stuff boolean not null default false;

 aha! that's not what you posted last time.  you appended 'not null
 default false'; which inexplicably breaks the ALTER.

 try this:
 ALTER TABLE a ADD COLUMN even_more_stuff text not null;
 ALTER TABLE a ALTER even_more_stuff set default false;
 ALTER TABLE a DROP COLUMN even_more_stuff;
 ALTER TABLE a ADD COLUMN even_more_stuff boolean not null default false;

 (this really looks like a bug in postgres, cc-ing to bugs)

It is not a bug.  The ALTER ADD ... DEFAULT ... form implies rewriting
every existing tuple of the rowtype to insert a non-null value in the
added column, and we don't have support for doing that to rowtype
columns, only to the target table and descendants.  Without a default,
it's just a catalog adjustment and doesn't involve rewriting any data.
(This stems from the fact that columns beyond a tuple's natts value are
presumed null, so we can let ADD COLUMN without a default just change
the catalogs and a null column effectively springs into existence for
every existing tuple.  ALTER ADD ... DEFAULT is specified to have a
different result, and it's not free.)

This probably could be done for rowtype columns as well, but nobody has
collected the necessary round tuits.  I think there was some fear of
locking/deadlock issues, too.

regards, tom lane

-- 
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [BUGS] [GENERAL] Altering a table with a rowtype column

2012-03-07 Thread Alvaro Herrera

Excerpts from Tom Lane's message of mié mar 07 17:31:32 -0300 2012:

 This probably could be done for rowtype columns as well, but nobody has
 collected the necessary round tuits.  I think there was some fear of
 locking/deadlock issues, too.

It's probably easy to do if you require it to be marked INVALID
initially and then validate the tables using it one by one.

-- 
Álvaro Herrera alvhe...@commandprompt.com
The PostgreSQL Company - Command Prompt, Inc.
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

-- 
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [BUGS] [GENERAL] Altering a table with a rowtype column

2012-03-07 Thread Merlin Moncure
On Wed, Mar 7, 2012 at 2:31 PM, Tom Lane t...@sss.pgh.pa.us wrote:
 Merlin Moncure mmonc...@gmail.com writes:
 On Wed, Mar 7, 2012 at 11:45 AM, Mike Blackwell mike.blackw...@rrd.com 
 wrote:
 alter table a add column even_more_stuff boolean not null default false;

 aha! that's not what you posted last time.  you appended 'not null
 default false'; which inexplicably breaks the ALTER.

 try this:
 ALTER TABLE a ADD COLUMN even_more_stuff text not null;
 ALTER TABLE a ALTER even_more_stuff set default false;
 ALTER TABLE a DROP COLUMN even_more_stuff;
 ALTER TABLE a ADD COLUMN even_more_stuff boolean not null default false;

 (this really looks like a bug in postgres, cc-ing to bugs)

 It is not a bug.  The ALTER ADD ... DEFAULT ... form implies rewriting
 every existing tuple of the rowtype to insert a non-null value in the
 added column, and we don't have support for doing that to rowtype
 columns, only to the target table and descendants.

I'm not buying that..it implies no such thing.  In particular, for
table-as-rowtype columns, there's no way that I can see to have
default values be generated.  So why does it follow that the dependent
table has to be rewritten?  Column constraints are not enforced on the
rowtype, so it follows that default shouldn't be either considering
there's no way to get the default to fire.  Composite type (or table
based composite) defaults are applied to the composite as a whole, not
to specific fields.

On a practical level, the error blocks nothing -- you can bypass it
trivially.   It's just an annoyance that prevents things that users
would like to be able to do with table row types.  So I'd argue to
remove the check, although I can kinda see the argument that it's not
a bug unless the check was recently introduced so that it broke older
code.

merlin

-- 
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general