3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
11 # This file implements regression tests for SQLite library. The
12 # focus of this file is testing the VACUUM INTO statement.
15 set testdir [file dirname $argv0]
16 source $testdir/tester.tcl
18 # If the VACUUM statement is disabled in the current build, skip all
19 # the tests in this file.
22 omit_test vacuum.test {Compiled with SQLITE_OMIT_VACUUM}
28 do_execsql_test vacuum-into-100 {
30 a INTEGER PRIMARY KEY,
32 c INT AS (b+1), --- See "2024-04-09" block
33 CHECK( typeof(b)!='integer' OR b>a-5 ) --- comment below
35 WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
36 INSERT INTO t1(a,b) SELECT x, randomblob(600) FROM c;
37 CREATE INDEX t1b ON t1(b);
38 DELETE FROM t1 WHERE a%2;
39 SELECT count(*), sum(a), sum(length(b)) FROM t1;
42 # Update 2024-04-09 for forum post eec177d68fe7fa2c.
44 # VACUUM INTO is sensitive to tables holding both generated columns
45 # and CHECK constraints.
47 # CHECK constraints are ignored for read-only databases in order to save
48 # memory (see check-in 34ddf02d3d21151b on 2014-05-21). But the xfer
49 # optimization normally only works if CHECK constraints match between the
50 # source and destination tables. So the xfer optimization was not
51 # working for VACUUM INTO when the source was a read-only database and the
52 # table held CHECK constraints. But if the table has generated columns,
53 # then the xfer optimization is required or else VACUUM will raise an
56 # Fix this by ignoring CHECK constraints when determining whether or not
57 # the xfer optimization can run while doing VACUUM.
59 do_execsql_test vacuum-into-110 {
60 VACUUM main INTO 'out.db';
63 do_test vacuum-into-120 {
64 db2 eval {SELECT count(*), sum(a), sum(length(b)) FROM t1}
66 do_catchsql_test vacuum-into-130 {
68 } {1 {output file already exists}}
70 do_catchsql_test vacuum-into-140 {
71 VACUUM INTO 'out2.db';
73 do_catchsql_test vacuum-into-150 {
74 VACUUM INTO 'out2.db';
75 } {1 {output file already exists}}
77 do_catchsql_test vacuum-into-200 {
78 VACUUM main INTO ':memory:';
81 # The INTO argument can be an arbitrary expression.
83 do_execsql_test vacuum-into-300 {
84 CREATE TABLE t2(name TEXT);
85 INSERT INTO t2 VALUES(':memory:');
86 VACUUM main INTO (SELECT name FROM t2);
88 do_catchsql_test vacuum-into-310 {
90 } {1 {non-text filename}}
91 do_catchsql_test vacuum-into-320 {
93 } {1 {no such column: x}}
94 do_catchsql_test vacuum-into-330 {
95 VACUUM INTO t1.nosuchcol;
96 } {1 {no such column: t1.nosuchcol}}
97 do_catchsql_test vacuum-into-340 {
98 VACUUM INTO main.t1.nosuchcol;
99 } {1 {no such column: main.t1.nosuchcol}}
102 db func target target
103 proc target {} { return "test.db2" }
104 do_test vacuum-into-410 {
105 execsql { VACUUM INTO target() }
108 do_catchsql_test vacuum-into-420 {
109 VACUUM INTO target2()
110 } {1 {no such function: target2}}
112 # The ability to VACUUM INTO a read-only database
114 if {$tcl_platform(platform)=="windows"} {
115 file attributes test.db -readonly 1
117 file attributes test.db -permissions 292 ;# 292 == 0444
119 sqlite3 db test.db -readonly 1
121 do_execsql_test vacuum-into-500 {
122 VACUUM INTO 'test.db2';
124 if {$tcl_platform(platform)=="windows"} {
125 file attributes test.db -readonly 0
127 file attributes test.db -permissions 420 ;# 420 = 0644
130 do_test vacuum-into-510 {
131 db2 eval {SELECT name FROM sqlite_master ORDER BY 1}
136 # Change the page-size on a VACUUM INTO even if the original
137 # database is in WAL mode.
139 if {[wal_is_capable]} {
142 do_test vacuum-into-600 {
145 PRAGMA page_size=4096;
146 PRAGMA journal_mode=WAL;
148 INSERT INTO t1 VALUES(19);
149 CREATE INDEX t1a ON t1(a);
150 PRAGMA integrity_check;
153 do_execsql_test vacuum-into-610 {
156 do_execsql_test vacuum-into-620 {
157 PRAGMA page_size=1024;
158 VACUUM INTO 'test.db2';
160 do_test vacuum-into-630 {
164 PRAGMA integrity_check;
169 #-------------------------------------------------------------------------
171 testvfs tvfs -default 1
174 proc xSyncCb {method file fileid flags} {
180 do_execsql_test vacuum-into-700 {
181 CREATE TABLE t1(a, b);
182 INSERT INTO t1 VALUES(1, 2);
185 foreach {tn pragma res} {
187 PRAGMA synchronous = normal
190 PRAGMA synchronous = full
193 PRAGMA synchronous = off
196 PRAGMA synchronous = extra;
199 PRAGMA fullfsync = 1;
200 PRAGMA synchronous = full;
201 } {full|dataonly 1 full 2}
206 do_execsql_test vacuum-into-$tn.1 "
208 VACUUM INTO 'test.db2'
211 do_test vacuum-into-$tn.2 {