SQLite

View Ticket
Login
2009-10-16
20:55 Fixed ticket [f777251d]: Assertion fault following ROLLBACK with running queries plus 3 other changes (artifact: d0214927 user: drh)
14:55
Experimental fix for [f777251dc7]. This may be changed yet. (check-in: 174477bc user: dan tags: trunk)
2009-10-15
23:03
When a forced rollback occurs, cause all active statements on the same database connection to halt immediately with an SQLITE_ABORT error code. This is a partial fix to ticket [f777251dc7]. (Closed-Leaf check-in: f256bc07 user: drh tags: trunk, experimental)
19:45
On any rollback, immediately interrupt all running statements on the same database connection. This is a partial fix for ticket [f777251dc7]. (Closed-Leaf check-in: c304b44c user: drh tags: experimental)
18:06 Ticket [f777251d] Assertion fault following ROLLBACK with running queries status still Open with 1 other change (artifact: c960b09e user: drh)
17:17 Ticket [f777251d]: 1 change (artifact: 0cd02a47 user: drh)
17:16 Ticket [f777251d]: 3 changes (artifact: a05e9078 user: drh)
16:58 New ticket [f777251d]. (artifact: de4eb17b user: drh)

Ticket Hash: f777251dc7abcf45d3f3e86efd09d7951132c30b
Title: Assertion fault following ROLLBACK with running queries
Status: Fixed Type: Code_Defect
Severity: Critical Priority: Immediate
Subsystem: B-Tree Resolution: Fixed
Last Modified: 2009-10-16 20:55:03
Version Found In: 3.6.19
Description:
The following TCL script (run on a TCL interpreter that has the SQLite extension installed) generates an assertion fault:
   file delete -force b2.db
   sqlite3 db b2.db
   db eval {
     CREATE TEMP TABLE t1(x UNIQUE);
     INSERT INTO t1 VALUES(1);
     CREATE TABLE t2(x, y);
     INSERT INTO t2 VALUES(1, 2);
     CREATE TEMP TABLE t3(w, z);
   }
   proc force_rollback {} {
     catch {db eval {INSERT OR ROLLBACK INTO t1 VALUES(1)}}
   }
   db function force_rollback force_rollback
   db eval {
     BEGIN IMMEDIATE;
   }
   db eval {
     SELECT x, force_rollback(), EXISTS(SELECT 1 FROM t3 WHERE w=x) FROM t2
   } {
     puts x=$x
   }

Bisecting show the problem was introduced by check-in [c76a366ed4]. (2009-07-04, version 3.6.17)

The failed assert() is the same one reported as Firefox bug 520445.


drh added on 2009-10-15 17:16:17:
A slightly different script causes problems going all the way back to version 3.1.3 (2005-02-19):

  file delete -force b2.db
  sqlite3 db b2.db
  db eval {
    CREATE TEMP TABLE t1(x UNIQUE);
    INSERT INTO t1 VALUES(1);
    CREATE TABLE t2(x, y);
    INSERT INTO t2 VALUES(1, 2);
  }
  proc force_rollback {} {
    set rc [catch {db eval {INSERT OR ROLLBACK INTO t1 VALUES(1)}} msg]
  }
  db function force_rollback force_rollback
  db eval {
    BEGIN IMMEDIATE;
    CREATE TEMP TABLE t3(w, z);
  }
  db eval {
    SELECT x, force_rollback(), EXISTS(SELECT 1 FROM t3 WHERE w=x) FROM t2
  } {
    puts x=$x
  }

drh added on 2009-10-15 18:06:16:
Here is another way to hit the same assert() that does not use the OR ROLLBACK clause. We believe that this is the path that Firefox is using to reach the problem. This route to the assert() was first opened in 3.6.17

  file delete -force b2.db
  sqlite3 db b2.db
  db eval {
    CREATE TEMP TABLE t1(x);
    CREATE TABLE t2(x);
    CREATE TABLE t3(x);
  
    INSERT INTO t1 VALUES(1);
    INSERT INTO t1 VALUES(2);
    INSERT INTO t2 VALUES(1);
    INSERT INTO t2 VALUES(2);
  }
  proc ins {} { db eval {INSERT INTO t3 VALUES('hello')} }
  db function ins ins
  
  db eval { SELECT ins() AS x FROM t2 UNION ALL SELECT ins() AS x FROM t1 }

drh added on 2009-10-16 20:55:03:
Fixed by check-in [174477bca05d019e663fd2b7cd031189ab2e010a]