xref: /sqlite-3.40.0/ext/recover/recover1.test (revision a16edfa2)
1# 2022 August 28
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#
12
13source [file join [file dirname [info script]] recover_common.tcl]
14set testprefix recover1
15
16proc compare_result {db1 db2 sql} {
17  set r1 [$db1 eval $sql]
18  set r2 [$db2 eval $sql]
19  if {$r1 != $r2} {
20    puts "r1: $r1"
21    puts "r2: $r2"
22    error "mismatch for $sql"
23  }
24  return ""
25}
26
27proc compare_dbs {db1 db2} {
28  compare_result $db1 $db2 "SELECT sql FROM sqlite_master ORDER BY 1"
29  foreach tbl [$db1 eval {SELECT name FROM sqlite_master WHERE type='table'}] {
30    compare_result $db1 $db2 "SELECT * FROM $tbl"
31  }
32
33  compare_result $db1 $db2 "PRAGMA page_size"
34  compare_result $db1 $db2 "PRAGMA auto_vacuum"
35  compare_result $db1 $db2 "PRAGMA encoding"
36  compare_result $db1 $db2 "PRAGMA user_version"
37  compare_result $db1 $db2 "PRAGMA application_id"
38}
39
40proc do_recover_test {tn} {
41  forcedelete test.db2
42  forcedelete rstate.db
43
44  uplevel [list do_test $tn.1 {
45    set R [sqlite3_recover_init db main test.db2]
46    $R config testdb rstate.db
47    $R run
48    $R finish
49  } {}]
50
51  sqlite3 db2 test.db2
52  uplevel [list do_test $tn.2 [list compare_dbs db db2] {}]
53  db2 close
54
55  forcedelete test.db2
56  forcedelete rstate.db
57
58  uplevel [list do_test $tn.3 {
59    set ::sqlhook [list]
60    set R [sqlite3_recover_init_sql db main my_sql_hook]
61    $R config testdb rstate.db
62    $R config rowids 1
63    $R run
64    $R finish
65  } {}]
66
67  sqlite3 db2 test.db2
68  execsql [join $::sqlhook ";"] db2
69  db2 close
70  sqlite3 db2 test.db2
71  uplevel [list do_test $tn.4 [list compare_dbs db db2] {}]
72  db2 close
73}
74
75proc my_sql_hook {sql} {
76  lappend ::sqlhook $sql
77  return 0
78}
79
80do_execsql_test 1.0 {
81  CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
82  CREATE TABLE t2(a INTEGER PRIMARY KEY, b) WITHOUT ROWID;
83  WITH s(i) AS (
84    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10
85  )
86  INSERT INTO t1 SELECT i*2, hex(randomblob(250)) FROM s;
87  INSERT INTO t2 SELECT * FROM t1;
88}
89
90do_recover_test 1
91
92do_execsql_test 2.0 {
93  ALTER TABLE t1 ADD COLUMN c DEFAULT 'xyz'
94}
95do_recover_test 2
96
97do_execsql_test 3.0 {
98  CREATE INDEX i1 ON t1(c);
99}
100do_recover_test 3
101
102do_execsql_test 4.0 {
103  CREATE VIEW v1 AS SELECT * FROM t2;
104}
105do_recover_test 4
106
107do_execsql_test 5.0 {
108  CREATE UNIQUE INDEX i2 ON t1(c, b);
109}
110do_recover_test 5
111
112#--------------------------------------------------------------------------
113#
114reset_db
115do_execsql_test 6.0 {
116  CREATE TABLE t1(
117      a INTEGER PRIMARY KEY,
118      b INT,
119      c TEXT,
120      d INT GENERATED ALWAYS AS (a*abs(b)) VIRTUAL,
121      e TEXT GENERATED ALWAYS AS (substr(c,b,b+1)) STORED,
122      f TEXT GENERATED ALWAYS AS (substr(c,b,b+1)) STORED
123  );
124
125  INSERT INTO t1 VALUES(1, 2, 'hello world');
126}
127do_recover_test 6
128
129do_execsql_test 7.0 {
130  CREATE TABLE t2(i, j GENERATED ALWAYS AS (i+1) STORED, k);
131  INSERT INTO t2 VALUES(10, 'ten');
132}
133do_execsql_test 7.1 {
134  SELECT * FROM t2
135} {10 11 ten}
136
137do_recover_test 7.2
138
139#--------------------------------------------------------------------------
140#
141reset_db
142do_execsql_test 8.0 {
143  CREATE TABLE x1(a INTEGER PRIMARY KEY AUTOINCREMENT, b, c);
144  WITH s(i) AS (
145    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<2
146  )
147  INSERT INTO x1(b, c) SELECT hex(randomblob(100)), hex(randomblob(100)) FROM s;
148
149  CREATE INDEX x1b ON x1(b);
150  CREATE INDEX x1cb ON x1(c, b);
151  DELETE FROM x1 WHERE a>50;
152
153  ANALYZE;
154}
155
156do_recover_test 8
157
158#-------------------------------------------------------------------------
159reset_db
160ifcapable fts5 {
161  do_execsql_test 9.1 {
162    CREATE VIRTUAL TABLE ft5 USING fts5(a, b);
163    INSERT INTO ft5 VALUES('hello', 'world');
164  }
165  do_recover_test 9
166}
167
168#-------------------------------------------------------------------------
169reset_db
170do_execsql_test 10.1 {
171  CREATE TABLE x1(a PRIMARY KEY, str TEXT) WITHOUT ROWID;
172  INSERT INTO x1 VALUES(1, '
173    \nhello\012world(\n0)(\n1)
174  ');
175  INSERT INTO x1 VALUES(2, '
176    \nhello
177  ');
178}
179do_execsql_test 10.2 "
180  INSERT INTO x1 VALUES(3, '\012hello there\015world');
181  INSERT INTO x1 VALUES(4, '\015hello there\015world');
182"
183do_recover_test 10
184
185#-------------------------------------------------------------------------
186reset_db
187do_execsql_test 11.1 {
188  PRAGMA page_size = 4096;
189  PRAGMA encoding='utf16';
190  PRAGMA auto_vacuum = 2;
191  PRAGMA user_version = 45;
192  PRAGMA application_id = 22;
193
194  CREATE TABLE u1(u, v);
195  INSERT INTO u1 VALUES('edvin marton', 'bond');
196  INSERT INTO u1 VALUES(1, 4.0);
197}
198do_execsql_test 11.1a {
199  PRAGMA auto_vacuum;
200} {2}
201
202do_recover_test 11
203
204do_test 12.1 {
205  set R [sqlite3_recover_init db "" test.db2]
206  $R config lostandfound ""
207  $R config invalid xyz
208} {12}
209do_test 12.2 {
210  $R run
211  $R run
212} {0}
213
214do_test 12.3 {
215  $R finish
216} {}
217
218
219
220#-------------------------------------------------------------------------
221reset_db
222file_control_reservebytes db 16
223do_execsql_test 12.1 {
224  PRAGMA auto_vacuum = 2;
225  PRAGMA user_version = 45;
226  PRAGMA application_id = 22;
227
228  CREATE TABLE u1(u, v);
229  CREATE UNIQUE INDEX i1 ON u1(u, v);
230  INSERT INTO u1 VALUES(1, 2), (3, 4);
231
232  CREATE TABLE u2(u, v);
233  CREATE UNIQUE INDEX i2 ON u1(u, v);
234  INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
235  INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
236  INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
237  INSERT INTO u2 VALUES(hex(randomblob(50000)), hex(randomblob(20000)));
238}
239
240do_recover_test 12
241
242#-------------------------------------------------------------------------
243reset_db
244sqlite3 db ""
245do_recover_test 13
246
247do_execsql_test 14.1 {
248  PRAGMA auto_vacuum = 2;
249  PRAGMA user_version = 45;
250  PRAGMA application_id = 22;
251
252  CREATE TABLE u1(u, v);
253  CREATE UNIQUE INDEX i1 ON u1(u, v);
254  INSERT INTO u1 VALUES(1, 2), (3, 4);
255
256  CREATE TABLE u2(u, v);
257  CREATE UNIQUE INDEX i2 ON u1(u, v);
258  INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
259  INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
260  INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
261  INSERT INTO u2 VALUES(hex(randomblob(50000)), hex(randomblob(20000)));
262}
263do_recover_test 14
264
265#-------------------------------------------------------------------------
266reset_db
267execsql {
268  PRAGMA journal_mode=OFF;
269  PRAGMA mmap_size=10;
270}
271do_execsql_test 15.1 {
272  CREATE TABLE t1(x);
273} {}
274do_recover_test 15
275
276finish_test
277
278