~ubuntu-branches/ubuntu/karmic/gears/karmic

« back to all changes in this revision

Viewing changes to third_party/sqlite_google/test/lock.test

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Lesicnik
  • Date: 2009-04-30 19:15:25 UTC
  • Revision ID: james.westby@ubuntu.com-20090430191525-0790sb5wzg8ou0xb
Tags: upstream-0.5.21.0~svn3334+dfsg
ImportĀ upstreamĀ versionĀ 0.5.21.0~svn3334+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# 2001 September 15
 
2
#
 
3
# The author disclaims copyright to this source code.  In place of
 
4
# a legal notice, here is a blessing:
 
5
#
 
6
#    May you do good and not evil.
 
7
#    May you find forgiveness for yourself and forgive others.
 
8
#    May you share freely, never taking more than you give.
 
9
#
 
10
#***********************************************************************
 
11
# This file implements regression tests for SQLite library.  The
 
12
# focus of this script is database locks.
 
13
#
 
14
# $Id: lock.test,v 1.33 2006/08/16 16:42:48 drh Exp $
 
15
 
 
16
 
 
17
set testdir [file dirname $argv0]
 
18
source $testdir/tester.tcl
 
19
 
 
20
# Create an alternative connection to the database
 
21
#
 
22
do_test lock-1.0 {
 
23
  sqlite3 db2 ./test.db
 
24
  set dummy {}
 
25
} {}
 
26
do_test lock-1.1 {
 
27
  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
 
28
} {}
 
29
do_test lock-1.2 {
 
30
  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} db2
 
31
} {}
 
32
do_test lock-1.3 {
 
33
  execsql {CREATE TABLE t1(a int, b int)}
 
34
  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
 
35
} {t1}
 
36
do_test lock-1.5 {
 
37
  catchsql {
 
38
     SELECT name FROM sqlite_master WHERE type='table' ORDER BY name
 
39
  } db2
 
40
} {0 t1}
 
41
 
 
42
do_test lock-1.6 {
 
43
  execsql {INSERT INTO t1 VALUES(1,2)}
 
44
  execsql {SELECT * FROM t1}
 
45
} {1 2}
 
46
# Update: The schema is now brought up to date by test lock-1.5.
 
47
# do_test lock-1.7.1 {
 
48
#   catchsql {SELECT * FROM t1} db2
 
49
# } {1 {no such table: t1}}
 
50
do_test lock-1.7.2 {
 
51
  catchsql {SELECT * FROM t1} db2
 
52
} {0 {1 2}}
 
53
do_test lock-1.8 {
 
54
  execsql {UPDATE t1 SET a=b, b=a} db2
 
55
  execsql {SELECT * FROM t1} db2
 
56
} {2 1}
 
57
do_test lock-1.9 {
 
58
  execsql {SELECT * FROM t1}
 
59
} {2 1}
 
60
do_test lock-1.10 {
 
61
  execsql {BEGIN TRANSACTION}
 
62
  execsql {UPDATE t1 SET a = 0 WHERE 0}
 
63
  execsql {SELECT * FROM t1}
 
64
} {2 1}
 
65
do_test lock-1.11 {
 
66
  catchsql {SELECT * FROM t1} db2
 
67
} {0 {2 1}}
 
68
do_test lock-1.12 {
 
69
  execsql {ROLLBACK}
 
70
  catchsql {SELECT * FROM t1}
 
71
} {0 {2 1}}
 
72
 
 
73
do_test lock-1.13 {
 
74
  execsql {CREATE TABLE t2(x int, y int)}
 
75
  execsql {INSERT INTO t2 VALUES(8,9)}
 
76
  execsql {SELECT * FROM t2}
 
77
} {8 9}
 
78
do_test lock-1.14.1 {
 
79
  catchsql {SELECT * FROM t2} db2
 
80
} {1 {no such table: t2}}
 
81
do_test lock-1.14.2 {
 
82
  catchsql {SELECT * FROM t1} db2
 
83
} {0 {2 1}}
 
84
do_test lock-1.15 {
 
85
  catchsql {SELECT * FROM t2} db2
 
86
} {0 {8 9}}
 
87
 
 
88
do_test lock-1.16 {
 
89
  db eval {SELECT * FROM t1} qv {
 
90
    set x [db eval {SELECT * FROM t1}]
 
91
  }
 
92
  set x
 
93
} {2 1}
 
94
do_test lock-1.17 {
 
95
  db eval {SELECT * FROM t1} qv {
 
96
    set x [db eval {SELECT * FROM t2}]
 
97
  }
 
98
  set x
 
99
} {8 9}
 
100
 
 
101
# You cannot UPDATE a table from within the callback of a SELECT
 
102
# on that same table because the SELECT has the table locked.
 
103
#
 
104
# 2006-08-16:  Reads no longer block writes within the same
 
105
# database connection.
 
106
#
 
107
#do_test lock-1.18 {
 
108
#  db eval {SELECT * FROM t1} qv {
 
109
#    set r [catch {db eval {UPDATE t1 SET a=b, b=a}} msg]
 
