0
0
mirror of https://github.com/tursodatabase/libsql.git synced 2025-06-16 06:23:12 +00:00
Files
.cargo
.github
bindings
bottomless
bottomless-cli
docker-compose
docs
libsql
libsql-ffi
libsql-replication
libsql-rusqlite
libsql-server
libsql-shell
libsql-sqlite3
art
autoconf
contrib
crates
doc
ext
mptest
src
test
json
rust_suite
8_3_names.test
affinity2.test
affinity3.test
aggerror.test
aggfault.test
aggnested.test
aggorderby.test
alias.test
all.test
alter.test
alter2.test
alter3.test
alter4.test
alterauth.test
alterauth2.test
altercol.test
altercorrupt.test
alterdropcol.test
alterdropcol2.test
alterfault.test
alterlegacy.test
altermalloc.test
altermalloc2.test
altermalloc3.test
alterqf.test
altertab.test
altertab2.test
altertab3.test
altertrig.test
amatch1.test
analyze.test
analyze3.test
analyze4.test
analyze5.test
analyze6.test
analyze7.test
analyze8.test
analyze9.test
analyzeC.test
analyzeD.test
analyzeE.test
analyzeF.test
analyzeG.test
analyzer1.test
async.test
async2.test
async3.test
async4.test
async5.test
atof1.test
atomic.test
atomic2.test
atrc.c
attach.test
attach2.test
attach3.test
attach4.test
attachmalloc.test
auth.test
auth2.test
auth3.test
autoanalyze1.test
autoinc.test
autoindex1.test
autoindex2.test
autoindex3.test
autoindex4.test
autoindex5.test
autovacuum.test
autovacuum2.test
autovacuum_ioerr2.test
avfs.test
avtrans.test
backcompat.test
backup.test
backup2.test
backup4.test
backup5.test
backup_ioerr.test
backup_malloc.test
badutf.test
badutf2.test
basexx1.test
bc_common.tcl
bestindex1.test
bestindex2.test
bestindex3.test
bestindex4.test
bestindex5.test
bestindex6.test
bestindex7.test
bestindex8.test
bestindex9.test
bestindexA.test
bestindexB.test
between.test
bigfile.test
bigfile2.test
bigmmap.test
bigrow.test
bigsort.test
bind.test
bind2.test
bindxfer.test
bitvec.test
blob.test
bloom1.test
boundary1.tcl
boundary1.test
boundary2.tcl
boundary2.test
boundary3.tcl
boundary3.test
boundary4.tcl
boundary4.test
btree01.test
btree02.test
btreefault.test
busy.test
busy2.test
cache.test
cacheflush.test
cachespill.test
capi2.test
capi3.test
capi3b.test
capi3c.test
capi3d.test
capi3e.test
carray01.test
cast.test
cffault.test
changes.test
changes2.test
check.test
checkfault.test
chunksize.test
close.test
closure01.test
coalesce.test
collate1.test
collate2.test
collate3.test
collate4.test
collate5.test
collate6.test
collate7.test
collate8.test
collate9.test
collateA.test
collateB.test
colmeta.test
colname.test
columncount.test
conflict.test
conflict2.test
conflict3.test
contrib01.test
corrupt.test
corrupt2.test
corrupt3.test
corrupt4.test
corrupt5.test
corrupt6.test
corrupt7.test
corrupt8.test
corrupt9.test
corruptA.test
corruptB.test
corruptC.test
corruptD.test
corruptE.test
corruptF.test
corruptG.test
corruptH.test
corruptI.test
corruptJ.test
corruptK.test
corruptL.test
corruptM.test
corruptN.test
cost.test
count.test
countofview.test
coveridxscan.test
crash.test
crash2.test
crash3.test
crash4.test
crash5.test
crash6.test
crash7.test
crash8.test
crashM.test
crashtest1.c
createtab.test
cse.test
csv01.test
ctime.test
cursorhint.test
cursorhint2.test
dataversion1.test
date.test
date2.test
date3.test
date4.test
dbdata.test
dbfuzz.c
dbfuzz001.test
dbfuzz2-seed1.db
dbfuzz2.c
dbpage.test
dbpagefault.test
dbstatus.test
dbstatus2.test
decimal.test
default.test
delete.test
delete2.test
delete3.test
delete4.test
delete_db.test
descidx1.test
descidx2.test
descidx3.test
diskfull.test
distinct.test
distinct2.test
distinctagg.test
e_blobbytes.test
e_blobclose.test
e_blobopen.test
e_blobwrite.test
e_changes.test
e_createtable.test
e_delete.test
e_droptrigger.test
e_dropview.test
e_expr.test
e_fkey.test
e_fts3.test
e_insert.test
e_reindex.test
e_resolve.test
e_select.test
e_select2.test
e_totalchanges.test
e_update.test
e_uri.test
e_vacuum.test
e_wal.test
e_walauto.test
e_walckpt.test
e_walhook.test
emptytable.test
enc.test
enc2.test
enc3.test
enc4.test
eqp.test
errmsg.test
eval.test
exclusive.test
exclusive2.test
exec.test
exists.test
expr.test
expr2.test
exprfault.test
extension01.test
external_reader.test
extraquick.test
fallocate.test
filectrl.test
filefmt.test
filter1.test
filter2.tcl
filter2.test
filterfault.test
fkey1.test
fkey2.test
fkey3.test
fkey4.test
fkey5.test
fkey6.test
fkey7.test
fkey8.test
fkey_malloc.test
fordelete.test
format4.test
fp-speed-1.c
fpconv1.test
fts-9fd058691.test
fts3.test
fts3_common.tcl
fts3aa.test
fts3ab.test
fts3ac.test
fts3ad.test
fts3ae.test
fts3af.test
fts3ag.test
fts3ah.test
fts3ai.test
fts3aj.test
fts3ak.test
fts3al.test
fts3am.test
fts3an.test
fts3ao.test
fts3atoken.test
fts3auto.test
fts3aux1.test
fts3aux2.test
fts3b.test
fts3c.test
fts3comp1.test
fts3conf.test
fts3corrupt.test
fts3corrupt2.test
fts3corrupt3.test
fts3corrupt4.test
fts3corrupt5.test
fts3corrupt6.test
fts3cov.test
fts3d.test
fts3defer.test
fts3defer2.test
fts3defer3.test
fts3drop.test
fts3dropmod.test
fts3e.test
fts3expr.test
fts3expr2.test
fts3expr3.test
fts3expr4.test
fts3expr5.test
fts3f.test
fts3fault.test
fts3fault2.test
fts3fault3.test
fts3first.test
fts3fuzz001.test
fts3join.test
fts3malloc.test
fts3matchinfo.test
fts3matchinfo2.test
fts3misc.test
fts3near.test
fts3offsets.test
fts3prefix.test
fts3prefix2.test
fts3query.test
fts3rank.test
fts3rnd.test
fts3shared.test
fts3snippet.test
fts3snippet2.test
fts3sort.test
fts3tok1.test
fts3tok_err.test
fts3varint.test
fts4aa.test
fts4check.test
fts4content.test
fts4docid.test
fts4growth.test
fts4growth2.test
fts4incr.test
fts4intck1.test
fts4langid.test
fts4lastrowid.test
fts4merge.test
fts4merge2.test
fts4merge3.test
fts4merge4.test
fts4merge5.test
fts4min.test
fts4noti.test
fts4onepass.test
fts4opt.test
fts4record.test
fts4rename.test
fts4umlaut.test
fts4unicode.test
fts4upfrom.test
full.test
func.test
func2.test
func3.test
func4.test
func5.test
func6.test
func7.test
func8.test
func9.test
fuzz-oss1.test
fuzz.test
fuzz2.test
fuzz3.test
fuzz4.test
fuzz_common.tcl
fuzz_malloc.test
fuzzcheck.c
fuzzdata1.db
fuzzdata2.db
fuzzdata3.db
fuzzdata4.db
fuzzdata5.db
fuzzdata6.db
fuzzdata7.db
fuzzdata8.db
fuzzer1.test
fuzzer2.test
fuzzerfault.test
fuzzinvariants.c
gcfault.test
gencol1.test
genesis.tcl
having.test
hexlit.test
hidden.test
hook.test
hook2.test
icu.test
ieee754.test
imposter1.test
in.test
in2.test
in3.test
in4.test
in5.test
in6.test
incrblob.test
incrblob2.test
incrblob3.test
incrblob4.test
incrblob_err.test
incrblobfault.test
incrcorrupt.test
incrvacuum.test
incrvacuum2.test
incrvacuum3.test
incrvacuum_ioerr.test
index.test
index2.test
index3.test
index4.test
index5.test
index6.test
index7.test
index8.test
index9.test
indexA.test
indexedby.test
indexexpr1.test
indexexpr2.test
indexfault.test
init.test
insert.test
insert2.test
insert3.test
insert4.test
insert5.test
insertfault.test
instr.test
instrfault.test
intarray.test
interrupt.test
interrupt2.test
intpkey.test
intreal.test
io.test
ioerr.test
ioerr2.test
ioerr3.test
ioerr4.test
ioerr5.test
ioerr6.test
istrue.test
join.test
join2.test
join3.test
join4.test
join5.test
join6.test
join7.test
join8.test
join9.test
joinA.test
joinB.test
joinC.test
joinD.test
joinE.test
joinF.test
joinH.test
journal1.test
journal2.test
journal3.test
jrnlmode.test
jrnlmode2.test
jrnlmode3.test
json101.test
json102.test
json103.test
json104.test
json105.test
json501.test
json502.test
keyword1.test
kvtest.c
lastinsert.test
laststmtchanges.test
lemon-test01.y
like.test
like2.test
like3.test
limit.test
limit2.test
loadext.test
loadext2.test
lock.test
lock2.test
lock3.test
lock4.test
lock5.test
lock6.test
lock7.test
lock_common.tcl
lookaside.test
main.test
make-where7.tcl
malloc.test
malloc3.test
malloc4.test
malloc5.test
malloc6.test
malloc7.test
malloc8.test
malloc9.test
mallocA.test
mallocAll.test
mallocB.test
mallocC.test
mallocD.test
mallocE.test
mallocF.test
mallocG.test
mallocH.test
mallocI.test
mallocJ.test
mallocK.test
mallocL.test
mallocM.test
malloc_common.tcl
malloctraceviewer.tcl
manydb.test
mem5.test
memdb.test
memdb1.test
memdb2.test
memjournal.test
memjournal2.test
memleak.test
memsubsys1.test
memsubsys2.test
merge1.test
minmax.test
minmax2.test
minmax3.test
minmax4.test
misc1.test
misc2.test
misc3.test
misc4.test
misc5.test
misc6.test
misc7.test
misc8.test
misuse.test
mjournal.test
mmap1.test
mmap2.test
mmap3.test
mmap4.test
mmapfault.test
mmapwarm.test
multiplex.test
multiplex2.test
multiplex3.test
multiplex4.test
mutex1.test
mutex2.test
nan.test
nockpt.test
nolock.test
normalize.test
notify1.test
notify2.test
notify3.test
notnull.test
notnull2.test
notnullfault.test
null.test
nulls1.test
numcast.test
numindex1.test
offset1.test
openv2.test
optfuzz-db01.c
optfuzz-db01.txt
optfuzz.c
orderby1.test
orderby2.test
orderby3.test
orderby4.test
orderby5.test
orderby6.test
orderby7.test
orderby8.test
orderby9.test
orderbyA.test
oserror.test
ossfuzz.c
ossshell.c
ovfl.test
pager1.test
pager2.test
pager3.test
pager4.test
pagerfault.test
pagerfault2.test
pagerfault3.test
pageropt.test
pagesize.test
parser1.test
pcache.test
pcache2.test
pendingrace.test
percentile.test
permutations.test
pg_common.tcl
pragma.test
pragma2.test
pragma3.test
pragma4.test
pragma5.test
pragmafault.test
prefixes.test
printf.test
printf2.test
progress.test
ptrchng.test
pushdown.test
queryonly.test
quick.test
quickcheck.test
quota-glob.test
quota.test
quota2.test
quote.test
randexpr1.tcl
randexpr1.test
rbu.test
rdonly.test
recover.test
regexp1.test
regexp2.test
reindex.test
releasetest_data.tcl
resetdb.test
resolver01.test
returning1.test
returningfault.test
rollback.test
rollback2.test
rollbackfault.test
round1.test
rowallock.test
rowhash.test
rowid.test
rowvalue.test
rowvalue2.test
rowvalue3.test
rowvalue4.test
rowvalue5.test
rowvalue6.test
rowvalue7.test
rowvalue8.test
rowvalue9.test
rowvalueA.test
rowvaluefault.test
rowvaluevtab.test
rtree.test
run-wordcount.sh
savepoint.test
savepoint2.test
savepoint4.test
savepoint5.test
savepoint6.test
savepoint7.test
savepointfault.test
scanstatus.test
scanstatus2.test
schema.test
schema2.test
schema3.test
schema4.test
schema5.test
schema6.test
schemafault.test
securedel.test
securedel2.test
seekscan1.test
select1.test
select2.test
select3.test
select4.test
select5.test
select6.test
select7.test
select8.test
select9.test
selectA.test
selectB.test
selectC.test
selectD.test
selectE.test
selectF.test
selectG.test
selectH.test
session.test
sessionfuzz-data1.db
sessionfuzz.c
shared.test
shared2.test
shared3.test
shared4.test
shared6.test
shared7.test
shared8.test
shared9.test
sharedA.test
sharedB.test
shared_err.test
sharedlock.test
shell1.test
shell2.test
shell3.test
shell4.test
shell5.test
shell6.test
shell7.test
shell8.test
shmlock.test
shortread1.test
show_speedtest1_rtree.tcl
shrink.test
sidedelete.test
skipscan1.test
skipscan2.test
skipscan3.test
skipscan5.test
skipscan6.test
snapshot.test
snapshot2.test
snapshot3.test
snapshot4.test
snapshot_fault.test
snapshot_up.test
soak.test
softheap1.test
sort.test
sort2.test
sort3.test
sort4.test
sort5.test
sorterref.test
sortfault.test
speed1.test
speed1p.explain
speed1p.test
speed2.test
speed3.test
speed4.test
speed4p.explain
speed4p.test
speedtest1.c
spellfix.test
spellfix2.test
spellfix3.test
spellfix4.test
sqldiff1.test
sqllimits1.test
sqllog.test
startup.c
stat.test
statfault.test
stmt.test
stmtvtab1.test
strict1.test
strict2.test
subjournal.test
subquery.test
subquery2.test
subselect.test
substr.test
subtype1.test
superlock.test
swarmvtab.test
swarmvtab2.test
swarmvtab3.test
swarmvtabfault.test
symlink.test
symlink2.test
sync.test
sync2.test
syscall.test
sysfault.test
tabfunc01.test
table.test
tableapi.test
tableopts.test
tclsqlite.test
tempdb.test
tempdb2.test
tempfault.test
temptable.test
temptable2.test
temptable3.test
temptrigger.test
tester.tcl
testrunner.tcl
testrunner_data.tcl
thread001.test
thread002.test
thread003.test
thread004.test
thread005.test
thread1.test
thread2.test
thread3.test
thread_common.tcl
threadtest1.c
threadtest2.c
threadtest3.c
threadtest4.c
threadtest5.c
time-wordcount.sh
timediff1.test
tkt-02a8e81d44.test
tkt-18458b1a.test
tkt-26ff0c2d1e.test
tkt-2a5629202f.test
tkt-2d1a5c67d.test
tkt-2ea2425d34.test
tkt-31338dca7e.test
tkt-313723c356.test
tkt-385a5b56b9.test
tkt-38cb5df375.test
tkt-3998683a16.test
tkt-3a77c9714e.test
tkt-3fe897352e.test
tkt-4a03edc4c8.test
tkt-4c86b126f2.test
tkt-4dd95f6943.test
tkt-4ef7e3cfca.test
tkt-54844eea3f.test
tkt-5d863f876e.test
tkt-5e10420e8d.test
tkt-5ee23731f.test
tkt-6bfb98dfc0.test
tkt-752e1646fc.test
tkt-78e04e52ea.test
tkt-7a31705a7e6.test
tkt-7bbfb7d442.test
tkt-80ba201079.test
tkt-80e031a00f.test
tkt-8454a207b9.test
tkt-868145d012.test
tkt-8c63ff0ec.test
tkt-91e2e8ba6f.test
tkt-94c04eaadb.test
tkt-99378177930f87bd.test
tkt-9a8b09f8e6.test
tkt-9d68c883.test
tkt-9f2eb3abac.test
tkt-a7b7803e.test
tkt-a7debbe0.test
tkt-a8a0d2996a.test
tkt-b1d3a2e531.test
tkt-b351d95f9.test
tkt-b72787b1.test
tkt-b75a9ca6b0.test
tkt-ba7cbfaedc.test
tkt-bd484a090c.test
tkt-bdc6bbbb38.test
tkt-c48d99d690.test
tkt-c694113d5.test
tkt-cbd054fa6b.test
tkt-d11f09d36e.test
tkt-d635236375.test
tkt-d82e3f3721.test
tkt-f3e5abed55.test
tkt-f67b41381a.test
tkt-f777251dc7a.test
tkt-f7b4edec.test
tkt-f973c7ac31.test
tkt-fa7bf5ec.test
tkt-fc62af4523.test
tkt-fc7bd6358f.test
tkt1435.test
tkt1443.test
tkt1444.test
tkt1449.test
tkt1473.test
tkt1501.test
tkt1512.test
tkt1514.test
tkt1536.test
tkt1537.test
tkt1567.test
tkt1644.test
tkt1667.test
tkt1873.test
tkt2141.test
tkt2192.test
tkt2213.test
tkt2251.test
tkt2285.test
tkt2332.test
tkt2339.test
tkt2391.test
tkt2409.test
tkt2450.test
tkt2565.test
tkt2640.test
tkt2643.test
tkt2686.test
tkt2767.test
tkt2817.test
tkt2820.test
tkt2822.test
tkt2832.test
tkt2854.test
tkt2920.test
tkt2927.test
tkt2942.test
tkt3080.test
tkt3093.test
tkt3121.test
tkt3201.test
tkt3292.test
tkt3298.test
tkt3334.test
tkt3346.test
tkt3357.test
tkt3419.test
tkt3424.test
tkt3442.test
tkt3457.test
tkt3461.test
tkt3493.test
tkt3508.test
tkt3522.test
tkt3527.test
tkt3541.test
tkt3554.test
tkt3581.test
tkt35xx.test
tkt3630.test
tkt3718.test
tkt3731.test
tkt3757.test
tkt3761.test
tkt3762.test
tkt3773.test
tkt3791.test
tkt3793.test
tkt3810.test
tkt3824.test
tkt3832.test
tkt3838.test
tkt3841.test
tkt3871.test
tkt3879.test
tkt3911.test
tkt3918.test
tkt3922.test
tkt3929.test
tkt3935.test
tkt3992.test
tkt3997.test
tkt4018.test
tokenize.test
tpch01.test
trace.test
trace2.test
trace3.test
trans.test
trans2.test
trans3.test
transitive1.test
trigger1.test
trigger2.test
trigger3.test
trigger4.test
trigger5.test
trigger6.test
trigger7.test
trigger8.test
trigger9.test
triggerA.test
triggerB.test
triggerC.test
triggerD.test
triggerE.test
triggerF.test
triggerG.test
triggerupfrom.test
trustschema1.test
tt3_checkpoint.c
tt3_index.c
tt3_lookaside1.c
tt3_shared.c
tt3_stress.c
tt3_vacuum.c
types.test
types2.test
types3.test
unhex.test
unionall.test
unionall2.test
unionallfault.test
unionvtab.test
unionvtabfault.test
unique.test
unique2.test
unixexcl.test
unordered.test
update.test
update2.test
upfrom1.tcl
upfrom1.test
upfrom2.test
upfrom3.test
upfrom4.test
upfromfault.test
upsert1.test
upsert2.test
upsert3.test
upsert4.test
upsert5.test
upsertfault.test
uri.test
uri2.test
userauth01.test
utf16align.test
vacuum-into.test
vacuum.test
vacuum2.test
vacuum3.test
vacuum4.test
vacuum5.test
vacuum6.test
vacuummem.test
varint.test
veryquick.test
view.test
view2.test
view3.test
vt02.c
vtab1.test
vtab2.test
vtab3.test
vtab4.test
vtab5.test
vtab6.test
vtab7.test
vtab8.test
vtab9.test
vtabA.test
vtabB.test
vtabC.test
vtabD.test
vtabE.test
vtabF.test
vtabH.test
vtabI.test
vtabJ.test
vtabK.test
vtab_alter.test
vtab_err.test
vtab_shared.test
vtabdistinct.test
vtabdrop.test
vtabrhs1.test
wal.test
wal2.test
wal3.test
wal4.test
wal5.test
wal6.test
wal64k.test
wal7.test
wal8.test
wal9.test
wal_common.tcl
walbak.test
walbig.test
walblock.test
walcksum.test
walcrash.test
walcrash2.test
walcrash3.test
walcrash4.test
walfault.test
walfault2.test
walhook.test
walmode.test
walnoshm.test
waloverwrite.test
walpersist.test
walprotocol.test
walprotocol2.test
walro.test
walro2.test
walrofault.test
walseh1.test
walsetlk.test
walshared.test
walslow.test
walthread.test
walvfs.test
wapp.tcl
wapptest.tcl
where.test
where2.test
where3.test
where4.test
where5.test
where6.test
where7.test
where8.test
where9.test
whereA.test
whereB.test
whereC.test
whereD.test
whereE.test
whereF.test
whereG.test
whereH.test
whereI.test
whereJ.test
whereK.test
whereL.test
whereM.test
wherefault.test
wherelfault.test
wherelimit.test
wherelimit2.test
widetab1.test
win32heap.test
win32lock.test
win32longpath.test
win32nolock.test
window1.test
window2.tcl
window2.test
window3.tcl
window3.test
window4.tcl
window4.test
window5.test
window6.test
window7.tcl
window7.test
window8.tcl
window8.test
window9.test
windowA.test
windowB.test
windowC.test
windowD.test
windowE.test
windowerr.tcl
windowerr.test
windowfault.test
windowpushd.test
with1.test
with2.test
with3.test
with4.test
with5.test
with6.test
withM.test
without_rowid1.test
without_rowid2.test
without_rowid3.test
without_rowid4.test
without_rowid5.test
without_rowid6.test
without_rowid7.test
wordcount.c
writecrash.test
zeroblob.test
zeroblobfault.test
zerodamage.test
zipfile.test
zipfile2.test
zipfilefault.test
tool
vsixtest
.gitignore
Dockerfile-wasm-udf
LIBSQL_VERSION
LICENSE.md
Makefile.in
Makefile.linux-gcc
Makefile.msc
README-SQLite.md
VERSION
aclocal.m4
config.guess
config.sub
configure
configure.ac
install-sh
libsql.pc.in
ltmain.sh
magic.txt
main.mk
manifest
manifest.uuid
spec.template
sqlite.pc.in
sqlite3.1
sqlite3.pc.in
sqlite_cfg.h.in
libsql-sys
vendored
xtask
.dockerignore
.env
.gitignore
CODE_OF_CONDUCT.md
Cargo.toml
Dockerfile
Dockerfile.dev
LICENSE.md
README-libsql.md
README.md
docker-entrypoint.sh
fly.toml
rust-toolchain.toml
libsql/libsql-sqlite3/test/shared.test
2023-10-16 13:58:16 +02:00

