xref: /sqlite-3.40.0/test/lock.test (revision 7f8def28)
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