1b19a2bc6Sdrh# 2001 September 15 22dfbbcafSdrh# 3b19a2bc6Sdrh# The author disclaims copyright to this source code. In place of 4b19a2bc6Sdrh# a legal notice, here is a blessing: 52dfbbcafSdrh# 6b19a2bc6Sdrh# May you do good and not evil. 7b19a2bc6Sdrh# May you find forgiveness for yourself and forgive others. 8b19a2bc6Sdrh# May you share freely, never taking more than you give. 92dfbbcafSdrh# 102dfbbcafSdrh#*********************************************************************** 112dfbbcafSdrh# This file implements regression tests for SQLite library. The 122dfbbcafSdrh# focus of this script is database locks. 132dfbbcafSdrh# 149da742f9Sdrh# $Id: lock.test,v 1.40 2009/06/16 17:49:36 drh Exp $ 15767c2001Sdrh 162dfbbcafSdrh 172dfbbcafSdrhset testdir [file dirname $argv0] 182dfbbcafSdrhsource $testdir/tester.tcl 192dfbbcafSdrh 20ecdc7530Sdrh# Create an alternative connection to the database 212dfbbcafSdrh# 222dfbbcafSdrhdo_test lock-1.0 { 2394dfe476Sdrh # Give a complex pathname to stress the path simplification logic in 2494dfe476Sdrh # the vxworks driver and in test_async. 25107886abSdrh file mkdir tempdir/t1/t2 26107886abSdrh sqlite3 db2 ./tempdir/../tempdir/t1/.//t2/../../..//test.db 27c22bd47dSdrh set dummy {} 282dfbbcafSdrh} {} 292dfbbcafSdrhdo_test lock-1.1 { 30ecdc7530Sdrh execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} 312dfbbcafSdrh} {} 32ecdc7530Sdrhdo_test lock-1.2 { 33ecdc7530Sdrh execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} db2 34ecdc7530Sdrh} {} 35ecdc7530Sdrhdo_test lock-1.3 { 36ecdc7530Sdrh execsql {CREATE TABLE t1(a int, b int)} 37ecdc7530Sdrh execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} 38ecdc7530Sdrh} {t1} 39ecdc7530Sdrhdo_test lock-1.5 { 40ad75e987Sdrh catchsql { 41ecdc7530Sdrh SELECT name FROM sqlite_master WHERE type='table' ORDER BY name 42ad75e987Sdrh } db2 43ecdc7530Sdrh} {0 t1} 442dfbbcafSdrh 45ecdc7530Sdrhdo_test lock-1.6 { 46ecdc7530Sdrh execsql {INSERT INTO t1 VALUES(1,2)} 47ecdc7530Sdrh execsql {SELECT * FROM t1} 48ecdc7530Sdrh} {1 2} 49f9d19a6bSdanielk1977# Update: The schema is now brought up to date by test lock-1.5. 50f9d19a6bSdanielk1977# do_test lock-1.7.1 { 51f9d19a6bSdanielk1977# catchsql {SELECT * FROM t1} db2 52f9d19a6bSdanielk1977# } {1 {no such table: t1}} 53f8646695Sdrhdo_test lock-1.7.2 { 54f8646695Sdrh catchsql {SELECT * FROM t1} db2 55f8646695Sdrh} {0 {1 2}} 56ecdc7530Sdrhdo_test lock-1.8 { 57ecdc7530Sdrh execsql {UPDATE t1 SET a=b, b=a} db2 58ecdc7530Sdrh execsql {SELECT * FROM t1} db2 59ecdc7530Sdrh} {2 1} 60ecdc7530Sdrhdo_test lock-1.9 { 61ecdc7530Sdrh execsql {SELECT * FROM t1} 62ecdc7530Sdrh} {2 1} 63ecdc7530Sdrhdo_test lock-1.10 { 64ecdc7530Sdrh execsql {BEGIN TRANSACTION} 651d850a72Sdanielk1977 execsql {UPDATE t1 SET a = 0 WHERE 0} 66ecdc7530Sdrh execsql {SELECT * FROM t1} 67ecdc7530Sdrh} {2 1} 68ecdc7530Sdrhdo_test lock-1.11 { 69ad75e987Sdrh catchsql {SELECT * FROM t1} db2 70a6ecd338Sdrh} {0 {2 1}} 71ecdc7530Sdrhdo_test lock-1.12 { 72ecdc7530Sdrh execsql {ROLLBACK} 73ad75e987Sdrh catchsql {SELECT * FROM t1} 74ecdc7530Sdrh} {0 {2 1}} 75ecdc7530Sdrh 76ecdc7530Sdrhdo_test lock-1.13 { 77ecdc7530Sdrh execsql {CREATE TABLE t2(x int, y int)} 78ecdc7530Sdrh execsql {INSERT INTO t2 VALUES(8,9)} 79ecdc7530Sdrh execsql {SELECT * FROM t2} 80ecdc7530Sdrh} {8 9} 81a1f9b5eeSdrhdo_test lock-1.14.1 { 82a1f9b5eeSdrh catchsql {SELECT * FROM t2} db2 839da742f9Sdrh} {0 {8 9}} 84a1f9b5eeSdrhdo_test lock-1.14.2 { 85ad75e987Sdrh catchsql {SELECT * FROM t1} db2 86a1f9b5eeSdrh} {0 {2 1}} 87ecdc7530Sdrhdo_test lock-1.15 { 88ad75e987Sdrh catchsql {SELECT * FROM t2} db2 89ecdc7530Sdrh} {0 {8 9}} 90ecdc7530Sdrh 91ecdc7530Sdrhdo_test lock-1.16 { 92ecdc7530Sdrh db eval {SELECT * FROM t1} qv { 93ecdc7530Sdrh set x [db eval {SELECT * FROM t1}] 94ecdc7530Sdrh } 95ecdc7530Sdrh set x 96ecdc7530Sdrh} {2 1} 97ecdc7530Sdrhdo_test lock-1.17 { 98ecdc7530Sdrh db eval {SELECT * FROM t1} qv { 99ecdc7530Sdrh set x [db eval {SELECT * FROM t2}] 100ecdc7530Sdrh } 101ecdc7530Sdrh set x 102ecdc7530Sdrh} {8 9} 103ecdc7530Sdrh 10412b13002Sdanielk1977# You cannot UPDATE a table from within the callback of a SELECT 10512b13002Sdanielk1977# on that same table because the SELECT has the table locked. 106980b1a74Sdrh# 107980b1a74Sdrh# 2006-08-16: Reads no longer block writes within the same 108980b1a74Sdrh# database connection. 109980b1a74Sdrh# 110980b1a74Sdrh#do_test lock-1.18 { 111980b1a74Sdrh# db eval {SELECT * FROM t1} qv { 112980b1a74Sdrh# set r [catch {db eval {UPDATE t1 SET a=b, b=a}} msg] 113980b1a74Sdrh# lappend r $msg 114980b1a74Sdrh# } 115980b1a74Sdrh# set r 116980b1a74Sdrh#} {1 {database table is locked}} 1172dfbbcafSdrh 118ecdc7530Sdrh# But you can UPDATE a different table from the one that is used in 119ecdc7530Sdrh# the SELECT. 1202dfbbcafSdrh# 121ecdc7530Sdrhdo_test lock-1.19 { 122ecdc7530Sdrh db eval {SELECT * FROM t1} qv { 123ecdc7530Sdrh set r [catch {db eval {UPDATE t2 SET x=y, y=x}} msg] 124ecdc7530Sdrh lappend r $msg 125ecdc7530Sdrh } 126ecdc7530Sdrh set r 127ecdc7530Sdrh} {0 {}} 128ecdc7530Sdrhdo_test lock-1.20 { 129ecdc7530Sdrh execsql {SELECT * FROM t2} 130ecdc7530Sdrh} {9 8} 1312dfbbcafSdrh 132ecdc7530Sdrh# It is possible to do a SELECT of the same table within the 133ecdc7530Sdrh# callback of another SELECT on that same table because two 134ecdc7530Sdrh# or more read-only cursors can be open at once. 1352dfbbcafSdrh# 136ecdc7530Sdrhdo_test lock-1.21 { 137ecdc7530Sdrh db eval {SELECT * FROM t1} qv { 138ecdc7530Sdrh set r [catch {db eval {SELECT a FROM t1}} msg] 139ecdc7530Sdrh lappend r $msg 140ecdc7530Sdrh } 141ecdc7530Sdrh set r 142ecdc7530Sdrh} {0 2} 1432dfbbcafSdrh 144ecdc7530Sdrh# Under UNIX you can do two SELECTs at once with different database 145ecdc7530Sdrh# connections, because UNIX supports reader/writer locks. Under windows, 146ecdc7530Sdrh# this is not possible. 1472dfbbcafSdrh# 148ecdc7530Sdrhif {$::tcl_platform(platform)=="unix"} { 149ecdc7530Sdrh do_test lock-1.22 { 150ecdc7530Sdrh db eval {SELECT * FROM t1} qv { 151ecdc7530Sdrh set r [catch {db2 eval {SELECT a FROM t1}} msg] 152ecdc7530Sdrh lappend r $msg 153ecdc7530Sdrh } 154ecdc7530Sdrh set r 155ecdc7530Sdrh } {0 2} 156ecdc7530Sdrh} 1572150432eSdrhintegrity_check lock-1.23 1582dfbbcafSdrh 15990bfcdacSdrh# If one thread has a transaction another thread cannot start 160a6ecd338Sdrh# a transaction. -> Not true in version 3.0. But if one thread 161a6ecd338Sdrh# as a RESERVED lock another thread cannot acquire one. 16290bfcdacSdrh# 16390bfcdacSdrhdo_test lock-2.1 { 16490bfcdacSdrh execsql {BEGIN TRANSACTION} 1651d850a72Sdanielk1977 execsql {UPDATE t1 SET a = 0 WHERE 0} 1661d850a72Sdanielk1977 execsql {BEGIN TRANSACTION} db2 1671d850a72Sdanielk1977 set r [catch {execsql {UPDATE t1 SET a = 0 WHERE 0} db2} msg] 1681d850a72Sdanielk1977 execsql {ROLLBACK} db2 16990bfcdacSdrh lappend r $msg 17090bfcdacSdrh} {1 {database is locked}} 17190bfcdacSdrh 172a6ecd338Sdrh# A thread can read when another has a RESERVED lock. 17390bfcdacSdrh# 17490bfcdacSdrhdo_test lock-2.2 { 175a6ecd338Sdrh catchsql {SELECT * FROM t2} db2 176a6ecd338Sdrh} {0 {9 8}} 17790bfcdacSdrh 178a6ecd338Sdrh# If the other thread (the one that does not hold the transaction with 179b8ef32c3Sdrh# a RESERVED lock) tries to get a RESERVED lock, we do get a busy callback 180b8ef32c3Sdrh# as long as we were not orginally holding a READ lock. 18190bfcdacSdrh# 182b8ef32c3Sdrhdo_test lock-2.3.1 { 1832a764eb0Sdanielk1977 proc callback {count} { 1842a764eb0Sdanielk1977 set ::callback_value $count 18590bfcdacSdrh break 18690bfcdacSdrh } 18790bfcdacSdrh set ::callback_value {} 18890bfcdacSdrh db2 busy callback 189b8ef32c3Sdrh # db2 does not hold a lock so we should get a busy callback here 190b8ef32c3Sdrh set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg] 191b8ef32c3Sdrh lappend r $msg 192b8ef32c3Sdrh lappend r $::callback_value 193b8ef32c3Sdrh} {1 {database is locked} 0} 194b8ef32c3Sdrhdo_test lock-2.3.2 { 195b8ef32c3Sdrh set ::callback_value {} 196b8ef32c3Sdrh execsql {BEGIN; SELECT rowid FROM sqlite_master LIMIT 1} db2 197b8ef32c3Sdrh # This time db2 does hold a read lock. No busy callback this time. 198a6ecd338Sdrh set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg] 19990bfcdacSdrh lappend r $msg 20090bfcdacSdrh lappend r $::callback_value 2011d64fc1aSdrh} {1 {database is locked} {}} 202b8ef32c3Sdrhcatch {execsql {ROLLBACK} db2} 203b8ef32c3Sdrhdo_test lock-2.4.1 { 2042a764eb0Sdanielk1977 proc callback {count} { 20590bfcdacSdrh lappend ::callback_value $count 20690bfcdacSdrh if {$count>4} break 20790bfcdacSdrh } 20890bfcdacSdrh set ::callback_value {} 20990bfcdacSdrh db2 busy callback 210b8ef32c3Sdrh # We get a busy callback because db2 is not holding a lock 211b8ef32c3Sdrh set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg] 212b8ef32c3Sdrh lappend r $msg 213b8ef32c3Sdrh lappend r $::callback_value 214b8ef32c3Sdrh} {1 {database is locked} {0 1 2 3 4 5}} 215b8ef32c3Sdrhdo_test lock-2.4.2 { 216b8ef32c3Sdrh proc callback {count} { 217b8ef32c3Sdrh lappend ::callback_value $count 218b8ef32c3Sdrh if {$count>4} break 219b8ef32c3Sdrh } 220b8ef32c3Sdrh set ::callback_value {} 221b8ef32c3Sdrh db2 busy callback 222b8ef32c3Sdrh execsql {BEGIN; SELECT rowid FROM sqlite_master LIMIT 1} db2 223b8ef32c3Sdrh # No busy callback this time because we are holding a lock 224a6ecd338Sdrh set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg] 22590bfcdacSdrh lappend r $msg 22690bfcdacSdrh lappend r $::callback_value 2271d64fc1aSdrh} {1 {database is locked} {}} 228b8ef32c3Sdrhcatch {execsql {ROLLBACK} db2} 22990bfcdacSdrhdo_test lock-2.5 { 2302a764eb0Sdanielk1977 proc callback {count} { 23190bfcdacSdrh lappend ::callback_value $count 23290bfcdacSdrh if {$count>4} break 23390bfcdacSdrh } 23490bfcdacSdrh set ::callback_value {} 23590bfcdacSdrh db2 busy callback 23690bfcdacSdrh set r [catch {execsql {SELECT * FROM t1} db2} msg] 23790bfcdacSdrh lappend r $msg 23890bfcdacSdrh lappend r $::callback_value 239a6ecd338Sdrh} {0 {2 1} {}} 24090bfcdacSdrhexecsql {ROLLBACK} 241d1bec47aSdrh 242d1bec47aSdrh# Test the built-in busy timeout handler 243d1bec47aSdrh# 2449d356fbeSdrh# EVIDENCE-OF: R-23579-05241 PRAGMA busy_timeout; PRAGMA busy_timeout = 2459d356fbeSdrh# milliseconds; Query or change the setting of the busy timeout. 2469d356fbeSdrh# 247d1bec47aSdrhdo_test lock-2.8 { 248d1bec47aSdrh db2 timeout 400 249d1bec47aSdrh execsql BEGIN 2501d850a72Sdanielk1977 execsql {UPDATE t1 SET a = 0 WHERE 0} 2514397de57Sdanielk1977 catchsql {BEGIN EXCLUSIVE;} db2 252d1bec47aSdrh} {1 {database is locked}} 253f360396cSdrhdo_test lock-2.8b { 254f360396cSdrh db2 eval {PRAGMA busy_timeout} 255f360396cSdrh} {400} 256d1bec47aSdrhdo_test lock-2.9 { 257d1bec47aSdrh db2 timeout 0 258d1bec47aSdrh execsql COMMIT 259d1bec47aSdrh} {} 260f360396cSdrhdo_test lock-2.9b { 261f360396cSdrh db2 eval {PRAGMA busy_timeout} 262f360396cSdrh} {0} 263d1bec47aSdrhintegrity_check lock-2.10 264f360396cSdrhdo_test lock-2.11 { 265f360396cSdrh db2 eval {PRAGMA busy_timeout(400)} 266f360396cSdrh execsql BEGIN 267f360396cSdrh execsql {UPDATE t1 SET a = 0 WHERE 0} 268f360396cSdrh catchsql {BEGIN EXCLUSIVE;} db2 269f360396cSdrh} {1 {database is locked}} 270f360396cSdrhdo_test lock-2.11b { 271f360396cSdrh db2 eval {PRAGMA busy_timeout} 272f360396cSdrh} {400} 273f360396cSdrhdo_test lock-2.12 { 274f360396cSdrh db2 eval {PRAGMA busy_timeout(0)} 275f360396cSdrh execsql COMMIT 276f360396cSdrh} {} 27750610df8Smistachkindo_test lock-2.12b { 278f360396cSdrh db2 eval {PRAGMA busy_timeout} 279f360396cSdrh} {0} 28050610df8Smistachkinintegrity_check lock-2.13 28190bfcdacSdrh 28290bfcdacSdrh# Try to start two transactions in a row 28390bfcdacSdrh# 28490bfcdacSdrhdo_test lock-3.1 { 28590bfcdacSdrh execsql {BEGIN TRANSACTION} 28690bfcdacSdrh set r [catch {execsql {BEGIN TRANSACTION}} msg] 28790bfcdacSdrh execsql {ROLLBACK} 28890bfcdacSdrh lappend r $msg 2896b8b8749Sdrh} {1 {cannot start a transaction within a transaction}} 2902150432eSdrhintegrity_check lock-3.2 291ecdc7530Sdrh 2921e0ccab9Sdrh# Make sure the busy handler and error messages work when 2931e0ccab9Sdrh# opening a new pointer to the database while another pointer 2941e0ccab9Sdrh# has the database locked. 2951e0ccab9Sdrh# 2961e0ccab9Sdrhdo_test lock-4.1 { 2971e0ccab9Sdrh db2 close 2981e0ccab9Sdrh catch {db eval ROLLBACK} 2991e0ccab9Sdrh db eval BEGIN 3001d850a72Sdanielk1977 db eval {UPDATE t1 SET a=0 WHERE 0} 301ef4ac8f9Sdrh sqlite3 db2 ./test.db 302a6ecd338Sdrh catchsql {UPDATE t1 SET a=0} db2 3031e0ccab9Sdrh} {1 {database is locked}} 3041e0ccab9Sdrhdo_test lock-4.2 { 3051e0ccab9Sdrh set ::callback_value {} 306a6ecd338Sdrh set rc [catch {db2 eval {UPDATE t1 SET a=0}} msg] 3071e0ccab9Sdrh lappend rc $msg $::callback_value 3081e0ccab9Sdrh} {1 {database is locked} {}} 3091e0ccab9Sdrhdo_test lock-4.3 { 3102a764eb0Sdanielk1977 proc callback {count} { 3111e0ccab9Sdrh lappend ::callback_value $count 3121e0ccab9Sdrh if {$count>4} break 3131e0ccab9Sdrh } 3141e0ccab9Sdrh db2 busy callback 315a6ecd338Sdrh set rc [catch {db2 eval {UPDATE t1 SET a=0}} msg] 3161e0ccab9Sdrh lappend rc $msg $::callback_value 317b8ef32c3Sdrh} {1 {database is locked} {0 1 2 3 4 5}} 318cabb0819Sdrhexecsql {ROLLBACK} 3191e0ccab9Sdrh 320cabb0819Sdrh# When one thread is writing, other threads cannot read. Except if the 321cabb0819Sdrh# writing thread is writing to its temporary tables, the other threads 322a6ecd338Sdrh# can still read. -> Not so in 3.0. One thread can read while another 323a6ecd338Sdrh# holds a RESERVED lock. 324cabb0819Sdrh# 325cabb0819Sdrhproc tx_exec {sql} { 326cabb0819Sdrh db2 eval $sql 327cabb0819Sdrh} 328cabb0819Sdrhdo_test lock-5.1 { 329cabb0819Sdrh execsql { 330cabb0819Sdrh SELECT * FROM t1 331cabb0819Sdrh } 332cabb0819Sdrh} {2 1} 333cabb0819Sdrhdo_test lock-5.2 { 334cabb0819Sdrh db function tx_exec tx_exec 335cabb0819Sdrh catchsql { 336cabb0819Sdrh INSERT INTO t1(a,b) SELECT 3, tx_exec('SELECT y FROM t2 LIMIT 1'); 337cabb0819Sdrh } 338a6ecd338Sdrh} {0 {}} 33953c0f748Sdanielk1977 34053c0f748Sdanielk1977ifcapable tempdb { 341cabb0819Sdrh do_test lock-5.3 { 342cabb0819Sdrh execsql { 343cabb0819Sdrh CREATE TEMP TABLE t3(x); 344cabb0819Sdrh SELECT * FROM t3; 345cabb0819Sdrh } 346cabb0819Sdrh } {} 347cabb0819Sdrh do_test lock-5.4 { 348cabb0819Sdrh catchsql { 349cabb0819Sdrh INSERT INTO t3 SELECT tx_exec('SELECT y FROM t2 LIMIT 1'); 350cabb0819Sdrh } 351cabb0819Sdrh } {0 {}} 352cabb0819Sdrh do_test lock-5.5 { 353cabb0819Sdrh execsql { 354cabb0819Sdrh SELECT * FROM t3; 355cabb0819Sdrh } 356cabb0819Sdrh } {8} 357cabb0819Sdrh do_test lock-5.6 { 358cabb0819Sdrh catchsql { 359cabb0819Sdrh UPDATE t1 SET a=tx_exec('SELECT x FROM t2'); 360cabb0819Sdrh } 361a6ecd338Sdrh } {0 {}} 362cabb0819Sdrh do_test lock-5.7 { 363cabb0819Sdrh execsql { 364cabb0819Sdrh SELECT * FROM t1; 365cabb0819Sdrh } 366a6ecd338Sdrh } {9 1 9 8} 367cabb0819Sdrh do_test lock-5.8 { 368cabb0819Sdrh catchsql { 369cabb0819Sdrh UPDATE t3 SET x=tx_exec('SELECT x FROM t2'); 370cabb0819Sdrh } 371cabb0819Sdrh } {0 {}} 372cabb0819Sdrh do_test lock-5.9 { 373cabb0819Sdrh execsql { 374cabb0819Sdrh SELECT * FROM t3; 375cabb0819Sdrh } 376cabb0819Sdrh } {9} 37753c0f748Sdanielk1977} 3781e0ccab9Sdrh 379104f1fefSdanielk1977do_test lock-6.1 { 380104f1fefSdanielk1977 execsql { 381104f1fefSdanielk1977 CREATE TABLE t4(a PRIMARY KEY, b); 382104f1fefSdanielk1977 INSERT INTO t4 VALUES(1, 'one'); 383104f1fefSdanielk1977 INSERT INTO t4 VALUES(2, 'two'); 384104f1fefSdanielk1977 INSERT INTO t4 VALUES(3, 'three'); 385104f1fefSdanielk1977 } 386104f1fefSdanielk1977 387104f1fefSdanielk1977 set STMT [sqlite3_prepare $DB "SELECT * FROM sqlite_master" -1 TAIL] 388104f1fefSdanielk1977 sqlite3_step $STMT 389104f1fefSdanielk1977 390104f1fefSdanielk1977 execsql { DELETE FROM t4 } 391104f1fefSdanielk1977 execsql { SELECT * FROM sqlite_master } db2 392104f1fefSdanielk1977 execsql { SELECT * FROM t4 } db2 393104f1fefSdanielk1977} {} 394104f1fefSdanielk1977 395104f1fefSdanielk1977do_test lock-6.2 { 396104f1fefSdanielk1977 execsql { 397104f1fefSdanielk1977 BEGIN; 398104f1fefSdanielk1977 INSERT INTO t4 VALUES(1, 'one'); 399104f1fefSdanielk1977 INSERT INTO t4 VALUES(2, 'two'); 400104f1fefSdanielk1977 INSERT INTO t4 VALUES(3, 'three'); 401104f1fefSdanielk1977 COMMIT; 402104f1fefSdanielk1977 } 403104f1fefSdanielk1977 404104f1fefSdanielk1977 execsql { SELECT * FROM t4 } db2 405104f1fefSdanielk1977} {1 one 2 two 3 three} 406104f1fefSdanielk1977 407104f1fefSdanielk1977do_test lock-6.3 { 408104f1fefSdanielk1977 execsql { SELECT a FROM t4 ORDER BY a } db2 409104f1fefSdanielk1977} {1 2 3} 410104f1fefSdanielk1977 411104f1fefSdanielk1977do_test lock-6.4 { 412104f1fefSdanielk1977 execsql { PRAGMA integrity_check } db2 413104f1fefSdanielk1977} {ok} 414104f1fefSdanielk1977 415104f1fefSdanielk1977do_test lock-6.5 { 416104f1fefSdanielk1977 sqlite3_finalize $STMT 417104f1fefSdanielk1977} {SQLITE_OK} 418104f1fefSdanielk1977 4193cfe0703Sdanielk1977# At one point the following set of conditions would cause SQLite to 4203cfe0703Sdanielk1977# retain a RESERVED or EXCLUSIVE lock after the transaction was committed: 4213cfe0703Sdanielk1977# 4223cfe0703Sdanielk1977# * The journal-mode is set to something other than 'delete', and 4233cfe0703Sdanielk1977# * there exists one or more active read-only statements, and 4243cfe0703Sdanielk1977# * a transaction that modified zero database pages is committed. 4253cfe0703Sdanielk1977# 426*7f8def28Sdan#set temp_status unlocked 427*7f8def28Sdan#if {$TEMP_STORE>=2} {set temp_status unknown} 428*7f8def28Sdanset temp_status unknown 4293cfe0703Sdanielk1977do_test lock-7.1 { 4303cfe0703Sdanielk1977 set STMT [sqlite3_prepare $DB "SELECT * FROM sqlite_master" -1 TAIL] 4313cfe0703Sdanielk1977 sqlite3_step $STMT 4323cfe0703Sdanielk1977} {SQLITE_ROW} 4333cfe0703Sdanielk1977do_test lock-7.2 { 4343cfe0703Sdanielk1977 execsql { PRAGMA lock_status } 4351435ccd5Sdanielk1977} [list main shared temp $temp_status] 4363cfe0703Sdanielk1977do_test lock-7.3 { 4373cfe0703Sdanielk1977 execsql { 4383cfe0703Sdanielk1977 PRAGMA journal_mode = truncate; 4393cfe0703Sdanielk1977 BEGIN; 4403cfe0703Sdanielk1977 UPDATE t4 SET a = 10 WHERE 0; 4413cfe0703Sdanielk1977 COMMIT; 4423cfe0703Sdanielk1977 } 4433cfe0703Sdanielk1977 execsql { PRAGMA lock_status } 4441435ccd5Sdanielk1977} [list main shared temp $temp_status] 4453cfe0703Sdanielk1977do_test lock-7.4 { 4463cfe0703Sdanielk1977 sqlite3_finalize $STMT 4473cfe0703Sdanielk1977} {SQLITE_OK} 4483cfe0703Sdanielk1977 449ecdc7530Sdrhdo_test lock-999.1 { 450ecdc7530Sdrh rename db2 {} 451ecdc7530Sdrh} {} 4522dfbbcafSdrh 4532dfbbcafSdrhfinish_test 454