Re: what fired a trigger - Mailing list pgsql-general

From Ivan Sergio Borgonovo
Subject Re: what fired a trigger
Date
Msg-id 20060906211231.246b5660@localhost
Whole thread Raw
In response to what fired a trigger  (Ivan Sergio Borgonovo <mail@webthatworks.it>)
List pgsql-general
On Tue, 5 Sep 2006 22:53:14 +0200
Ivan Sergio Borgonovo <mail@webthatworks.it> wrote:

> Hi,
>
> The most general problem that may be a design problem (and I'm not
> asking to do my homework even if well, you may still help <g>) is
> I've a "temporary relation" and a permanent relation. A typical
> situation is the one of session in a web app and temporary basket.
> Once the user log in, the temporary basket becomes "permanent". But
> I'd like automatic garbage collection for all tables simply related
> to sessions. When a session get deleted all row that are *just*
> related to the session, but not to the user, should be deleted.
> Anyway I still need normal "User related" delete.

OK let's see if I can make the description of the problem more general.

on delete cascade is comfortable because every time someone will add a new Session related table he just has to
rememberto add it making the garbage collection a "local" problem. 
Adding a rule on delete of session table will require modification to the rule every time a new table is added; unless
Ican think of a very smart way that will look into system tables[*] etc... but I suspect this will be terribly
inefficient.

A trigger on delete doesn't have any information about how it was called, it seems to me it can just know on which
tableit was fired and which field was deleted from the TG_NAME eventually, but considering that more than one trigger
maybe called for the same row, and the first one is determined by alphabetical order, it doesn't seem too useful. 
Arguments can't be passed because triggers are fired "indirectly". That means that a trigger may cause a delete that
willfire another trigger. The delete won't pass the argument of the previous trigger to the next. 

A possible workaround could be to use an update trigger to delete sessions/users.
A trigger may be linked to the update of the idUser, stored in the session table.
Updates that set to null a idUser are "alias" for delete everything unconditionally.
A delete... may be a conditional delete.
On every idSession/idUser table I'll have 2 triggers.

One on delete idSession. This one should be similar to the previous one I wrote.

One on update idUser should be something like

if NEW.idUser is null then
begin
--    delete from TG_RELNAME where idSession=OLD.idSession;
    delete from TG_RELNAME where idUser=OLD.idUser; --??
end;
return NEW;

I'm still considering if this approach is feasible and if it has any drawback.
Surely a bit more overhead to unset idUser when anyway the row is going to be deleted and the risk I'll have to
"delete"by idSession since the idUser get lost (I've to play with after/before). 
It doesn't seem too elegant and my main concern is it doesn't look flexible/general enough.


/****************
Anyway I'm still interested to know if there is any system to pass parameters between triggers or at least to know what
causeda trigger (a direct operation or a cascade operation). 
If anyone can enlighten me I'd be grateful.
*****************/



[*] eg. find in the system table all the tables that have an idSession column, use a cursor, a dynamically generated
statementand delete unconditionally on tables that don't have idUser, and conditionally (idUser is null) on table that
haveit. 
If there are tables where idSession is not unique this could be more efficient than triggers. But this won't be the
mostcommon case and dynamically generated statements and cursors will be expensive. 



--
Ivan Sergio Borgonovo
http://www.webthatworks.it


pgsql-general by date:

Previous
From: Andrew Sullivan
Date:
Subject: Re: Estimate on gborg rescue?
Next
From: SebaM
Date:
Subject: inet/cidr type ?!