/ Check-in [a8f6341d]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Add pager test cases. Change a condition in pager.c to NEVER().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: a8f6341d3b12d64ef56ed05226e3b4f183b8957d
User & Date: dan 2010-07-01 15:09:48
Context
2010-07-01
19:01
Add tests to pager1.test and pagerfault.test. check-in: c6e75950 user: dan tags: trunk
15:09
Add pager test cases. Change a condition in pager.c to NEVER(). check-in: a8f6341d user: dan tags: trunk
2010-06-30
10:36
Add further test cases. Fix an assert() in pager.c. check-in: 8e65c0e3 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/pager.c.

  5959   5959   /*
  5960   5960   ** Return TRUE if the pager is in a state where it is OK to change the
  5961   5961   ** journalmode.  Journalmode changes can only happen when the database
  5962   5962   ** is unmodified.
  5963   5963   */
  5964   5964   int sqlite3PagerOkToChangeJournalMode(Pager *pPager){
  5965   5965     if( pPager->dbModified ) return 0;
  5966         -  if( isOpen(pPager->jfd) && pPager->journalOff>0 ) return 0;
         5966  +  if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0;
  5967   5967     return 1;
  5968   5968   }
  5969   5969   
  5970   5970   /*
  5971   5971   ** Get/set the size-limit used for persistent journal files.
  5972   5972   **
  5973   5973   ** Setting the size limit to -1 means no limit is enforced.

Changes to src/test1.c.

  1898   1898   static int sqlite_abort(
  1899   1899     void *NotUsed,
  1900   1900     Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  1901   1901     int argc,              /* Number of arguments */
  1902   1902     char **argv            /* Text of each argument */
  1903   1903   ){
  1904   1904     assert( interp==0 );   /* This will always fail */
         1905  +  abort();
  1905   1906     return TCL_OK;
  1906   1907   }
  1907   1908   
  1908   1909   /*
  1909   1910   ** The following routine is a user-defined SQL function whose purpose
  1910   1911   ** is to test the sqlite_set_result() API.
  1911   1912   */

