Fix the ability to read read-only WAL-mode database when -shm is present,

([00ec95fcd02bb415|check-in 00ec95fcd02bb415]) so that it works
for the case of 64K page size.

FossilOrigin-Name: f426874e005e3c23e8a00083b7c201408e072bca413e52bfc436da6483afb0cd
This commit is contained in:
drh 2022-01-20 02:04:53 +00:00
parent 29a7bbffba
commit d6b44ec32a
4 changed files with 359 additions and 352 deletions

View File

@ -1,5 +1,5 @@
C Fix\sa\stest\sresult\sfor\salterauth2.test\sdue\sto\sthe\srecent\sfix\sto\sauthorizer\ncalls\sfor\sALTER\sTABLE\sDROP\sCOLUMN.
D 2022-01-19T18:31:43.542
C Fix\sthe\sability\sto\sread\sread-only\sWAL-mode\sdatabase\swhen\s-shm\sis\spresent,\n([00ec95fcd02bb415|check-in\s00ec95fcd02bb415])\sso\sthat\sit\sworks\nfor\sthe\scase\sof\s64K\spage\ssize.
D 2022-01-20T02:04:53.654
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -635,7 +635,7 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8
F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c
F src/vtab.c a47cc12ebaa350800c0c87b6b0095debbb5a6ed32727bcab9d82ad070a81b738
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c ed0398a7adf02c31e34aada42cc86c58f413a7afe5f741a5d373ad087abde028
F src/wal.c c55ef660f9ee91e1331ced61f312aae81179ff9ec8632639136bcb252ce86e1b
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
F src/where.c eedf0311d59095bcd8523bd13bf25865e1caf1fab9beddbff9093340a1a409c7
@ -1753,7 +1753,7 @@ F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6
F test/walprotocol.test 1b3f922125e341703f6e946d77fdc564d38fb3e07a9385cfdc6c99cac1ecf878
F test/walprotocol2.test 7d3b6b4bf0b12f8007121b1e6ef714bc99101fb3b48e46371df1db868eebc131
F test/walro.test cb438d05ba0d191f10b688e39c4f0cd5b71569a1d1f4440e5bdf3c6880e08c20
F test/walro2.test 0e79dd15cbdb4f482c01ea248373669c732414a726b357d04846a816afafb768
F test/walro2.test 33955a6fd874dd9724005e17f77fef89d334b3171454a1256fe4941a96766cdc
F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68
F test/walsetlk.test 3185bebc90557e0d611442c8d64f7a0cb7b06f8e156eea37a4a7358f722715be
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
@ -1938,8 +1938,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P aca6c61d79215519fb006af19d9011029df68f195a4ce65aff7a1bf4e36efb94
R 49af707cd669468ece46f1dd370b2f63
P e799a35f2bf85ce43b476738bfbd9b6b378bbf02fa0708dda0deba71dd37f608
R a570f2b782808526402854b4e442ef9f
U drh
Z 256bb3763483caaf79af6f149c662bf0
Z ad5c72d40960b0db8c967cbfe55162e8
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
e799a35f2bf85ce43b476738bfbd9b6b378bbf02fa0708dda0deba71dd37f608
f426874e005e3c23e8a00083b7c201408e072bca413e52bfc436da6483afb0cd

View File