110
#    lappend r $msg
 
111
#  }
 
112
#  set r
 
113
#} {1 {database table is locked}}
 
114
 
 
115
# But you can UPDATE a different table from the one that is used in
 
116
# the SELECT.
 
117
#
 
118
do_test lock-1.19 {
 
119
  db eval {SELECT * FROM t1} qv {
 
120
    set r [catch {db eval {UPDATE t2 SET x=y, y=x}} msg]
 
121
    lappend r $msg
 
122
  }
 
123
  set r
 
124
} {0 {}}
 
125
do_test lock-1.20 {
 
126
  execsql {SELECT * FROM t2}
 
127
} {9 8}
 
128
 
 
129
# It is possible to do a SELECT of the same table within the
 
130
# callback of another SELECT on that same table because two
 
131
# or more read-only cursors can be open at once.
 
132
#
 
133
do_test lock-1.21 {
 
134
  db eval {SELECT * FROM t1} qv {
 
135
    set r [catch {db eval {SELECT a FROM t1}} msg]
 
136
    lappend r $msg
 
137
  }
 
138
  set r
 
139
} {0 2}
 
140
 
 
141
# Under UNIX you can do two SELECTs at once with different database
 
142
# connections, because UNIX supports reader/writer locks.  Under windows,
 
143
# this is not possible.
 
144
#
 
145
if {$::tcl_platform(platform)=="unix"} {
 
146
  do_test lock-1.22 {
 
147
    db eval {SELECT * FROM t1} qv {
 
148
      set r [catch {db2 eval {SELECT a FROM t1}} msg]
 
149
      lappend r $msg
 
150
    }
 
151
    set r
 
152
  } {0 2}
 
153
}
 
154
integrity_check lock-1.23
 
155
 
 
156
# If one thread has a transaction another thread cannot start
 
157
# a transaction.  -> Not true in version 3.0.  But if one thread
 
158
# as a RESERVED lock another thread cannot acquire one.
 
159
#
 
160
do_test lock-2.1 {
 
161
  execsql {BEGIN TRANSACTION}
 
162
  execsql {UPDATE t1 SET a = 0 WHERE 0}
 
163
  execsql {BEGIN TRANSACTION} db2
 
164
  set r [catch {execsql {UPDATE t1 SET a = 0 WHERE 0} db2} msg]
 
165
  execsql {ROLLBACK} db2
 
166
  lappend r $msg
 
167
} {1 {database is locked}}
 
168
 
 
169
# A thread can read when another has a RESERVED lock.
 
170
#
 
171
do_test lock-2.2 {
 
172
  catchsql {SELECT * FROM t2} db2
 
173
} {0 {9 8}}
 
174
 
 
175
# If the other thread (the one that does not hold the transaction with
 
176
# a RESERVED lock) tries to get a RESERVED lock, we do get a busy callback
 
177
# as long as we were not orginally holding a READ lock.
 
178
#
 
179
do_test lock-2.3.1 {
 
180
  proc callback {count} {
 
181
    set ::callback_value $count
 
182
    break
 
183
  }
 
184
  set ::callback_value {}
 
185
  db2 busy callback
 
186
  # db2 does not hold a lock so we should get a busy callback here
 
187
  set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg]
 
188
  lappend r $msg
 
189
  lappend r $::callback_value
 
190
} {1 {database is locked} 0}
 
191
do_test lock-2.3.2 {
 
192
  set ::callback_value {}
 
193
  execsql {BEGIN; SELECT rowid FROM sqlite_master LIMIT 1} db2
 
194
  # This time db2 does hold a read lock.  No busy callback this time.
 
195
  set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg]
 
196
  lappend r $msg
 
197
  lappend r $::callback_value
 
198
} {1 {database is locked} {}}
 
199
catch {execsql {ROLLBACK} db2}
 
200
do_test lock-2.4.1 {
 
201
  proc callback {count} {
 
202
    lappend ::callback_value $count
 
203
    if {$count>4} break
 
204
  }
 
205
  set ::callback_value {}
 
206
  db2 busy callback
 
207
  # We get a busy callback because db2 is not holding a lock
 
208
  set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg]
 
209
  lappend r $msg
 
210
  lappend r $::callback_value
 
211
} {1 {database is locked} {0 1 2 3 4 5}}
 
212
do_test lock-2.4.2 {
 
213
  proc callback {count} {
 
214
    lappend ::callback_value $count
 
215
    if {$count>4} break
 
216
  }
 
217
  set ::callback_value {}
 
218
  db2 busy callback
 
219
  execsql {BEGIN; SELECT rowid FROM sqlite_master LIMIT 1} db2
 
220
  # No busy callback this time because we are holding a lock
 
221
  set r [catch {execsql {UPDATE t1 SET a=b, b=a} db2} msg]
 
222
  lappend r $msg
 
223
  lappend r $::callback_value
 
224
} {1 {database is locked} {}}
 
225
catch {execsql {ROLLBACK} db2}
 