Changes to src/test_vfs.c.

   186    186   static int tvfsShmOpen(sqlite3_file*);
   187    187   static int tvfsShmLock(sqlite3_file*, int , int, int);
   188    188   static int tvfsShmMap(sqlite3_file*,int,int,int, void volatile **);
   189    189   static void tvfsShmBarrier(sqlite3_file*);
   190    190   static int tvfsShmClose(sqlite3_file*, int);
   191    191   
   192    192   static sqlite3_io_methods tvfs_io_methods = {
   193         -  2,                            /* iVersion */
          193  +  2,                              /* iVersion */
   194    194     tvfsClose,                      /* xClose */
   195    195     tvfsRead,                       /* xRead */
   196    196     tvfsWrite,                      /* xWrite */
   197    197     tvfsTruncate,                   /* xTruncate */
   198    198     tvfsSync,                       /* xSync */
   199    199     tvfsFileSize,                   /* xFileSize */
   200    200     tvfsLock,                       /* xLock */
................................................................................
   571    571     Tcl_IncrRefCount(pId);
   572    572     pFd->pShmId = pId;
   573    573     Tcl_ResetResult(p->interp);
   574    574   
   575    575     rc = sqlite3OsOpen(PARENTVFS(pVfs), zName, pFd->pReal, flags, pOutFlags);
   576    576     if( pFd->pReal->pMethods ){
   577    577       sqlite3_io_methods *pMethods;
   578         -    pMethods = (sqlite3_io_methods *)ckalloc(sizeof(sqlite3_io_methods));
   579         -    memcpy(pMethods, &tvfs_io_methods, sizeof(sqlite3_io_methods));
   580         -    if( ((Testvfs *)pVfs->pAppData)->isNoshm ){
          578  +    int nByte;
          579  +
          580  +    if( pVfs->iVersion>1 ){
          581  +      nByte = sizeof(sqlite3_io_methods);
          582  +    }else{
          583  +      nByte = offsetof(sqlite3_io_methods, xShmOpen);
          584  +    }
          585  +
          586  +    pMethods = (sqlite3_io_methods *)ckalloc(nByte);
          587  +    memcpy(pMethods, &tvfs_io_methods, nByte);
          588  +    pMethods->iVersion = pVfs->iVersion;
          589  +    if( pVfs->iVersion>1 && ((Testvfs *)pVfs->pAppData)->isNoshm ){
   581    590         pMethods->xShmOpen = 0;
   582    591         pMethods->xShmClose = 0;
   583    592         pMethods->xShmLock = 0;
   584    593         pMethods->xShmBarrier = 0;
   585    594         pMethods->xShmMap = 0;
   586    595       }
   587    596       pFile->pMethods = pMethods;
................................................................................
  1296   1305     int nByte;                      /* Bytes of space to allocate at p */
  1297   1306   
  1298   1307     int i;
  1299   1308     int isNoshm = 0;                /* True if -noshm is passed */
  1300   1309     int isDefault = 0;              /* True if -default is passed */
  1301   1310     int szOsFile = 0;               /* Value passed to -szosfile */
  1302   1311     int mxPathname = -1;            /* Value passed to -mxpathname */
         1312  +  int iVersion = 2;               /* Value passed to -iversion */
  1303   1313   
  1304   1314     if( objc<2 || 0!=(objc%2) ) goto bad_args;
  1305   1315     for(i=2; i<objc; i += 2){
  1306   1316       int nSwitch;
  1307   1317       char *zSwitch;
  1308   1318       zSwitch = Tcl_GetStringFromObj(objv[i], &nSwitch); 
  1309   1319   
................................................................................
  1322   1332           return TCL_ERROR;
  1323   1333         }
  1324   1334       }
  1325   1335       else if( nSwitch>2 && 0==strncmp("-mxpathname", zSwitch, nSwitch) ){
  1326   1336         if( Tcl_GetIntFromObj(interp, objv[i+1], &mxPathname) ){
  1327   1337           return TCL_ERROR;
  1328   1338         }
         1339  +    }
         1340  +    else if( nSwitch>2 && 0==strncmp("-iversion", zSwitch, nSwitch) ){
         1341  +      if( Tcl_GetIntFromObj(interp, objv[i+1], &iVersion) ){
         1342  +        return TCL_ERROR;
         1343  +      }
  1329   1344       }
  1330   1345       else{
  1331   1346         goto bad_args;
  1332   1347       }
  1333   1348     }
  1334   1349   
  1335   1350     if( szOsFile<sizeof(TestvfsFile) ){
................................................................................
  1355   1370   
  1356   1371     p->zName = (char *)&p[1];
  1357   1372     memcpy(p->zName, zVfs, strlen(zVfs)+1);
  1358   1373   
  1359   1374     pVfs = (sqlite3_vfs *)ckalloc(sizeof(sqlite3_vfs));
  1360   1375     memcpy(pVfs, &tvfs_vfs, sizeof(sqlite3_vfs));
  1361   1376     pVfs->pAppData = (void *)p;
         1377  +  pVfs->iVersion = iVersion;
  1362   1378     pVfs->zName = p->zName;
  1363   1379     pVfs->mxPathname = p->pParent->mxPathname;
  1364   1380     if( mxPathname>=0 && mxPathname<pVfs->mxPathname ){
  1365   1381       pVfs->mxPathname = mxPathname;
  1366   1382     }
  1367   1383     pVfs->szOsFile = szOsFile;
  1368   1384     p->pVfs = pVfs;
................................................................................
  1370   1386     p->mask = TESTVFS_ALL_MASK;
  1371   1387   
  1372   1388     sqlite3_vfs_register(pVfs, isDefault);
  1373   1389   
  1374   1390     return TCL_OK;
  1375   1391   
  1376   1392    bad_args:
  1377         -  Tcl_WrongNumArgs(interp, 1, objv, "VFSNAME ?-noshm BOOL? ?-default BOOL? ?-mxpathname INT? ?-szosfile INT?");
         1393  +  Tcl_WrongNumArgs(interp, 1, objv, "VFSNAME ?-noshm BOOL? ?-default BOOL? ?-mxpathname INT? ?-szosfile INT? ?-iversion INT?");
  1378   1394     return TCL_ERROR;
  1379   1395   }
  1380   1396   
  1381   1397   int Sqlitetestvfs_Init(Tcl_Interp *interp){
  1382   1398     Tcl_CreateObjCommand(interp, "testvfs", testvfs_cmd, 0, 0);
  1383   1399     return TCL_OK;
  1384   1400   }
  1385   1401   
  1386   1402   #endif

Changes to test/pager1.test.

  1088   1088     }] {
  1089   1089       do_execsql_test pager1-7.1.$tn.1 $sql $res
  1090   1090       catch { set J -1 ; set J [file size test.db-journal] }
  1091   1091       catch { set W -1 ; set W [file size test.db-wal] }
  1092   1092       do_test pager1-7.1.$tn.2 { list $J $W } [list $js $ws]
  1093   1093     }
  1094   1094   }
         1095  +
         1096  +do_test pager1-7.2.1 {
         1097  +  faultsim_delete_and_reopen
         1098  +  execsql {
         1099  +    PRAGMA locking_mode = EXCLUSIVE;
         1100  +    CREATE TABLE t1(a, b);
         1101  +    BEGIN;
         1102  +      PRAGMA journal_mode = delete;
         1103  +      PRAGMA journal_mode = truncate;
         1104  +  }
         1105  +} {exclusive delete truncate}
         1106  +do_test pager1-7.2.2 {
         1107  +  execsql { INSERT INTO t1 VALUES(1, 2) }
         1108  +  execsql { PRAGMA journal_mode = persist }
         1109  +} {truncate}
         1110  +do_test pager1-7.2.3 {
         1111  +  execsql { COMMIT }
         1112  +  execsql {
         1113  +    PRAGMA journal_mode = persist;
         1114  +    PRAGMA journal_size_limit;
         1115  +  }
         1116  +} {persist -1}
  1095   1117   
  1096   1118   #-------------------------------------------------------------------------
  1097   1119   # The following tests, pager1-8.*, test that the special filenames 
  1098   1120   # ":memory:" and "" open temporary databases.
  1099   1121   #
  1100   1122   foreach {tn filename} {
  1101   1123     1 :memory:
................................................................................
  1752   1774       BEGIN;
  1753   1775       INSERT INTO t2 VALUES('xxxx');
  1754   1776     }
  1755   1777     recursive_select 32
  1756   1778     execsql COMMIT
  1757   1779   } {}
  1758   1780   
  1759         -  
         1781  +#-------------------------------------------------------------------------
         1782  +# Test that a WAL database may not be opened if:
         1783  +#
         1784  +#   pager1-21.1.*: The VFS has an iVersion less than 2, or
         1785  +#   pager1-21.2.*: The VFS does not provide xShmXXX() methods.
         1786  +#
         1787  +do_test pager1-21.0 {
         1788  +  faultsim_delete_and_reopen
         1789  +  execsql {
         1790  +    PRAGMA journal_mode = WAL;
         1791  +    CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def');
         1792  +    INSERT INTO ko DEFAULT VALUES;
         1793  +  }
         1794  +} {wal}
         1795  +do_test pager1-21.1 {
         1796  +  testvfs tv -noshm 1
         1797  +  sqlite3 db2 test.db -vfs tv
         1798  +  catchsql { SELECT * FROM ko } db2
         1799  +} {1 {unable to open database file}}
         1800  +db2 close
         1801  +tv delete
         1802  +do_test pager1-21.2 {
         1803  +breakpoint
         1804  +  testvfs tv -iversion 1
         1805  +  sqlite3 db2 test.db -vfs tv
         1806  +  catchsql { SELECT * FROM ko } db2
         1807  +} {1 {unable to open database file}}
         1808  +db2 close
         1809  +tv delete
         1810  +
         1811  +#-------------------------------------------------------------------------
         1812  +# Test that a "PRAGMA wal_checkpoint":
         1813  +#
         1814  +#   pager1-22.1.*: is a no-op on a non-WAL db, and
         1815  +#   pager1-22.2.*: does not cause xSync calls with a synchronous=off db.
         1816  +#
         1817  +do_test pager1-22.1.1 {
         1818  +  faultsim_delete_and_reopen
         1819  +  execsql {
         1820  +    CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def');
         1821  +    INSERT INTO ko DEFAULT VALUES;
         1822  +  }
         1823  +  execsql { PRAGMA wal_checkpoint }
         1824  +} {}
         1825  +do_test pager1-22.2.1 {
         1826  +  testvfs tv -default 1
         1827  +  tv filter xSync
         1828  +  tv script xSyncCb
         1829  +  proc xSyncCb {args} {incr ::synccount}
         1830  +  set ::synccount 0
         1831  +  sqlite3 db test.db
         1832  +  execsql {
         1833  +    PRAGMA synchronous = off;
         1834  +    PRAGMA journal_mode = WAL;
         1835  +    INSERT INTO ko DEFAULT VALUES;
         1836  +  }
         1837  +  execsql { PRAGMA wal_checkpoint }
         1838  +  set synccount
         1839  +} {0}
         1840  +db close
         1841  +tv delete
         1842  +
         1843  +#-------------------------------------------------------------------------
         1844  +# Tests for changing journal mode.
         1845  +#
         1846  +#   pager1-23.1.*: Test that when changing from PERSIST to DELETE mode,
         1847  +#                  the journal file is deleted.
         1848  +#
         1849  +#   pager1-23.2.*: Same test as above, but while a shared lock is held
         1850  +#                  on the database file.
         1851  +#
         1852  +#   pager1-23.3.*: Same test as above, but while a reserved lock is held
         1853  +#                  on the database file.
         1854  +#
         1855  +#   pager1-23.4.*: And, for fun, while holding an exclusive lock.
         1856  +#
         1857  +#   pager1-23.5.*: Try to set various different journal modes with an
         1858  +#                  in-memory database (only MEMORY and OFF should work).
         1859  +#
         1860  +do_test pager1-23.1.1 {
         1861  +  faultsim_delete_and_reopen
         1862  +  execsql {
         1863  +    PRAGMA journal_mode = PERSIST;
         1864  +    CREATE TABLE t1(a, b);
         1865  +  }
         1866  +  file exists test.db-journal
         1867  +} {1}
         1868  +do_test pager1-23.1.2 {
         1869  +  execsql { PRAGMA journal_mode = DELETE }
         1870  +  file exists test.db-journal
         1871  +} {0}
         1872  +
         1873  +do_test pager1-23.2.1 {
         1874  +  execsql {
         1875  +    PRAGMA journal_mode = PERSIST;
         1876  +    INSERT INTO t1 VALUES('Canberra', 'ACT');
         1877  +  }
         1878  +  db eval { SELECT * FROM t1 } {
         1879  +    db eval { PRAGMA journal_mode = DELETE }
         1880  +  }
         1881  +  execsql { PRAGMA journal_mode }
         1882  +} {delete}
         1883  +do_test pager1-23.2.2 {
         1884  +  file exists test.db-journal
         1885  +} {0}
         1886  +
         1887  +do_test pager1-23.3.1 {
         1888  +  execsql {
         1889  +    PRAGMA journal_mode = PERSIST;
         1890  +    INSERT INTO t1 VALUES('Darwin', 'NT');
         1891  +    BEGIN IMMEDIATE;
         1892  +  }
         1893  +  db eval { PRAGMA journal_mode = DELETE }
         1894  +  execsql { PRAGMA journal_mode }
         1895  +} {delete}
         1896  +do_test pager1-23.3.2 {
         1897  +  file exists test.db-journal
         1898  +} {0}
         1899  +do_test pager1-23.3.3 {
         1900  +  execsql COMMIT
         1901  +} {}
         1902  +
         1903  +do_test pager1-23.4.1 {
         1904  +  execsql {
         1905  +    PRAGMA journal_mode = PERSIST;
         1906  +    INSERT INTO t1 VALUES('Adelaide', 'SA');
         1907  +    BEGIN EXCLUSIVE;
         1908  +  }
         1909  +  db eval { PRAGMA journal_mode = DELETE }
         1910  +  execsql { PRAGMA journal_mode }
         1911  +} {delete}
         1912  +do_test pager1-23.4.2 {
         1913  +  file exists test.db-journal
         1914  +} {0}
         1915  +do_test pager1-23.4.3 {
         1916  +  execsql COMMIT
         1917  +} {}
         1918  +
         1919  +do_test pager1-23.5.1 {
         1920  +  faultsim_delete_and_reopen
         1921  +  sqlite3 db :memory:
         1922  +} {}
         1923  +foreach {tn mode possible} {
         1924  +  2  off      1
         1925  +  3  memory   1
         1926  +  4  persist  0
         1927  +  5  delete   0
         1928  +  6  wal      0
         1929  +  7  truncate 0
         1930  +} {
         1931  +  do_test pager1-23.5.$tn.1 {
         1932  +    execsql "PRAGMA journal_mode = off"
         1933  +    execsql "PRAGMA journal_mode = $mode"
         1934  +  } [if $possible {list $mode} {list off}]
         1935  +  do_test pager1-23.5.$tn.2 {
         1936  +    execsql "PRAGMA journal_mode = memory"
         1937  +    execsql "PRAGMA journal_mode = $mode"
         1938  +  } [if $possible {list $mode} {list memory}]
         1939  +}
         1940  +do_test pager1-23.8.1 {
         1941  +  execsql {PRAGMA locking_mode = normal}
         1942  +} {exclusive}
         1943  +do_test pager1-23.8.2 {
         1944  +  execsql {PRAGMA locking_mode = exclusive}
         1945  +} {exclusive}
         1946  +do_test pager1-23.8.3 {
         1947  +  execsql {PRAGMA locking_mode}
         1948  +} {exclusive}
         1949  +do_test pager1-23.8.4 {
         1950  +  execsql {PRAGMA main.locking_mode}
         1951  +} {exclusive}
         1952  +
  1760   1953   
  1761   1954   finish_test
  1762   1955   

