xref: /sqlite-3.40.0/test/resetdb.test (revision 41e0717b)
1b57e3ec5Sdrh# 2018-04-28
2b57e3ec5Sdrh#
3b57e3ec5Sdrh# The author disclaims copyright to this source code.  In place of
4b57e3ec5Sdrh# a legal notice, here is a blessing:
5b57e3ec5Sdrh#
6b57e3ec5Sdrh#    May you do good and not evil.
7b57e3ec5Sdrh#    May you find forgiveness for yourself and forgive others.
8b57e3ec5Sdrh#    May you share freely, never taking more than you give.
9b57e3ec5Sdrh#
10b57e3ec5Sdrh#***********************************************************************
11b57e3ec5Sdrh# Test cases for SQLITE_DBCONFIG_RESET_DATABASE
12b57e3ec5Sdrh#
13b57e3ec5Sdrh
14b57e3ec5Sdrhset testdir [file dirname $argv0]
15b57e3ec5Sdrhsource $testdir/tester.tcl
16b57e3ec5Sdrhset testprefix resetdb
17b57e3ec5Sdrh
185d311287Sdrhdo_not_use_codec
195d311287Sdrh
20b57e3ec5Sdrhifcapable !vtab||!compound {
21b57e3ec5Sdrh  finish_test
22b57e3ec5Sdrh  return
23b57e3ec5Sdrh}
24b57e3ec5Sdrh
2566e82b47Sdan# In the "inmemory_journal" permutation, each new connection executes
2666e82b47Sdan# "PRAGMA journal_mode = memory". This fails with SQLITE_BUSY if attempted
2766e82b47Sdan# on a wal mode database with existing connections. For this and a few
2866e82b47Sdan# other reasons, this test is not run as part of "inmemory_journal".
2966e82b47Sdan#
30867e6de4Sdan# Permutation "journaltest" does not support wal mode.
31867e6de4Sdan#
32867e6de4Sdanif {[permutation]=="inmemory_journal"
33867e6de4Sdan || [permutation]=="journaltest"
34867e6de4Sdan} {
3566e82b47Sdan  finish_test
3666e82b47Sdan  return
3766e82b47Sdan}
3866e82b47Sdan
39b57e3ec5Sdrh# Create a sample database
40b57e3ec5Sdrhdo_execsql_test 100 {
411d40cdbdSdan  PRAGMA auto_vacuum = 0;
42b57e3ec5Sdrh  PRAGMA page_size=4096;
43b57e3ec5Sdrh  CREATE TABLE t1(a,b);
44b57e3ec5Sdrh  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<20)
45b57e3ec5Sdrh    INSERT INTO t1(a,b) SELECT x, randomblob(300) FROM c;
46b57e3ec5Sdrh  CREATE INDEX t1a ON t1(a);
47b57e3ec5Sdrh  CREATE INDEX t1b ON t1(b);
48b57e3ec5Sdrh  SELECT sum(a), sum(length(b)) FROM t1;
49b57e3ec5Sdrh  PRAGMA integrity_check;
50b57e3ec5Sdrh  PRAGMA journal_mode;
51b57e3ec5Sdrh  PRAGMA page_count;
52b57e3ec5Sdrh} {210 6000 ok delete 8}
53b57e3ec5Sdrh
54b57e3ec5Sdrh# Verify that the same content is seen from a separate database connection
55b57e3ec5Sdrhsqlite3 db2 test.db
56b57e3ec5Sdrhdo_test 110 {
57b57e3ec5Sdrh  execsql {
58b57e3ec5Sdrh    SELECT sum(a), sum(length(b)) FROM t1;
59b57e3ec5Sdrh    PRAGMA integrity_check;
60b57e3ec5Sdrh    PRAGMA journal_mode;
61b57e3ec5Sdrh    PRAGMA page_count;
62b57e3ec5Sdrh  } db2
63b57e3ec5Sdrh} {210 6000 ok delete 8}
64b57e3ec5Sdrh
65b57e3ec5Sdrhdo_test 200 {
66b57e3ec5Sdrh  # Thoroughly corrupt the database file by overwriting the first
67b57e3ec5Sdrh  # page with randomness.
686ab91a7aSdrh  sqlite3_db_config db DEFENSIVE 0
69b57e3ec5Sdrh  catchsql {
70b57e3ec5Sdrh    UPDATE sqlite_dbpage SET data=randomblob(4096) WHERE pgno=1;
71b57e3ec5Sdrh    PRAGMA quick_check;
72b57e3ec5Sdrh  }
73e6370e9cSdan} {1 {file is not a database}}
74b57e3ec5Sdrhdo_test 201 {
75b57e3ec5Sdrh  catchsql {
76b57e3ec5Sdrh    PRAGMA quick_check;
77b57e3ec5Sdrh  } db2
78e6370e9cSdan} {1 {file is not a database}}
79b57e3ec5Sdrh
80b57e3ec5Sdrhdo_test 210 {
81b57e3ec5Sdrh  # Reset the database file using SQLITE_DBCONFIG_RESET_DATABASE
82b57e3ec5Sdrh  sqlite3_db_config db RESET_DB 1
83b57e3ec5Sdrh  db eval VACUUM
84b57e3ec5Sdrh  sqlite3_db_config db RESET_DB 0
85b57e3ec5Sdrh
86*41e0717bSdan  # If using sqlite3_prepare() instead of _v2() or _v3(), the block
87*41e0717bSdan  # below raises an SQLITE_SCHEMA error. The following fixes this.
88*41e0717bSdan  if {[permutation]=="prepare"} { catchsql "SELECT * FROM sqlite_master" db2 }
89*41e0717bSdan
90b57e3ec5Sdrh  # Verify that the reset took, even on the separate database connection
91b57e3ec5Sdrh  catchsql {
92b57e3ec5Sdrh     PRAGMA page_count;
93b57e3ec5Sdrh     PRAGMA page_size;
94b57e3ec5Sdrh     PRAGMA quick_check;
95b57e3ec5Sdrh     PRAGMA journal_mode;
96b57e3ec5Sdrh  } db2
97b57e3ec5Sdrh} {0 {1 4096 ok delete}}
98b57e3ec5Sdrh
99b57e3ec5Sdrh# Delete the old connections and database and start over again
100b57e3ec5Sdrh# with a different page size and in WAL mode.
101b57e3ec5Sdrh#
102b57e3ec5Sdrhdb close
103b57e3ec5Sdrhdb2 close
104b57e3ec5Sdrhforcedelete test.db
105b57e3ec5Sdrhsqlite3 db test.db
106b57e3ec5Sdrhdo_execsql_test 300 {
1071d40cdbdSdan  PRAGMA auto_vacuum = 0;
108b57e3ec5Sdrh  PRAGMA page_size=8192;
109b57e3ec5Sdrh  PRAGMA journal_mode=WAL;
110b57e3ec5Sdrh  CREATE TABLE t1(a,b);
111b57e3ec5Sdrh  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<20)
112b57e3ec5Sdrh    INSERT INTO t1(a,b) SELECT x, randomblob(1300) FROM c;
113b57e3ec5Sdrh  CREATE INDEX t1a ON t1(a);
114b57e3ec5Sdrh  CREATE INDEX t1b ON t1(b);
115b57e3ec5Sdrh  SELECT sum(a), sum(length(b)) FROM t1;
116b57e3ec5Sdrh  PRAGMA integrity_check;
117b57e3ec5Sdrh  PRAGMA journal_mode;
118b57e3ec5Sdrh  PRAGMA page_size;
119b57e3ec5Sdrh  PRAGMA page_count;
120b57e3ec5Sdrh} {wal 210 26000 ok wal 8192 12}
121b57e3ec5Sdrhsqlite3 db2 test.db
122b57e3ec5Sdrhdo_test 310 {
123b57e3ec5Sdrh  execsql {
124b57e3ec5Sdrh    SELECT sum(a), sum(length(b)) FROM t1;
125b57e3ec5Sdrh    PRAGMA integrity_check;
126b57e3ec5Sdrh    PRAGMA journal_mode;
127b57e3ec5Sdrh    PRAGMA page_size;
128b57e3ec5Sdrh    PRAGMA page_count;
129b57e3ec5Sdrh  } db2
130b57e3ec5Sdrh} {210 26000 ok wal 8192 12}
131b57e3ec5Sdrh
132b57e3ec5Sdrh# Corrupt the database again
1336ab91a7aSdrhsqlite3_db_config db DEFENSIVE 0
134b57e3ec5Sdrhdo_catchsql_test 320 {
135b57e3ec5Sdrh  UPDATE sqlite_dbpage SET data=randomblob(8192) WHERE pgno=1;
136b57e3ec5Sdrh  PRAGMA quick_check
137b57e3ec5Sdrh} {1 {file is not a database}}
138b57e3ec5Sdrh
139b57e3ec5Sdrhdo_test 330 {
140b57e3ec5Sdrh  catchsql {
141b57e3ec5Sdrh    PRAGMA quick_check
142b57e3ec5Sdrh  } db2
143b57e3ec5Sdrh} {1 {file is not a database}}
144b57e3ec5Sdrh
145867e6de4Sdandb2 cache flush         ;# Required by permutation "prepare".
146867e6de4Sdan
147b57e3ec5Sdrh# Reset the database yet again.  Verify that the page size and
148b57e3ec5Sdrh# journal mode are preserved.
149b57e3ec5Sdrh#
150b57e3ec5Sdrhdo_test 400 {
151b57e3ec5Sdrh  sqlite3_db_config db RESET_DB 1
152b57e3ec5Sdrh  db eval VACUUM
153b57e3ec5Sdrh  sqlite3_db_config db RESET_DB 0
154b57e3ec5Sdrh  catchsql {
155b57e3ec5Sdrh     PRAGMA page_count;
156b57e3ec5Sdrh     PRAGMA page_size;
157b57e3ec5Sdrh     PRAGMA journal_mode;
158b57e3ec5Sdrh     PRAGMA quick_check;
159b57e3ec5Sdrh  } db2
160b57e3ec5Sdrh} {0 {1 8192 wal ok}}
161b57e3ec5Sdrhdb2 close
162b57e3ec5Sdrh
1636ea9a728Sdan# Reset the database yet again. This time immediately after it is closed
1646ea9a728Sdan# and reopened. So that the VACUUM is the first statement run.
1656ea9a728Sdan#
1666ea9a728Sdandb close
1676ea9a728Sdansqlite3 db test.db
1686ea9a728Sdando_test 500 {
1696ea9a728Sdan  sqlite3_finalize [
1706ea9a728Sdan    sqlite3_prepare db "SELECT 1 FROM sqlite_master LIMIT 1" -1 tail
1716ea9a728Sdan  ]
1726ea9a728Sdan  sqlite3_db_config db RESET_DB 1
1736ea9a728Sdan  db eval VACUUM
1746ea9a728Sdan  sqlite3_db_config db RESET_DB 0
1756ea9a728Sdan  sqlite3 db2 test.db
1766ea9a728Sdan  catchsql {
1776ea9a728Sdan     PRAGMA page_count;
1786ea9a728Sdan     PRAGMA page_size;
1796ea9a728Sdan     PRAGMA journal_mode;
1806ea9a728Sdan     PRAGMA quick_check;
1816ea9a728Sdan  } db2
1826ea9a728Sdan} {0 {1 8192 wal ok}}
1836ea9a728Sdandb2 close
184b57e3ec5Sdrh
18574901282Sdan#-------------------------------------------------------------------------
18674901282Sdanreset_db
18774901282Sdansqlite3 db2 test.db
18874901282Sdando_execsql_test 600 {
18974901282Sdan  PRAGMA journal_mode = wal;
19074901282Sdan  CREATE TABLE t1(a);
19174901282Sdan  INSERT INTO t1 VALUES(1), (2), (3), (4);
19274901282Sdan} {wal}
19374901282Sdan
19474901282Sdando_execsql_test -db db2 610 {
19574901282Sdan  SELECT * FROM t1
19674901282Sdan} {1 2 3 4}
19774901282Sdan
19874901282Sdando_test 620 {
19974901282Sdan  set res [list]
20074901282Sdan  db2 eval {SELECT a FROM t1} {
20174901282Sdan    lappend res $a
20274901282Sdan    if {$a==3} {
20374901282Sdan      sqlite3_db_config db RESET_DB 1
20474901282Sdan      db eval VACUUM
20574901282Sdan      sqlite3_db_config db RESET_DB 0
20674901282Sdan    }
20774901282Sdan  }
20874901282Sdan
20974901282Sdan  set res
21074901282Sdan} {1 2 3 4}
21174901282Sdan
21274901282Sdando_execsql_test -db db2 630 {
21374901282Sdan  SELECT * FROM sqlite_master
21474901282Sdan} {}
21574901282Sdan
216ea933f07Sdan#-------------------------------------------------------------------------
2179676e611Smistachkindb2 close
218ea933f07Sdanreset_db
219ea933f07Sdan
220ea933f07Sdando_execsql_test 700 {
221ea933f07Sdan  PRAGMA page_size=512;
222202a0274Sdan  PRAGMA auto_vacuum = 0;
223ea933f07Sdan  CREATE TABLE t1(a,b,c);
224ea933f07Sdan  CREATE INDEX t1a ON t1(a);
225ea933f07Sdan  CREATE INDEX t1bc ON t1(b,c);
226ea933f07Sdan  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10)
227ea933f07Sdan    INSERT INTO t1(a,b,c) SELECT x, randomblob(100),randomblob(100) FROM c;
228ea933f07Sdan  PRAGMA page_count;
229ea933f07Sdan  PRAGMA integrity_check;
230ea933f07Sdan} {19 ok}
231ea933f07Sdan
23215c42942Sdrhif {[nonzero_reserved_bytes]} {
23315c42942Sdrh  finish_test
23415c42942Sdrh  return
23515c42942Sdrh}
23615c42942Sdrh
2376ab91a7aSdrhsqlite3_db_config db DEFENSIVE 0
238ea933f07Sdando_execsql_test 710 {
239ea933f07Sdan  UPDATE sqlite_dbpage SET data=
240ea933f07Sdan    X'53514C69746520666F726D61742033000200030100402020000000000000001300000000000000000000000300000004000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000D00000003017C0001D801AC017C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E03061715110145696E6465787431626374310443524541544520494E4445582074316263204F4E20743128622C63292A0206171311013F696E64657874316174310343524541544520494E44455820743161204F4E20743128612926010617111101397461626C657431743102435245415445205441424C4520743128612C622C6329' WHERE pgno=1;
241ea933f07Sdan}
242ea933f07Sdan
243ea933f07Sdando_execsql_test 720 {
244ea933f07Sdan  PRAGMA integrity_check;
245ea933f07Sdan} {ok}
246ea933f07Sdan
247ea933f07Sdando_test 730 {
248ea933f07Sdan  sqlite3_db_config db RESET_DB 1
249ea933f07Sdan  db eval VACUUM
250ea933f07Sdan  sqlite3_db_config db RESET_DB 0
251ea933f07Sdan} {0}
252ea933f07Sdan
253ea933f07Sdando_execsql_test 740 {
254ea933f07Sdan  PRAGMA page_count;
255ea933f07Sdan  PRAGMA integrity_check;
256ea933f07Sdan} {1 ok}
257ea933f07Sdan
258b57e3ec5Sdrhfinish_test
259