1# 2001 September 15 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 VACUUM statement. 13# 14# $Id: vacuum.test,v 1.24 2004/07/26 23:07:52 drh Exp $ 15 16set testdir [file dirname $argv0] 17source $testdir/tester.tcl 18 19set fcnt 1 20proc cksum {{db db}} { 21 set sql "SELECT name, type, sql FROM sqlite_master ORDER BY name, type" 22 set txt [$db eval $sql]\n 23 set sql "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name" 24 foreach tbl [$db eval $sql] { 25 append txt [$db eval "SELECT * FROM $tbl"]\n 26 } 27 foreach prag {default_cache_size} { 28 append txt $prag-[$db eval "PRAGMA $prag"]\n 29 } 30 if 1 { 31 global fcnt 32 set fd [open dump$fcnt.txt w] 33 puts -nonewline $fd $txt 34 close $fd 35 incr fcnt 36 } 37 set cksum [string length $txt]-[md5 $txt] 38 # puts $cksum-[file size test.db] 39 return $cksum 40} 41do_test vacuum-1.1 { 42 execsql { 43 BEGIN; 44 CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); 45 INSERT INTO t1 VALUES(NULL,randstr(10,100),randstr(5,50)); 46 INSERT INTO t1 VALUES(123456,randstr(10,100),randstr(5,50)); 47 INSERT INTO t1 SELECT NULL, b||'-'||rowid, c||'-'||rowid FROM t1; 48 INSERT INTO t1 SELECT NULL, b||'-'||rowid, c||'-'||rowid FROM t1; 49 INSERT INTO t1 SELECT NULL, b||'-'||rowid, c||'-'||rowid FROM t1; 50 INSERT INTO t1 SELECT NULL, b||'-'||rowid, c||'-'||rowid FROM t1; 51 INSERT INTO t1 SELECT NULL, b||'-'||rowid, c||'-'||rowid FROM t1; 52 INSERT INTO t1 SELECT NULL, b||'-'||rowid, c||'-'||rowid FROM t1; 53 INSERT INTO t1 SELECT NULL, b||'-'||rowid, c||'-'||rowid FROM t1; 54 CREATE INDEX i1 ON t1(b,c); 55 CREATE UNIQUE INDEX i2 ON t1(c,a); 56 CREATE TABLE t2 AS SELECT * FROM t1; 57 COMMIT; 58 DROP TABLE t2; 59 } 60 set ::size1 [file size test.db] 61 set ::cksum [cksum] 62 expr {$::cksum!=""} 63} {1} 64do_test vacuum-1.2 { 65 execsql { 66 VACUUM; 67 } 68 cksum 69} $cksum 70do_test vacuum-1.3 { 71 expr {[file size test.db]<$::size1} 72} {1} 73do_test vacuum-1.4 { 74 execsql { 75 BEGIN; 76 CREATE TABLE t2 AS SELECT * FROM t1; 77 CREATE TABLE t3 AS SELECT * FROM t1; 78 CREATE VIEW v1 AS SELECT b, c FROM t3; 79 CREATE TRIGGER r1 AFTER DELETE ON t2 BEGIN 80 SELECT 1; 81 END; 82 COMMIT; 83 DROP TABLE t2; 84 } 85 set ::size1 [file size test.db] 86 set ::cksum [cksum] 87 expr {$::cksum!=""} 88} {1} 89do_test vacuum-1.5 { 90 execsql { 91 VACUUM; 92 } 93 cksum 94} $cksum 95do_test vacuum-1.6 { 96 expr {[file size test.db]<$::size1} 97} {1} 98 99do_test vacuum-2.1 { 100 catchsql { 101 BEGIN; 102 VACUUM; 103 COMMIT; 104 } 105} {1 {cannot VACUUM from within a transaction}} 106catch {db eval COMMIT} 107do_test vacuum-2.2 { 108 sqlite3 db2 test.db 109 execsql { 110 BEGIN; 111 CREATE TABLE t4 AS SELECT * FROM t1; 112 CREATE TABLE t5 AS SELECT * FROM t1; 113 COMMIT; 114 DROP TABLE t4; 115 DROP TABLE t5; 116 } db2 117 set ::cksum [cksum db2] 118 catchsql { 119 VACUUM 120 } 121} {0 {}} 122do_test vacuum-2.3 { 123 cksum 124} $cksum 125do_test vacuum-2.4 { 126 catch {db2 eval {SELECT count(*) FROM sqlite_master}} 127 cksum db2 128} $cksum 129 130# Ticket #427. Make sure VACUUM works when the EMPTY_RESULT_CALLBACKS 131# pragma is turned on. 132# 133do_test vacuum-3.1 { 134 db close 135 db2 close 136 file delete test.db 137 sqlite3 db test.db 138 execsql { 139 PRAGMA empty_result_callbacks=on; 140 VACUUM; 141 } 142} {} 143 144# Ticket #464. Make sure VACUUM works with the sqlite3_prepare() API. 145# 146do_test vacuum-4.1 { 147 db close 148 set DB [sqlite3 db test.db] 149 set VM [sqlite3_prepare $DB {VACUUM} -1 TAIL] 150 sqlite3_step $VM 151} {SQLITE_DONE} 152do_test vacuum-4.2 { 153 sqlite3_finalize $VM 154} SQLITE_OK 155 156# Ticket #515. VACUUM after deleting and recreating the table that 157# a view refers to. 158# 159do_test vacuum-5.1 { 160 db close 161 file delete -force test.db 162 sqlite3 db test.db 163 catchsql { 164 CREATE TABLE Test (TestID int primary key); 165 INSERT INTO Test VALUES (NULL); 166 CREATE VIEW viewTest AS SELECT * FROM Test; 167 168 BEGIN; 169 CREATE TEMP TABLE tempTest (TestID int primary key, Test2 int NULL); 170 INSERT INTO tempTest SELECT TestID, 1 FROM Test; 171 DROP TABLE Test; 172 CREATE TABLE Test(TestID int primary key, Test2 int NULL); 173 INSERT INTO Test SELECT * FROM tempTest; 174 COMMIT; 175 VACUUM; 176 } 177} {0 {}} 178do_test vacuum-5.2 { 179 catchsql { 180 VACUUM; 181 } 182} {0 {}} 183 184# Ensure vacuum works with complicated tables names. 185do_test vacuum-6.1 { 186 execsql { 187 CREATE TABLE "abc abc"(a, b, c); 188 INSERT INTO "abc abc" VALUES(1, 2, 3); 189 VACUUM; 190 } 191} {} 192do_test vacuum-6.2 { 193 execsql { 194 select * from "abc abc"; 195 } 196} {1 2 3} 197 198# Also ensure that blobs survive a vacuum. 199do_test vacuum-6.3 { 200 execsql { 201 DELETE FROM "abc abc"; 202 INSERT INTO "abc abc" VALUES(X'00112233', NULL, NULL); 203 VACUUM; 204 } 205} {} 206do_test vacuum-6.4 { 207 execsql { 208 select count(*) from "abc abc" WHERE a = X'00112233'; 209 } 210} {1} 211 212# Check what happens when an in-memory database is vacuumed. 213do_test vacuum-7.0 { 214 sqlite3 db2 :memory: 215 execsql { 216 CREATE TABLE t1(t); 217 VACUUM; 218 } db2 219} {} 220db2 close 221 222# finish_test 223