Changes to test/pagerfault.test.

   610    610     faultsim_restore_and_reopen
   611    611   } -body {
   612    612     execsql { CREATE TABLE xx(a, b) }
   613    613   } -test {
   614    614     faultsim_test_result {0 {}}
   615    615   }
   616    616   
   617         -}
   618         -
   619    617   
   620    618   #---------------------------------------------------------------------------
   621    619   # Test fault injection into a small backup operation.
   622    620   #
   623    621   do_test pagerfault-14-pre1 {
   624    622     faultsim_delete_and_reopen
   625    623     db func a_string a_string;
................................................................................
   708    706     }
   709    707   } -test {
   710    708     faultsim_test_result {0 {exclusive wal delete wal persist}}
   711    709     faultsim_integrity_check
   712    710   }
   713    711   
   714    712   
          713  +#-------------------------------------------------------------------------
          714  +# Test fault injection while changing into and out of WAL mode.
          715  +#
          716  +do_test pagerfault-17-pre1 {
          717  +  faultsim_delete_and_reopen
          718  +  execsql {
          719  +    CREATE TABLE t1(a PRIMARY KEY, b);
          720  +    INSERT INTO t1 VALUES(1862, 'Botha');
          721  +    INSERT INTO t1 VALUES(1870, 'Smuts');
          722  +    INSERT INTO t1 VALUES(1866, 'Hertzog');
          723  +  }
          724  +  faultsim_save_and_close
          725  +} {}
          726  +do_faultsim_test pagerfault-17a -prep {
          727  +  faultsim_restore_and_reopen
          728  +} -body {
          729  +  execsql {
          730  +    PRAGMA journal_mode = wal;
          731  +    PRAGMA journal_mode = delete;
          732  +  }
          733  +} -test {
          734  +  faultsim_test_result {0 {wal delete}}
          735  +  faultsim_integrity_check
          736  +}
          737  +do_faultsim_test pagerfault-17b -prep {
          738  +  faultsim_restore_and_reopen
          739  +  execsql { PRAGMA synchronous = OFF }
          740  +} -body {
          741  +  execsql {
          742  +    PRAGMA journal_mode = wal;
          743  +    INSERT INTO t1 VALUES(22, 'Clarke');
          744  +    PRAGMA journal_mode = delete;
          745  +  }
          746  +} -test {
          747  +  faultsim_test_result {0 {wal delete}}
          748  +  faultsim_integrity_check
          749  +}
          750  +do_faultsim_test pagerfault-17c -prep {
          751  +  faultsim_restore_and_reopen
          752  +  execsql { 
          753  +    PRAGMA locking_mode = exclusive;
          754  +    PRAGMA journal_mode = wal;
          755  +  }
          756  +} -body {
          757  +  execsql { PRAGMA journal_mode = delete }
          758  +} -test {
          759  +  faultsim_test_result {0 delete}
          760  +  faultsim_integrity_check
          761  +}
          762  +do_faultsim_test pagerfault-17d -prep {
          763  +  faultsim_restore_and_reopen
          764  +  sqlite3 db2 test.db
          765  +  execsql { PRAGMA journal_mode = delete }
          766  +  execsql { PRAGMA journal_mode = wal }
          767  +  execsql { INSERT INTO t1 VALUES(99, 'Bradman') } db2
          768  +} -body {
          769  +  execsql { PRAGMA journal_mode = delete }
          770  +} -test {
          771  +  faultsim_test_result {1 {database is locked}}
          772  +  faultsim_integrity_check
          773  +}
          774  +do_faultsim_test pagerfault-17e -prep {
          775  +  faultsim_restore_and_reopen
          776  +  sqlite3 db2 test.db
          777  +  execsql { PRAGMA journal_mode = delete }
          778  +  execsql { PRAGMA journal_mode = wal }
          779  +  set ::chan [launch_testfixture]
          780  +  testfixture $::chan {
          781  +    sqlite3 db test.db
          782  +    db eval { INSERT INTO t1 VALUES(101, 'Latham') }
          783  +  }
          784  +  catch { testfixture $::chan sqlite_abort }
          785  +  catch { close $::chan }
          786  +} -body {
          787  +  execsql { PRAGMA journal_mode = delete }
          788  +} -test {
          789  +  faultsim_test_result {0 delete}
          790  +  faultsim_integrity_check
          791  +}
          792  +
          793  +#-------------------------------------------------------------------------
          794  +# Test fault-injection when changing from journal_mode=persist to 
          795  +# journal_mode=delete (this involves deleting the journal file).
          796  +#
          797  +do_test pagerfault-18-pre1 {
          798  +  faultsim_delete_and_reopen
          799  +  execsql {
          800  +    CREATE TABLE qq(x);
          801  +    INSERT INTO qq VALUES('Herbert');
          802  +    INSERT INTO qq VALUES('Macalister');
          803  +    INSERT INTO qq VALUES('Mackenzie');
          804  +    INSERT INTO qq VALUES('Lilley');
          805  +    INSERT INTO qq VALUES('Palmer');
          806  +  }
          807  +  faultsim_save_and_close
          808  +} {}
          809  +do_faultsim_test pagerfault-18 -prep {
          810  +  faultsim_restore_and_reopen
          811  +  execsql {
          812  +    PRAGMA journal_mode = PERSIST;
          813  +    INSERT INTO qq VALUES('Beatty');
          814  +  }
          815  +} -body {
          816  +  execsql { PRAGMA journal_mode = delete }
          817  +} -test {
          818  +  faultsim_test_result {0 delete}
          819  +  faultsim_integrity_check
          820  +}
          821  +
          822  +}
          823  +
          824  +do_faultsim_test pagerfault-19a -prep {
          825  +  sqlite3 db :memory:
          826  +  db func a_string a_string
          827  +  execsql {
          828  +    PRAGMA auto_vacuum = FULL;
          829  +    BEGIN;
          830  +      CREATE TABLE t1(a, b);
          831  +      INSERT INTO t1 VALUES(a_string(5000), a_string(6000));
          832  +    COMMIT;
          833  +  }
          834  +} -body {
          835  +  execsql { 
          836  +    CREATE TABLE t2(a, b);
          837  +    INSERT INTO t2 SELECT * FROM t1; 
          838  +    DELETE FROM t1;
          839  +  }
          840  +} -test {
          841  +  faultsim_test_result {0 {}}
          842  +}
          843  +
          844  +do_test pagerfault-19-pre1 {
          845  +  faultsim_delete_and_reopen
          846  +  execsql {
          847  +    PRAGMA auto_vacuum = FULL;
          848  +    CREATE TABLE t1(x); INSERT INTO t1 VALUES(1);
          849  +    CREATE TABLE t2(x); INSERT INTO t2 VALUES(2);
          850  +    CREATE TABLE t3(x); INSERT INTO t3 VALUES(3);
          851  +    CREATE TABLE t4(x); INSERT INTO t4 VALUES(4);
          852  +    CREATE TABLE t5(x); INSERT INTO t5 VALUES(5);
          853  +    CREATE TABLE t6(x); INSERT INTO t6 VALUES(6);
          854  +  }
          855  +  faultsim_save_and_close
          856  +} {}
          857  +do_faultsim_test pagerfault-19b -prep {
          858  +  faultsim_restore_and_reopen
          859  +} -body {
          860  +  execsql { 
          861  +    BEGIN;
          862  +      UPDATE t4 SET x = x+1;
          863  +      UPDATE t6 SET x = x+1;
          864  +      SAVEPOINT one;
          865  +        UPDATE t3 SET x = x+1;
          866  +        SAVEPOINT two;
          867  +          DROP TABLE t2;
          868  +      ROLLBACK TO one;
          869  +    COMMIT;
          870  +    SELECT * FROM t3;
          871  +    SELECT * FROM t4;
          872  +    SELECT * FROM t6;
          873  +  }
          874  +} -test {
          875  +  faultsim_test_result {0 {3 5 7}}
          876  +}
          877  +
          878  +do_test pagerfault-20-pre1 {
          879  +  faultsim_delete_and_reopen
          880  +  db func a_string a_string
          881  +  execsql {
          882  +    CREATE TABLE x1(x, y, z, PRIMARY KEY(y, z));
          883  +    INSERT INTO x1 VALUES(a_string(400), a_string(500), a_string(600));
          884  +    INSERT INTO x1 SELECT a_string(600), a_string(400), a_string(500) FROM x1;
          885  +    INSERT INTO x1 SELECT a_string(500), a_string(600), a_string(400) FROM x1;
          886  +    INSERT INTO x1 SELECT a_string(400), a_string(500), a_string(600) FROM x1;
          887  +    INSERT INTO x1 SELECT a_string(600), a_string(400), a_string(500) FROM x1;
          888  +    INSERT INTO x1 SELECT a_string(500), a_string(600), a_string(400) FROM x1;
          889  +    INSERT INTO x1 SELECT a_string(400), a_string(500), a_string(600) FROM x1;
          890  +  }
          891  +  faultsim_save_and_close
          892  +} {}
          893  +do_faultsim_test pagerfault-20 -prep {
          894  +  faultsim_restore_and_reopen
          895  +  db func a_string a_string
          896  +} -body {
          897  +  execsql { 
          898  +    BEGIN;
          899  +    UPDATE x1 SET z = a_string(300);
          900  +    DELETE FROM x1 WHERE rowid<32;
          901  +    COMMIT;
          902  +  }
          903  +} -test {
          904  +  faultsim_test_result {0 {}}
          905  +  faultsim_integrity_check
          906  +  set nRow [db one {SELECT count(*) FROM x1}]
          907  +  if {$nRow!=33 && $nRow!=64} {error "Wrong number of rows $nRow"}
          908  +}
   715    909   
   716    910   finish_test