/ Check-in [e5d42c69]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix savepoint related bugs. A rollback caused by an IO error or "OR ROLLBACK" clause while one or more savepoints were open was leaving the sqlite3 structure in an invalid state. (CVS 6128)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e5d42c69a3b325ca12f53184e33964230acbdd1f
User & Date: danielk1977 2009-01-07 08:12:16
Context
2009-01-07
10:35
Fix a problem with reverting a 'DROP TABLE' command executed inside of a savepoint on an auto-vacuum database. (CVS 6129) check-in: 3a4bb832 user: danielk1977 tags: trunk
08:12
Fix savepoint related bugs. A rollback caused by an IO error or "OR ROLLBACK" clause while one or more savepoints were open was leaving the sqlite3 structure in an invalid state. (CVS 6128) check-in: e5d42c69 user: danielk1977 tags: trunk
03:59
Add a HIGHSTRESS parameter to the sqlite3_config_alt_pcache debugging command in the test harness - to force calling pagerStress() more frequently. (CVS 6127) check-in: e426860b user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbeaux.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used for creating, destroying, and populating
    13     13   ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.)  Prior
    14     14   ** to version 2.8.7, all this code was combined into the vdbe.c source file.
    15     15   ** But that file was getting too big so this subroutines were split out.
    16     16   **
    17         -** $Id: vdbeaux.c,v 1.429 2009/01/03 14:04:39 drh Exp $
           17  +** $Id: vdbeaux.c,v 1.430 2009/01/07 08:12:16 danielk1977 Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include <ctype.h>
    21     21   #include "vdbeInt.h"
    22     22   
    23     23   
    24     24   
................................................................................
  1579   1579             xFunc = sqlite3BtreeRollbackStmt;
  1580   1580           }else{
  1581   1581             /* We are forced to roll back the active transaction. Before doing
  1582   1582             ** so, abort any other statements this handle currently has active.
  1583   1583             */
  1584   1584             invalidateCursorsOnModifiedBtrees(db);
  1585   1585             sqlite3RollbackAll(db);
         1586  +          sqlite3CloseSavepoints(db);
  1586   1587             db->autoCommit = 1;
  1587   1588           }
  1588   1589         }
  1589   1590       }
  1590   1591     
  1591   1592       /* If the auto-commit flag is set and this is the only active vdbe, then
  1592   1593       ** we do either a commit or rollback of the current transaction. 
................................................................................
  1623   1624             xFunc = sqlite3BtreeCommitStmt;
  1624   1625           } 
  1625   1626         }else if( p->errorAction==OE_Abort ){
  1626   1627           xFunc = sqlite3BtreeRollbackStmt;
  1627   1628         }else{
  1628   1629           invalidateCursorsOnModifiedBtrees(db);
  1629   1630           sqlite3RollbackAll(db);
         1631  +        sqlite3CloseSavepoints(db);
  1630   1632           db->autoCommit = 1;
  1631   1633         }
  1632   1634       }
  1633   1635     
  1634   1636       /* If xFunc is not NULL, then it is one of sqlite3BtreeRollbackStmt or
  1635   1637       ** sqlite3BtreeCommitStmt. Call it once on each backend. If an error occurs
  1636   1638       ** and the return code is still SQLITE_OK, set the return code to the new

Changes to test/savepoint.test.

     5      5   #
     6      6   #    May you do good and not evil.
     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   #
    12         -# $Id: savepoint.test,v 1.8 2009/01/06 13:40:08 danielk1977 Exp $
           12  +# $Id: savepoint.test,v 1.9 2009/01/07 08:12:16 danielk1977 Exp $
    13     13   
    14     14   set testdir [file dirname $argv0]
    15     15   source $testdir/tester.tcl
    16     16   
    17     17   
    18     18   #----------------------------------------------------------------------
    19     19   # The following tests - savepoint-1.* - test that the SAVEPOINT, RELEASE
................................................................................
   740    740     }
   741    741   } {}
   742    742   integrity_check savepoint-11.7
   743    743   do_test savepoint-11.6 {
   744    744     execsql { ROLLBACK }
   745    745     file size test.db
   746    746   } {8192}
          747  +
          748  +#-------------------------------------------------------------------------
          749  +# The following tests - savepoint-12.* - test the interaction of 
          750  +# savepoints and "ON CONFLICT ROLLBACK" clauses.
          751  +# 
          752  +do_test savepoint-12.1 {
          753  +  execsql {
          754  +    CREATE TABLE t4(a PRIMARY KEY, b);
          755  +    INSERT INTO t4 VALUES(1, 'one');
          756  +  }
          757  +} {}
          758  +do_test savepoint-12.2 {
          759  +  # The final statement of the following SQL hits a constraint when the
          760  +  # conflict handling mode is "OR ROLLBACK" and there are a couple of
          761  +  # open savepoints. At one point this would fail to clear the internal
          762  +  # record of the open savepoints, resulting in an assert() failure 
          763  +  # later on.
          764  +  # 
          765  +  catchsql {
          766  +    BEGIN;
          767  +      INSERT INTO t4 VALUES(2, 'two');
          768  +      SAVEPOINT sp1;
          769  +        INSERT INTO t4 VALUES(3, 'three');
          770  +        SAVEPOINT sp2;
          771  +          INSERT OR ROLLBACK INTO t4 VALUES(1, 'one');
          772  +  }
          773  +} {1 {column a is not unique}}
          774  +do_test savepoint-12.3 {
          775  +  sqlite3_get_autocommit db
          776  +} {1}
          777  +do_test savepoint-12.4 {
          778  +  execsql { SAVEPOINT one }
          779  +} {}
   747    780   
   748    781   finish_test
   749    782   

Changes to test/savepoint3.test.

     5      5   #
     6      6   #    May you do good and not evil.
     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   #
    12         -# $Id: savepoint3.test,v 1.2 2009/01/01 15:20:37 danielk1977 Exp $
           12  +# $Id: savepoint3.test,v 1.3 2009/01/07 08:12:16 danielk1977 Exp $
    13     13   
    14     14   set testdir [file dirname $argv0]
    15     15   source $testdir/tester.tcl
    16     16   
    17     17   source $testdir/malloc_common.tcl
    18     18   
    19     19   do_malloc_test savepoint3-1 -sqlprep {
................................................................................
    54     54       DELETE FROM t1 WHERE rowid < 5;
    55     55       SAVEPOINT two;
    56     56         DELETE FROM t1 WHERE rowid > 10;
    57     57       ROLLBACK TO two;
    58     58     ROLLBACK TO one;
    59     59     RELEASE one;
    60     60   }
           61  +
           62  +do_ioerr_test savepoint3.3 -sqlprep {
           63  +  CREATE TABLE t1(a, b, c);
           64  +  INSERT INTO t1 VALUES(1, randstr(1000,1000), randstr(1000,1000));
           65  +  INSERT INTO t1 VALUES(2, randstr(1000,1000), randstr(1000,1000));
           66  +} -sqlbody {
           67  +  BEGIN;
           68  +    UPDATE t1 SET a = 3 WHERE a = 1;
           69  +    SAVEPOINT one;
           70  +      UPDATE t1 SET a = 4 WHERE a = 2;
           71  +  COMMIT;
           72  +} -cleanup {
           73  +  db eval {
           74  +    SAVEPOINT one;
           75  +    RELEASE one;
           76  +  }
           77  +}
    61     78   
    62     79   finish_test
    63     80