xref: /sqlite-3.40.0/test/memdb1.test (revision 70a05e91)
1ac442f41Sdrh# 2018-01-02
2ac442f41Sdrh#
3ac442f41Sdrh# The author disclaims copyright to this source code.  In place of
4ac442f41Sdrh# a legal notice, here is a blessing:
5ac442f41Sdrh#
6ac442f41Sdrh#    May you do good and not evil.
7ac442f41Sdrh#    May you find forgiveness for yourself and forgive others.
8ac442f41Sdrh#    May you share freely, never taking more than you give.
9ac442f41Sdrh#
10ac442f41Sdrh#***********************************************************************
11ac442f41Sdrh# This file implements regression tests for SQLite library.  The
12ac442f41Sdrh# focus of this file is the "memdb" VFS
13ac442f41Sdrh#
14ac442f41Sdrh
15ac442f41Sdrhset testdir [file dirname $argv0]
16ac442f41Sdrhsource $testdir/tester.tcl
17ac442f41Sdrhset testprefix memdb1
18ac442f41Sdrhdo_not_use_codec
19ac442f41Sdrh
209c6396ecSdrhifcapable !deserialize {
21ac442f41Sdrh  finish_test
22ac442f41Sdrh  return
23ac442f41Sdrh}
24ac442f41Sdrh
25ac442f41Sdrh# Create a MEMDB and populate it with some dummy data.
26ac442f41Sdrh# Then extract the database into the $::db1 variable.
27ac442f41Sdrh# Verify that the size of $::db1 is the same as the size of
28ac442f41Sdrh# the database.
29ac442f41Sdrh#
30ac442f41Sdrhunset -nocomplain db1
31ac442f41Sdrhunset -nocomplain sz1
32ac442f41Sdrhunset -nocomplain pgsz
33ac442f41Sdrhdo_test 100 {
34ac442f41Sdrh  db eval {
35ac442f41Sdrh    CREATE TABLE t1(a,b);
36ac442f41Sdrh    INSERT INTO t1 VALUES(1,2);
37ac442f41Sdrh  }
38ac442f41Sdrh  set ::pgsz [db one {PRAGMA page_size}]
39ac442f41Sdrh  set ::sz1 [expr {$::pgsz*[db one {PRAGMA page_count}]}]
40cb7d541dSdrh  set ::db1 [db serialize]
41ac442f41Sdrh  expr {[string length $::db1]==$::sz1}
42ac442f41Sdrh} 1
43cb7d541dSdrhset fd [open db1.db wb]
44cb7d541dSdrhputs -nonewline $fd $db1
45cb7d541dSdrhclose $fd
46ac442f41Sdrh
47ac442f41Sdrh# Create a new MEMDB and initialize it to the content of $::db1
48ac442f41Sdrh# Verify that the content is the same.
49ac442f41Sdrh#
50ac442f41Sdrhdb close
513ec8665eSdrhsqlite3 db
523ec8665eSdrhdb deserialize $db1
53ac442f41Sdrhdo_execsql_test 110 {
54ac442f41Sdrh  SELECT * FROM t1;
55ac442f41Sdrh} {1 2}
56ac442f41Sdrh
57a5bb4351Sdrh# What happens when we try to VACUUM a MEMDB database?
58a5bb4351Sdrh#
59a5bb4351Sdrhdo_execsql_test 120 {
60d88690bdSdan  PRAGMA auto_vacuum = off;
61a5bb4351Sdrh  VACUUM;
62a5bb4351Sdrh} {}
63a5bb4351Sdrhdo_execsql_test 130 {
64a5bb4351Sdrh  CREATE TABLE t2(x, y);
65a5bb4351Sdrh  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
66a5bb4351Sdrh   INSERT INTO t2(x, y) SELECT x, randomblob(1000) FROM c;
67a5bb4351Sdrh  DROP TABLE t2;
68a5bb4351Sdrh  PRAGMA page_count;
69a5bb4351Sdrh} {116}
70a5bb4351Sdrhdo_execsql_test 140 {
71a5bb4351Sdrh  VACUUM;
72a5bb4351Sdrh  PRAGMA page_count;
73a5bb4351Sdrh} {2}
74a5bb4351Sdrh
756ca64481Sdrhdo_test 150 {
766ca64481Sdrh  catch {db deserialize -unknown 1 $db1} msg
776ca64481Sdrh  set msg
786ca64481Sdrh} {unknown option: -unknown}
796ca64481Sdrhdo_test 151 {
806ca64481Sdrh  db deserialize -readonly 1 $db1
816ca64481Sdrh  db eval {SELECT * FROM t1}
826ca64481Sdrh} {1 2}
836ca64481Sdrhdo_test 152 {
846ca64481Sdrh  catchsql {INSERT INTO t1 VALUES(3,4);}
856ca64481Sdrh} {1 {attempt to write a readonly database}}
866ca64481Sdrh
876ca64481Sdrhbreakpoint
886ca64481Sdrhdo_test 160 {
896ca64481Sdrh  db deserialize -maxsize 32768 $db1
906ca64481Sdrh  db eval {SELECT * FROM t1}
916ca64481Sdrh} {1 2}
926ca64481Sdrhdo_test 161 {
936ca64481Sdrh  db eval {INSERT INTO t1 VALUES(3,4); SELECT * FROM t1}
946ca64481Sdrh} {1 2 3 4}
956ca64481Sdrhdo_test 162 {
966ca64481Sdrh  catchsql {INSERT INTO t1 VALUES(5,randomblob(100000))}
976ca64481Sdrh} {1 {database or disk is full}}
986ca64481Sdrh
996ca64481Sdrh
100a5bb4351Sdrh# Build a largish on-disk database and serialize it.  Verify that the
101a5bb4351Sdrh# serialization works.
102a5bb4351Sdrh#
103a5bb4351Sdrhdb close
104a5bb4351Sdrhforcedelete test.db
105a5bb4351Sdrhsqlite3 db test.db
106a5bb4351Sdrhdo_execsql_test 200 {
107a5bb4351Sdrh  CREATE TABLE t3(x, y);
108a5bb4351Sdrh  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<400)
109a5bb4351Sdrh   INSERT INTO t3(x, y) SELECT x, randomblob(1000) FROM c;
110a5bb4351Sdrh  PRAGMA quick_check;
111a5bb4351Sdrh} {ok}
112a5bb4351Sdrhset fd [open test.db rb]
113a5bb4351Sdrhunset -nocomplain direct
114a5bb4351Sdrhset direct [read $fd]
115a5bb4351Sdrhclose $fd
116a5bb4351Sdrhdo_test 210 {
117a5bb4351Sdrh  string length [db serialize]
118a5bb4351Sdrh} [string length $direct]
119a5bb4351Sdrhdo_test 220 {
120a5bb4351Sdrh  db eval {ATTACH ':memory:' AS aux1}
121a5bb4351Sdrh  db deserialize aux1 $::direct
122a5bb4351Sdrh  db eval {
123a5bb4351Sdrh     SELECT x, y FROM main.t3 EXCEPT SELECT x, y FROM aux1.t3;
124a5bb4351Sdrh  }
125a5bb4351Sdrh} {}
126a5bb4351Sdrhunset -nocomplain direct
127a5bb4351Sdrh
128a5bb4351Sdrh# Do the same with a :memory: database.
129a5bb4351Sdrh#
130a5bb4351Sdrhdb close
131a5bb4351Sdrhsqlite3 db :memory:
132a5bb4351Sdrhdo_execsql_test 300 {
133a5bb4351Sdrh  CREATE TABLE t3(x, y);
134a5bb4351Sdrh  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<400)
135a5bb4351Sdrh   INSERT INTO t3(x, y) SELECT x, randomblob(1000) FROM c;
136a5bb4351Sdrh  PRAGMA quick_check;
137a5bb4351Sdrh} {ok}
138a5bb4351Sdrhdo_test 310 {
139a5bb4351Sdrh  db eval {ATTACH ':memory:' AS aux1}
140a5bb4351Sdrh  db deserialize aux1 [db serialize main]
141a5bb4351Sdrh  db eval {
142a5bb4351Sdrh     SELECT x, y FROM main.t3 EXCEPT SELECT x, y FROM aux1.t3;
143a5bb4351Sdrh  }
144a5bb4351Sdrh} {}
145a5bb4351Sdrh
146a5bb4351Sdrh# Deserialize an empty database
147a5bb4351Sdrh#
148a5bb4351Sdrhdb close
149a5bb4351Sdrhsqlite3 db
150a5bb4351Sdrhdb deserialize {}
151a5bb4351Sdrhdo_execsql_test 400 {
152a5bb4351Sdrh  PRAGMA integrity_check;
153a5bb4351Sdrh} {ok}
154a5bb4351Sdrhdo_execsql_test 410 {
155a5bb4351Sdrh  CREATE TABLE t4(a,b);
156a5bb4351Sdrh  INSERT INTO t4 VALUES('hello','world!');
157a5bb4351Sdrh  PRAGMA integrity_check;
158a5bb4351Sdrh  SELECT * FROM t4;
159a5bb4351Sdrh} {ok hello world!}
160d5e7fff2Sdrhdo_execsql_test 420 {
161d5e7fff2Sdrh  PRAGMA journal_mode=TRUNCATE;
162d5e7fff2Sdrh  PRAGMA journal_mode=OFF;
163d5e7fff2Sdrh  PRAGMA journal_mode=DELETE;
164d5e7fff2Sdrh  PRAGMA journal_mode=WAL;
165d5e7fff2Sdrh  PRAGMA journal_mode=PERSIST;
166d5e7fff2Sdrh  PRAGMA journal_mode=MEMORY;
167d5e7fff2Sdrh  PRAGMA journal_mode=OFF;
168d5e7fff2Sdrh  PRAGMA journal_mode=DELETE;
169d5e7fff2Sdrh} {truncate off delete delete persist memory off delete}
170a5bb4351Sdrh
171a5bb4351Sdrh# Deserialize something that is not a database.
172a5bb4351Sdrh#
173a5bb4351Sdrhdb close
174a5bb4351Sdrhsqlite3 db
175a5bb4351Sdrhdo_test 500 {
176a5bb4351Sdrh  set rc [catch {db deserialize not-a-database} msg]
177a5bb4351Sdrh  lappend rc $msg
178a5bb4351Sdrh} {0 {}}
179a5bb4351Sdrhdo_catchsql_test 510 {
180a5bb4351Sdrh  PRAGMA integrity_check;
181a5bb4351Sdrh} {1 {file is not a database}}
182a5bb4351Sdrh
183a5bb4351Sdrh# Abuse the serialize and deserialize commands.  Make sure errors are caught.
184a5bb4351Sdrh#
185a5bb4351Sdrhdo_test 600 {
186a5bb4351Sdrh  set rc [catch {db deserialize} msg]
187a5bb4351Sdrh  lappend rc $msg
188a5bb4351Sdrh} {1 {wrong # args: should be "db deserialize ?DATABASE? VALUE"}}
189a5bb4351Sdrhdo_test 610 {
190a5bb4351Sdrh  set rc [catch {db deserialize a b c} msg]
191a5bb4351Sdrh  lappend rc $msg
1926ca64481Sdrh} {1 {unknown option: a}}
193a5bb4351Sdrhdo_test 620 {
194a5bb4351Sdrh  set rc [catch {db serialize a b} msg]
195a5bb4351Sdrh  lappend rc $msg
196a5bb4351Sdrh} {1 {wrong # args: should be "db serialize ?DATABASE?"}}
197ac442f41Sdrh
19853fa0250Sdrh# 2021-07-19 https://sqlite.org/forum/forumpost/e1cbb5f450b98aa6
19953fa0250Sdrh# The TEMP database cannot participate in serialization or
20053fa0250Sdrh# deserialization.
20153fa0250Sdrh#
20253fa0250Sdrhreset_db
20353fa0250Sdrhdo_test 650 {
20453fa0250Sdrh  db eval {
20553fa0250Sdrh    CREATE TEMP TABLE t0(a);
20653fa0250Sdrh    CREATE TABLE t1(x);
20753fa0250Sdrh    WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000)
20853fa0250Sdrh    INSERT INTO t1(x) SELECT random() FROM c;
20953fa0250Sdrh  }
21053fa0250Sdrh  set rc [catch {db deserialize temp [db serialize main]} err]
21153fa0250Sdrh  lappend rc err
21253fa0250Sdrh} {1 err}
21353fa0250Sdrh
214fcb02429Sdan#-------------------------------------------------------------------------
215150dfbd2Sdanifcapable vtab {
216fcb02429Sdan  reset_db
217fcb02429Sdan  do_execsql_test 700 {
218fcb02429Sdan    CREATE TABLE t1(a, b);
219fcb02429Sdan    PRAGMA schema_version = 0;
220fcb02429Sdan  }
221fcb02429Sdan  do_test 710 {
222fcb02429Sdan    set ser [db serialize main]
223fcb02429Sdan    db close
224fcb02429Sdan    sqlite3 db
225fcb02429Sdan    db deserialize main $ser
226fcb02429Sdan    catchsql {
227fcb02429Sdan      CREATE VIRTUAL TABLE t1 USING rtree(id, a, b, c, d);
228fcb02429Sdan    }
229fcb02429Sdan  } {1 {table t1 already exists}}
230150dfbd2Sdan}
231fcb02429Sdan
2321a39e456Sdan
2331a39e456Sdan#-------------------------------------------------------------------------
2341a39e456Sdan# dbsqlfuzz  0a13dfb474d4f2f11a48a2ea57075c96fb456dd7
2351a39e456Sdan#
236*70a05e91Sdanif {[wal_is_capable]} {
2371a39e456Sdan  reset_db
2381a39e456Sdan  do_execsql_test 800 {
23942ac4c2eSdan    PRAGMA auto_vacuum = 0;
2401a39e456Sdan    PRAGMA page_size = 8192;
2411a39e456Sdan    PRAGMA journal_mode = wal;
2421a39e456Sdan    CREATE TABLE t1(x, y);
2431a39e456Sdan    INSERT INTO t1 VALUES(1, 2);
2441a39e456Sdan    CREATE TABLE t2(x, y);
2451a39e456Sdan  } {wal}
2461a39e456Sdan  db close
2471a39e456Sdan
2481a39e456Sdan  set fd [open test.db]
2491a39e456Sdan  fconfigure $fd -translation binary -encoding binary
2501a39e456Sdan  set data [read $fd [expr 20*1024]]
2511a39e456Sdan
2521a39e456Sdan  sqlite3 db ""
2531a39e456Sdan  db deserialize $data
2541a39e456Sdan
2551a39e456Sdan  do_execsql_test 810 {
2561a39e456Sdan    PRAGMA locking_mode = exclusive;
2571a39e456Sdan    SELECT * FROM t1
2581a39e456Sdan  } {exclusive 1 2}
2591a39e456Sdan
2601a39e456Sdan  do_execsql_test 820 {
2611a39e456Sdan    INSERT INTO t1 VALUES(3, 4);
2621a39e456Sdan    SELECT * FROM t1;
2631a39e456Sdan  } {1 2 3 4}
2641a39e456Sdan
2651a39e456Sdan  do_catchsql_test 830 {
2661a39e456Sdan    PRAGMA wal_checkpoint;
2671a39e456Sdan  } {1 {database disk image is malformed}}
268*70a05e91Sdan}
2691a39e456Sdan
270ac442f41Sdrhfinish_test
271