Annotation of embedaddon/sqlite3/test/incrvacuum.test, revision 1.1.1.1

1.1       misho       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.23 2009/02/18 20:31:18 drh 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: forcedelete 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:   forcedelete 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: forcedelete 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: forcedelete 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: } {2}   ;# Still 2 because PRAGMA auto_vacuum setting held in case of vacuum
                    677: do_test incrvacuum-12.4 {
                    678:   db close
                    679:   sqlite3 db test.db
                    680:   execsql { PRAGMA auto_vacuum }
                    681: } {1}   ;# Revert to 1 because the database file did not change
                    682: 
                    683: do_test incrvacuum-12.5 {
                    684:   execsql { SELECT * FROM sqlite_master }
                    685:   execsql { PRAGMA auto_vacuum }
                    686: } {1}
                    687: 
                    688: #----------------------------------------------------------------------
                    689: # Special case #2: What if one process prepares a "PRAGMA auto_vacuum = XXX"
                    690: # statement when the database is empty, but doesn't execute it until
                    691: # after some other process has created the database.
                    692: #
                    693: db2 close
                    694: db close
                    695: forcedelete test.db test.db-journal
                    696: sqlite3 db test.db  ;  set ::DB [sqlite3_connection_pointer db]
                    697: sqlite3 db2 test.db
                    698: 
                    699: do_test incrvacuum-13.1 {
                    700:   # File size is sometimes 1 instead of 0 due to the hack we put in
                    701:   # to work around ticket #3260.  Search for comments on #3260 in
                    702:   # os_unix.c.
                    703:   expr {[file size test.db]>1}
                    704: } {0}
                    705: do_test incrvacuum-13.2 {
                    706:   set ::STMT [sqlite3_prepare $::DB {PRAGMA auto_vacuum = 2} -1 DUMMY]
                    707:   execsql {
                    708:     PRAGMA auto_vacuum = none;
                    709:     PRAGMA default_cache_size = 1024;
                    710:     PRAGMA auto_vacuum;
                    711:   } db2
                    712: } {0}
                    713: do_test incrvacuum-13.3 {
                    714:   expr {[file size test.db]>0}
                    715: } {1}
                    716: do_test incrvacuum-13.4 {
                    717:   set rc [sqlite3_step $::STMT]
                    718:   list $rc [sqlite3_finalize $::STMT]
                    719: } {SQLITE_DONE SQLITE_OK}
                    720: do_test incrvacuum-13.5 {
                    721:   execsql {
                    722:     PRAGMA auto_vacuum;
                    723:   }
                    724: } {0}
                    725: 
                    726: 
                    727: # Verify that the incremental_vacuum pragma fails gracefully if it
                    728: # is used against an invalid database file.
                    729: #
                    730: if {[permutation] == ""} {
                    731:   do_test incrvacuum-14.1 {
                    732:     set out [open invalid.db w]
                    733:     puts $out "This is not an SQLite database file"
                    734:     close $out
                    735:     sqlite3 db3 invalid.db
                    736:     catchsql {
                    737:       PRAGMA incremental_vacuum(10);
                    738:     } db3
                    739:   } {1 {file is encrypted or is not a database}}
                    740:   db3 close
                    741: }
                    742: 
                    743: do_test incrvacuum-15.1 {
                    744:   db close
                    745:   db2 close
                    746:   forcedelete test.db
                    747:   sqlite3 db test.db
                    748: 
                    749:   set str [string repeat "abcdefghij" 500]
                    750: 
                    751:   execsql {
                    752:     PRAGMA cache_size = 10;
                    753:     PRAGMA auto_vacuum = incremental;
                    754:     CREATE TABLE t1(x, y);
                    755:     INSERT INTO t1 VALUES('a', $str);
                    756:     INSERT INTO t1 VALUES('b', $str);
                    757:     INSERT INTO t1 VALUES('c', $str);
                    758:     INSERT INTO t1 VALUES('d', $str);
                    759:     INSERT INTO t1 VALUES('e', $str);
                    760:     INSERT INTO t1 VALUES('f', $str);
                    761:     INSERT INTO t1 VALUES('g', $str);
                    762:     INSERT INTO t1 VALUES('h', $str);
                    763:     INSERT INTO t1 VALUES('i', $str);
                    764:     INSERT INTO t1 VALUES('j', $str);
                    765:     INSERT INTO t1 VALUES('j', $str);
                    766: 
                    767:     CREATE TABLE t2(x PRIMARY KEY, y);
                    768:     INSERT INTO t2 VALUES('a', $str);
                    769:     INSERT INTO t2 VALUES('b', $str);
                    770:     INSERT INTO t2 VALUES('c', $str);
                    771:     INSERT INTO t2 VALUES('d', $str);
                    772: 
                    773:     BEGIN;
                    774:       DELETE FROM t2;
                    775:       PRAGMA incremental_vacuum;
                    776:   }
                    777: 
                    778:   catchsql {INSERT INTO t2 SELECT * FROM t1}
                    779: 
                    780:   execsql { 
                    781:     COMMIT;
                    782:     PRAGMA integrity_check;
                    783:   }
                    784: } {ok}
                    785: 
                    786: finish_test

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>