xref: /sqlite-3.40.0/test/shared_err.test (revision 5a3032b3)
1# 2005 December 30
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#
12# The focus of the tests in this file are IO errors that occur in a shared
13# cache context. What happens to connection B if one connection A encounters
14# an IO-error whilst reading or writing the file-system?
15#
16# $Id: shared_err.test,v 1.17 2007/09/03 16:12:10 drh Exp $
17
18proc skip {args} {}
19
20
21set testdir [file dirname $argv0]
22source $testdir/tester.tcl
23source $testdir/malloc_common.tcl
24db close
25
26ifcapable !shared_cache||!subquery {
27  finish_test
28  return
29}
30
31set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
32
33do_ioerr_test shared_ioerr-1 -tclprep {
34  sqlite3 db2 test.db
35  execsql {
36    PRAGMA read_uncommitted = 1;
37    CREATE TABLE t1(a,b,c);
38    BEGIN;
39    SELECT * FROM sqlite_master;
40  } db2
41} -sqlbody {
42  SELECT * FROM sqlite_master;
43  INSERT INTO t1 VALUES(1,2,3);
44  BEGIN TRANSACTION;
45  INSERT INTO t1 VALUES(1,2,3);
46  INSERT INTO t1 VALUES(4,5,6);
47  ROLLBACK;
48  SELECT * FROM t1;
49  BEGIN TRANSACTION;
50  INSERT INTO t1 VALUES(1,2,3);
51  INSERT INTO t1 VALUES(4,5,6);
52  COMMIT;
53  SELECT * FROM t1;
54  DELETE FROM t1 WHERE a<100;
55} -cleanup {
56  do_test shared_ioerr-1.$n.cleanup.1 {
57    set res [catchsql {
58      SELECT * FROM t1;
59    } db2]
60    set possible_results [list            \
61      "1 {disk I/O error}"                \
62      "0 {1 2 3}"                         \
63      "0 {1 2 3 1 2 3 4 5 6}"             \
64      "0 {1 2 3 1 2 3 4 5 6 1 2 3 4 5 6}" \
65      "0 {}"                              \
66    ]
67    set rc [expr [lsearch -exact $possible_results $res] >= 0]
68    if {$rc != 1} {
69      puts ""
70      puts "Result: $res"
71    }
72    set rc
73  } {1}
74  db2 close
75}
76
77do_ioerr_test shared_ioerr-2 -tclprep {
78  sqlite3 db2 test.db
79  execsql {
80    PRAGMA read_uncommitted = 1;
81    BEGIN;
82    CREATE TABLE t1(a, b);
83    INSERT INTO t1(oid) VALUES(NULL);
84    INSERT INTO t1(oid) SELECT NULL FROM t1;
85    INSERT INTO t1(oid) SELECT NULL FROM t1;
86    INSERT INTO t1(oid) SELECT NULL FROM t1;
87    INSERT INTO t1(oid) SELECT NULL FROM t1;
88    INSERT INTO t1(oid) SELECT NULL FROM t1;
89    INSERT INTO t1(oid) SELECT NULL FROM t1;
90    INSERT INTO t1(oid) SELECT NULL FROM t1;
91    INSERT INTO t1(oid) SELECT NULL FROM t1;
92    INSERT INTO t1(oid) SELECT NULL FROM t1;
93    INSERT INTO t1(oid) SELECT NULL FROM t1;
94    UPDATE t1 set a = oid, b = 'abcdefghijklmnopqrstuvwxyz0123456789';
95    CREATE INDEX i1 ON t1(a);
96    COMMIT;
97    BEGIN;
98    SELECT * FROM sqlite_master;
99  } db2
100} -tclbody {
101  set ::residx 0
102  execsql {DELETE FROM t1 WHERE 0 = (a % 2);}
103  incr ::residx
104
105  # When this transaction begins the table contains 512 entries. The
106  # two statements together add 512+146 more if it succeeds.
107  # (1024/7==146)
108  execsql {BEGIN;}
109  execsql {INSERT INTO t1 SELECT a+1, b FROM t1;}
110  execsql {INSERT INTO t1 SELECT 'string' || a, b FROM t1 WHERE 0 = (a%7);}
111  execsql {COMMIT;}
112
113  incr ::residx
114} -cleanup {
115  do_test shared_ioerr-2.$n.cleanup.1 {
116    set res [catchsql {
117      SELECT max(a), min(a), count(*) FROM (SELECT a FROM t1 order by a);
118    } db2]
119    set possible_results [list \
120      {0 {1024 1 1024}}        \
121      {0 {1023 1 512}}         \
122      {0 {string994 1 1170}}   \
123    ]
124    set idx [lsearch -exact $possible_results $res]
125    set success [expr {$idx==$::residx || $res=="1 {disk I/O error}"}]
126    if {!$success} {
127      puts ""
128      puts "Result: \"$res\" ($::residx)"
129    }
130    set success
131  } {1}
132  db2 close
133}
134
135# This test is designed to provoke an IO error when a cursor position is
136# "saved" (because another cursor is going to modify the underlying table).
137#
138do_ioerr_test shared_ioerr-3 -tclprep {
139  sqlite3 db2 test.db
140  execsql {
141    PRAGMA read_uncommitted = 1;
142    PRAGMA cache_size = 10;
143    BEGIN;
144    CREATE TABLE t1(a, b, UNIQUE(a, b));
145  } db2
146  for {set i 0} {$i < 200} {incr i} {
147    set a [string range [string repeat "[format %03d $i]." 5] 0 end-1]
148
149    set b [string repeat $i 2000]
150    execsql {INSERT INTO t1 VALUES($a, $b)} db2
151  }
152  execsql {COMMIT} db2
153  set ::DB2 [sqlite3_connection_pointer db2]
154  set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
155  sqlite3_step $::STMT       ;# Cursor points at 000.000.000.000
156  sqlite3_step $::STMT       ;# Cursor points at 001.001.001.001
157
158} -tclbody {
159  execsql {
160    BEGIN;
161    INSERT INTO t1 VALUES('201.201.201.201.201', NULL);
162    UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%';
163    COMMIT;
164  }
165} -cleanup {
166  set ::steprc  [sqlite3_step $::STMT]
167  set ::column  [sqlite3_column_text $::STMT 0]
168  set ::finalrc [sqlite3_finalize $::STMT]
169
170  # There are three possible outcomes here (assuming persistent IO errors):
171  #
172  # 1. If the [sqlite3_step] did not require any IO (required pages in
173  #    the cache), then the next row ("002...") may be retrieved
174  #    successfully.
175  #
176  # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns
177  #    SQLITE_ERROR and [sqlite3_finalize] returns IOERR.
178  #
179  # 3. If, after the initial IO error, SQLite tried to rollback the
180  #    active transaction and a second IO error was encountered, then
181  #    statement $::STMT will have been aborted. This means [sqlite3_stmt]
182  #    returns SQLITE_ABORT, and the statement cursor does not move. i.e.
183  #    [sqlite3_column] still returns the current row ("001...") and
184  #    [sqlite3_finalize] returns SQLITE_OK.
185  #
186
187  do_test shared_ioerr-3.$n.cleanup.1 {
188    expr {
189      $::steprc eq "SQLITE_ROW" ||
190      $::steprc eq "SQLITE_ERROR" ||
191      $::steprc eq "SQLITE_ABORT"
192    }
193  } {1}
194  do_test shared_ioerr-3.$n.cleanup.2 {
195    expr {
196      ($::steprc eq "SQLITE_ROW" && $::column eq "002.002.002.002.002") ||
197      ($::steprc eq "SQLITE_ERROR" && $::column eq "") ||
198      ($::steprc eq "SQLITE_ABORT" && $::column eq "001.001.001.001.001")
199    }
200  } {1}
201  do_test shared_ioerr-3.$n.cleanup.3 {
202    expr {
203      ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") ||
204      ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") ||
205      ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_ABORT")
206    }
207  } {1}
208
209# db2 eval {select * from sqlite_master}
210  db2 close
211}
212
213# This is a repeat of the previous test except that this time we
214# are doing a reverse-order scan of the table when the cursor is
215# "saved".
216#
217do_ioerr_test shared_ioerr-3rev -tclprep {
218  sqlite3 db2 test.db
219  execsql {
220    PRAGMA read_uncommitted = 1;
221    PRAGMA cache_size = 10;
222    BEGIN;
223    CREATE TABLE t1(a, b, UNIQUE(a, b));
224  } db2
225  for {set i 0} {$i < 200} {incr i} {
226    set a [string range [string repeat "[format %03d $i]." 5] 0 end-1]
227
228    set b [string repeat $i 2000]
229    execsql {INSERT INTO t1 VALUES($a, $b)} db2
230  }
231  execsql {COMMIT} db2
232  set ::DB2 [sqlite3_connection_pointer db2]
233  set ::STMT [sqlite3_prepare $::DB2 \
234           "SELECT a FROM t1 ORDER BY a DESC" -1 DUMMY]
235  sqlite3_step $::STMT       ;# Cursor points at 199.199.199.199.199
236  sqlite3_step $::STMT       ;# Cursor points at 198.198.198.198.198
237
238} -tclbody {
239  execsql {
240    BEGIN;
241    INSERT INTO t1 VALUES('201.201.201.201.201', NULL);
242    UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%';
243    COMMIT;
244  }
245} -cleanup {
246  set ::steprc  [sqlite3_step $::STMT]
247  set ::column  [sqlite3_column_text $::STMT 0]
248  set ::finalrc [sqlite3_finalize $::STMT]
249
250  # There are three possible outcomes here (assuming persistent IO errors):
251  #
252  # 1. If the [sqlite3_step] did not require any IO (required pages in
253  #    the cache), then the next row ("002...") may be retrieved
254  #    successfully.
255  #
256  # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns
257  #    SQLITE_ERROR and [sqlite3_finalize] returns IOERR.
258  #
259  # 3. If, after the initial IO error, SQLite tried to rollback the
260  #    active transaction and a second IO error was encountered, then
261  #    statement $::STMT will have been aborted. This means [sqlite3_stmt]
262  #    returns SQLITE_ABORT, and the statement cursor does not move. i.e.
263  #    [sqlite3_column] still returns the current row ("001...") and
264  #    [sqlite3_finalize] returns SQLITE_OK.
265  #
266
267  do_test shared_ioerr-3rev.$n.cleanup.1 {
268    expr {
269      $::steprc eq "SQLITE_ROW" ||
270      $::steprc eq "SQLITE_ERROR" ||
271      $::steprc eq "SQLITE_ABORT"
272    }
273  } {1}
274  do_test shared_ioerr-3rev.$n.cleanup.2 {
275    expr {
276      ($::steprc eq "SQLITE_ROW" && $::column eq "197.197.197.197.197") ||
277      ($::steprc eq "SQLITE_ERROR" && $::column eq "") ||
278      ($::steprc eq "SQLITE_ABORT" && $::column eq "198.198.198.198.198")
279    }
280  } {1}
281  do_test shared_ioerr-3rev.$n.cleanup.3 {
282    expr {
283      ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") ||
284      ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") ||
285      ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_ABORT")
286    }
287  } {1}
288
289# db2 eval {select * from sqlite_master}
290  db2 close
291}
292
293# Only run these tests if memory debugging is turned on.
294#
295ifcapable !memdebug {
296   puts "Skipping tests shared_err-4 through -9:\
297         not compiled with -DSQLITE_MEMDEBUG..."
298   db close
299   sqlite3_enable_shared_cache $::enable_shared_cache
300   finish_test
301   return
302}
303
304# Provoke a malloc() failure when a cursor position is being saved. This
305# only happens with index cursors (because they malloc() space to save the
306# current key value). It does not happen with tables, because an integer
307# key does not require a malloc() to store.
308#
309# The library should return an SQLITE_NOMEM to the caller. The query that
310# owns the cursor (the one for which the position is not saved) should
311# continue unaffected.
312#
313do_malloc_test shared_err-4 -tclprep {
314  sqlite3 db2 test.db
315  execsql {
316    PRAGMA read_uncommitted = 1;
317    BEGIN;
318    CREATE TABLE t1(a, b, UNIQUE(a, b));
319  } db2
320  for {set i 0} {$i < 5} {incr i} {
321    set a [string repeat $i 10]
322    set b [string repeat $i 2000]
323    execsql {INSERT INTO t1 VALUES($a, $b)} db2
324  }
325  execsql {COMMIT} db2
326  set ::DB2 [sqlite3_connection_pointer db2]
327  set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
328  sqlite3_step $::STMT       ;# Cursor points at 0000000000
329  sqlite3_step $::STMT       ;# Cursor points at 1111111111
330} -tclbody {
331  execsql {
332    INSERT INTO t1 VALUES(6, NULL);
333  }
334} -cleanup {
335  do_test shared_malloc-4.$::n.cleanup.1 {
336    set ::rc [sqlite3_step $::STMT]
337    expr {$::rc=="SQLITE_ROW" || $::rc=="SQLITE_ERROR"}
338  } {1}
339  if {$::rc=="SQLITE_ROW"} {
340    do_test shared_malloc-4.$::n.cleanup.2 {
341      sqlite3_column_text $::STMT 0
342    } {2222222222}
343  }
344  do_test shared_malloc-4.$::n.cleanup.3 {
345   set rc [sqlite3_finalize $::STMT]
346   expr {$rc=="SQLITE_OK" || $rc=="SQLITE_ABORT" || $rc=="SQLITE_NOMEM"}
347  } {1}
348# db2 eval {select * from sqlite_master}
349  db2 close
350}
351
352do_malloc_test shared_err-5 -tclbody {
353  db close
354  sqlite3 dbX test.db
355  sqlite3 dbY test.db
356  dbX close
357  dbY close
358} -cleanup {
359  catch {dbX close}
360  catch {dbY close}
361}
362
363do_malloc_test shared_err-6 -tclbody {
364  catch {db close}
365  sqlite3_thread_cleanup
366  sqlite3_enable_shared_cache 0
367} -cleanup {
368  sqlite3_enable_shared_cache 1
369}
370
371# As of 3.5.0, sqlite3_enable_shared_cache can be called at
372# any time and from any thread
373#do_test shared_err-misuse-7.1 {
374#  sqlite3 db test.db
375#  catch {
376#    sqlite3_enable_shared_cache 0
377#  } msg
378#  set msg
379#} {library routine called out of sequence}
380
381# Again provoke a malloc() failure when a cursor position is being saved,
382# this time during a ROLLBACK operation by some other handle.
383#
384# The library should return an SQLITE_NOMEM to the caller. The query that
385# owns the cursor (the one for which the position is not saved) should
386# be aborted.
387#
388set ::aborted 0
389do_malloc_test shared_err-8 -tclprep {
390  sqlite3 db2 test.db
391  execsql {
392    PRAGMA read_uncommitted = 1;
393    BEGIN;
394    CREATE TABLE t1(a, b, UNIQUE(a, b));
395  } db2
396  for {set i 0} {$i < 2} {incr i} {
397    set a [string repeat $i 10]
398    set b [string repeat $i 2000]
399    execsql {INSERT INTO t1 VALUES($a, $b)} db2
400  }
401  execsql {COMMIT} db2
402  set ::DB2 [sqlite3_connection_pointer db2]
403  set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
404  sqlite3_step $::STMT       ;# Cursor points at 0000000000
405  sqlite3_step $::STMT       ;# Cursor points at 1111111111
406} -tclbody {
407  execsql {
408    BEGIN;
409    INSERT INTO t1 VALUES(6, NULL);
410    ROLLBACK;
411  }
412} -cleanup {
413  do_test shared_malloc-8.$::n.cleanup.1 {
414    lrange [execsql {
415      SELECT a FROM t1;
416    } db2] 0 1
417  } {0000000000 1111111111}
418  do_test shared_malloc-8.$::n.cleanup.2 {
419    set rc1 [sqlite3_step $::STMT]
420    set rc2 [sqlite3_finalize $::STMT]
421    if {$rc2=="SQLITE_ABORT"} {
422      incr ::aborted
423    }
424    expr {
425      ($rc1=="SQLITE_DONE" && $rc2=="SQLITE_OK") ||
426      ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_ABORT") ||
427      ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_NOMEM")
428    }
429  } {1}
430  db2 close
431}
432do_test shared_malloc-8.X {
433  # Test that one or more queries were aborted due to the malloc() failure.
434  expr $::aborted>=1
435} {1}
436
437# This test is designed to catch a specific bug that was present during
438# development of 3.5.0. If a malloc() failed while setting the page-size,
439# a buffer (Pager.pTmpSpace) was being freed. This could cause a seg-fault
440# later if another connection tried to use the pager.
441#
442# This test will crash 3.4.2.
443#
444do_malloc_test shared_err-9 -tclprep {
445  sqlite3 db2 test.db
446} -sqlbody {
447  PRAGMA page_size = 4096;
448  PRAGMA page_size = 1024;
449} -cleanup {
450  db2 eval {
451    CREATE TABLE abc(a, b, c);
452    BEGIN;
453    INSERT INTO abc VALUES(1, 2, 3);
454    ROLLBACK;
455  }
456  db2 close
457}
458
459
460catch {db close}
461catch {db2 close}
462sqlite3_enable_shared_cache $::enable_shared_cache
463finish_test
464