1185 lines
31 KiB
Plaintext

# 2005 December 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# $Id: shared.test,v 1.36 2009/03/16 13:19:36 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
db close
# These tests cannot be run without the ATTACH command.
#
ifcapable !shared_cache||!attach {
finish_test
return
}
set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
foreach av [list 0 1] {
# Open the database connection and execute the auto-vacuum pragma
forcedelete test.db
sqlite3 db test.db
ifcapable autovacuum {
do_test shared-[expr $av+1].1.0 {
execsql "pragma auto_vacuum=$::av"
execsql {pragma auto_vacuum}
} "$av"
} else {
if {$av} {
db close
break
}
}
# if we're using proxy locks, we use 2 filedescriptors for a db
# that is open but NOT yet locked, after a lock is taken we'll have 3,
# normally sqlite uses 1 (proxy locking adds the conch and the local lock)
set using_proxy 0
foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {
set using_proxy $value
}
set extrafds_prelock 0
set extrafds_postlock 0
if {$using_proxy>0} {
set extrafds_prelock 1
set extrafds_postlock 2
}
# $av is currently 0 if this loop iteration is to test with auto-vacuum turned
# off, and 1 if it is turned on. Increment it so that (1 -> no auto-vacuum)
# and (2 -> auto-vacuum). The sole reason for this is so that it looks nicer
# when we use this variable as part of test-case names.
#
incr av
# Test organization:
#
# shared-1.*: Simple test to verify basic sanity of table level locking when
# two connections share a pager cache.
# shared-2.*: Test that a read transaction can co-exist with a
# write-transaction, including a simple test to ensure the
# external locking protocol is still working.
# shared-3.*: Simple test of read-uncommitted mode.
# shared-4.*: Check that the schema is locked and unlocked correctly.
# shared-5.*: Test that creating/dropping schema items works when databases
# are attached in different orders to different handles.
# shared-6.*: Locking, UNION ALL queries and sub-queries.
# shared-7.*: Autovacuum and shared-cache.
# shared-8.*: Tests related to the text encoding of shared-cache databases.
# shared-9.*: TEMP triggers and shared-cache databases.
# shared-10.*: Tests of sqlite3_close().
# shared-11.*: Test transaction locking.
#
do_test shared-$av.1.1 {
# Open a second database on the file test.db. It should use the same pager
# cache and schema as the original connection. Verify that only 1 file is
# opened.
sqlite3 db2 test.db
set ::sqlite_open_file_count
expr $sqlite_open_file_count-$extrafds_postlock
} {1}
do_test shared-$av.1.2 {
# Add a table and a single row of data via the first connection.
# Ensure that the second connection can see them.
execsql {
CREATE TABLE abc(a, b, c);
INSERT INTO abc VALUES(1, 2, 3);
} db
execsql {
SELECT * FROM abc;
} db2
} {1 2 3}
do_test shared-$av.1.3 {
# Have the first connection begin a transaction and obtain a read-lock
# on table abc. This should not prevent the second connection from
# querying abc.
execsql {
BEGIN;
SELECT * FROM abc;
}
execsql {
SELECT * FROM abc;
} db2
} {1 2 3}
do_test shared-$av.1.4 {
# Try to insert a row into abc via connection 2. This should fail because
# of the read-lock connection 1 is holding on table abc (obtained in the
# previous test case).
catchsql {
INSERT INTO abc VALUES(4, 5, 6);
} db2
} {1 {database table is locked: abc}}
do_test shared-$av.1.5 {
# Using connection 2 (the one without the open transaction), try to create
# a new table. This should fail because of the open read transaction
# held by connection 1.
catchsql {
CREATE TABLE def(d, e, f);
} db2
} {1 {database table is locked: sqlite_master}}
do_test shared-$av.1.6 {
# Upgrade connection 1's transaction to a write transaction. Create
# a new table - def - and insert a row into it. Because the connection 1
# transaction modifies the schema, it should not be possible for
# connection 2 to access the database at all until the connection 1
# has finished the transaction.
execsql {
CREATE TABLE def(d, e, f);
INSERT INTO def VALUES('IV', 'V', 'VI');
}
} {}
do_test shared-$av.1.7 {
# Read from the sqlite_master table with connection 1 (inside the
# transaction). Then test that we can not do this with connection 2. This
# is because of the schema-modified lock established by connection 1
# in the previous test case.
execsql {
SELECT * FROM sqlite_master;
}
catchsql {
SELECT * FROM sqlite_master;
} db2
} {1 {database schema is locked: main}}
do_test shared-$av.1.8 {
# Commit the connection 1 transaction.
execsql {
COMMIT;
}
} {}
do_test shared-$av.2.1 {
# Open connection db3 to the database.
if {$::tcl_platform(platform)=="unix"} {
sqlite3 db3 "file:test.db?cache=private" -uri 1
} else {
sqlite3 db3 TEST.DB
}
set ::sqlite_open_file_count
expr $sqlite_open_file_count-($extrafds_prelock+$extrafds_postlock)
} {2}
do_test shared-$av.2.2 {
# Start read transactions on db and db2 (the shared pager cache). Ensure
# db3 cannot write to the database.
execsql {
BEGIN;
SELECT * FROM abc;
}
execsql {
BEGIN;
SELECT * FROM abc;
} db2
catchsql {
INSERT INTO abc VALUES(1, 2, 3);
} db2
} {1 {database table is locked: abc}}
do_test shared-$av.2.3 {
# Turn db's transaction into a write-transaction. db3 should still be
# able to read from table def (but will not see the new row). Connection
# db2 should not be able to read def (because of the write-lock).
# Todo: The failed "INSERT INTO abc ..." statement in the above test
# has started a write-transaction on db2 (should this be so?). This
# would prevent connection db from starting a write-transaction. So roll the
# db2 transaction back and replace it with a new read transaction.
execsql {
ROLLBACK;
BEGIN;
SELECT * FROM abc;
} db2
execsql {
INSERT INTO def VALUES('VII', 'VIII', 'IX');
}
concat [
catchsql { SELECT * FROM def; } db3
] [
catchsql { SELECT * FROM def; } db2
]
} {0 {IV V VI} 1 {database table is locked: def}}
do_test shared-$av.2.4 {
# Commit the open transaction on db. db2 still holds a read-transaction.
# This should prevent db3 from writing to the database, but not from
# reading.
execsql {
COMMIT;
}
concat [
catchsql { SELECT * FROM def; } db3
] [
catchsql { INSERT INTO def VALUES('X', 'XI', 'XII'); } db3
]
} {0 {IV V VI VII VIII IX} 1 {database is locked}}
catchsql COMMIT db2
do_test shared-$av.3.1.1 {
# This test case starts a linear scan of table 'seq' using a
# read-uncommitted connection. In the middle of the scan, rows are added
# to the end of the seq table (ahead of the current cursor position).
# The uncommitted rows should be included in the results of the scan.
execsql "
CREATE TABLE seq(i PRIMARY KEY, x);
INSERT INTO seq VALUES(1, '[string repeat X 500]');
INSERT INTO seq VALUES(2, '[string repeat X 500]');
"
execsql {SELECT * FROM sqlite_master} db2
execsql {PRAGMA read_uncommitted = 1} db2
set ret [list]
db2 eval {SELECT i FROM seq ORDER BY i} {
if {$i < 4} {
set max [execsql {SELECT max(i) FROM seq}]
db eval {
INSERT INTO seq SELECT i + :max, x FROM seq;
}
}
lappend ret $i
}
set ret
} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16}
do_test shared-$av.3.1.2 {
# Another linear scan through table seq using a read-uncommitted connection.
# This time, delete each row as it is read. Should not affect the results of
# the scan, but the table should be empty after the scan is concluded
# (test 3.1.3 verifies this).
set ret [list]
db2 eval {SELECT i FROM seq} {
db eval {DELETE FROM seq WHERE i = :i}
lappend ret $i
}
set ret
} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16}
do_test shared-$av.3.1.3 {
execsql {
SELECT * FROM seq;
}
} {}
catch {db close}
catch {db2 close}
catch {db3 close}
#--------------------------------------------------------------------------
# Tests shared-4.* test that the schema locking rules are applied
# correctly. i.e.:
#
# 1. All transactions require a read-lock on the schemas of databases they
# access.
# 2. Transactions that modify a database schema require a write-lock on that
# schema.
# 3. It is not possible to compile a statement while another handle has a
# write-lock on the schema.
#
# Open two database handles db and db2. Each has a single attach database
# (as well as main):
#
# db.main -> ./test.db
# db.test2 -> ./test2.db
# db2.main -> ./test2.db
# db2.test -> ./test.db
#
forcedelete test.db
forcedelete test2.db
forcedelete test2.db-journal
sqlite3 db test.db
sqlite3 db2 test2.db
do_test shared-$av.4.1.1 {
set sqlite_open_file_count
expr $sqlite_open_file_count-($extrafds_prelock*2)
} {2}
do_test shared-$av.4.1.2 {
execsql {ATTACH 'test2.db' AS test2}
set sqlite_open_file_count
expr $sqlite_open_file_count-($extrafds_postlock*2)
} {2}
do_test shared-$av.4.1.3 {
execsql {ATTACH 'test.db' AS test} db2
set sqlite_open_file_count
expr $sqlite_open_file_count-($extrafds_postlock*2)
} {2}
# Sanity check: Create a table in ./test.db via handle db, and test that handle
# db2 can "see" the new table immediately. A handle using a seperate pager
# cache would have to reload the database schema before this were possible.
#
do_test shared-$av.4.2.1 {
execsql {
CREATE TABLE abc(a, b, c);
CREATE TABLE def(d, e, f);
INSERT INTO abc VALUES('i', 'ii', 'iii');
INSERT INTO def VALUES('I', 'II', 'III');
}
} {}
do_test shared-$av.4.2.2 {
execsql {
SELECT * FROM test.abc;
} db2
} {i ii iii}
# Open a read-transaction and read from table abc via handle 2. Check that
# handle 1 can read table abc. Check that handle 1 cannot modify table abc
# or the database schema. Then check that handle 1 can modify table def.
#
do_test shared-$av.4.3.1 {
execsql {
BEGIN;
SELECT * FROM test.abc;
} db2
} {i ii iii}
do_test shared-$av.4.3.2 {
catchsql {
INSERT INTO abc VALUES('iv', 'v', 'vi');
}
} {1 {database table is locked: abc}}
do_test shared-$av.4.3.3 {
catchsql {
CREATE TABLE ghi(g, h, i);
}
} {1 {database table is locked: sqlite_master}}
do_test shared-$av.4.3.3 {
catchsql {
INSERT INTO def VALUES('IV', 'V', 'VI');
}
} {0 {}}
do_test shared-$av.4.3.4 {
# Cleanup: commit the transaction opened by db2.
execsql {
COMMIT
} db2
} {}
# Open a write-transaction using handle 1 and modify the database schema.
# Then try to execute a compiled statement to read from the same
# database via handle 2 (fails to get the lock on sqlite_master). Also
# try to compile a read of the same database using handle 2 (also fails).
# Finally, compile a read of the other database using handle 2. This
# should also fail.
#
ifcapable compound {
do_test shared-$av.4.4.1.2 {
# Sanity check 1: Check that the schema is what we think it is when viewed
# via handle 1.
execsql {
CREATE TABLE test2.ghi(g, h, i);
SELECT 'test.db:'||name FROM sqlite_master
UNION ALL
SELECT 'test2.db:'||name FROM test2.sqlite_master;
}
} {test.db:abc test.db:def test2.db:ghi}
do_test shared-$av.4.4.1.2 {
# Sanity check 2: Check that the schema is what we think it is when viewed
# via handle 2.
execsql {
SELECT 'test2.db:'||name FROM sqlite_master
UNION ALL
SELECT 'test.db:'||name FROM test.sqlite_master;
} db2
} {test2.db:ghi test.db:abc test.db:def}
}
do_test shared-$av.4.4.2 {
set ::DB2 [sqlite3_connection_pointer db2]
set sql {SELECT * FROM abc}
set ::STMT1 [sqlite3_prepare $::DB2 $sql -1 DUMMY]
execsql {
BEGIN;
CREATE TABLE jkl(j, k, l);
}
sqlite3_step $::STMT1
} {SQLITE_ERROR}
do_test shared-$av.4.4.3 {
sqlite3_finalize $::STMT1
} {SQLITE_LOCKED}
do_test shared-$av.4.4.4 {
set rc [catch {
set ::STMT1 [sqlite3_prepare $::DB2 $sql -1 DUMMY]
} msg]
list $rc $msg
} {1 {(6) database schema is locked: test}}
do_test shared-$av.4.4.5 {
set rc [catch {
set ::STMT1 [sqlite3_prepare $::DB2 "SELECT * FROM ghi" -1 DUMMY]
} msg]
list $rc $msg
} {1 {(6) database schema is locked: test}}
catch {db2 close}
catch {db close}
#--------------------------------------------------------------------------
# Tests shared-5.*
#
foreach db [list test.db test1.db test2.db test3.db] {
forcedelete $db ${db}-journal
}
do_test shared-$av.5.1.1 {
sqlite3 db1 test.db
sqlite3 db2 test.db
execsql {
ATTACH 'test1.db' AS test1;
ATTACH 'test2.db' AS test2;
ATTACH 'test3.db' AS test3;
} db1
execsql {
ATTACH 'test3.db' AS test3;
ATTACH 'test2.db' AS test2;
ATTACH 'test1.db' AS test1;
} db2
} {}
do_test shared-$av.5.1.2 {
execsql {
CREATE TABLE test1.t1(a, b);
CREATE INDEX test1.i1 ON t1(a, b);
} db1
} {}
ifcapable view {
do_test shared-$av.5.1.3 {
execsql {
CREATE VIEW test1.v1 AS SELECT * FROM t1;
} db1
} {}
}
ifcapable trigger {
do_test shared-$av.5.1.4 {
execsql {
CREATE TRIGGER test1.trig1 AFTER INSERT ON t1 BEGIN
INSERT INTO t1 VALUES(new.a, new.b);
END;
} db1
} {}
}
do_test shared-$av.5.1.5 {
execsql {
DROP INDEX i1;
} db2
} {}
ifcapable view {
do_test shared-$av.5.1.6 {
execsql {
DROP VIEW v1;
} db2
} {}
}
ifcapable trigger {
do_test shared-$av.5.1.7 {
execsql {
DROP TRIGGER trig1;
} db2
} {}
}
do_test shared-$av.5.1.8 {
execsql {
DROP TABLE t1;
} db2
} {}
ifcapable compound {
do_test shared-$av.5.1.9 {
execsql {
SELECT * FROM sqlite_master UNION ALL SELECT * FROM test1.sqlite_master
} db1
} {}
}
#--------------------------------------------------------------------------
# Tests shared-6.* test that a query obtains all the read-locks it needs
# before starting execution of the query. This means that there is no chance
# some rows of data will be returned before a lock fails and SQLITE_LOCK
# is returned.
#
do_test shared-$av.6.1.1 {
execsql {
CREATE TABLE t1(a, b);
CREATE TABLE t2(a, b);
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t2 VALUES(3, 4);
} db1
} {}
ifcapable compound {
do_test shared-$av.6.1.2 {
execsql {
SELECT * FROM t1 UNION ALL SELECT * FROM t2;
} db2
} {1 2 3 4}
}
do_test shared-$av.6.1.3 {
# Establish a write lock on table t2 via connection db2. Then make a
# UNION all query using connection db1 that first accesses t1, followed
# by t2. If the locks are grabbed at the start of the statement (as
# they should be), no rows are returned. If (as was previously the case)
# they are grabbed as the tables are accessed, the t1 rows will be
# returned before the query fails.
#
execsql {
BEGIN;
INSERT INTO t2 VALUES(5, 6);
} db2
set ret [list]
catch {
db1 eval {SELECT * FROM t1 UNION ALL SELECT * FROM t2} {
lappend ret $a $b
}
}
set ret
} {}
do_test shared-$av.6.1.4 {
execsql {
COMMIT;
BEGIN;
INSERT INTO t1 VALUES(7, 8);
} db2
set ret [list]
catch {
db1 eval {
SELECT (CASE WHEN a>4 THEN (SELECT a FROM t1) ELSE 0 END) AS d FROM t2;
} {
lappend ret $d
}
}
set ret
} {}
catch {db1 close}
catch {db2 close}
foreach f [list test.db test2.db] {
forcedelete $f ${f}-journal
}
#--------------------------------------------------------------------------
# Tests shared-7.* test auto-vacuum does not invalidate cursors from
# other shared-cache users when it reorganizes the database on
# COMMIT.
#
do_test shared-$av.7.1 {
# This test case sets up a test database in auto-vacuum mode consisting
# of two tables, t1 and t2. Both have a single index. Table t1 is
# populated first (so consists of pages toward the start of the db file),
# t2 second (pages toward the end of the file).
sqlite3 db test.db
sqlite3 db2 test.db
execsql {
BEGIN;
CREATE TABLE t1(a PRIMARY KEY, b);
CREATE TABLE t2(a PRIMARY KEY, b);
}
set ::contents {}
for {set i 0} {$i < 100} {incr i} {
set a [string repeat "$i " 20]
set b [string repeat "$i " 20]
db eval {
INSERT INTO t1 VALUES(:a, :b);
}
lappend ::contents [list [expr $i+1] $a $b]
}
execsql {
INSERT INTO t2 SELECT * FROM t1;
COMMIT;
}
} {}
do_test shared-$av.7.2 {
# This test case deletes the contents of table t1 (the one at the start of
# the file) while many cursors are open on table t2 and its index. All of
# the non-root pages will be moved from the end to the start of the file
# when the DELETE is committed - this test verifies that moving the pages
# does not disturb the open cursors.
#
proc lockrow {db tbl oids body} {
set ret [list]
db eval "SELECT oid AS i, a, b FROM $tbl ORDER BY a" {
if {$i==[lindex $oids 0]} {
set noids [lrange $oids 1 end]
if {[llength $noids]==0} {
set subret [eval $body]
} else {
set subret [lockrow $db $tbl $noids $body]
}
}
lappend ret [list $i $a $b]
}
return [linsert $subret 0 $ret]
}
proc locktblrows {db tbl body} {
set oids [db eval "SELECT oid FROM $tbl"]
lockrow $db $tbl $oids $body
}
set scans [locktblrows db t2 {
execsql {
DELETE FROM t1;
} db2
}]
set error 0
# Test that each SELECT query returned the expected contents of t2.
foreach s $scans {
if {[lsort -integer -index 0 $s]!=$::contents} {
set error 1
}
}
set error
} {0}
catch {db close}
catch {db2 close}
unset -nocomplain contents
#--------------------------------------------------------------------------
# The following tests try to trick the shared-cache code into assuming
# the wrong encoding for a database.
#
forcedelete test.db test.db-journal
ifcapable utf16 {
do_test shared-$av.8.1.1 {
sqlite3 db test.db
execsql {
PRAGMA encoding = 'UTF-16';
SELECT * FROM sqlite_master;
}
} {}
do_test shared-$av.8.1.2 {
string range [execsql {PRAGMA encoding;}] 0 end-2
} {UTF-16}
do_test shared-$av.8.1.3 {
sqlite3 db2 test.db
execsql {
PRAGMA encoding = 'UTF-8';
CREATE TABLE abc(a, b, c);
} db2
} {}
do_test shared-$av.8.1.4 {
execsql {
SELECT * FROM sqlite_master;
}
} "table abc abc [expr $AUTOVACUUM?3:2] {CREATE TABLE abc(a, b, c)}"
do_test shared-$av.8.1.5 {
db2 close
execsql {
PRAGMA encoding;
}
} {UTF-8}
forcedelete test2.db test2.db-journal
do_test shared-$av.8.2.1 {
execsql {
ATTACH 'test2.db' AS aux;
SELECT * FROM aux.sqlite_master;
}
} {}
do_test shared-$av.8.2.2 {
sqlite3 db2 test2.db
execsql {
PRAGMA encoding = 'UTF-16';
CREATE TABLE def(d, e, f);
} db2
string range [execsql {PRAGMA encoding;} db2] 0 end-2
} {UTF-16}
catch {db close}
catch {db2 close}
forcedelete test.db test2.db
do_test shared-$av.8.3.2 {
sqlite3 db test.db
execsql { CREATE TABLE def(d, e, f) }
execsql { PRAGMA encoding }
} {UTF-8}
do_test shared-$av.8.3.3 {
set zDb16 "[encoding convertto unicode test.db]\x00\x00"
set db16 [sqlite3_open16 $zDb16 {}]
set stmt [sqlite3_prepare $db16 "SELECT sql FROM sqlite_master" -1 DUMMY]
sqlite3_step $stmt
set sql [sqlite3_column_text $stmt 0]
sqlite3_finalize $stmt
set sql
} {CREATE TABLE def(d, e, f)}
do_test shared-$av.8.3.4 {
set stmt [sqlite3_prepare $db16 "PRAGMA encoding" -1 DUMMY]
sqlite3_step $stmt
set enc [sqlite3_column_text $stmt 0]
sqlite3_finalize $stmt
set enc
} {UTF-8}
sqlite3_close $db16
# Bug #2547 is causing this to fail.
if 0 {
do_test shared-$av.8.2.3 {
catchsql {
SELECT * FROM aux.sqlite_master;
}
} {1 {attached databases must use the same text encoding as main database}}
}
}
catch {db close}
catch {db2 close}
forcedelete test.db test2.db
#---------------------------------------------------------------------------
# The following tests - shared-9.* - test interactions between TEMP triggers
# and shared-schemas.
#
ifcapable trigger&&tempdb {
do_test shared-$av.9.1 {
sqlite3 db test.db
sqlite3 db2 test.db
execsql {
CREATE TABLE abc(a, b, c);
CREATE TABLE abc_mirror(a, b, c);
CREATE TEMP TRIGGER BEFORE INSERT ON abc BEGIN
INSERT INTO abc_mirror(a, b, c) VALUES(new.a, new.b, new.c);
END;
INSERT INTO abc VALUES(1, 2, 3);
SELECT * FROM abc_mirror;
}
} {1 2 3}
do_test shared-$av.9.2 {
execsql {
INSERT INTO abc VALUES(4, 5, 6);
SELECT * FROM abc_mirror;
} db2
} {1 2 3}
do_test shared-$av.9.3 {
db close
db2 close
} {}
} ; # End shared-9.*
#---------------------------------------------------------------------------
# The following tests - shared-10.* - test that the library behaves
# correctly when a connection to a shared-cache is closed.
#
do_test shared-$av.10.1 {
# Create a small sample database with two connections to it (db and db2).
forcedelete test.db
sqlite3 db test.db
sqlite3 db2 test.db
execsql {
CREATE TABLE ab(a PRIMARY KEY, b);
CREATE TABLE de(d PRIMARY KEY, e);
INSERT INTO ab VALUES('Chiang Mai', 100000);
INSERT INTO ab VALUES('Bangkok', 8000000);
INSERT INTO de VALUES('Ubon', 120000);
INSERT INTO de VALUES('Khon Kaen', 200000);
}
} {}
do_test shared-$av.10.2 {
# Open a read-transaction with the first connection, a write-transaction
# with the second.
execsql {
BEGIN;
SELECT * FROM ab;
}
execsql {
BEGIN;
INSERT INTO de VALUES('Pataya', 30000);
} db2
} {}
do_test shared-$av.10.3 {
# An external connection should be able to read the database, but not
# prepare a write operation.
if {$::tcl_platform(platform)=="unix"} {
sqlite3 db3 "file:test.db?cache=private" -uri 1
} else {
sqlite3 db3 TEST.DB
}
execsql {
SELECT * FROM ab;
} db3
catchsql {
BEGIN;
INSERT INTO de VALUES('Pataya', 30000);
} db3
} {1 {database is locked}}
do_test shared-$av.10.4 {
# Close the connection with the write-transaction open
db2 close
} {}
do_test shared-$av.10.5 {
# Test that the db2 transaction has been automatically rolled back.
# If it has not the ('Pataya', 30000) entry will still be in the table.
execsql {
SELECT * FROM de;
}
} {Ubon 120000 {Khon Kaen} 200000}
do_test shared-$av.10.5 {
# Closing db2 should have dropped the shared-cache back to a read-lock.
# So db3 should be able to prepare a write...
catchsql {INSERT INTO de VALUES('Pataya', 30000);} db3
} {0 {}}
do_test shared-$av.10.6 {
# ... but not commit it.
catchsql {COMMIT} db3
} {1 {database is locked}}
do_test shared-$av.10.7 {
# Commit the (read-only) db transaction. Check via db3 to make sure the
# contents of table "de" are still as they should be.
execsql {
COMMIT;
}
execsql {
SELECT * FROM de;
} db3
} {Ubon 120000 {Khon Kaen} 200000 Pataya 30000}
do_test shared-$av.10.9 {
# Commit the external transaction.
catchsql {COMMIT} db3
} {0 {}}
integrity_check shared-$av.10.10
do_test shared-$av.10.11 {
db close
db3 close
} {}
do_test shared-$av.11.1 {
forcedelete test.db
sqlite3 db test.db
sqlite3 db2 test.db
execsql {
CREATE TABLE abc(a, b, c);
CREATE TABLE abc2(a, b, c);
BEGIN;
INSERT INTO abc VALUES(1, 2, 3);
}
} {}
do_test shared-$av.11.2 {
catchsql {BEGIN;} db2
catchsql {SELECT * FROM abc;} db2
} {1 {database table is locked: abc}}
do_test shared-$av.11.3 {
catchsql {BEGIN} db2
} {1 {cannot start a transaction within a transaction}}
do_test shared-$av.11.4 {
catchsql {SELECT * FROM abc2;} db2
} {0 {}}
do_test shared-$av.11.5 {
catchsql {INSERT INTO abc2 VALUES(1, 2, 3);} db2
} {1 {database table is locked}}
do_test shared-$av.11.6 {
catchsql {SELECT * FROM abc2}
} {0 {}}
do_test shared-$av.11.6 {
execsql {
ROLLBACK;
PRAGMA read_uncommitted = 1;
} db2
} {}
do_test shared-$av.11.7 {
execsql {
INSERT INTO abc2 VALUES(4, 5, 6);
INSERT INTO abc2 VALUES(7, 8, 9);
}
} {}
do_test shared-$av.11.8 {
set res [list]
db2 eval {
SELECT abc.a as I, abc2.a as II FROM abc, abc2;
} {
execsql {
DELETE FROM abc WHERE 1;
}
lappend res $I $II
}
set res
} {1 4 {} 7}
if {[llength [info command sqlite3_shared_cache_report]]==1} {
ifcapable curdir {
do_test shared-$av.11.9 {
string tolower [sqlite3_shared_cache_report]
} [string tolower [list [file nativename [file normalize test.db]] 2]]
}
}
do_test shared-$av.11.11 {
db close
db2 close
} {}
# This tests that if it is impossible to free any pages, SQLite will
# exceed the limit set by PRAGMA cache_size.
forcedelete test.db test.db-journal
sqlite3 db test.db
ifcapable pager_pragmas {
do_test shared-$av.12.1 {
execsql {
PRAGMA cache_size = 10;
PRAGMA cache_size;
}
} {10}
}
do_test shared-$av.12.2 {
set ::db_handles [list]
for {set i 1} {$i < 15} {incr i} {
lappend ::db_handles db$i
sqlite3 db$i test.db
execsql "CREATE TABLE db${i}(a, b, c)" db$i
execsql "INSERT INTO db${i} VALUES(1, 2, 3)"
}
} {}
proc nested_select {handles} {
[lindex $handles 0] eval "SELECT * FROM [lindex $handles 0]" {
lappend ::res $a $b $c
if {[llength $handles]>1} {
nested_select [lrange $handles 1 end]
}
}
}
do_test shared-$av.12.3 {
set ::res [list]
nested_select $::db_handles
set ::res
} [string range [string repeat "1 2 3 " [llength $::db_handles]] 0 end-1]
do_test shared-$av.12.X {
db close
foreach h $::db_handles {
$h close
}
} {}
# Internally, locks are acquired on shared B-Tree structures in the order
# that the structures appear in the virtual memory address space. This
# test case attempts to cause the order of the structures in memory
# to be different from the order in which they are attached to a given
# database handle. This covers an extra line or two.
#
do_test shared-$av.13.1 {
forcedelete test2.db test3.db test4.db test5.db
sqlite3 db :memory:
execsql {
ATTACH 'test2.db' AS aux2;
ATTACH 'test3.db' AS aux3;
ATTACH 'test4.db' AS aux4;
ATTACH 'test5.db' AS aux5;
DETACH aux2;
DETACH aux3;
DETACH aux4;
ATTACH 'test2.db' AS aux2;
ATTACH 'test3.db' AS aux3;
ATTACH 'test4.db' AS aux4;
}
} {}
do_test shared-$av.13.2 {
execsql {
CREATE TABLE t1(a, b, c);
CREATE TABLE aux2.t2(a, b, c);
CREATE TABLE aux3.t3(a, b, c);
CREATE TABLE aux4.t4(a, b, c);
CREATE TABLE aux5.t5(a, b, c);
SELECT count(*) FROM
aux2.sqlite_master,
aux3.sqlite_master,
aux4.sqlite_master,
aux5.sqlite_master
}
} {1}
do_test shared-$av.13.3 {
db close
} {}
# Test that nothing horrible happens if a connection to a shared B-Tree
# structure is closed while some other connection has an open cursor.
#
do_test shared-$av.14.1 {
sqlite3 db test.db
sqlite3 db2 test.db
execsql {SELECT name FROM sqlite_master}
} {db1 db2 db3 db4 db5 db6 db7 db8 db9 db10 db11 db12 db13 db14}
do_test shared-$av.14.2 {
set res [list]
db eval {SELECT name FROM sqlite_master} {
if {$name eq "db7"} {
db2 close
}
lappend res $name
}
set res
} {db1 db2 db3 db4 db5 db6 db7 db8 db9 db10 db11 db12 db13 db14}
do_test shared-$av.14.3 {
db close
} {}
# Populate a database schema using connection [db]. Then drop it using
# [db2]. This is to try to find any points where shared-schema elements
# are allocated using the lookaside buffer of [db].
#
# Mutexes are enabled for this test as that activates a couple of useful
# assert() statements in the C code.
#
do_test shared-$av-15.1 {
forcedelete test.db
sqlite3 db test.db -fullmutex 1
sqlite3 db2 test.db -fullmutex 1
execsql {
CREATE TABLE t1(a, b, c);
CREATE INDEX i1 ON t1(a, b);
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE VIEW v2 AS SELECT * FROM t1, v1
WHERE t1.c=v1.c GROUP BY t1.a ORDER BY v1.b;
CREATE TRIGGER tr1 AFTER INSERT ON t1
WHEN new.a!=1
BEGIN
DELETE FROM t1 WHERE a=5;
INSERT INTO t1 VALUES(1, 2, 3);
UPDATE t1 SET c=c+1;
END;
INSERT INTO t1 VALUES(5, 6, 7);
INSERT INTO t1 VALUES(8, 9, 10);
INSERT INTO t1 VALUES(11, 12, 13);
ANALYZE;
SELECT * FROM t1;
}
} {1 2 6 8 9 12 1 2 5 11 12 14 1 2 4}
do_test shared-$av-15.2 {
execsql { DROP TABLE t1 } db2
} {}
db close
db2 close
# Shared cache on a :memory: database. This only works for URI filenames.
#
do_test shared-$av-16.1 {
sqlite3 db1 file::memory: -uri 1
sqlite3 db2 file::memory: -uri 1
db1 eval {
CREATE TABLE t1(x); INSERT INTO t1 VALUES(1),(2),(3);
}
db2 eval {
SELECT x FROM t1 ORDER BY x;
}
} {1 2 3}
do_test shared-$av-16.2 {
db2 eval {
INSERT INTO t1 VALUES(99);
DELETE FROM t1 WHERE x=2;
}
db1 eval {
SELECT x FROM t1 ORDER BY x;
}
} {1 3 99}
# Verify that there is no cache sharing ordinary (non-URI) filenames are
# used.
#
do_test shared-$av-16.3 {
db1 close
db2 close
sqlite3 db1 :memory:
sqlite3 db2 :memory:
db1 eval {
CREATE TABLE t1(x); INSERT INTO t1 VALUES(4),(5),(6);
}
catchsql {
SELECT * FROM t1;
} db2
} {1 {no such table: t1}}
# Shared cache on named memory databases.
#
do_test shared-$av-16.4 {
db1 close
db2 close
forcedelete test.db test.db-wal test.db-journal
sqlite3 db1 file:test.db?mode=memory -uri 1
sqlite3 db2 file:test.db?mode=memory -uri 1
db1 eval {
CREATE TABLE t1(x); INSERT INTO t1 VALUES(1),(2),(3);
}
db2 eval {
SELECT x FROM t1 ORDER BY x;
}
} {1 2 3}
do_test shared-$av-16.5 {
db2 eval {
INSERT INTO t1 VALUES(99);
DELETE FROM t1 WHERE x=2;
}
db1 eval {
SELECT x FROM t1 ORDER BY x;
}
} {1 3 99}
do_test shared-$av-16.6 {
file exists test.db
} {0} ;# Verify that the database is in-memory
# Shared cache on named memory databases with different names.
#
do_test shared-$av-16.7 {
db1 close
db2 close
forcedelete test1.db test2.db
sqlite3 db1 file:test1.db?mode=memory -uri 1
sqlite3 db2 file:test2.db?mode=memory -uri 1
db1 eval {
CREATE TABLE t1(x); INSERT INTO t1 VALUES(1),(2),(3);
}
catchsql {
SELECT x FROM t1 ORDER BY x;
} db2
} {1 {no such table: t1}}
do_test shared-$av-16.8 {
file exists test1.db
} {0} ;# Verify that the database is in-memory
# Shared cache on named memory databases attached to readonly connections.
#
if {![sqlite3 -has-codec]} {
do_test shared-$av-16.8.1 {
db1 close
db2 close
sqlite3 db test1.db
db eval {
CREATE TABLE yy(a, b);
INSERT INTO yy VALUES(77, 88);
}
db close
sqlite3 db1 test1.db -uri 1 -readonly 1
sqlite3 db2 test2.db -uri 1
db1 eval {
ATTACH 'file:mem?mode=memory&cache=shared' AS shared;
CREATE TABLE shared.xx(a, b);
INSERT INTO xx VALUES(55, 66);
}
db2 eval {
ATTACH 'file:mem?mode=memory&cache=shared' AS shared;
SELECT * FROM xx;
}
} {55 66}
do_test shared-$av-16.8.2 { db1 eval { SELECT * FROM yy } } {77 88}
do_test shared-$av-16.8.3 {
list [catch {db1 eval { INSERT INTO yy VALUES(1, 2) }} msg] $msg
} {1 {attempt to write a readonly database}}
db1 close
db2 close
}
} ;# end of autovacuum on/off loop
sqlite3_enable_shared_cache $::enable_shared_cache
finish_test