Re: Trigger function not executing - Mailing list pgsql-bugs
From | Donald Fraser |
---|---|
Subject | Re: Trigger function not executing |
Date | |
Msg-id | 004401c2d0e8$d6adce20$1664a8c0@DEMOLITION Whole thread Raw |
In response to | Trigger function not executing ("Donald Fraser" <demolish@cwgsy.net>) |
Responses |
Re: Trigger function not executing
|
List | pgsql-bugs |
----- Original Message -----=20 From: Donald Fraser=20 To: pgsql-bugs@postgresql.org=20 Sent: Thursday, February 06, 2003 11:27 AM Subject: [BUGS] Trigger function not executing OS: Redhat, kernel 2.4 PostgreSQL 7.3.1 on i686-pc-linux-gnu, compiled by GCC 2.96 I have a table that has two triggers functions applied to it 1) CREATE TRIGGER trig_delete_user BEFORE DELETE ON tbl_user FOR EACH ROW= EXECUTE PROCEDURE delete_user(); 2) CREATE TRIGGER trig_insert_sys_user AFTER INSERT OR DELETE OR UPDATE O= N tbl_user FOR EACH ROW EXECUTE PROCEDURE insert_sys_user(); The BEFORE trigger function basically does nothing to modify the tuple in= any way. It does run a SELECT on the same table to do some routine checks = and before it can exit the function it sets a global flag to tell the AFTER= trigger function what to do. The AFTER trigger function resets the flag set by the BEFORE function and= then performs some administration commands for users . In this instance it= issues a "DROP USER" command. I've included the above summary as an insight to where the problem may be. Here is the problem: If I run SQL such as DELETE FROM tbl_user WHERE id =3D '2'; then I don't = get any problems. If I run SQL such as DELETE FROM tbl_user WHERE id > '40'; and there is o= nly one record that meets the condition (id > '40') then I don't get any pr= oblems. If I run SQL such as DELETE FROM tbl_user WHERE id > '20'; and there is m= ore than one record that meets the condition (id > '20') then I get the fol= lowing problem. The BEFORE trigger function is only being called on the fir= st record that is being deleted yet the AFTER function is being called on a= ll of the records - well in this case it only gets to the second record and= fails because the flag has not been set by the BEFORE function. Just to re= -iterate - the BFORE function is very simple - it cannot exit the function = without setting the flag I have mentioned. Have I misunderstood trigger functions or is this a legitimate bug? Regards Donald Fraser ----- Original Message -----=20 From: "Tom Lane" <tgl@sss.pgh.pa.us> To: "Donald Fraser" <demolish@cwgsy.net> Cc: <pgsql-bugs@postgresql.org> Sent: Thursday, February 06, 2003 2:42 PM Subject: Re: [BUGS] Trigger function not executing=20 > "Donald Fraser" <demolish@cwgsy.net> writes: > > If I run SQL such as DELETE FROM tbl_user WHERE id > '20'; and there = is mor=3D > > e than one record that meets the condition (id > '20') then I get the= follo=3D > > wing problem. The BEFORE trigger function is only being called on the= first=3D > > record that is being deleted=20 >=20 > I don't believe it --- and you haven't provided any evidence to support > your claim. More than likely, this is just an error in your own trigger > code; but with no details it's pointless to speculate. >=20 > regards, tom lane >=20 Tom I have had another look at this problem and you were correct in that th= e trigger functions were being called, just not in the order that I had exp= ected. There were "no bugs" in my code as such, just a total misunderstandi= ng on how trigger functions are processed in a SQL command that effects mor= e than one record - hence the reason why I'm writing this email. I don't wa= nt other people to be caught out with the same problem and it may well be w= orth putting a note in the documentation under the trigger manager section = and correcting the example in Chapter 16.4.=20 I made the following assumption (based on the documents): The sequence of e= vents for trigger functions would be exactly the same regardless of the SQL= statement/s to achieve the same result. That is I thought that for example= : DELETE FROM tbl_user WHERE id =3D '20'; DELETE FROM tbl_user WHERE id =3D= '21'; would produce exactly the same sequence of events as DELETE FROM tb= l_user WHERE (id >=3D '20' AND id <=3D '21'); This is not the case. The sequence of events for the first set of SQL statements is as follows: 1: Trigger BEFORE EVENT for record with id =3D 20; 2: Trigger AFTER EVENT for record with id =3D 20; 3: Trigger BEFORE EVENT for record with id =3D 21; 4: Trigger AFTER EVENT for record with id =3D 21; The sequence of events for the second set of SQL statements is as follows: 1: Trigger BEFORE EVENT for record with id =3D 20; 2: Trigger BEFORE EVENT for record with id =3D 21; 3: Trigger AFTER EVENT for record with id =3D 20; 4: Trigger AFTER EVENT for record with id =3D 21; According to the example in the documentation - 'Chapter 16.4 Examples', th= e sequence of events for the DELETE is as follows: vac=3D> DELETE FROM ttest; INFO: trigf (fired before): there are 2 tuples in ttest INFO: trigf (fired after ): there are 1 tuples in ttest INFO: trigf (fired before): there are 1 tuples in ttest INFO: trigf (fired after ): there are 0 tuples in ttest So you can see that the documented sequence of events is not the same as wh= at actually happens. To prove this I created and ran the example from the documentation (cut and= paste exactly from the documentation). Here is the output that I got: CISX=3D# INSERT INTO ttest VALUES('100'); NOTICE: trigf (fired before): there are 0 tuples in ttest NOTICE: trigf (fired after ): there are 1 tuples in ttest INSERT 17497 1 CISX=3D# INSERT INTO ttest VALUES('101'); NOTICE: trigf (fired before): there are 1 tuples in ttest NOTICE: trigf (fired after ): there are 2 tuples in ttest INSERT 17498 1 CISX=3D# INSERT INTO ttest VALUES('102'); NOTICE: trigf (fired before): there are 2 tuples in ttest NOTICE: trigf (fired after ): there are 3 tuples in ttest INSERT 17499 1 CISX=3D# INSERT INTO ttest VALUES('122'); NOTICE: trigf (fired before): there are 3 tuples in ttest NOTICE: trigf (fired after ): there are 4 tuples in ttest INSERT 17500 1 CISX=3D# DELETE FROM ttest WHERE x >=3D '100'; NOTICE: trigf (fired before): there are 4 tuples in ttest NOTICE: trigf (fired before): there are 3 tuples in ttest NOTICE: trigf (fired before): there are 2 tuples in ttest NOTICE: trigf (fired before): there are 1 tuples in ttest NOTICE: trigf (fired after ): there are 0 tuples in ttest NOTICE: trigf (fired after ): there are 0 tuples in ttest NOTICE: trigf (fired after ): there are 0 tuples in ttest NOTICE: trigf (fired after ): there are 0 tuples in ttest DELETE 4 As you can see the actual sequence of events differs to what is documented = and what I had logically expected - hence why I was questioning whether the= re was a bug with triggers, albeit that I was pointing the finger at the wr= ong thing. Next time I want be so keen to come forward with a bug without i= nvestigating it further - sorry for that. Regards Donald Fraser.
pgsql-bugs by date: