persistentstorage/sqlite3api/TEST/TclScript/incrvacuum.test
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 # 2007 April 26
       
     2 #
       
     3 # The author disclaims copyright to this source code.  In place of
       
     4 # a legal notice, here is a blessing:
       
     5 #
       
     6 #    May you do good and not evil.
       
     7 #    May you find forgiveness for yourself and forgive others.
       
     8 #    May you share freely, never taking more than you give.
       
     9 #
       
    10 #***********************************************************************
       
    11 # This file implements regression tests for SQLite library.  The
       
    12 # focus of this file is testing the incremental vacuum feature.
       
    13 #
       
    14 # Note: There are also some tests for incremental vacuum and IO 
       
    15 # errors in incrvacuum_ioerr.test.
       
    16 #
       
    17 # $Id: incrvacuum.test,v 1.20 2008/09/10 10:57:28 danielk1977 Exp $
       
    18 
       
    19 set testdir [file dirname $argv0]
       
    20 source $testdir/tester.tcl
       
    21 
       
    22 # If this build of the library does not support auto-vacuum, omit this
       
    23 # whole file.
       
    24 ifcapable {!autovacuum || !pragma} {
       
    25   finish_test
       
    26   return
       
    27 }
       
    28 
       
    29 #---------------------------------------------------------------------
       
    30 # Test the pragma on an empty database.
       
    31 #
       
    32 do_test incrvacuum-1.1 {
       
    33   execsql {
       
    34     pragma auto_vacuum;
       
    35   }
       
    36 } $sqlite_options(default_autovacuum)
       
    37 do_test incrvacuum-1.2.0 {
       
    38   # File size is sometimes 1 instead of 0 due to the hack we put in
       
    39   # to work around ticket #3260.  Search for comments on #3260 in
       
    40   # os_unix.c.
       
    41   expr {[file size test.db] > 1}
       
    42 } {0}
       
    43 do_test incrvacuum-1.2 {
       
    44   # This command will create the database.
       
    45   execsql {
       
    46     pragma auto_vacuum = 'full';
       
    47     pragma auto_vacuum;
       
    48   }
       
    49 } {1}
       
    50 do_test incrvacuum-1.2.1 {
       
    51   expr {[file size test.db] > 0}
       
    52 } {1}
       
    53 do_test incrvacuum-1.3 {
       
    54   execsql {
       
    55     pragma auto_vacuum = 'incremental';
       
    56     pragma auto_vacuum;
       
    57   }
       
    58 } {2}
       
    59 do_test incrvacuum-1.4 {
       
    60   # In this case the invalid value is ignored and the auto_vacuum
       
    61   # setting remains unchanged.
       
    62   execsql {
       
    63     pragma auto_vacuum = 'invalid';
       
    64     pragma auto_vacuum;
       
    65   }
       
    66 } {2}
       
    67 do_test incrvacuum-1.5 {
       
    68   execsql {
       
    69     pragma auto_vacuum = 1;
       
    70     pragma auto_vacuum;
       
    71   }
       
    72 } {1}
       
    73 do_test incrvacuum-1.6 {
       
    74   execsql {
       
    75     pragma auto_vacuum = '2';
       
    76     pragma auto_vacuum;
       
    77   }
       
    78 } {2}
       
    79 do_test incrvacuum-1.7 {
       
    80   # Invalid value. auto_vacuum setting remains unchanged.
       
    81   execsql {
       
    82     pragma auto_vacuum = 5;
       
    83     pragma auto_vacuum;
       
    84   }
       
    85 } {2}
       
    86 
       
    87 #---------------------------------------------------------------------
       
    88 # Test the pragma on a non-empty database. It is possible to toggle
       
    89 # the connection between "full" and "incremental" mode, but not to
       
    90 # change from either of these to "none", or from "none" to "full" or
       
    91 # "incremental".
       
    92 #
       
    93 do_test incrvacuum-2.1 {
       
    94   execsql {
       
    95     pragma auto_vacuum = 1;
       
    96     CREATE TABLE abc(a, b, c);
       
    97   }
       
    98 } {}
       
    99 do_test incrvacuum-2.2 {
       
   100   execsql {
       
   101     pragma auto_vacuum = 'none';
       
   102     pragma auto_vacuum;
       
   103   }
       
   104 } {1}
       
   105 do_test incrvacuum-2.2.1 {
       
   106   db close
       
   107   sqlite3 db test.db
       
   108   execsql {
       
   109     pragma auto_vacuum;
       
   110   }
       
   111 } {1}
       
   112 do_test incrvacuum-2.3 {
       
   113   execsql {
       
   114     pragma auto_vacuum = 'incremental';
       
   115     pragma auto_vacuum;
       
   116   }
       
   117 } {2}
       
   118 do_test incrvacuum-2.4 {
       
   119   execsql {
       
   120     pragma auto_vacuum = 'full';
       
   121     pragma auto_vacuum;
       
   122   }
       
   123 } {1}
       
   124 
       
   125 #---------------------------------------------------------------------
       
   126 # Test that when the auto_vacuum mode is "incremental", the database
       
   127 # does not shrink when pages are removed from it. But it does if
       
   128 # the mode is set to "full".
       
   129 #
       
   130 do_test incrvacuum-3.1 {
       
   131   execsql {
       
   132     pragma auto_vacuum;
       
   133   }
       
   134 } {1}
       
   135 do_test incrvacuum-3.2 {
       
   136   set ::str [string repeat 1234567890 110]
       
   137   execsql {
       
   138     PRAGMA auto_vacuum = 2;
       
   139     BEGIN;
       
   140     CREATE TABLE tbl2(str);
       
   141     INSERT INTO tbl2 VALUES($::str);
       
   142     COMMIT;
       
   143   }
       
   144   # 5 pages:
       
   145   #
       
   146   #   1 -> database header
       
   147   #   2 -> first back-pointer page
       
   148   #   3 -> table abc
       
   149   #   4 -> table tbl2
       
   150   #   5 -> table tbl2 overflow page.
       
   151   #
       
   152   expr {[file size test.db] / 1024}
       
   153 } {5}
       
   154 do_test incrvacuum-3.3 {
       
   155   execsql {
       
   156     DROP TABLE abc;
       
   157     DELETE FROM tbl2;
       
   158   }
       
   159   expr {[file size test.db] / 1024}
       
   160 } {5}
       
   161 do_test incrvacuum-3.4 {
       
   162   execsql {
       
   163     PRAGMA auto_vacuum = 1;
       
   164     INSERT INTO tbl2 VALUES('hello world');
       
   165   }
       
   166   expr {[file size test.db] / 1024}
       
   167 } {3}
       
   168 
       
   169 #---------------------------------------------------------------------
       
   170 # Try to run a very simple incremental vacuum. Also verify that 
       
   171 # PRAGMA incremental_vacuum is a harmless no-op against a database that
       
   172 # does not support auto-vacuum.
       
   173 #
       
   174 do_test incrvacuum-4.1 {
       
   175   set ::str [string repeat 1234567890 110]
       
   176   execsql {
       
   177     PRAGMA auto_vacuum = 2;
       
   178     INSERT INTO tbl2 VALUES($::str);
       
   179     CREATE TABLE tbl1(a, b, c);
       
   180   }
       
   181   expr {[file size test.db] / 1024}
       
   182 } {5}
       
   183 do_test incrvacuum-4.2 {
       
   184   execsql {
       
   185     DELETE FROM tbl2;
       
   186     DROP TABLE tbl1;
       
   187   }
       
   188   expr {[file size test.db] / 1024}
       
   189 } {5}
       
   190 do_test incrvacuum-4.3 {
       
   191   set ::nStep 0
       
   192   db eval {pragma incremental_vacuum(10)} {
       
   193     incr ::nStep
       
   194   }
       
   195   list [expr {[file size test.db] / 1024}] $::nStep
       
   196 } {3 2}
       
   197 
       
   198 #---------------------------------------------------------------------
       
   199 # The following tests - incrvacuum-5.* - test incremental vacuum
       
   200 # from within a transaction.
       
   201 #
       
   202 do_test incrvacuum-5.1.1 {
       
   203   expr {[file size test.db] / 1024}
       
   204 } {3}
       
   205 do_test incrvacuum-5.1.2 {
       
   206   execsql {
       
   207     BEGIN;
       
   208     DROP TABLE tbl2;
       
   209     PRAGMA incremental_vacuum;
       
   210     COMMIT;
       
   211   }
       
   212   expr {[file size test.db] / 1024}
       
   213 } {1}
       
   214 
       
   215 do_test incrvacuum-5.2.1 {
       
   216   set ::str [string repeat abcdefghij 110]
       
   217   execsql {
       
   218     BEGIN;
       
   219     CREATE TABLE tbl1(a);
       
   220     INSERT INTO tbl1 VALUES($::str);
       
   221     PRAGMA incremental_vacuum;                 -- this is a no-op.
       
   222     COMMIT;
       
   223   }
       
   224   expr {[file size test.db] / 1024}
       
   225 } {4}
       
   226 do_test incrvacuum-5.2.2 {
       
   227   set ::str [string repeat abcdefghij 110]
       
   228   execsql {
       
   229     BEGIN;
       
   230     INSERT INTO tbl1 VALUES($::str);
       
   231     INSERT INTO tbl1 SELECT * FROM tbl1;
       
   232     DELETE FROM tbl1 WHERE oid%2;        -- Put 2 overflow pages on free-list.
       
   233     COMMIT;
       
   234   }
       
   235   expr {[file size test.db] / 1024}
       
   236 } {7}
       
   237 do_test incrvacuum-5.2.3 {
       
   238   execsql {
       
   239     BEGIN;
       
   240     PRAGMA incremental_vacuum;           -- Vacuum up the two pages.
       
   241     CREATE TABLE tbl2(b);                -- Use one free page as a table root.
       
   242     INSERT INTO tbl2 VALUES('a nice string');
       
   243     COMMIT;
       
   244   }
       
   245   expr {[file size test.db] / 1024}
       
   246 } {6}
       
   247 do_test incrvacuum-5.2.4 {
       
   248   execsql {
       
   249     SELECT * FROM tbl2;
       
   250   }
       
   251 } {{a nice string}}
       
   252 do_test incrvacuum-5.2.5 {
       
   253   execsql {
       
   254     DROP TABLE tbl1;
       
   255     DROP TABLE tbl2;
       
   256     PRAGMA incremental_vacuum;
       
   257   }
       
   258   expr {[file size test.db] / 1024}
       
   259 } {1}
       
   260 
       
   261 
       
   262 # Test cases incrvacuum-5.3.* use the following list as input data.
       
   263 # Two new databases are opened, one with incremental vacuum enabled,
       
   264 # the other with no auto-vacuum completely disabled. After executing
       
   265 # each element of the following list on both databases, test that
       
   266 # the integrity-check passes and the contents of each are identical.
       
   267 # 
       
   268 set TestScriptList [list {
       
   269   BEGIN;
       
   270   CREATE TABLE t1(a, b);
       
   271   CREATE TABLE t2(a, b);
       
   272   CREATE INDEX t1_i ON t1(a);
       
   273   CREATE INDEX t2_i ON t2(a);
       
   274 } {
       
   275   INSERT INTO t1 VALUES($::str1, $::str2);
       
   276   INSERT INTO t1 VALUES($::str1||$::str2, $::str2||$::str1);
       
   277   INSERT INTO t2 SELECT b, a FROM t1;
       
   278   INSERT INTO t2 SELECT a, b FROM t1;
       
   279   INSERT INTO t1 SELECT b, a FROM t2;
       
   280   UPDATE t2 SET b = '';
       
   281   PRAGMA incremental_vacuum;
       
   282 } {
       
   283   UPDATE t2 SET b = (SELECT b FROM t1 WHERE t1.oid = t2.oid);
       
   284   PRAGMA incremental_vacuum;
       
   285 } {
       
   286   CREATE TABLE t3(a, b);
       
   287   INSERT INTO t3 SELECT * FROM t2;
       
   288   DROP TABLE t2;
       
   289   PRAGMA incremental_vacuum;
       
   290 } {
       
   291   CREATE INDEX t3_i ON t3(a);
       
   292   COMMIT;
       
   293 } {
       
   294   BEGIN;
       
   295   DROP INDEX t3_i;
       
   296   PRAGMA incremental_vacuum;
       
   297   INSERT INTO t3 VALUES('hello', 'world');
       
   298   ROLLBACK;
       
   299 } {
       
   300   INSERT INTO t3 VALUES('hello', 'world');
       
   301 }
       
   302 ]
       
   303 
       
   304 # If this build omits subqueries, step 2 in the above list will not
       
   305 # work. Replace it with "" in this case. 
       
   306 #
       
   307 ifcapable !subquery { lset TestScriptList 2 "" }
       
   308 
       
   309 # Compare the contents of databases $A and $B.
       
   310 #
       
   311 proc compare_dbs {A B tname} {
       
   312   set tbl_list [execsql {
       
   313     SELECT tbl_name FROM sqlite_master WHERE type = 'table'
       
   314   } $A]
       
   315 
       
   316   do_test ${tname}.1 [subst {
       
   317     execsql {
       
   318       SELECT tbl_name FROM sqlite_master WHERE type = 'table'
       
   319     } $B
       
   320   }] $tbl_list
       
   321 
       
   322   set tn 1
       
   323   foreach tbl $tbl_list {
       
   324     set control [execsql "SELECT * FROM $tbl" $A]
       
   325     do_test ${tname}.[incr tn] [subst {
       
   326       execsql "SELECT * FROM $tbl" $B
       
   327     }] $control
       
   328   }
       
   329 }
       
   330 
       
   331 set ::str1 [string repeat abcdefghij 130]
       
   332 set ::str2 [string repeat 1234567890 105]
       
   333 
       
   334 file delete -force test1.db test1.db-journal test2.db test2.db-journal
       
   335 sqlite3 db1 test1.db
       
   336 sqlite3 db2 test2.db
       
   337 execsql { PRAGMA auto_vacuum = 'none' } db1
       
   338 execsql { PRAGMA auto_vacuum = 'incremental' } db2
       
   339 
       
   340 set tn 1
       
   341 foreach sql $::TestScriptList {
       
   342   execsql $sql db1
       
   343   execsql $sql db2
       
   344 
       
   345   compare_dbs db1 db2 incrvacuum-5.3.${tn}
       
   346   do_test incrvacuum-5.3.${tn}.integrity1 {
       
   347     execsql { PRAGMA integrity_check; } db1
       
   348   } {ok}
       
   349   do_test incrvacuum-5.3.${tn}.integrity2 {
       
   350     execsql { PRAGMA integrity_check; } db2
       
   351   } {ok}
       
   352   incr tn
       
   353 }
       
   354 db1 close
       
   355 db2 close
       
   356 #
       
   357 # End of test cases 5.3.*
       
   358 
       
   359 #---------------------------------------------------------------------
       
   360 # The following tests - incrvacuum-6.* - test running incremental 
       
   361 # vacuum while another statement (a read) is being executed.
       
   362 #
       
   363 for {set jj 0} {$jj < 10} {incr jj} {
       
   364   # Build some test data. Two tables are created in an empty
       
   365   # database. tbl1 data is a contiguous block starting at page 5 (pages
       
   366   # 3 and 4 are the table roots). tbl2 is a contiguous block starting 
       
   367   # right after tbl1.
       
   368   #
       
   369   # Then drop tbl1 so that when an incr vacuum is run the pages
       
   370   # of tbl2 have to be moved to fill the gap.
       
   371   #
       
   372   do_test incrvacuum-6.${jj}.1 {
       
   373     execsql {
       
   374       DROP TABLE IF EXISTS tbl1;
       
   375       DROP TABLE IF EXISTS tbl2;
       
   376       PRAGMA incremental_vacuum;
       
   377       CREATE TABLE tbl1(a, b);
       
   378       CREATE TABLE tbl2(a, b);
       
   379       BEGIN;
       
   380     }
       
   381     for {set ii 0} {$ii < 1000} {incr ii} {
       
   382       db eval {INSERT INTO tbl1 VALUES($ii, $ii || $ii)}
       
   383     }
       
   384     execsql {
       
   385       INSERT INTO tbl2 SELECT * FROM tbl1;
       
   386       COMMIT;
       
   387       DROP TABLE tbl1;
       
   388     }
       
   389     expr {[file size test.db] / 1024}
       
   390   } {36}
       
   391 
       
   392   # Run a linear scan query on tbl2. After reading ($jj*100) rows, 
       
   393   # run the incremental vacuum to shrink the database.
       
   394   #
       
   395   do_test incrvacuum-6.${jj}.2 {
       
   396     set ::nRow 0
       
   397     db eval {SELECT a FROM tbl2} {} {
       
   398       if {$a == [expr $jj*100]} {
       
   399         db eval {PRAGMA incremental_vacuum}
       
   400       }
       
   401       incr ::nRow
       
   402     }
       
   403     list [expr {[file size test.db] / 1024}] $nRow
       
   404   } {19 1000}
       
   405 }
       
   406 
       
   407 #---------------------------------------------------------------------
       
   408 # This test - incrvacuum-7.* - is to check that the database can be
       
   409 # written in the middle of an incremental vacuum.
       
   410 #
       
   411 set ::iWrite 1
       
   412 while 1 {
       
   413   do_test incrvacuum-7.${::iWrite}.1 {
       
   414     execsql {
       
   415       DROP TABLE IF EXISTS tbl1;
       
   416       DROP TABLE IF EXISTS tbl2;
       
   417       PRAGMA incremental_vacuum;
       
   418       CREATE TABLE tbl1(a, b);
       
   419       CREATE TABLE tbl2(a, b);
       
   420       BEGIN;
       
   421     }
       
   422     for {set ii 0} {$ii < 1000} {incr ii} {
       
   423       db eval {INSERT INTO tbl1 VALUES($ii, $ii || $ii)}
       
   424     }
       
   425     execsql {
       
   426       INSERT INTO tbl2 SELECT * FROM tbl1;
       
   427       COMMIT;
       
   428       DROP TABLE tbl1;
       
   429     }
       
   430     expr {[file size test.db] / 1024}
       
   431   } {36}
       
   432 
       
   433   do_test incrvacuum-7.${::iWrite}.2 {
       
   434     set ::nRow 0
       
   435     db eval {PRAGMA incremental_vacuum} {
       
   436       incr ::nRow
       
   437       if {$::nRow == $::iWrite} {
       
   438         db eval {
       
   439           CREATE TABLE tbl1(a, b);
       
   440           INSERT INTO tbl1 VALUES('hello', 'world');
       
   441         }
       
   442       }
       
   443     }
       
   444     list [expr {[file size test.db] / 1024}]
       
   445   } {20}
       
   446 
       
   447   do_test incrvacuum-7.${::iWrite}.3 {
       
   448     execsql {
       
   449       SELECT * FROM tbl1;
       
   450     }
       
   451   } {hello world}
       
   452 
       
   453   if {$::nRow == $::iWrite} break
       
   454   incr ::iWrite
       
   455 }
       
   456 
       
   457 #---------------------------------------------------------------------
       
   458 # This test - incrvacuum-8.* - is to check that nothing goes wrong
       
   459 # with an incremental-vacuum if it is the first statement executed
       
   460 # after an existing database is opened.
       
   461 #
       
   462 # At one point, this would always return SQLITE_SCHEMA (which 
       
   463 # causes an infinite loop in tclsqlite.c if using the Tcl interface).
       
   464 #
       
   465 do_test incrvacuum-8.1 {
       
   466   db close
       
   467   sqlite3 db test.db
       
   468   execsql {
       
   469     PRAGMA incremental_vacuum(50);
       
   470   }
       
   471 } {}
       
   472 
       
   473 #---------------------------------------------------------------------
       
   474 # At one point this test case was causing an assert() to fail.
       
   475 #
       
   476 do_test incrvacuum-9.1 {
       
   477   db close
       
   478   file delete -force test.db test.db-journal
       
   479   sqlite3 db test.db
       
   480 
       
   481   execsql {
       
   482     PRAGMA auto_vacuum = 'incremental';
       
   483     CREATE TABLE t1(a, b, c);
       
   484     CREATE TABLE t2(a, b, c);
       
   485     INSERT INTO t2 VALUES(randstr(500,500),randstr(500,500),randstr(500,500));
       
   486     INSERT INTO t1 VALUES(1, 2, 3);
       
   487     INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1;
       
   488     INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1;
       
   489     INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1;
       
   490     INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1;
       
   491     INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1;
       
   492     INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1;
       
   493     INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1;
       
   494     INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1;
       
   495   }
       
   496 } {}
       
   497 
       
   498 do_test incrvacuum-9.2 {
       
   499   execsql {
       
   500     PRAGMA synchronous = 'OFF';
       
   501     BEGIN;
       
   502     UPDATE t1 SET a = a, b = b, c = c;
       
   503     DROP TABLE t2;
       
   504     PRAGMA incremental_vacuum(10);
       
   505     ROLLBACK;
       
   506   }
       
   507 } {}
       
   508 
       
   509 do_test incrvacuum-9.3 {
       
   510   execsql {
       
   511     PRAGMA cache_size = 10;
       
   512     BEGIN;
       
   513     UPDATE t1 SET a = a, b = b, c = c;
       
   514     DROP TABLE t2;
       
   515     PRAGMA incremental_vacuum(10);
       
   516     ROLLBACK;
       
   517   }
       
   518 } {}
       
   519 
       
   520 #---------------------------------------------------------------------
       
   521 # Test that the parameter to the incremental_vacuum pragma works. That
       
   522 # is, if the user executes "PRAGMA incremental_vacuum(N)", at most
       
   523 # N pages are vacuumed.
       
   524 #
       
   525 do_test incrvacuum-10.1 {
       
   526   execsql {
       
   527     DROP TABLE t1;
       
   528     DROP TABLE t2;
       
   529   }
       
   530   expr [file size test.db] / 1024
       
   531 } {29}
       
   532 
       
   533 do_test incrvacuum-10.2 {
       
   534   execsql {
       
   535     PRAGMA incremental_vacuum(1);
       
   536   }
       
   537   expr [file size test.db] / 1024
       
   538 } {28}
       
   539 
       
   540 do_test incrvacuum-10.3 {
       
   541   execsql {
       
   542     PRAGMA incremental_vacuum(5);
       
   543   }
       
   544   expr [file size test.db] / 1024
       
   545 } {23}
       
   546 
       
   547 do_test incrvacuum-10.4 {
       
   548   execsql {
       
   549     PRAGMA incremental_vacuum('1');
       
   550   }
       
   551   expr [file size test.db] / 1024
       
   552 } {22}
       
   553 
       
   554 do_test incrvacuum-10.5 {
       
   555   execsql {
       
   556     PRAGMA incremental_vacuum("+3");
       
   557   }
       
   558   expr [file size test.db] / 1024
       
   559 } {19}
       
   560 
       
   561 do_test incrvacuum-10.6 {
       
   562   execsql {
       
   563     PRAGMA incremental_vacuum = 1;
       
   564   }
       
   565   expr [file size test.db] / 1024
       
   566 } {18}
       
   567 
       
   568 do_test incrvacuum-10.7 {
       
   569   # Use a really big number as an argument to incremetal_vacuum. Should
       
   570   # be interpreted as "free all possible space".
       
   571   execsql {
       
   572     PRAGMA incremental_vacuum(2147483649);
       
   573   }
       
   574   expr [file size test.db] / 1024
       
   575 } {1}
       
   576 
       
   577 do_test incrvacuum-10.8 {
       
   578   execsql {
       
   579     CREATE TABLE t1(x);
       
   580     INSERT INTO t1 VALUES(hex(randomblob(1000)));
       
   581     DROP TABLE t1;
       
   582   }
       
   583   # A negative number means free all possible space.
       
   584   execsql {
       
   585     PRAGMA incremental_vacuum=-1;
       
   586   }
       
   587   expr [file size test.db] / 1024
       
   588 } {1}
       
   589 
       
   590 #----------------------------------------------------------------
       
   591 # Test that if we set the auto_vacuum mode to 'incremental', then
       
   592 # create a database, thereafter that database defaults to incremental 
       
   593 # vacuum mode.
       
   594 #
       
   595 db close
       
   596 file delete -force test.db test.db-journal
       
   597 sqlite3 db test.db
       
   598 
       
   599 ifcapable default_autovacuum {
       
   600   do_test incrvacuum-11.1-av-dflt-on {
       
   601     execsql {
       
   602       PRAGMA auto_vacuum;
       
   603     }
       
   604   } $AUTOVACUUM
       
   605 } else {
       
   606   do_test incrvacuum-11.1-av-dflt-off {
       
   607     execsql {
       
   608       PRAGMA auto_vacuum;
       
   609     }
       
   610   } {0}
       
   611 }
       
   612 do_test incrvacuum-11.2 {
       
   613   execsql {
       
   614     PRAGMA auto_vacuum = incremental;
       
   615   }
       
   616 } {}
       
   617 do_test incrvacuum-11.3 {
       
   618   execsql {
       
   619     PRAGMA auto_vacuum;
       
   620   }
       
   621 } {2}
       
   622 do_test incrvacuum-11.4 {
       
   623   # The database has now been created.
       
   624   expr {[file size test.db]>0}
       
   625 } {1}
       
   626 do_test incrvacuum-11.5 {
       
   627   # Close and reopen the connection.
       
   628   db close
       
   629   sqlite3 db test.db
       
   630 
       
   631   # Test we are still in incremental vacuum mode.
       
   632   execsql { PRAGMA auto_vacuum; }
       
   633 } {2}
       
   634 do_test incrvacuum-11.6 {
       
   635   execsql {
       
   636     PRAGMA auto_vacuum = 'full';
       
   637     PRAGMA auto_vacuum;
       
   638   }
       
   639 } {1}
       
   640 do_test incrvacuum-11.7 {
       
   641   # Close and reopen the connection.
       
   642   db close
       
   643   sqlite3 db test.db
       
   644 
       
   645   # Test we are still in "full" auto-vacuum mode.
       
   646   execsql { PRAGMA auto_vacuum; }
       
   647 } {1}
       
   648 
       
   649 #----------------------------------------------------------------------
       
   650 # Special case: What happens if the database is locked when a "PRAGMA
       
   651 # auto_vacuum = XXX" statement is executed.
       
   652 #
       
   653 db close
       
   654 file delete -force test.db test.db-journal
       
   655 sqlite3 db test.db
       
   656 
       
   657 do_test incrvacuum-12.1 {
       
   658   execsql {
       
   659     PRAGMA auto_vacuum = 1;
       
   660   }
       
   661   expr {[file size test.db]>0}
       
   662 } {1}
       
   663 
       
   664 # Try to change the auto-vacuum from "full" to "incremental" while the
       
   665 # database is locked. Nothing should change.
       
   666 #
       
   667 do_test incrvacuum-12.2 {
       
   668   sqlite3 db2 test.db
       
   669   execsql { BEGIN EXCLUSIVE; } db2
       
   670   catchsql { PRAGMA auto_vacuum = 2; }
       
   671 } {1 {database is locked}}
       
   672 
       
   673 do_test incrvacuum-12.3 {
       
   674   execsql { ROLLBACK; } db2
       
   675   execsql { PRAGMA auto_vacuum }
       
   676 } {1}
       
   677 
       
   678 do_test incrvacuum-12.3 {
       
   679   execsql { SELECT * FROM sqlite_master }
       
   680   execsql { PRAGMA auto_vacuum }
       
   681 } {1}
       
   682 
       
   683 #----------------------------------------------------------------------
       
   684 # Special case #2: What if one process prepares a "PRAGMA auto_vacuum = XXX"
       
   685 # statement when the database is empty, but doesn't execute it until
       
   686 # after some other process has created the database.
       
   687 #
       
   688 db2 close
       
   689 db close
       
   690 file delete -force test.db test.db-journal
       
   691 sqlite3 db test.db  ;  set ::DB [sqlite3_connection_pointer db]
       
   692 sqlite3 db2 test.db
       
   693 
       
   694 do_test incrvacuum-13.1 {
       
   695   # File size is sometimes 1 instead of 0 due to the hack we put in
       
   696   # to work around ticket #3260.  Search for comments on #3260 in
       
   697   # os_unix.c.
       
   698   expr {[file size test.db]>1}
       
   699 } {0}
       
   700 do_test incrvacuum-13.2 {
       
   701   set ::STMT [sqlite3_prepare $::DB {PRAGMA auto_vacuum = 2} -1 DUMMY]
       
   702   execsql {
       
   703     PRAGMA auto_vacuum = none;
       
   704     PRAGMA default_cache_size = 1024;
       
   705     PRAGMA auto_vacuum;
       
   706   } db2
       
   707 } {0}
       
   708 do_test incrvacuum-13.3 {
       
   709   expr {[file size test.db]>0}
       
   710 } {1}
       
   711 do_test incrvacuum-13.4 {
       
   712   set rc [sqlite3_step $::STMT]
       
   713   list $rc [sqlite3_finalize $::STMT]
       
   714 } {SQLITE_DONE SQLITE_OK}
       
   715 do_test incrvacuum-13.5 {
       
   716   execsql {
       
   717     PRAGMA auto_vacuum;
       
   718   }
       
   719 } {0}
       
   720 
       
   721 
       
   722 # Verify that the incremental_vacuum pragma fails gracefully if it
       
   723 # is used against an invalid database file.
       
   724 #
       
   725 do_test incrvacuum-14.1 {
       
   726   set out [open invalid.db w]
       
   727   puts $out "This is not an SQLite database file"
       
   728   close $out
       
   729   sqlite3 db3 invalid.db
       
   730   catchsql {
       
   731     PRAGMA incremental_vacuum(10);
       
   732   } db3
       
   733 } {1 {file is encrypted or is not a database}}
       
   734 
       
   735 db2 close
       
   736 db3 close
       
   737 finish_test