10f68fd1bSdrh# 2005 February 15 20f68fd1bSdrh# 30f68fd1bSdrh# The author disclaims copyright to this source code. In place of 40f68fd1bSdrh# a legal notice, here is a blessing: 50f68fd1bSdrh# 60f68fd1bSdrh# May you do good and not evil. 70f68fd1bSdrh# May you find forgiveness for yourself and forgive others. 80f68fd1bSdrh# May you share freely, never taking more than you give. 90f68fd1bSdrh# 100f68fd1bSdrh#*********************************************************************** 110f68fd1bSdrh# This file implements regression tests for SQLite library. The 120f68fd1bSdrh# focus of this file is testing the VACUUM statement. 130f68fd1bSdrh# 14076d4661Sdrh# $Id: vacuum2.test,v 1.10 2009/02/18 20:31:18 drh Exp $ 150f68fd1bSdrh 160f68fd1bSdrhset testdir [file dirname $argv0] 170f68fd1bSdrhsource $testdir/tester.tcl 18481ecd95Sdanset testprefix vacuum2 190f68fd1bSdrh 20ae23162eSshaneh# Do not use a codec for tests in this file, as the database file is 21ae23162eSshaneh# manipulated directly using tcl scripts (using the [hexio_write] command). 22ae23162eSshaneh# 23ae23162eSshanehdo_not_use_codec 24ae23162eSshaneh 250f68fd1bSdrh# If the VACUUM statement is disabled in the current build, skip all 260f68fd1bSdrh# the tests in this file. 270f68fd1bSdrh# 28ff890793Sdanielk1977ifcapable {!vacuum||!autoinc} { 290f68fd1bSdrh finish_test 300f68fd1bSdrh return 310f68fd1bSdrh} 320f68fd1bSdrhif $AUTOVACUUM { 330f68fd1bSdrh finish_test 340f68fd1bSdrh return 350f68fd1bSdrh} 360f68fd1bSdrh 370f68fd1bSdrh# Ticket #1121 - make sure vacuum works if all autoincrement tables 380f68fd1bSdrh# have been deleted. 390f68fd1bSdrh# 400f68fd1bSdrhdo_test vacuum2-1.1 { 410f68fd1bSdrh execsql { 420f68fd1bSdrh CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y); 430f68fd1bSdrh DROP TABLE t1; 440f68fd1bSdrh VACUUM; 450f68fd1bSdrh } 460f68fd1bSdrh} {} 470f68fd1bSdrh 48f85953edSdrh# Ticket #2518. Make sure vacuum increments the change counter 49f85953edSdrh# in the database header. 50f85953edSdrh# 51f85953edSdrhdo_test vacuum2-2.1 { 52f85953edSdrh execsql { 53f85953edSdrh CREATE TABLE t1(x); 54f85953edSdrh CREATE TABLE t2(y); 55f85953edSdrh INSERT INTO t1 VALUES(1); 56f85953edSdrh } 57f85953edSdrh hexio_get_int [hexio_read test.db 24 4] 58f85953edSdrh} [expr {[hexio_get_int [hexio_read test.db 24 4]]+3}] 59*ebbf3687Sdando_test vacuum2-2.2 { 60f85953edSdrh execsql { 61f85953edSdrh VACUUM 62f85953edSdrh } 63f85953edSdrh hexio_get_int [hexio_read test.db 24 4] 64f85953edSdrh} [expr {[hexio_get_int [hexio_read test.db 24 4]]+1}] 65f85953edSdrh 66ddac25c7Sdrh############################################################################ 67ddac25c7Sdrh# Verify that we can use the auto_vacuum pragma to request a new 68ddac25c7Sdrh# autovacuum setting, do a VACUUM, and the new setting takes effect. 69ddac25c7Sdrh# Make sure this happens correctly even if there are multiple open 70ddac25c7Sdrh# connections to the same database file. 71ddac25c7Sdrh# 72ddac25c7Sdrhsqlite3 db2 test.db 73ddac25c7Sdrhset pageSize [db eval {pragma page_size}] 74ddac25c7Sdrh 75ddac25c7Sdrh# We are currently not autovacuuming so the database should be 3 pages 76ddac25c7Sdrh# in size. 1 page for each of sqlite_master, t1, and t2. 77ddac25c7Sdrh# 78ddac25c7Sdrhdo_test vacuum2-3.1 { 79ddac25c7Sdrh execsql { 80ddac25c7Sdrh INSERT INTO t1 VALUES('hello'); 81ddac25c7Sdrh INSERT INTO t2 VALUES('out there'); 82ddac25c7Sdrh } 83ddac25c7Sdrh expr {[file size test.db]/$pageSize} 84ddac25c7Sdrh} {3} 851db639ceSdrhset cksum [cksum] 86ddac25c7Sdrhdo_test vacuum2-3.2 { 871db639ceSdrh cksum db2 88ddac25c7Sdrh} $cksum 89ddac25c7Sdrh 90ddac25c7Sdrh# Convert the database to an autovacuumed database. 91c8330f4bSshaneifcapable autovacuum { 92ddac25c7Sdrh do_test vacuum2-3.3 { 93ddac25c7Sdrh execsql { 94ddac25c7Sdrh PRAGMA auto_vacuum=FULL; 95ddac25c7Sdrh VACUUM; 96ddac25c7Sdrh } 97ddac25c7Sdrh expr {[file size test.db]/$pageSize} 98ddac25c7Sdrh } {4} 99c8330f4bSshane} 100ddac25c7Sdrhdo_test vacuum2-3.4 { 1011db639ceSdrh cksum db2 102ddac25c7Sdrh} $cksum 103ddac25c7Sdrhdo_test vacuum2-3.5 { 1041db639ceSdrh cksum 105ddac25c7Sdrh} $cksum 106ddac25c7Sdrhdo_test vacuum2-3.6 { 107ddac25c7Sdrh execsql {PRAGMA integrity_check} db2 108ddac25c7Sdrh} {ok} 109ddac25c7Sdrhdo_test vacuum2-3.7 { 110ddac25c7Sdrh execsql {PRAGMA integrity_check} db 111ddac25c7Sdrh} {ok} 112ddac25c7Sdrh 113ddac25c7Sdrh# Convert the database back to a non-autovacuumed database. 114ddac25c7Sdrhdo_test vacuum2-3.13 { 115ddac25c7Sdrh execsql { 116ddac25c7Sdrh PRAGMA auto_vacuum=NONE; 117ddac25c7Sdrh VACUUM; 118ddac25c7Sdrh } 119ddac25c7Sdrh expr {[file size test.db]/$pageSize} 120ddac25c7Sdrh} {3} 121ddac25c7Sdrhdo_test vacuum2-3.14 { 1221db639ceSdrh cksum db2 123ddac25c7Sdrh} $cksum 124ddac25c7Sdrhdo_test vacuum2-3.15 { 1251db639ceSdrh cksum 126ddac25c7Sdrh} $cksum 127ddac25c7Sdrhdo_test vacuum2-3.16 { 128ddac25c7Sdrh execsql {PRAGMA integrity_check} db2 129ddac25c7Sdrh} {ok} 130ddac25c7Sdrhdo_test vacuum2-3.17 { 131ddac25c7Sdrh execsql {PRAGMA integrity_check} db 132ddac25c7Sdrh} {ok} 133ddac25c7Sdrh 134464fc33aSdrhdb2 close 135464fc33aSdrh 13606249db1Sdanielk1977ifcapable autovacuum { 13706249db1Sdanielk1977 do_test vacuum2-4.1 { 13806249db1Sdanielk1977 db close 139fda06befSmistachkin forcedelete test.db 14006249db1Sdanielk1977 sqlite3 db test.db 14106249db1Sdanielk1977 execsql { 14206249db1Sdanielk1977 pragma auto_vacuum=1; 14306249db1Sdanielk1977 create table t(a, b); 14406249db1Sdanielk1977 insert into t values(1, 2); 14506249db1Sdanielk1977 insert into t values(1, 2); 14606249db1Sdanielk1977 pragma auto_vacuum=0; 14706249db1Sdanielk1977 vacuum; 14806249db1Sdanielk1977 pragma auto_vacuum; 14906249db1Sdanielk1977 } 15006249db1Sdanielk1977 } {0} 15106249db1Sdanielk1977 do_test vacuum2-4.2 { 15206249db1Sdanielk1977 execsql { 15306249db1Sdanielk1977 pragma auto_vacuum=1; 15406249db1Sdanielk1977 vacuum; 15506249db1Sdanielk1977 pragma auto_vacuum; 15606249db1Sdanielk1977 } 15706249db1Sdanielk1977 } {1} 15806249db1Sdanielk1977 do_test vacuum2-4.3 { 15906249db1Sdanielk1977 execsql { 16006249db1Sdanielk1977 pragma integrity_check 16106249db1Sdanielk1977 } 16206249db1Sdanielk1977 } {ok} 16306249db1Sdanielk1977 do_test vacuum2-4.4 { 164076d4661Sdrh db close 165076d4661Sdrh sqlite3 db test.db 16606249db1Sdanielk1977 execsql { 16706249db1Sdanielk1977 pragma auto_vacuum; 16806249db1Sdanielk1977 } 16906249db1Sdanielk1977 } {1} 170076d4661Sdrh do_test vacuum2-4.5 { # Ticket #3663 171076d4661Sdrh execsql { 172076d4661Sdrh pragma auto_vacuum=2; 173076d4661Sdrh vacuum; 174076d4661Sdrh pragma auto_vacuum; 175076d4661Sdrh } 176076d4661Sdrh } {2} 177076d4661Sdrh do_test vacuum2-4.6 { 178076d4661Sdrh execsql { 179076d4661Sdrh pragma integrity_check 180076d4661Sdrh } 181076d4661Sdrh } {ok} 182076d4661Sdrh do_test vacuum2-4.7 { 183076d4661Sdrh db close 184076d4661Sdrh sqlite3 db test.db 185076d4661Sdrh execsql { 186076d4661Sdrh pragma auto_vacuum; 187076d4661Sdrh } 188076d4661Sdrh } {2} 18906249db1Sdanielk1977} 19006249db1Sdanielk1977 191099d1470Sdan 192099d1470Sdan#------------------------------------------------------------------------- 193099d1470Sdan# The following block of tests verify the behaviour of the library when 194099d1470Sdan# a database is VACUUMed when there are one or more unfinalized SQL 195099d1470Sdan# statements reading the same database using the same db handle. 196099d1470Sdan# 197099d1470Sdandb close 198099d1470Sdanforcedelete test.db 199099d1470Sdansqlite3 db test.db 200099d1470Sdando_execsql_test vacuum2-5.1 { 201099d1470Sdan CREATE TABLE t1(a PRIMARY KEY, b UNIQUE); 202099d1470Sdan INSERT INTO t1 VALUES(1, randomblob(500)); 203099d1470Sdan INSERT INTO t1 SELECT a+1, randomblob(500) FROM t1; -- 2 204099d1470Sdan INSERT INTO t1 SELECT a+2, randomblob(500) FROM t1; -- 4 205099d1470Sdan INSERT INTO t1 SELECT a+4, randomblob(500) FROM t1; -- 8 206099d1470Sdan INSERT INTO t1 SELECT a+8, randomblob(500) FROM t1; -- 16 207099d1470Sdan} {} 208099d1470Sdan 209099d1470Sdando_test vacuum2-5.2 { 210099d1470Sdan list [catch { 211099d1470Sdan db eval {SELECT a, b FROM t1} { if {$a == 8} { execsql VACUUM } } 212099d1470Sdan } msg] $msg 213099d1470Sdan} {1 {cannot VACUUM - SQL statements in progress}} 214099d1470Sdan 215099d1470Sdando_test vacuum2-5.3 { 216099d1470Sdan list [catch { 217099d1470Sdan db eval {SELECT 1, 2, 3} { execsql VACUUM } 218099d1470Sdan } msg] $msg 219099d1470Sdan} {1 {cannot VACUUM - SQL statements in progress}} 220099d1470Sdan 221099d1470Sdando_test vacuum2-5.4 { 222099d1470Sdan set res "" 223099d1470Sdan set res2 "" 224099d1470Sdan db eval {SELECT a, b FROM t1 WHERE a<=10} { 225099d1470Sdan if {$a==6} { set res [catchsql VACUUM] } 226099d1470Sdan lappend res2 $a 227099d1470Sdan } 228099d1470Sdan lappend res2 $res 229099d1470Sdan} {1 2 3 4 5 6 7 8 9 10 {1 {cannot VACUUM - SQL statements in progress}}} 230099d1470Sdan 231481ecd95Sdan#------------------------------------------------------------------------- 232481ecd95Sdan# Check that if the definition of a collation sequence is changed and 233481ecd95Sdan# VACUUM run, records are store in the (new) correct order following the 234481ecd95Sdan# VACUUM. Even if the modified collation is attached to a PK of a WITHOUT 235481ecd95Sdan# ROWID table. 236481ecd95Sdan 237481ecd95Sdanproc cmp {lhs rhs} { string compare $lhs $rhs } 238481ecd95Sdandb collate cmp cmp 239481ecd95Sdando_execsql_test 6.0 { 240481ecd95Sdan CREATE TABLE t6(x PRIMARY KEY COLLATE cmp, y) WITHOUT ROWID; 241481ecd95Sdan CREATE INDEX t6y ON t6(y); 242481ecd95Sdan INSERT INTO t6 VALUES('i', 'one'); 243481ecd95Sdan INSERT INTO t6 VALUES('ii', 'one'); 244481ecd95Sdan INSERT INTO t6 VALUES('iii', 'one'); 245481ecd95Sdan} 246481ecd95Sdanintegrity_check 6.1 247481ecd95Sdanproc cmp {lhs rhs} { string compare $rhs $lhs } 248481ecd95Sdando_execsql_test 6.2 VACUUM 249481ecd95Sdanintegrity_check 6.3 250099d1470Sdan 2510f68fd1bSdrhfinish_test 252