Обсуждение: I think I know what I'm doing wrong, but....

Поиск
Список
Период
Сортировка

I think I know what I'm doing wrong, but....

От
"Eric Nielsen"
Дата:
My problem arises in a subset of three tables of my database, foo, bar, and
baz.
Foo hold high level information about an activity
Bar holds a many to many mapping of people to activities
baz holds some predicted information about the size of the mappings and the
current registrations and is keyed by the same values as Foo (ie its primary
key is also declared "references foo on delete cascade on update cascade)

(Yes I am aware that holding the current registrations is redundant and
could be generate using select count(*) from bar where activityid="baf", but
for performance reasons I was advised to keep it current with rules.)

So I made the tables, and the rules for insert,update, and deletes so that
bar and baz are kept consistent.  Now I want to automate the initialization
of baz on the creation of foo.  I thought I could continue to use rules,
such as
create rule foo_insert on insert to foo as insert into baz values
(new.activityid,0,0);

However the insert fails, with a referential integrity problem.  I _think_
this is because it tries to do the rule's trigger before actually doing the
original select, so the key does not exist.

Can anyone confirm my hypothesis?  Is there a solution using rules, or do I
need to use triggers, which seem to have a notion of before and after? (I
have not examined triggers in detail yet)

Thank you
Eric Nielsen




Re: I think I know what I'm doing wrong, but....

От
"Eric Nielsen"
Дата:
So I solved my problem using a trigger/function combo, but I would still
like to know if what I was trying is possible using rules (see below).

Thank you.
Eric
----- Original Message -----
From: Eric Nielsen <ericnielsen@earthlink.net>
To: <pgsql-novice@postgresql.org>
Sent: Thursday, January 04, 2001 11:13 PM
Subject: I think I know what I'm doing wrong, but....


> My problem arises in a subset of three tables of my database, foo, bar,
and
> baz.
> Foo hold high level information about an activity
> Bar holds a many to many mapping of people to activities
> baz holds some predicted information about the size of the mappings and
the
> current registrations and is keyed by the same values as Foo (ie its
primary
> key is also declared "references foo on delete cascade on update cascade)
>
> (Yes I am aware that holding the current registrations is redundant and
> could be generate using select count(*) from bar where activityid="baf",
but
> for performance reasons I was advised to keep it current with rules.)
>
> So I made the tables, and the rules for insert,update, and deletes so that
> bar and baz are kept consistent.  Now I want to automate the
initialization
> of baz on the creation of foo.  I thought I could continue to use rules,
> such as
> create rule foo_insert on insert to foo as insert into baz values
> (new.activityid,0,0);
>
> However the insert fails, with a referential integrity problem.  I _think_
> this is because it tries to do the rule's trigger before actually doing
the
> original select, so the key does not exist.
>
> Can anyone confirm my hypothesis?  Is there a solution using rules, or do
I
> need to use triggers, which seem to have a notion of before and after? (I
> have not examined triggers in detail yet)
>
> Thank you
> Eric Nielsen
>
>
>
>


Re: Re: I think I know what I'm doing wrong, but....

От
Tom Lane
Дата:
"Eric Nielsen" <ericnielsen@earthlink.net> writes:
>> However the insert fails, with a referential integrity problem.  I _think_
>> this is because it tries to do the rule's trigger before actually doing
>> the original select, so the key does not exist.

I think you are right.  Non-INSTEAD rule actions are executed before the
original query is carried out.  I have argued in the past that this is
stupid for ON INSERT rules, which would be better done after the
original query, but I haven't had any luck getting agreement to change
it.

>> Is there a solution using rules,

Only if you can use a delayed referential integrity check that isn't
checked till end of transaction.  I don't know offhand if we even
implement such a feature, let alone whether it'd be OK for your
application logic.

            regards, tom lane

Re: Re: I think I know what I'm doing wrong, but....

От
"Robert B. Easter"
Дата:
On Saturday 06 January 2001 12:04, Tom Lane wrote:
> "Eric Nielsen" <ericnielsen@earthlink.net> writes:
> >> However the insert fails, with a referential integrity problem.  I
> >> _think_ this is because it tries to do the rule's trigger before
> >> actually doing the original select, so the key does not exist.
>
> I think you are right.  Non-INSTEAD rule actions are executed before the
> original query is carried out.  I have argued in the past that this is
> stupid for ON INSERT rules, which would be better done after the
> original query, but I haven't had any luck getting agreement to change
> it.
>
> >> Is there a solution using rules,
>
> Only if you can use a delayed referential integrity check that isn't
> checked till end of transaction.  I don't know offhand if we even
> implement such a feature, let alone whether it'd be OK for your
> application logic.
>
>             regards, tom lane


The man-page for create_table has all the info in it about

CONSTRAINT [name]
    [NOT] DEFERRABLE
    INITIALLY DEFERRED|IMMEDIATE

NOT DEFERRABLE is the default.

I've used INITIALLY DEFERRED before to avoid these problems. If just
DEFERRABLE is used, then it is implicitly INITIALLY IMMEDIATE.  To make a
deferrable constraint deferred, SET CONSTRAINTS {ALL|name,...} DEFERRED has
to be done first.

--
-------- Robert B. Easter  reaster@comptechnews.com ---------
-- CompTechNews Message Board http://www.comptechnews.com/ --
-- CompTechServ Tech Services http://www.comptechserv.com/ --
---------- http://www.comptechnews.com/~reaster/ ------------