Thread: Foreign Key Constraint Deletion Order

Foreign Key Constraint Deletion Order

From
Date:
I have found from a small number of tests that
deletions executed by foreign key constraint does NOT
guarantee the detail table to be deleted BEFORE
master table. This makes some of my trigger functions
assocated with the detail table mulfunction because
the trigger function can't find its parent record.

Is there any plan to change the foreign key
constraint deletion (and update in
master-then-detail) order?

Thanks you all!

CN

--------------------------------------------------------
You too can have your own email address from Eurosport.
http://www.eurosport.com







Re: Foreign Key Constraint Deletion Order

From
Stephan Szabo
Date:
On Mon, 19 Nov 2001 cnliou@eurosport.com wrote:

> I have found from a small number of tests that
> deletions executed by foreign key constraint does NOT
> guarantee the detail table to be deleted BEFORE
> master table. This makes some of my trigger functions
> assocated with the detail table mulfunction because
> the trigger function can't find its parent record.

The detail table rows are currently deleted at
end of statement or end of transaction (based on
deferrability).  Technically the time is indeterminate
in regards to user triggers on the master table.
We've been having discussions on hackers about the behavior,
but it's unlikely that the rows will be deleted before
the master row.



Re: Foreign Key Constraint Deletion Order

From
Date:
Thanks! Stephan,

> We've been having discussions on hackers about the
behavior,
> but it's unlikely that the rows will be deleted
before
> the master row.

Then I am in big big trouble! Please imagine a very
usual scenario:

create table PurchaseMaster (book text primary key,
UnitPrice float);

create table PurchaseDetail (
CONSTRAINT fk_abc FOREIGN KEY (book) REFERENCES
PurchaseMaster (book) on delete cascade on update
cascade,
primary key (book,buyer),
book text, 
buyer text,
quantity smallint
);

create table HowMuchIOwe (buyer text primary
key,amount float);

CREATE FUNCTION MyTrigger() RETURNS opaque AS '
BEGIN UPDATE HowMuchIOwe set
amount=amount-old.quantity*(select UnitPrice from
PurchaseMaster where book=old.book) where buyer=old.buyer;
END;

CREATE TRIGGER TriggerDetail AFTER DELETE ON
PurchaseDetail FOR EACH ROW EXECUTE PROCEDURE
MyTrigger(
);

Now when a row in PurchaseMaster is deleted by user,
because:

(1) getting rid of fk_abc constraint and replacing it
with a custom trigger function associated with
PurchaseMaster in order to delete PurchaseDetail
"manually" does not work either since PurchaseMaster
row may be deleted BEFORE this custom trigger
function is called;

(2) and row in PurchaseMaster may be deleted before
PurchaseDetail.

so I have no way out!

CN 

--------------------------------------------------------
You too can have your own email address from Eurosport.
http://www.eurosport.com







Re: Foreign Key Constraint Deletion Order

From
Stephan Szabo
Date:
On Mon, 19 Nov 2001 cnliou@eurosport.com wrote:

> Then I am in big big trouble! Please imagine a very
> usual scenario:
> [example snipped]

I think you can do this as part of a trigger on PurchaseMaster and
something that doesn't do the subtraction if the subselect returns
a NULL in the detail trigger (or subtracts 0), not as pretty, but
it should function.  The master trigger would subtract as necessary
for the details for the user.




Re: Foreign Key Constraint Deletion Order

From
Date:
Thanks again! Stephan,

> I think you can do this as part of a trigger on
PurchaseMaster and
> something that doesn't do the subtraction if the
subselect returns
> a NULL in the detail trigger (or subtracts 0), not
as pretty, but
> it should function.  The master trigger would
subtract as necessary
> for the details for the user.

This is really a pain though it works.

Since delete from PurchaseMaster and PurchaseDetail
are both possible, two subtraction trigger functions
must be written for PurchaseMaster and
PurchaseDetail, respectively.

It also seems unwise not to use the
powerful-but-easy-to-use RI capability (on delete
cascade on update cascade) but to implement it with
my own trigger to be fired by PurchaseMaster.

If the delete was always done on PurchaseDetail
before PurchaseMaster, then one subtraction function
for PurchaseDetail along with the RI would settle
down everything.

Am I asking for too much, or RI and triggers were not
designed for operations like this example in the
first place?

CN

--------------------------------------------------------
You too can have your own email address from Eurosport.
http://www.eurosport.com







Re: Foreign Key Constraint Deletion Order

From
Tom Lane
Date:
<cnliou@eurosport.com> writes:
> Am I asking for too much, or RI and triggers were not
> designed for operations like this example in the
> first place?

The problem is that RI is implemented by triggers, and there's
no guarantees about the firing order of multiple triggers.
So you don't know whether your custom triggers will fire
before or after the RI actions occur.

We've had some discussions in the past about arranging things
so that trigger firing order could be predicted/controlled.
But nothing's been done about it yet.  Search the archives
if you want to see the prior discussions.
        regards, tom lane


Re: Foreign Key Constraint Deletion Order

From
Stephan Szabo
Date:
On Mon, 19 Nov 2001, Tom Lane wrote:

> <cnliou@eurosport.com> writes:
> > Am I asking for too much, or RI and triggers were not
> > designed for operations like this example in the
> > first place?
>
> The problem is that RI is implemented by triggers, and there's
> no guarantees about the firing order of multiple triggers.
> So you don't know whether your custom triggers will fire
> before or after the RI actions occur.

Even specifying the after trigger order wouldn't help him
I think. He'd want the deletion of the details rows and their
associated triggers to run before the actual deletion of the
master row. I'd guess that would require the cascade delete
to be being done as a before delete trigger.




Re: Foreign Key Constraint Deletion Order

From
Stephan Szabo
Date:
On Tue, 20 Nov 2001 cnliou@eurosport.com wrote:

> This is really a pain though it works.
>
> Since delete from PurchaseMaster and PurchaseDetail
> are both possible, two subtraction trigger functions
> must be written for PurchaseMaster and
> PurchaseDetail, respectively.
>
> It also seems unwise not to use the
> powerful-but-easy-to-use RI capability (on delete
> cascade on update cascade) but to implement it with
> my own trigger to be fired by PurchaseMaster.

Yeah, there's also some locking gotchas involved
so while the RI stuff isn't nearly perfect it's
probably a good idea to stick with it unless
you're running one of the problem cases.

> If the delete was always done on PurchaseDetail
> before PurchaseMaster, then one subtraction function
> for PurchaseDetail along with the RI would settle
> down everything.
>
> Am I asking for too much, or RI and triggers were not
> designed for operations like this example in the
> first place?

For the particular case you're looking for I don't think
so.  It sounds like it'd make sense, but I don't think
it'd fit the spec wording (given that we've been arguing
how far after the deletion that the cascade occurs, I
don't think anyone's argued for before the deletion).