Annotation of embedaddon/sqlite3/test/incrvacuum.test, revision 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>