@ -2520,6 +2520,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){
volatile void *pDummy; /* Dummy argument for xShmMap */
int rc; /* Return code */
u32 aSaveCksum[2]; /* Saved copy of pWal->hdr.aFrameCksum */
int szPage; /* Page size */
assert( pWal->bShmUnreliable );
assert( pWal->readOnly & WAL_SHM_RDONLY );
@ -2603,7 +2604,8 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){
}
/* Allocate a buffer to read frames into */
szFrame = pWal->hdr.szPage + WAL_FRAME_HDRSIZE;
szPage = walPagesize(pWal);
szFrame = szPage + WAL_FRAME_HDRSIZE;
aFrame = (u8 *)sqlite3_malloc64(szFrame);
if( aFrame==0 ){
rc = SQLITE_NOMEM_BKPT;
@ -2617,7 +2619,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){
** the caller. */
aSaveCksum[0] = pWal->hdr.aFrameCksum[0];
aSaveCksum[1] = pWal->hdr.aFrameCksum[1];
for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->hdr.szPage);
for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, szPage);
iOffset+szFrame<=szWal;
iOffset+=szFrame
){

View File

@ -50,357 +50,362 @@ do_execsql_test 0.0 {
CREATE TABLE t1(x);
} {wal}
set MINSHMSZ [file size test.db-shm]
set dfltpgsz [db one {PRAGMA page_size}]
foreach bZeroShm {0 1} {
set TN [expr $bZeroShm+1]
do_multiclient_test tn {
# Close all connections and delete the database.
#
code1 { db close }
code2 { db2 close }
code3 { db3 close }
forcedelete test.db
# Do not run tests with the connections in the same process.
#
if {$tn==2} continue
foreach c {code1 code2 code3} {
$c {
sqlite3_shutdown
sqlite3_config_uri 1
}
}
do_test $TN.1.1 {
code2 { sqlite3 db2 test.db }
sql2 {
CREATE TABLE t1(x, y);
PRAGMA journal_mode = WAL;
INSERT INTO t1 VALUES('a', 'b');
INSERT INTO t1 VALUES('c', 'd');
}
file exists test.db-shm
} {1}
do_test $TN.1.2.1 {
copy_to_test2 $bZeroShm
code1 {
sqlite3 db file:test.db2?readonly_shm=1
}
sql1 { SELECT * FROM t1 }
} {a b c d}
do_test $TN.1.2.2 {
sql1 { SELECT * FROM t1 }
} {a b c d}
do_test $TN.1.3.1 {
code3 { sqlite3 db3 test.db2 }
sql3 { SELECT * FROM t1 }
} {a b c d}
do_test $TN.1.3.2 {
sql1 { SELECT * FROM t1 }
} {a b c d}
code1 { db close }
code2 { db2 close }
code3 { db3 close }
do_test $TN.2.1 {
code2 { sqlite3 db2 test.db }
sql2 {
INSERT INTO t1 VALUES('e', 'f');
INSERT INTO t1 VALUES('g', 'h');
}
file exists test.db-shm
} {1}
do_test $TN.2.2 {
copy_to_test2 $bZeroShm
code1 {
sqlite3 db file:test.db2?readonly_shm=1
}
sql1 {
BEGIN;
SELECT * FROM t1;
}
} {a b c d e f g h}
do_test $TN.2.3.1 {
code3 { sqlite3 db3 test.db2 }
sql3 { SELECT * FROM t1 }
} {a b c d e f g h}
do_test $TN.2.3.2 {
sql3 { INSERT INTO t1 VALUES('i', 'j') }
code3 { db3 close }
sql1 { COMMIT }
} {}
do_test $TN.2.3.3 {
sql1 { SELECT * FROM t1 }
} {a b c d e f g h i j}
#-----------------------------------------------------------------------
# 3.1.*: That a readonly_shm connection can read a database file if both
# the *-wal and *-shm files are zero bytes in size.
#
# 3.2.*: That it flushes the cache if, between transactions on a db with a
# zero byte *-wal file, some other connection modifies the db, then
# does "PRAGMA wal_checkpoint=truncate" to truncate the wal file
# back to zero bytes in size.
#
# 3.3.*: That, if between transactions some other process wraps the wal
# file, the readonly_shm client reruns recovery.
#
catch { code1 { db close } }
catch { code2 { db2 close } }
catch { code3 { db3 close } }
do_test $TN.3.1.0 {
list [file exists test.db-wal] [file exists test.db-shm]
} {0 0}
do_test $TN.3.1.1 {
close [open test.db-wal w]
close [open test.db-shm w]
code1 {
sqlite3 db file:test.db?readonly_shm=1
}
sql1 { SELECT * FROM t1 }
} {a b c d e f g h}
do_test $TN.3.2.0 {
list [file size test.db-wal] [file size test.db-shm]
} {0 0}
do_test $TN.3.2.1 {
code2 { sqlite3 db2 test.db }
sql2 { INSERT INTO t1 VALUES(1, 2) ; PRAGMA wal_checkpoint=truncate }
code2 { db2 close }
sql1 { SELECT * FROM t1 }
} {a b c d e f g h 1 2}
do_test $TN.3.2.2 {
list [file size test.db-wal] [file size test.db-shm]
} [list 0 $MINSHMSZ]
do_test $TN.3.3.0 {
code2 { sqlite3 db2 test.db }
sql2 {
INSERT INTO t1 VALUES(3, 4);
INSERT INTO t1 VALUES(5, 6);
INSERT INTO t1 VALUES(7, 8);
INSERT INTO t1 VALUES(9, 10);
}
code2 { db2 close }
code1 { db close }
list [file size test.db-wal] [file size test.db-shm]
} [list [wal_file_size 4 1024] $MINSHMSZ]
do_test $TN.3.3.1 {
code1 { sqlite3 db file:test.db?readonly_shm=1 }
sql1 { SELECT * FROM t1 }
} {a b c d e f g h 1 2 3 4 5 6 7 8 9 10}
do_test $TN.3.3.2 {
code2 { sqlite3 db2 test.db }
sql2 {
PRAGMA wal_checkpoint;
DELETE FROM t1;
INSERT INTO t1 VALUES('i', 'ii');
}
code2 { db2 close }
list [file size test.db-wal] [file size test.db-shm]
} [list [wal_file_size 4 1024] $MINSHMSZ]
do_test $TN.3.3.3 {
sql1 { SELECT * FROM t1 }
} {i ii}
#-----------------------------------------------------------------------
#
#
catch { code1 { db close } }
catch { code2 { db2 close } }
catch { code3 { db3 close } }
do_test $TN.4.0 {
code1 { forcedelete test.db }
code1 { sqlite3 db test.db }
sql1 {
PRAGMA journal_mode = wal;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('hello');
INSERT INTO t1 VALUES('world');
}
copy_to_test2 $bZeroShm
code1 { db close }
} {}
do_test $TN.4.1.1 {
code2 { sqlite3 db2 file:test.db2?readonly_shm=1 }
sql2 { SELECT * FROM t1 }
} {hello world}
do_test $TN.4.1.2 {
code3 { sqlite3 db3 test.db2 }
sql3 {
INSERT INTO t1 VALUES('!');
PRAGMA wal_checkpoint = truncate;
}
code3 { db3 close }
} {}
do_test $TN.4.1.3 {
sql2 { SELECT * FROM t1 }
} {hello world !}
catch { code1 { db close } }
catch { code2 { db2 close } }
catch { code3 { db3 close } }
do_test $TN.4.2.1 {
code1 { sqlite3 db test.db }
sql1 {
INSERT INTO t1 VALUES('!');
INSERT INTO t1 VALUES('!');
PRAGMA cache_size = 10;
CREATE TABLE t2(x);
BEGIN;
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<500
)
INSERT INTO t2 SELECT randomblob(500) FROM s;
SELECT count(*) FROM t2;
}
} {500}
set sz [file size test.db-wal]
do_test $TN.4.2.2.(sz=$sz) {
expr {$sz>400000}
} {1}
do_test $TN.4.2.4 {
file_control_persist_wal db 1; db close
copy_to_test2 $bZeroShm
code2 { sqlite3 db2 file:test.db2?readonly_shm=1 }
sql2 {
SELECT * FROM t1;
SELECT count(*) FROM t2;
}
} {hello world ! ! 0}
#-----------------------------------------------------------------------
#
#
catch { code1 { db close } }
catch { code2 { db2 close } }
catch { code3 { db3 close } }
do_test $TN.5.0 {
code1 { forcedelete test.db }
code1 { sqlite3 db test.db }
sql1 {
PRAGMA journal_mode = wal;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('hello');
INSERT INTO t1 VALUES('world');
INSERT INTO t1 VALUES('!');
INSERT INTO t1 VALUES('world');
INSERT INTO t1 VALUES('hello');
}
copy_to_test2 $bZeroShm
for {set pgsz 512} {$pgsz<=65536} {set pgsz [expr {$pgsz*2}]} {
set TN [expr $bZeroShm+1]-$pgsz
do_multiclient_test tn {
# Close all connections and delete the database.
#
code1 { db close }
code2 { db2 close }
code3 { db3 close }
forcedelete test.db
# Do not run tests with the connections in the same process.
#
if {$tn==2} continue
code1 { db close }
} {}
do_test $TN.5.1 {
code2 { sqlite3 db2 file:test.db2?readonly_shm=1 }
sql2 {
SELECT * FROM t1;
}
} {hello world ! world hello}
do_test $TN.5.2 {
code1 {
proc handle_read {op args} {
if {$op=="xRead" && [file tail [lindex $args 0]]=="test.db2-wal"} {
set ::res2 [sql2 { SELECT * FROM t1 }]
foreach c {code1 code2 code3} {
$c {
sqlite3_shutdown
sqlite3_config_uri 1
}
puts "$msg xRead $args"
return "SQLITE_OK"
}
testvfs tvfs -fullshm 1
sqlite3 db file:test.db2?vfs=tvfs
db eval { SELECT * FROM sqlite_master }
tvfs filter xRead
tvfs script handle_read
}
sql1 {
PRAGMA wal_checkpoint = truncate;
}
code1 { set ::res2 }
} {hello world ! world hello}
do_test $TN.5.3 {
code1 { db close }
code1 { tvfs delete }
} {}
#-----------------------------------------------------------------------
#
#
catch { code1 { db close } }
catch { code2 { db2 close } }
catch { code3 { db3 close } }
do_test $TN.6.1 {
code1 { forcedelete test.db }
code1 { sqlite3 db test.db }
sql1 {
PRAGMA journal_mode = wal;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('hello');
INSERT INTO t1 VALUES('world');
INSERT INTO t1 VALUES('!');
INSERT INTO t1 VALUES('world');
INSERT INTO t1 VALUES('hello');
}
copy_to_test2 $bZeroShm
code1 { db close }
} {}
do_test $TN.6.2 {
code1 {
set ::nRem 5
proc handle_read {op args} {
if {$op=="xRead" && [file tail [lindex $args 0]]=="test.db2-wal"} {
incr ::nRem -1
if {$::nRem==0} {
code2 { sqlite3 db2 test.db2 }
sql2 { PRAGMA wal_checkpoint = truncate }
do_test $TN.1.1 {
code2 { sqlite3 db2 test.db }
sql2 "PRAGMA page_size=$::pgsz"
sql2 {
CREATE TABLE t1(x, y);
PRAGMA journal_mode = WAL;
INSERT INTO t1 VALUES('a', 'b');
INSERT INTO t1 VALUES('c', 'd');
}
file exists test.db-shm
} {1}
do_test $TN.1.2.1 {
copy_to_test2 $bZeroShm
code1 {
sqlite3 db file:test.db2?readonly_shm=1
}
sql1 { SELECT * FROM t1 }
} {a b c d}
do_test $TN.1.2.2 {
sql1 { SELECT * FROM t1 }
} {a b c d}
do_test $TN.1.3.1 {
code3 { sqlite3 db3 test.db2 }
sql3 { SELECT * FROM t1 }
} {a b c d}
do_test $TN.1.3.2 {
sql1 { SELECT * FROM t1 }
} {a b c d}
code1 { db close }
code2 { db2 close }
code3 { db3 close }
do_test $TN.2.1 {
code2 { sqlite3 db2 test.db }
sql2 "PRAGMA page_size=$::pgsz;"
sql2 {
INSERT INTO t1 VALUES('e', 'f');
INSERT INTO t1 VALUES('g', 'h');
}
file exists test.db-shm
} {1}
do_test $TN.2.2 {
copy_to_test2 $bZeroShm
code1 {
sqlite3 db file:test.db2?readonly_shm=1
}
sql1 {
BEGIN;
SELECT * FROM t1;
}
} {a b c d e f g h}
do_test $TN.2.3.1 {
code3 { sqlite3 db3 test.db2 }
sql3 { SELECT * FROM t1 }
} {a b c d e f g h}
do_test $TN.2.3.2 {
sql3 { INSERT INTO t1 VALUES('i', 'j') }
code3 { db3 close }
sql1 { COMMIT }
} {}
do_test $TN.2.3.3 {
sql1 { SELECT * FROM t1 }
} {a b c d e f g h i j}
#-----------------------------------------------------------------------
# 3.1.*: That a readonly_shm connection can read a database file if both
# the *-wal and *-shm files are zero bytes in size.
#
# 3.2.*: That it flushes the cache if, between transactions on a db with a
# zero byte *-wal file, some other connection modifies the db, then
# does "PRAGMA wal_checkpoint=truncate" to truncate the wal file
# back to zero bytes in size.
#
# 3.3.*: That, if between transactions some other process wraps the wal
# file, the readonly_shm client reruns recovery.
#
catch { code1 { db close } }
catch { code2 { db2 close } }
catch { code3 { db3 close } }
do_test $TN.3.1.0 {
list [file exists test.db-wal] [file exists test.db-shm]
} {0 0}
do_test $TN.3.1.1 {
close [open test.db-wal w]
close [open test.db-shm w]
code1 {
sqlite3 db file:test.db?readonly_shm=1
}
sql1 { SELECT * FROM t1 }
} {a b c d e f g h}
do_test $TN.3.2.0 {
list [file size test.db-wal] [file size test.db-shm]
} {0 0}
do_test $TN.3.2.1 {
code2 { sqlite3 db2 test.db }
sql2 { INSERT INTO t1 VALUES(1, 2) ; PRAGMA wal_checkpoint=truncate }
code2 { db2 close }
sql1 { SELECT * FROM t1 }
} {a b c d e f g h 1 2}
if {$pgsz!=$dfltpgsz} continue
do_test $TN.3.2.2 {
list [file size test.db-wal] [file size test.db-shm]
} [list 0 $MINSHMSZ]
do_test $TN.3.3.0 {
code2 { sqlite3 db2 test.db }
sql2 {
INSERT INTO t1 VALUES(3, 4);
INSERT INTO t1 VALUES(5, 6);
INSERT INTO t1 VALUES(7, 8);
INSERT INTO t1 VALUES(9, 10);
}
code2 { db2 close }
code1 { db close }
list [file size test.db-wal] [file size test.db-shm]
} [list [wal_file_size 4 1024] $MINSHMSZ]
do_test $TN.3.3.1 {
code1 { sqlite3 db file:test.db?readonly_shm=1 }
sql1 { SELECT * FROM t1 }
} {a b c d e f g h 1 2 3 4 5 6 7 8 9 10}
do_test $TN.3.3.2 {
code2 { sqlite3 db2 test.db }
sql2 {
PRAGMA wal_checkpoint;
DELETE FROM t1;
INSERT INTO t1 VALUES('i', 'ii');
}
code2 { db2 close }
list [file size test.db-wal] [file size test.db-shm]
} [list [wal_file_size 4 1024] $MINSHMSZ]
do_test $TN.3.3.3 {
sql1 { SELECT * FROM t1 }
} {i ii}
#-----------------------------------------------------------------------
#
#
catch { code1 { db close } }
catch { code2 { db2 close } }
catch { code3 { db3 close } }
do_test $TN.4.0 {
code1 { forcedelete test.db }
code1 { sqlite3 db test.db }
sql1 {
PRAGMA journal_mode = wal;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('hello');
INSERT INTO t1 VALUES('world');
}
copy_to_test2 $bZeroShm
code1 { db close }
} {}
do_test $TN.4.1.1 {
code2 { sqlite3 db2 file:test.db2?readonly_shm=1 }
sql2 { SELECT * FROM t1 }
} {hello world}
do_test $TN.4.1.2 {
code3 { sqlite3 db3 test.db2 }
sql3 {
INSERT INTO t1 VALUES('!');
PRAGMA wal_checkpoint = truncate;
}
code3 { db3 close }
} {}
do_test $TN.4.1.3 {
sql2 { SELECT * FROM t1 }
} {hello world !}
catch { code1 { db close } }
catch { code2 { db2 close } }
catch { code3 { db3 close } }
do_test $TN.4.2.1 {
code1 { sqlite3 db test.db }
sql1 {
INSERT INTO t1 VALUES('!');
INSERT INTO t1 VALUES('!');
PRAGMA cache_size = 10;
CREATE TABLE t2(x);
BEGIN;
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<500
)
INSERT INTO t2 SELECT randomblob(500) FROM s;
SELECT count(*) FROM t2;
}
} {500}
set sz [file size test.db-wal]
do_test $TN.4.2.2.(sz=$sz) {
expr {$sz>400000}
} {1}
do_test $TN.4.2.4 {
file_control_persist_wal db 1; db close
copy_to_test2 $bZeroShm
code2 { sqlite3 db2 file:test.db2?readonly_shm=1 }
sql2 {
SELECT * FROM t1;
SELECT count(*) FROM t2;
}
} {hello world ! ! 0}
#-----------------------------------------------------------------------
#
#
catch { code1 { db close } }
catch { code2 { db2 close } }
catch { code3 { db3 close } }
do_test $TN.5.0 {
code1 { forcedelete test.db }
code1 { sqlite3 db test.db }
sql1 {
PRAGMA journal_mode = wal;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('hello');
INSERT INTO t1 VALUES('world');
INSERT INTO t1 VALUES('!');
INSERT INTO t1 VALUES('world');
INSERT INTO t1 VALUES('hello');
}
copy_to_test2 $bZeroShm
code1 { db close }
} {}
do_test $TN.5.1 {
code2 { sqlite3 db2 file:test.db2?readonly_shm=1 }
sql2 {
SELECT * FROM t1;
}
} {hello world ! world hello}
do_test $TN.5.2 {
code1 {
proc handle_read {op args} {
if {$op=="xRead" && [file tail [lindex $args 0]]=="test.db2-wal"} {
set ::res2 [sql2 { SELECT * FROM t1 }]
}
puts "$msg xRead $args"
return "SQLITE_OK"
}
testvfs tvfs -fullshm 1
sqlite3 db file:test.db2?vfs=tvfs
db eval { SELECT * FROM sqlite_master }
tvfs filter xRead
tvfs script handle_read
}
return "SQLITE_OK"
}
testvfs tvfs -fullshm 1
tvfs filter xRead
tvfs script handle_read
sqlite3 db file:test.db2?readonly_shm=1&vfs=tvfs
db eval { SELECT * FROM t1 }
sql1 {
PRAGMA wal_checkpoint = truncate;
}
code1 { set ::res2 }
} {hello world ! world hello}
do_test $TN.5.3 {
code1 { db close }
code1 { tvfs delete }
} {}
#-----------------------------------------------------------------------
#
#
catch { code1 { db close } }
catch { code2 { db2 close } }
catch { code3 { db3 close } }
do_test $TN.6.1 {
code1 { forcedelete test.db }
code1 { sqlite3 db test.db }
sql1 {
PRAGMA journal_mode = wal;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('hello');
INSERT INTO t1 VALUES('world');
INSERT INTO t1 VALUES('!');
INSERT INTO t1 VALUES('world');
INSERT INTO t1 VALUES('hello');
}
copy_to_test2 $bZeroShm
code1 { db close }
} {}
do_test $TN.6.2 {
code1 {
set ::nRem 5
proc handle_read {op args} {
if {$op=="xRead" && [file tail [lindex $args 0]]=="test.db2-wal"} {
incr ::nRem -1
if {$::nRem==0} {
code2 { sqlite3 db2 test.db2 }
sql2 { PRAGMA wal_checkpoint = truncate }
}
}
return "SQLITE_OK"
}
testvfs tvfs -fullshm 1
tvfs filter xRead
tvfs script handle_read
sqlite3 db file:test.db2?readonly_shm=1&vfs=tvfs
db eval { SELECT * FROM t1 }
}
} {hello world ! world hello}
do_test $TN.6.3 {
code1 { db close }
code1 { tvfs delete }
} {}
}
} {hello world ! world hello}
do_test $TN.6.3 {
code1 { db close }
code1 { tvfs delete }
} {}
}
} ;# for pgsz
} ;# foreach bZeroShm
finish_test