141483468Sdanielk1977# 2007 March 24 241483468Sdanielk1977# 341483468Sdanielk1977# The author disclaims copyright to this source code. In place of 441483468Sdanielk1977# a legal notice, here is a blessing: 541483468Sdanielk1977# 641483468Sdanielk1977# May you do good and not evil. 741483468Sdanielk1977# May you find forgiveness for yourself and forgive others. 841483468Sdanielk1977# May you share freely, never taking more than you give. 941483468Sdanielk1977# 1041483468Sdanielk1977#*********************************************************************** 11ded6f4b2Sdanielk1977# This file implements regression tests for SQLite library. The focus 12ded6f4b2Sdanielk1977# of these tests is exclusive access mode (i.e. the thing activated by 13ded6f4b2Sdanielk1977# "PRAGMA locking_mode = EXCLUSIVE"). 1441483468Sdanielk1977# 1531559aeeSdanielk1977# $Id: exclusive.test,v 1.15 2009/06/26 12:30:40 danielk1977 Exp $ 1641483468Sdanielk1977 1741483468Sdanielk1977set testdir [file dirname $argv0] 1841483468Sdanielk1977source $testdir/tester.tcl 1941483468Sdanielk1977 2041483468Sdanielk1977ifcapable {!pager_pragmas} { 2141483468Sdanielk1977 finish_test 2241483468Sdanielk1977 return 2341483468Sdanielk1977} 2441483468Sdanielk1977 25fda06befSmistachkinforcedelete test2.db-journal 26fda06befSmistachkinforcedelete test2.db 27fda06befSmistachkinforcedelete test3.db-journal 28fda06befSmistachkinforcedelete test3.db 29fda06befSmistachkinforcedelete test4.db-journal 30fda06befSmistachkinforcedelete test4.db 3141483468Sdanielk1977 3241483468Sdanielk1977#---------------------------------------------------------------------- 3341483468Sdanielk1977# Test cases exclusive-1.X test the PRAGMA logic. 3441483468Sdanielk1977# 3541483468Sdanielk1977do_test exclusive-1.0 { 3641483468Sdanielk1977 execsql { 3741483468Sdanielk1977 pragma locking_mode; 3841483468Sdanielk1977 pragma main.locking_mode; 39369339dbSdrh pragma temp.locking_mode; 4041483468Sdanielk1977 } 418a7adb0dSdanielk1977} [list normal normal exclusive] 4241483468Sdanielk1977do_test exclusive-1.1 { 4341483468Sdanielk1977 execsql { 4441483468Sdanielk1977 pragma locking_mode = exclusive; 4541483468Sdanielk1977 } 4641483468Sdanielk1977} {exclusive} 4741483468Sdanielk1977do_test exclusive-1.2 { 4841483468Sdanielk1977 execsql { 4941483468Sdanielk1977 pragma locking_mode; 5041483468Sdanielk1977 pragma main.locking_mode; 51369339dbSdrh pragma temp.locking_mode; 5241483468Sdanielk1977 } 538a7adb0dSdanielk1977} [list exclusive exclusive exclusive] 5441483468Sdanielk1977do_test exclusive-1.3 { 5541483468Sdanielk1977 execsql { 5641483468Sdanielk1977 pragma locking_mode = normal; 5741483468Sdanielk1977 } 5841483468Sdanielk1977} {normal} 5941483468Sdanielk1977do_test exclusive-1.4 { 6041483468Sdanielk1977 execsql { 6141483468Sdanielk1977 pragma locking_mode; 6241483468Sdanielk1977 pragma main.locking_mode; 63369339dbSdrh pragma temp.locking_mode; 6441483468Sdanielk1977 } 658a7adb0dSdanielk1977} [list normal normal exclusive] 6641483468Sdanielk1977do_test exclusive-1.5 { 6741483468Sdanielk1977 execsql { 6841483468Sdanielk1977 pragma locking_mode = invalid; 6941483468Sdanielk1977 } 7041483468Sdanielk1977} {normal} 7141483468Sdanielk1977do_test exclusive-1.6 { 7241483468Sdanielk1977 execsql { 7341483468Sdanielk1977 pragma locking_mode; 7441483468Sdanielk1977 pragma main.locking_mode; 75369339dbSdrh pragma temp.locking_mode; 7641483468Sdanielk1977 } 778a7adb0dSdanielk1977} [list normal normal exclusive] 785a8f9374Sdanielk1977ifcapable attach { 7941483468Sdanielk1977 do_test exclusive-1.7 { 8041483468Sdanielk1977 execsql { 8141483468Sdanielk1977 pragma locking_mode = exclusive; 8241483468Sdanielk1977 ATTACH 'test2.db' as aux; 8341483468Sdanielk1977 } 8441483468Sdanielk1977 execsql { 8541483468Sdanielk1977 pragma main.locking_mode; 8641483468Sdanielk1977 pragma aux.locking_mode; 8741483468Sdanielk1977 } 8841483468Sdanielk1977 } {exclusive exclusive} 8941483468Sdanielk1977 do_test exclusive-1.8 { 9041483468Sdanielk1977 execsql { 9141483468Sdanielk1977 pragma main.locking_mode = normal; 9241483468Sdanielk1977 } 9341483468Sdanielk1977 execsql { 9441483468Sdanielk1977 pragma main.locking_mode; 95369339dbSdrh pragma temp.locking_mode; 9641483468Sdanielk1977 pragma aux.locking_mode; 9741483468Sdanielk1977 } 988a7adb0dSdanielk1977 } [list normal exclusive exclusive] 9941483468Sdanielk1977 do_test exclusive-1.9 { 10041483468Sdanielk1977 execsql { 10141483468Sdanielk1977 pragma locking_mode; 10241483468Sdanielk1977 } 10341483468Sdanielk1977 } {exclusive} 10441483468Sdanielk1977 do_test exclusive-1.10 { 10541483468Sdanielk1977 execsql { 10641483468Sdanielk1977 ATTACH 'test3.db' as aux2; 10741483468Sdanielk1977 } 10841483468Sdanielk1977 execsql { 10941483468Sdanielk1977 pragma main.locking_mode; 11041483468Sdanielk1977 pragma aux.locking_mode; 11141483468Sdanielk1977 pragma aux2.locking_mode; 11241483468Sdanielk1977 } 11341483468Sdanielk1977 } {normal exclusive exclusive} 11441483468Sdanielk1977 do_test exclusive-1.11 { 11541483468Sdanielk1977 execsql { 11641483468Sdanielk1977 pragma aux.locking_mode = normal; 11741483468Sdanielk1977 } 11841483468Sdanielk1977 execsql { 11941483468Sdanielk1977 pragma main.locking_mode; 12041483468Sdanielk1977 pragma aux.locking_mode; 12141483468Sdanielk1977 pragma aux2.locking_mode; 12241483468Sdanielk1977 } 12341483468Sdanielk1977 } {normal normal exclusive} 12441483468Sdanielk1977 do_test exclusive-1.12 { 12541483468Sdanielk1977 execsql { 12641483468Sdanielk1977 pragma locking_mode = normal; 12741483468Sdanielk1977 } 12841483468Sdanielk1977 execsql { 12941483468Sdanielk1977 pragma main.locking_mode; 130369339dbSdrh pragma temp.locking_mode; 13141483468Sdanielk1977 pragma aux.locking_mode; 13241483468Sdanielk1977 pragma aux2.locking_mode; 13341483468Sdanielk1977 } 1348a7adb0dSdanielk1977 } [list normal exclusive normal normal] 13541483468Sdanielk1977 do_test exclusive-1.13 { 13641483468Sdanielk1977 execsql { 13741483468Sdanielk1977 ATTACH 'test4.db' as aux3; 13841483468Sdanielk1977 } 13941483468Sdanielk1977 execsql { 14041483468Sdanielk1977 pragma main.locking_mode; 141369339dbSdrh pragma temp.locking_mode; 14241483468Sdanielk1977 pragma aux.locking_mode; 14341483468Sdanielk1977 pragma aux2.locking_mode; 14441483468Sdanielk1977 pragma aux3.locking_mode; 14541483468Sdanielk1977 } 1468a7adb0dSdanielk1977 } [list normal exclusive normal normal normal] 14741483468Sdanielk1977 14841483468Sdanielk1977 do_test exclusive-1.99 { 14941483468Sdanielk1977 execsql { 15041483468Sdanielk1977 DETACH aux; 15141483468Sdanielk1977 DETACH aux2; 15241483468Sdanielk1977 DETACH aux3; 15341483468Sdanielk1977 } 15441483468Sdanielk1977 } {} 1555a8f9374Sdanielk1977} 15641483468Sdanielk1977 15741483468Sdanielk1977#---------------------------------------------------------------------- 15841483468Sdanielk1977# Test cases exclusive-2.X verify that connections in exclusive 15941483468Sdanielk1977# locking_mode do not relinquish locks. 16041483468Sdanielk1977# 16141483468Sdanielk1977do_test exclusive-2.0 { 16241483468Sdanielk1977 execsql { 16341483468Sdanielk1977 CREATE TABLE abc(a, b, c); 16441483468Sdanielk1977 INSERT INTO abc VALUES(1, 2, 3); 16541483468Sdanielk1977 PRAGMA locking_mode = exclusive; 16641483468Sdanielk1977 } 16741483468Sdanielk1977} {exclusive} 16841483468Sdanielk1977do_test exclusive-2.1 { 16941483468Sdanielk1977 sqlite3 db2 test.db 17041483468Sdanielk1977 execsql { 17141483468Sdanielk1977 INSERT INTO abc VALUES(4, 5, 6); 17241483468Sdanielk1977 SELECT * FROM abc; 17341483468Sdanielk1977 } db2 17441483468Sdanielk1977} {1 2 3 4 5 6} 17541483468Sdanielk1977do_test exclusive-2.2 { 17641483468Sdanielk1977 # This causes connection 'db' (in exclusive mode) to establish 17741483468Sdanielk1977 # a shared-lock on the db. The other connection should now be 17841483468Sdanielk1977 # locked out as a writer. 17941483468Sdanielk1977 execsql { 18041483468Sdanielk1977 SELECT * FROM abc; 18141483468Sdanielk1977 } db 18241483468Sdanielk1977} {1 2 3 4 5 6} 18341483468Sdanielk1977do_test exclusive-2.4 { 18441483468Sdanielk1977 execsql { 18541483468Sdanielk1977 SELECT * FROM abc; 18641483468Sdanielk1977 } db2 18741483468Sdanielk1977} {1 2 3 4 5 6} 18841483468Sdanielk1977do_test exclusive-2.5 { 18941483468Sdanielk1977 catchsql { 19041483468Sdanielk1977 INSERT INTO abc VALUES(7, 8, 9); 19141483468Sdanielk1977 } db2 19241483468Sdanielk1977} {1 {database is locked}} 1933aefabafSdrhsqlite3_soft_heap_limit 0 19441483468Sdanielk1977do_test exclusive-2.6 { 19541483468Sdanielk1977 # Because connection 'db' only has a shared-lock, the other connection 19641483468Sdanielk1977 # will be able to get a RESERVED, but will fail to upgrade to EXCLUSIVE. 19741483468Sdanielk1977 execsql { 19841483468Sdanielk1977 BEGIN; 19941483468Sdanielk1977 INSERT INTO abc VALUES(7, 8, 9); 20041483468Sdanielk1977 } db2 20141483468Sdanielk1977 catchsql { 20241483468Sdanielk1977 COMMIT 20341483468Sdanielk1977 } db2 20441483468Sdanielk1977} {1 {database is locked}} 20541483468Sdanielk1977do_test exclusive-2.7 { 20641483468Sdanielk1977 catchsql { 20741483468Sdanielk1977 COMMIT 20841483468Sdanielk1977 } db2 20941483468Sdanielk1977} {1 {database is locked}} 21041483468Sdanielk1977do_test exclusive-2.8 { 21141483468Sdanielk1977 execsql { 21241483468Sdanielk1977 ROLLBACK; 21341483468Sdanielk1977 } db2 21441483468Sdanielk1977} {} 215c1a60c51Sdansqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit) 21641483468Sdanielk1977 21741483468Sdanielk1977do_test exclusive-2.9 { 21841483468Sdanielk1977 # Write the database to establish the exclusive lock with connection 'db. 21941483468Sdanielk1977 execsql { 22041483468Sdanielk1977 INSERT INTO abc VALUES(7, 8, 9); 22141483468Sdanielk1977 } db 22241483468Sdanielk1977 catchsql { 22341483468Sdanielk1977 SELECT * FROM abc; 22441483468Sdanielk1977 } db2 22541483468Sdanielk1977} {1 {database is locked}} 22641483468Sdanielk1977do_test exclusive-2.10 { 22741483468Sdanielk1977 # Changing the locking-mode does not release any locks. 22841483468Sdanielk1977 execsql { 22941483468Sdanielk1977 PRAGMA locking_mode = normal; 23041483468Sdanielk1977 } db 23141483468Sdanielk1977 catchsql { 23241483468Sdanielk1977 SELECT * FROM abc; 23341483468Sdanielk1977 } db2 23441483468Sdanielk1977} {1 {database is locked}} 23541483468Sdanielk1977do_test exclusive-2.11 { 23641483468Sdanielk1977 # After changing the locking mode, accessing the db releases locks. 23741483468Sdanielk1977 execsql { 23841483468Sdanielk1977 SELECT * FROM abc; 23941483468Sdanielk1977 } db 24041483468Sdanielk1977 execsql { 24141483468Sdanielk1977 SELECT * FROM abc; 24241483468Sdanielk1977 } db2 24341483468Sdanielk1977} {1 2 3 4 5 6 7 8 9} 24441483468Sdanielk1977db2 close 24541483468Sdanielk1977 24641483468Sdanielk1977#---------------------------------------------------------------------- 24741483468Sdanielk1977# Tests exclusive-3.X - test that a connection in exclusive mode 24841483468Sdanielk1977# truncates instead of deletes the journal file when committing 24941483468Sdanielk1977# a transaction. 25041483468Sdanielk1977# 251e5dd3896Sdanielk1977# These tests are not run on windows because the windows backend 252e5dd3896Sdanielk1977# opens the journal file for exclusive access, preventing its contents 253e5dd3896Sdanielk1977# from being inspected externally. 254e5dd3896Sdanielk1977# 25569aedc8dSdanif {$tcl_platform(platform) != "windows" 25669aedc8dSdan && [atomic_batch_write test.db]==0 25769aedc8dSdan} { 258d0864087Sdan 259d0864087Sdan # Return a list of two booleans (either 0 or 1). The first is true 260d0864087Sdan # if the named file exists. The second is true only if the file 261d0864087Sdan # exists and the first 28 bytes contain at least one non-zero byte. 262d0864087Sdan # 26341483468Sdanielk1977 proc filestate {fname} { 26441483468Sdanielk1977 set exists 0 26541483468Sdanielk1977 set content 0 26641483468Sdanielk1977 if {[file exists $fname]} { 26741483468Sdanielk1977 set exists 1 268f3a87624Sdrh set hdr [hexio_read $fname 0 28] 26931559aeeSdanielk1977 set content [expr {0==[string match $hdr [string repeat 0 56]]}] 27041483468Sdanielk1977 } 27141483468Sdanielk1977 list $exists $content 27241483468Sdanielk1977 } 273d0864087Sdan 27441483468Sdanielk1977 do_test exclusive-3.0 { 27541483468Sdanielk1977 filestate test.db-journal 27641483468Sdanielk1977 } {0 0} 27741483468Sdanielk1977 do_test exclusive-3.1 { 27841483468Sdanielk1977 execsql { 27941483468Sdanielk1977 PRAGMA locking_mode = exclusive; 28041483468Sdanielk1977 BEGIN; 28141483468Sdanielk1977 DELETE FROM abc; 28241483468Sdanielk1977 } 28341483468Sdanielk1977 filestate test.db-journal 28441483468Sdanielk1977 } {1 1} 28541483468Sdanielk1977 do_test exclusive-3.2 { 28641483468Sdanielk1977 execsql { 28741483468Sdanielk1977 COMMIT; 28841483468Sdanielk1977 } 28941483468Sdanielk1977 filestate test.db-journal 29041483468Sdanielk1977 } {1 0} 29141483468Sdanielk1977 do_test exclusive-3.3 { 29241483468Sdanielk1977 execsql { 29341483468Sdanielk1977 INSERT INTO abc VALUES('A', 'B', 'C'); 29441483468Sdanielk1977 SELECT * FROM abc; 29541483468Sdanielk1977 } 29641483468Sdanielk1977 } {A B C} 29741483468Sdanielk1977 do_test exclusive-3.4 { 29841483468Sdanielk1977 execsql { 29941483468Sdanielk1977 BEGIN; 30041483468Sdanielk1977 UPDATE abc SET a = 1, b = 2, c = 3; 30141483468Sdanielk1977 ROLLBACK; 30241483468Sdanielk1977 SELECT * FROM abc; 30341483468Sdanielk1977 } 304334cdb63Sdanielk1977 } {A B C} 30541483468Sdanielk1977 do_test exclusive-3.5 { 30641483468Sdanielk1977 filestate test.db-journal 30741483468Sdanielk1977 } {1 0} 30841483468Sdanielk1977 do_test exclusive-3.6 { 30941483468Sdanielk1977 execsql { 31041483468Sdanielk1977 PRAGMA locking_mode = normal; 31141483468Sdanielk1977 SELECT * FROM abc; 31241483468Sdanielk1977 } 31341483468Sdanielk1977 filestate test.db-journal 31441483468Sdanielk1977 } {0 0} 315e5dd3896Sdanielk1977} 31641483468Sdanielk1977 317334cdb63Sdanielk1977#---------------------------------------------------------------------- 318334cdb63Sdanielk1977# Tests exclusive-4.X - test that rollback works correctly when 319334cdb63Sdanielk1977# in exclusive-access mode. 320334cdb63Sdanielk1977# 321334cdb63Sdanielk1977 32241483468Sdanielk1977# The following procedure computes a "signature" for table "t3". If 32341483468Sdanielk1977# T3 changes in any way, the signature should change. 32441483468Sdanielk1977# 32541483468Sdanielk1977# This is used to test ROLLBACK. We gather a signature for t3, then 32641483468Sdanielk1977# make lots of changes to t3, then rollback and take another signature. 32741483468Sdanielk1977# The two signatures should be the same. 32841483468Sdanielk1977# 32941483468Sdanielk1977proc signature {} { 33041483468Sdanielk1977 return [db eval {SELECT count(*), md5sum(x) FROM t3}] 33141483468Sdanielk1977} 33241483468Sdanielk1977 33341483468Sdanielk1977do_test exclusive-4.0 { 33441483468Sdanielk1977 execsql { PRAGMA locking_mode = exclusive; } 335334cdb63Sdanielk1977 execsql { PRAGMA default_cache_size = 10; } 33641483468Sdanielk1977 execsql { 33741483468Sdanielk1977 BEGIN; 33841483468Sdanielk1977 CREATE TABLE t3(x TEXT); 33941483468Sdanielk1977 INSERT INTO t3 VALUES(randstr(10,400)); 34041483468Sdanielk1977 INSERT INTO t3 VALUES(randstr(10,400)); 34141483468Sdanielk1977 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 34241483468Sdanielk1977 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 34341483468Sdanielk1977 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 34441483468Sdanielk1977 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 34541483468Sdanielk1977 COMMIT; 34641483468Sdanielk1977 } 347334cdb63Sdanielk1977 execsql {SELECT count(*) FROM t3;} 348334cdb63Sdanielk1977} {32} 349334cdb63Sdanielk1977 350334cdb63Sdanielk1977set ::X [signature] 35141483468Sdanielk1977do_test exclusive-4.1 { 35241483468Sdanielk1977 execsql { 35341483468Sdanielk1977 BEGIN; 35441483468Sdanielk1977 DELETE FROM t3 WHERE random()%10!=0; 35541483468Sdanielk1977 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 35641483468Sdanielk1977 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 357334cdb63Sdanielk1977 SELECT count(*) FROM t3; 35841483468Sdanielk1977 ROLLBACK; 35941483468Sdanielk1977 } 36041483468Sdanielk1977 signature 361334cdb63Sdanielk1977} $::X 36241483468Sdanielk1977 363334cdb63Sdanielk1977do_test exclusive-4.2 { 364334cdb63Sdanielk1977 execsql { 365334cdb63Sdanielk1977 BEGIN; 366334cdb63Sdanielk1977 DELETE FROM t3 WHERE random()%10!=0; 367334cdb63Sdanielk1977 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 368334cdb63Sdanielk1977 DELETE FROM t3 WHERE random()%10!=0; 369334cdb63Sdanielk1977 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 370334cdb63Sdanielk1977 ROLLBACK; 37141483468Sdanielk1977 } 372334cdb63Sdanielk1977 signature 373334cdb63Sdanielk1977} $::X 374334cdb63Sdanielk1977 375334cdb63Sdanielk1977do_test exclusive-4.3 { 376334cdb63Sdanielk1977 execsql { 377334cdb63Sdanielk1977 INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0; 378334cdb63Sdanielk1977 } 379334cdb63Sdanielk1977} {} 380334cdb63Sdanielk1977 381334cdb63Sdanielk1977do_test exclusive-4.4 { 382334cdb63Sdanielk1977 catch {set ::X [signature]} 383334cdb63Sdanielk1977} {0} 384334cdb63Sdanielk1977do_test exclusive-4.5 { 385334cdb63Sdanielk1977 execsql { 386334cdb63Sdanielk1977 PRAGMA locking_mode = NORMAL; 387334cdb63Sdanielk1977 DROP TABLE t3; 388334cdb63Sdanielk1977 DROP TABLE abc; 389334cdb63Sdanielk1977 } 390334cdb63Sdanielk1977} {normal} 391334cdb63Sdanielk1977 392334cdb63Sdanielk1977#---------------------------------------------------------------------- 393334cdb63Sdanielk1977# Tests exclusive-5.X - test that statement journals are truncated 394334cdb63Sdanielk1977# instead of deleted when in exclusive access mode. 395334cdb63Sdanielk1977# 39669aedc8dSdanif {[atomic_batch_write test.db]==0} { 397369339dbSdrh 398369339dbSdrh# Close and reopen the database so that the temp database is no 399369339dbSdrh# longer active. 400369339dbSdrh# 401369339dbSdrhdb close 4024c0f1649Sdrhsqlite3 db test.db 403369339dbSdrh 404aebf413dSaswift# if we're using proxy locks, we use 3 filedescriptors for a db 405aebf413dSaswift# that is open but NOT writing changes, normally 406aebf413dSaswift# sqlite uses 1 (proxy locking adds the conch and the local lock) 407aebf413dSaswiftset using_proxy 0 408aebf413dSaswiftforeach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] { 409aebf413dSaswift set using_proxy $value 410aebf413dSaswift} 411aebf413dSaswiftset extrafds 0 412aebf413dSaswiftif {$using_proxy!=0} { 413aebf413dSaswift set extrafds 2 414aebf413dSaswift} 415369339dbSdrh 416334cdb63Sdanielk1977do_test exclusive-5.0 { 417334cdb63Sdanielk1977 execsql { 418334cdb63Sdanielk1977 CREATE TABLE abc(a UNIQUE, b UNIQUE, c UNIQUE); 419334cdb63Sdanielk1977 BEGIN; 420334cdb63Sdanielk1977 INSERT INTO abc VALUES(1, 2, 3); 421334cdb63Sdanielk1977 INSERT INTO abc SELECT a+1, b+1, c+1 FROM abc; 422334cdb63Sdanielk1977 } 423334cdb63Sdanielk1977} {} 424334cdb63Sdanielk1977do_test exclusive-5.1 { 425334cdb63Sdanielk1977 # Three files are open: The db, journal and statement-journal. 4263ac9a864Sdrh # (2016-03-04) The statement-journal is now opened lazily 427334cdb63Sdanielk1977 set sqlite_open_file_count 428aebf413dSaswift expr $sqlite_open_file_count-$extrafds 429b6eb6662Sdan} {2} 430334cdb63Sdanielk1977do_test exclusive-5.2 { 431334cdb63Sdanielk1977 execsql { 432334cdb63Sdanielk1977 COMMIT; 433334cdb63Sdanielk1977 } 434334cdb63Sdanielk1977 # One file open: the db. 435334cdb63Sdanielk1977 set sqlite_open_file_count 436aebf413dSaswift expr $sqlite_open_file_count-$extrafds 437334cdb63Sdanielk1977} {1} 438334cdb63Sdanielk1977do_test exclusive-5.3 { 439334cdb63Sdanielk1977 execsql { 440334cdb63Sdanielk1977 PRAGMA locking_mode = exclusive; 441334cdb63Sdanielk1977 BEGIN; 442334cdb63Sdanielk1977 INSERT INTO abc VALUES(5, 6, 7); 443334cdb63Sdanielk1977 } 444334cdb63Sdanielk1977 # Two files open: the db and journal. 445334cdb63Sdanielk1977 set sqlite_open_file_count 446aebf413dSaswift expr $sqlite_open_file_count-$extrafds 447f9d1a214Sdanielk1977} {2} 448334cdb63Sdanielk1977do_test exclusive-5.4 { 449334cdb63Sdanielk1977 execsql { 450334cdb63Sdanielk1977 INSERT INTO abc SELECT a+10, b+10, c+10 FROM abc; 451334cdb63Sdanielk1977 } 452334cdb63Sdanielk1977 # Three files are open: The db, journal and statement-journal. 4533ac9a864Sdrh # 2016-03-04: The statement-journal open is deferred 454334cdb63Sdanielk1977 set sqlite_open_file_count 455aebf413dSaswift expr $sqlite_open_file_count-$extrafds 456b6eb6662Sdan} {2} 457334cdb63Sdanielk1977do_test exclusive-5.5 { 458334cdb63Sdanielk1977 execsql { 459334cdb63Sdanielk1977 COMMIT; 460334cdb63Sdanielk1977 } 461334cdb63Sdanielk1977 # Three files are still open: The db, journal and statement-journal. 4623ac9a864Sdrh # 2016-03-04: The statement-journal open is deferred 463334cdb63Sdanielk1977 set sqlite_open_file_count 464aebf413dSaswift expr $sqlite_open_file_count-$extrafds 465b6eb6662Sdan} {2} 466334cdb63Sdanielk1977do_test exclusive-5.6 { 467334cdb63Sdanielk1977 execsql { 468334cdb63Sdanielk1977 PRAGMA locking_mode = normal; 469334cdb63Sdanielk1977 SELECT * FROM abc; 470334cdb63Sdanielk1977 } 471334cdb63Sdanielk1977} {normal 1 2 3 2 3 4 5 6 7 11 12 13 12 13 14 15 16 17} 472334cdb63Sdanielk1977do_test exclusive-5.7 { 473334cdb63Sdanielk1977 # Just the db open. 474334cdb63Sdanielk1977 set sqlite_open_file_count 475aebf413dSaswift expr $sqlite_open_file_count-$extrafds 476334cdb63Sdanielk1977} {1} 47741483468Sdanielk1977 47876de8a75Sdan#------------------------------------------------------------------------- 47976de8a75Sdan 48076de8a75Sdando_execsql_test exclusive-6.1 { 48176de8a75Sdan CREATE TABLE t4(a, b); 48276de8a75Sdan INSERT INTO t4 VALUES('Eden', 1955); 48376de8a75Sdan BEGIN; 48476de8a75Sdan INSERT INTO t4 VALUES('Macmillan', 1957); 48576de8a75Sdan INSERT INTO t4 VALUES('Douglas-Home', 1963); 48676de8a75Sdan INSERT INTO t4 VALUES('Wilson', 1964); 48776de8a75Sdan} 48876de8a75Sdando_test exclusive-6.2 { 48976de8a75Sdan forcedelete test2.db test2.db-journal 490fda06befSmistachkin copy_file test.db test2.db 491fda06befSmistachkin copy_file test.db-journal test2.db-journal 49276de8a75Sdan sqlite3 db test2.db 49376de8a75Sdan} {} 49476de8a75Sdan 49576de8a75Sdando_execsql_test exclusive-6.3 { 49676de8a75Sdan PRAGMA locking_mode = EXCLUSIVE; 49776de8a75Sdan SELECT * FROM t4; 49876de8a75Sdan} {exclusive Eden 1955} 49976de8a75Sdan 50076de8a75Sdando_test exclusive-6.4 { 50176de8a75Sdan db close 50276de8a75Sdan forcedelete test.db test.db-journal 50376de8a75Sdan set fd [open test.db-journal w] 50476de8a75Sdan puts $fd x 50576de8a75Sdan close $fd 50676de8a75Sdan sqlite3 db test.db 50776de8a75Sdan} {} 50876de8a75Sdan 50976de8a75Sdando_execsql_test exclusive-6.5 { 51076de8a75Sdan PRAGMA locking_mode = EXCLUSIVE; 51176de8a75Sdan SELECT * FROM sqlite_master; 512bfa7e199Sdan} {exclusive} 51376de8a75Sdan 514fce8165eSdrh# 2019-12-26 ticket fb3b3024ea238d5c 515*d0add948Sdanif {[permutation]!="journaltest"} { 516*d0add948Sdan # The custom VFS used by the "journaltest" permutation cannot open the 517*d0add948Sdan # shared-memory file. So, while it is able to switch the db file to 518*d0add948Sdan # journal_mode=WAL when locking_mode=EXCLUSIVE, it can no longer access 519*d0add948Sdan # it once the locking_mode is changed back to NORMAL. 520fce8165eSdrh do_test exclusive-7.1 { 521fce8165eSdrh db close 522fce8165eSdrh forcedelete test.db test.db-journal test.db-wal 523fce8165eSdrh sqlite3 db test.db 524fce8165eSdrh # The following sequence of pragmas would trigger an assert() 525fce8165eSdrh # associated with Pager.changeCountDone inside of assert_pager_state(), 526fce8165eSdrh # prior to the fix. 527fce8165eSdrh db eval { 528fce8165eSdrh PRAGMA locking_mode = EXCLUSIVE; 529fce8165eSdrh PRAGMA journal_mode = WAL; 530fce8165eSdrh PRAGMA locking_mode = NORMAL; 531fce8165eSdrh PRAGMA user_version; 532fce8165eSdrh PRAGMA journal_mode = DELETE; 533fce8165eSdrh } 534fce8165eSdrh } {exclusive wal normal 0 delete} 535*d0add948Sdan} 536fce8165eSdrh 537fce8165eSdrh 53869aedc8dSdan} ;# atomic_batch_write==0 53969aedc8dSdan 54041483468Sdanielk1977finish_test 541