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