On 1/4/2005 at 15:54 Paolo Vernazza wrote: >>It seems to me that recursion that never touches the same row twice is >>less an issue. That is a trigger that just updates all other rows in >>the table once should be fine. So one (I suspect hard to implement) >>idea would be to keep track of which rows have been touched as part of >>a trigger. Any row touched N times breaks out. This works for both >>your delete case, and update cases. >> >Mmmm... let's suppose that when deleting a row in the linke list table
>we update another table incrementing a counter so we can know how many >rows we have just deleted... > >CREATE TABLE list( > id INTEGER PRIMARY KEY, > next INTEGER REFERENCES list, > data BLOB > ); > >CREATE TABLE counter (value TEXT, count INTEGER); >INSERT INTO counter (value, count) VALUES ('deleted', 0); > > CREATE TRIGGER deep BEFORE DELETE ON list BEGIN > DELETE FROM list WHERE id=old.next; > UPDATE counter SET count=count+1 WHERE value='deleted'; > END; > > >It will reveal a loop on the second trigger because we are updating the >same row in the table "counter"... Good point. There is no way to solve the halting problem. No matter what limit we set, we need some way for the user to change the limits. In the end, limits are a convience for the programer who isn't thinking his triggers through. (not hard in a complex database where you are not the only one writing triggers) I present all my ideas as special cases where we can suspect something. We have already determined that a trigger that only deletes can never loop forever. On Update if a row is never touched more than once, we know there cannot be an infinite loop. In this case we can add the special case, a trigger on DELETE can never cause an infinite loop itself. (though of course it can hit other triggers which could loop themselves) I contend that we can keep adding special cases for a long time. I'm worried that checking all the special cases can easily make sqlite one of the slowest databases! Therefore I propose that all recursion checking be in code that can be excluded at compile time, in addition to run time changes to whatever limits we add. I could also see some embedded programers who have limits in their debug builds, but release builds are have none. (saves a a few bytes, something embedded programers will like) Note that it is not enough to detect out of memory situations. Several OSes will never fail malloc (except in the case where you are asking for memory than the hardware can address?), since they don't give you memory until you use it. Attempt to use memory when the system is out of it will cause your program to crash without warning! (linux 2.2 was this way, I think 2.6 will fail malloc)