Thread: In RULEs, INSERT does not use DEFAULTs

In RULEs, INSERT does not use DEFAULTs

From
David Fetter
Date:
Folks,

At one time, INSERTing a NULL into a column with a DEFAULT used to
INSERT the DEFAULT.  Is there some way to get this behavior back?  I
think that this is a bug introduced by removing the NULL -> DEFAULT
behavior and not replacing it somehow.  Below is a simple repro.

I think this is a bug.  Although there are workarounds, the ones I've
found have been clumsy and foot-gun-ish.  Is there some way to fix
this?

Cheers,
D

CREATE TABLE foo ( foo_id SERIAL PRIMARY KEY
, foo_truth BOOLEAN NOT NULL DEFAULT TRUE
, foo_text TEXT
);

CREATE VIEW foo_caps AS
SELECT foo_id, foo_truth, UPPER(foo_text) AS "foo_text_cap"
FROM foo;

/* The naïf way */
CREATE RULE foo_caps_insert AS
ON INSERT
TO foo_caps
DO INSTEAD   INSERT INTO foo (foo_id, foo_truth, foo_text)   VALUES (NEW.foo_id, NEW.foo_truth, NEW.foo_text_cap);

INSERT INTO foo_caps (foo_truth)
VALUES (false);
ERROR:  null value in column "foo_id" violates not-null constraint

/* Possibly less naïf, but... */

DROP RULE foo_caps_insert ON foo_caps;

CREATE RULE foo_caps_insert AS
ON INSERT
TO foo_caps
DO INSTEAD   INSERT INTO foo (       foo_id,       foo_truth,       foo_text   ) VALUES (       COALESCE(NEW.foo_id,
DEFAULT),      COALESCE(NEW.foo_truth, DEFAULT),       NEW.foo_text_cap   );
 

ERROR:  syntax error at or near "DEFAULT" at character 183
LINE 10:         COALESCE(NEW.foo_id, DEFAULT),                                     ^
-- 
David Fetter david@fetter.org http://fetter.org/
phone: +1 510 893 6100   mobile: +1 415 235 3778

Remember to vote!


Re: In RULEs, INSERT does not use DEFAULTs

From
Tom Lane
Date:
David Fetter <david@fetter.org> writes:
> At one time, INSERTing a NULL into a column with a DEFAULT used to
> INSERT the DEFAULT.  Is there some way to get this behavior back?

PG has *never* done that in any version that I can recall, and it isn't
likely that we would install such an obvious violation of the SQL spec.

The correct way to get the behavior you are after is to attach a default
to the view's column (ALTER view ALTER col SET DEFAULT ...)
        regards, tom lane


Re: In RULEs, INSERT does not use DEFAULTs

From
David Fetter
Date:
On Sun, Jun 12, 2005 at 10:56:22PM -0400, Tom Lane wrote:
> David Fetter <david@fetter.org> writes:
> > At one time, INSERTing a NULL into a column with a DEFAULT used to
> > INSERT the DEFAULT.  Is there some way to get this behavior back?
> 
> PG has *never* done that in any version that I can recall, and it
> isn't likely that we would install such an obvious violation of the
> SQL spec.

> The correct way to get the behavior you are after is to attach a
> default to the view's column (ALTER view ALTER col SET DEFAULT ...)

With all due respect, that's a giant foot gun in terms of maintenance,
i.e. making a single behavior depend on two things that can easily
get out of sync.  With hand-altered DEFAULTs, there's no way to alter
the DEFAULTs on the the base TABLE and have those changes propagate,
as people would usually want it to.

I can see how somebody might want a VIEW's column to have a DEFAULT
that was different from the column to which it refers in some specific
case.  However, "defaults to different from the underlying column's
DEFAULT" is a Bad Thing(TM).

I believe this isn't just my problem.  Without access to a the
underlying column's DEFAULT, how can people implement the automated
WRITEable VIEWs?

Cheers,
D
-- 
David Fetter david@fetter.org http://fetter.org/
phone: +1 510 893 6100   mobile: +1 415 235 3778

Remember to vote!


Re: In RULEs, INSERT does not use DEFAULTs

From
Tom Lane
Date:
David Fetter <david@fetter.org> writes:
> I believe this isn't just my problem.  Without access to a the
> underlying column's DEFAULT, how can people implement the automated
> WRITEable VIEWs?

That's a reasonable question, but translating "insert null" to "insert
the default" is not a reasonable answer.

There was some speculation just a couple days ago about inventing a
function that would compute the default associated with some other
table's column, but it's not clear how to make that work (in
particular, how to declare the result type of such a function).

Another possibility is a command along the lines ofALTER view ALTER col LINK DEFAULT TO othertable.col;
(syntax open to argument of course) which accomplishes the
same thing without having to figure a way to avoid the constraints
of a specific function result type.
        regards, tom lane


Re: In RULEs, INSERT does not use DEFAULTs

From
Rod Taylor
Date:
On Sun, 2005-06-12 at 20:33 -0700, David Fetter wrote:
> On Sun, Jun 12, 2005 at 10:56:22PM -0400, Tom Lane wrote:
> > David Fetter <david@fetter.org> writes:
> > > At one time, INSERTing a NULL into a column with a DEFAULT used to
> > > INSERT the DEFAULT.  Is there some way to get this behavior back?
> > 
> > PG has *never* done that in any version that I can recall, and it
> > isn't likely that we would install such an obvious violation of the
> > SQL spec.
> 
> > The correct way to get the behavior you are after is to attach a
> > default to the view's column (ALTER view ALTER col SET DEFAULT ...)
> 
> With all due respect, that's a giant foot gun in terms of maintenance,
> i.e. making a single behavior depend on two things that can easily
> get out of sync.  With hand-altered DEFAULTs, there's no way to alter
> the DEFAULTs on the the base TABLE and have those changes propagate,
> as people would usually want it to.

Change the table and view to use a domain.
       CREATE DOMAIN tabviewtype_x AS integer DEFAULT 12;

Altering the default of the domain will bump both the table and view
defaults, or anywhere else that type happens to be used.

-- 
Rod Taylor <pg@rbt.ca>



Re: In RULEs, INSERT does not use DEFAULTs

From
David Fetter
Date:
On Sun, Jun 12, 2005 at 11:48:29PM -0400, Tom Lane wrote:
> David Fetter <david@fetter.org> writes:
> > I believe this isn't just my problem.  Without access to a the
> > underlying column's DEFAULT, how can people implement the automated
> > WRITEable VIEWs?
> 
> That's a reasonable question, but translating "insert null" to "insert
> the default" is not a reasonable answer.

Right.  My mistake.

> There was some speculation just a couple days ago about inventing a
> function that would compute the default associated with some other
> table's column, but it's not clear how to make that work (in
> particular, how to declare the result type of such a function).

I was looking into polymorphic functions for this.  At least in
PL/PgSQL (which isn't a general solution, but I was looking for my own
solution) there is a way to get the return type based on the input
types.

> Another possibility is a command along the lines of
>     ALTER view ALTER col LINK DEFAULT TO othertable.col;

I still think that something like this (i.e. the VIEWs column has the
same default as its underlying base TABLE or VIEW, where there is one)
should be the default behavior.  Principle of Least Astonishiment.

> (syntax open to argument of course) which accomplishes the
> same thing without having to figure a way to avoid the constraints
> of a specific function result type.

It'd be nice to have one of these :)

Cheers,
D
-- 
David Fetter david@fetter.org http://fetter.org/
phone: +1 510 893 6100   mobile: +1 415 235 3778

Remember to vote!


Re: In RULEs, INSERT does not use DEFAULTs

From
Jaime Casanova
Date:
On 6/12/05, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> David Fetter <david@fetter.org> writes:
> > I believe this isn't just my problem.  Without access to a the
> > underlying column's DEFAULT, how can people implement the automated
> > WRITEable VIEWs?
>
> That's a reasonable question, but translating "insert null" to "insert
> the default" is not a reasonable answer.
>
> There was some speculation just a couple days ago about inventing a
> function that would compute the default associated with some other
> table's column, but it's not clear how to make that work (in
> particular, how to declare the result type of such a function).
>
I discarded the idea because i couldn't fight with the polymorphic
function to return the correct value in any case.

But i successfully found that hacking rewriteHandler.c can do the
trick. I am using that in updateable views project.

> Another possibility is a command along the lines of
>     ALTER view ALTER col LINK DEFAULT TO othertable.col;
> (syntax open to argument of course) which accomplishes the
> same thing without having to figure a way to avoid the constraints
> of a specific function result type.
>

That's sounds like a good idea too

--
Atentamente,
Jaime Casanova
(DBA: DataBase Aniquilator ;)