226
do_test lock-2.5 {
 
227
  proc callback {count} {
 
228
    lappend ::callback_value $count
 
229
    if {$count>4} break
 
230
  }
 
231
  set ::callback_value {}
 
232
  db2 busy callback
 
233
  set r [catch {execsql {SELECT * FROM t1} db2} msg]
 
234
  lappend r $msg
 
235
  lappend r $::callback_value
 
236
} {0 {2 1} {}}
 
237
execsql {ROLLBACK}
 
238
 
 
239
# Test the built-in busy timeout handler
 
240
#
 
241
do_test lock-2.8 {
 
242
  db2 timeout 400
 
243
  execsql BEGIN
 
244
  execsql {UPDATE t1 SET a = 0 WHERE 0}
 
245
  catchsql {BEGIN EXCLUSIVE;} db2
 
246
} {1 {database is locked}}
 
247
do_test lock-2.9 {
 
248
  db2 timeout 0
 
249
  execsql COMMIT
 
250
} {}
 
251
integrity_check lock-2.10
 
252
 
 
253
# Try to start two transactions in a row
 
254
#
 
255
do_test lock-3.1 {
 
256
  execsql {BEGIN TRANSACTION}
 
257
  set r [catch {execsql {BEGIN TRANSACTION}} msg]
 
258
  execsql {ROLLBACK}
 
259
  lappend r $msg
 
260
} {1 {cannot start a transaction within a transaction}}
 
261
integrity_check lock-3.2
 
262
 
 
263
# Make sure the busy handler and error messages work when
 
264
# opening a new pointer to the database while another pointer
 
265
# has the database locked.
 
266
#
 
267
do_test lock-4.1 {
 
268
  db2 close
 
269
  catch {db eval ROLLBACK}
 
270
  db eval BEGIN
 
271
  db eval {UPDATE t1 SET a=0 WHERE 0}
 
272
  sqlite3 db2 ./test.db
 
273
  catchsql {UPDATE t1 SET a=0} db2
 
274
} {1 {database is locked}}
 
275
do_test lock-4.2 {
 
276
  set ::callback_value {}
 
277
  set rc [catch {db2 eval {UPDATE t1 SET a=0}} msg]
 
278
  lappend rc $msg $::callback_value
 
279
} {1 {database is locked} {}}
 
280
do_test lock-4.3 {
 
281
  proc callback {count} {
 
282
    lappend ::callback_value $count
 
283
    if {$count>4} break
 
284
  }
 
285
  db2 busy callback
 
286
  set rc [catch {db2 eval {UPDATE t1 SET a=0}} msg]
 
287
  lappend rc $msg $::callback_value
 
288
} {1 {database is locked} {0 1 2 3 4 5}}
 
289
execsql {ROLLBACK}
 
290
 
 
291
# When one thread is writing, other threads cannot read.  Except if the
 
292
# writing thread is writing to its temporary tables, the other threads
 
293
# can still read.  -> Not so in 3.0.  One thread can read while another
 
294
# holds a RESERVED lock.
 
295
#
 
296
proc tx_exec {sql} {
 
297
  db2 eval $sql
 
298
}
 
299
do_test lock-5.1 {
 
300
  execsql {
 
301
    SELECT * FROM t1
 
302
  }
 
303
} {2 1}
 
304
do_test lock-5.2 {
 
305
  db function tx_exec tx_exec
 
306
  catchsql {
 
307
    INSERT INTO t1(a,b) SELECT 3, tx_exec('SELECT y FROM t2 LIMIT 1');
 
308
  }
 
309
} {0 {}}
 
310
 
 
311
ifcapable tempdb {
 
312
  do_test lock-5.3 {
 
313
    execsql {
 
314
      CREATE TEMP TABLE t3(x);
 
315
      SELECT * FROM t3;
 
316
    }
 
317
  } {}
 
318
  do_test lock-5.4 {
 
319
    catchsql {
 
320
      INSERT INTO t3 SELECT tx_exec('SELECT y FROM t2 LIMIT 1');
 
321
    }
 
322
  } {0 {}}
 
323
  do_test lock-5.5 {
 
324
    execsql {
 
325
      SELECT * FROM t3;
 
326
    }
 
327
  } {8}
 
328
  do_test lock-5.6 {
 
329
    catchsql {
 
330
      UPDATE t1 SET a=tx_exec('SELECT x FROM t2');
 
331
    }
 
332
  } {0 {}}
 
333
  do_test lock-5.7 {
 
334
    execsql {
 
335
      SELECT * FROM t1;
 
336
    }
 
337
  } {9 1 9 8}
 
338
  do_test lock-5.8 {
 
339
    catchsql {
 
340
      UPDATE t3 SET x=tx_exec('SELECT x FROM t2');
 
341
    }
 
342
  } {0 {}}
 
343
  do_test lock-5.9 {
 
344
    execsql {
 
345
      SELECT * FROM t3;
 
346
    }
 
347
  } {9}
 
348
}
 
349
 
 
350
do_test lock-999.1 {
 
351
  rename db2 {}
 
352
} {}
 
353
 
 
354
finish_test