xref: /sqlite-3.40.0/test/shared_err.test (revision 75c5fa88)
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.21 2008/07/07 17:55:29 danielk1977 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  catchsql ROLLBACK
116  do_test shared_ioerr-2.$n.cleanup.1 {
117    set res [catchsql {
118      SELECT max(a), min(a), count(*) FROM (SELECT a FROM t1 order by a);
119    } db2]
120    set possible_results [list \
121      {0 {1024 1 1024}}        \
122      {0 {1023 1 512}}         \
123      {0 {string994 1 1170}}   \
124    ]
125    set idx [lsearch -exact $possible_results $res]
126    set success [expr {$idx==$::residx || $res=="1 {disk I/O error}"}]
127    if {!$success} {
128      puts ""
129      puts "Result: \"$res\" ($::residx)"
130    }
131    set success
132  } {1}
133  db2 close
134}
135
136# This test is designed to provoke an IO error when a cursor position is
137# "saved" (because another cursor is going to modify the underlying table).
138#
139do_ioerr_test shared_ioerr-3 -tclprep {
140  sqlite3 db2 test.db
141  execsql {
142    PRAGMA read_uncommitted = 1;
143    PRAGMA cache_size = 10;
144    BEGIN;
145    CREATE TABLE t1(a, b, UNIQUE(a, b));
146  } db2
147  for {set i 0} {$i < 200} {incr i} {
148    set a [string range [string repeat "[format %03d $i]." 5] 0 end-1]
149
150    set b [string repeat $i 2000]
151    execsql {INSERT INTO t1 VALUES($a, $b)} db2
152  }
153  execsql {COMMIT} db2
154  set ::DB2 [sqlite3_connection_pointer db2]
155  set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
156  sqlite3_step $::STMT       ;# Cursor points at 000.000.000.000
157  sqlite3_step $::STMT       ;# Cursor points at 001.001.001.001
158
159} -tclbody {
160  execsql {
161    BEGIN;
162    INSERT INTO t1 VALUES('201.201.201.201.201', NULL);
163    UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%';
164    COMMIT;
165  }
166} -cleanup {
167  set ::steprc  [sqlite3_step $::STMT]
168  set ::column  [sqlite3_column_text $::STMT 0]
169  set ::finalrc [sqlite3_finalize $::STMT]
170
171  # There are three possible outcomes here (assuming persistent IO errors):
172  #
173  # 1. If the [sqlite3_step] did not require any IO (required pages in
174  #    the cache), then the next row ("002...") may be retrieved
175  #    successfully.
176  #
177  # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns
178  #    SQLITE_ERROR and [sqlite3_finalize] returns IOERR.
179  #
180  # 3. If, after the initial IO error, SQLite tried to rollback the
181  #    active transaction and a second IO error was encountered, then
182  #    statement $::STMT will have been aborted. This means [sqlite3_stmt]
183  #    returns SQLITE_ABORT, and the statement cursor does not move. i.e.
184  #    [sqlite3_column] still returns the current row ("001...") and
185  #    [sqlite3_finalize] returns SQLITE_OK.
186  #
187
188  do_test shared_ioerr-3.$n.cleanup.1 {
189    expr {
190      $::steprc eq "SQLITE_ROW" ||
191      $::steprc eq "SQLITE_ERROR" ||
192      $::steprc eq "SQLITE_ABORT"
193    }
194  } {1}
195  do_test shared_ioerr-3.$n.cleanup.2 {
196    expr {
197      ($::steprc eq "SQLITE_ROW" && $::column eq "002.002.002.002.002") ||
198      ($::steprc eq "SQLITE_ERROR" && $::column eq "") ||
199      ($::steprc eq "SQLITE_ABORT" && $::column eq "001.001.001.001.001")
200    }
201  } {1}
202  do_test shared_ioerr-3.$n.cleanup.3 {
203    expr {
204      ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") ||
205      ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") ||
206      ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_ABORT")
207    }
208  } {1}
209
210# db2 eval {select * from sqlite_master}
211  db2 close
212}
213
214# This is a repeat of the previous test except that this time we
215# are doing a reverse-order scan of the table when the cursor is
216# "saved".
217#
218do_ioerr_test shared_ioerr-3rev -tclprep {
219  sqlite3 db2 test.db
220  execsql {
221    PRAGMA read_uncommitted = 1;
222    PRAGMA cache_size = 10;
223    BEGIN;
224    CREATE TABLE t1(a, b, UNIQUE(a, b));
225  } db2
226  for {set i 0} {$i < 200} {incr i} {
227    set a [string range [string repeat "[format %03d $i]." 5] 0 end-1]
228
229    set b [string repeat $i 2000]
230    execsql {INSERT INTO t1 VALUES($a, $b)} db2
231  }
232  execsql {COMMIT} db2
233  set ::DB2 [sqlite3_connection_pointer db2]
234  set ::STMT [sqlite3_prepare $::DB2 \
235           "SELECT a FROM t1 ORDER BY a DESC" -1 DUMMY]
236  sqlite3_step $::STMT       ;# Cursor points at 199.199.199.199.199
237  sqlite3_step $::STMT       ;# Cursor points at 198.198.198.198.198
238
239} -tclbody {
240  execsql {
241    BEGIN;
242    INSERT INTO t1 VALUES('201.201.201.201.201', NULL);
243    UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%';
244    COMMIT;
245  }
246} -cleanup {
247  set ::steprc  [sqlite3_step $::STMT]
248  set ::column  [sqlite3_column_text $::STMT 0]
249  set ::finalrc [sqlite3_finalize $::STMT]
250
251  # There are three possible outcomes here (assuming persistent IO errors):
252  #
253  # 1. If the [sqlite3_step] did not require any IO (required pages in
254  #    the cache), then the next row ("002...") may be retrieved
255  #    successfully.
256  #
257  # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns
258  #    SQLITE_ERROR and [sqlite3_finalize] returns IOERR.
259  #
260  # 3. If, after the initial IO error, SQLite tried to rollback the
261  #    active transaction and a second IO error was encountered, then
262  #    statement $::STMT will have been aborted. This means [sqlite3_stmt]
263  #    returns SQLITE_ABORT, and the statement cursor does not move. i.e.
264  #    [sqlite3_column] still returns the current row ("001...") and
265  #    [sqlite3_finalize] returns SQLITE_OK.
266  #
267
268  do_test shared_ioerr-3rev.$n.cleanup.1 {
269    expr {
270      $::steprc eq "SQLITE_ROW" ||
271      $::steprc eq "SQLITE_ERROR" ||
272      $::steprc eq "SQLITE_ABORT"
273    }
274  } {1}
275  do_test shared_ioerr-3rev.$n.cleanup.2 {
276    expr {
277      ($::steprc eq "SQLITE_ROW" && $::column eq "197.197.197.197.197") ||
278      ($::steprc eq "SQLITE_ERROR" && $::column eq "") ||
279      ($::steprc eq "SQLITE_ABORT" && $::column eq "198.198.198.198.198")
280    }
281  } {1}
282  do_test shared_ioerr-3rev.$n.cleanup.3 {
283    expr {
284      ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") ||
285      ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") ||
286      ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_ABORT")
287    }
288  } {1}
289
290# db2 eval {select * from sqlite_master}
291  db2 close
292}
293
294# Provoke a malloc() failure when a cursor position is being saved. This
295# only happens with index cursors (because they malloc() space to save the
296# current key value). It does not happen with tables, because an integer
297# key does not require a malloc() to store.
298#
299# The library should return an SQLITE_NOMEM to the caller. The query that
300# owns the cursor (the one for which the position is not saved) should
301# continue unaffected.
302#
303do_malloc_test shared_err-4 -tclprep {
304  sqlite3 db2 test.db
305  execsql {
306    PRAGMA read_uncommitted = 1;
307    BEGIN;
308    CREATE TABLE t1(a, b, UNIQUE(a, b));
309  } db2
310  for {set i 0} {$i < 5} {incr i} {
311    set a [string repeat $i 10]
312    set b [string repeat $i 2000]
313    execsql {INSERT INTO t1 VALUES($a, $b)} db2
314  }
315  execsql {COMMIT} db2
316  set ::DB2 [sqlite3_connection_pointer db2]
317  set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
318  sqlite3_step $::STMT       ;# Cursor points at 0000000000
319  sqlite3_step $::STMT       ;# Cursor points at 1111111111
320} -tclbody {
321  execsql {
322    INSERT INTO t1 VALUES(6, NULL);
323  }
324} -cleanup {
325  do_test shared_malloc-4.$::n.cleanup.1 {
326    set ::rc [sqlite3_step $::STMT]
327    expr {$::rc=="SQLITE_ROW" || $::rc=="SQLITE_ERROR"}
328  } {1}
329  if {$::rc=="SQLITE_ROW"} {
330    do_test shared_malloc-4.$::n.cleanup.2 {
331      sqlite3_column_text $::STMT 0
332    } {2222222222}
333  }
334  do_test shared_malloc-4.$::n.cleanup.3 {
335   set rc [sqlite3_finalize $::STMT]
336   expr {$rc=="SQLITE_OK" || $rc=="SQLITE_ABORT" ||
337         $rc=="SQLITE_NOMEM" || $rc=="SQLITE_IOERR"}
338  } {1}
339# db2 eval {select * from sqlite_master}
340  db2 close
341}
342
343do_malloc_test shared_err-5 -tclbody {
344  db close
345  sqlite3 dbX test.db
346  sqlite3 dbY test.db
347  dbX close
348  dbY close
349} -cleanup {
350  catch {dbX close}
351  catch {dbY close}
352}
353
354do_malloc_test shared_err-6 -tclbody {
355  catch {db close}
356  sqlite3_thread_cleanup
357  sqlite3_enable_shared_cache 0
358} -cleanup {
359  sqlite3_enable_shared_cache 1
360}
361
362# As of 3.5.0, sqlite3_enable_shared_cache can be called at
363# any time and from any thread
364#do_test shared_err-misuse-7.1 {
365#  sqlite3 db test.db
366#  catch {
367#    sqlite3_enable_shared_cache 0
368#  } msg
369#  set msg
370#} {library routine called out of sequence}
371
372# Again provoke a malloc() failure when a cursor position is being saved,
373# this time during a ROLLBACK operation by some other handle.
374#
375# The library should return an SQLITE_NOMEM to the caller. The query that
376# owns the cursor (the one for which the position is not saved) should
377# be aborted.
378#
379set ::aborted 0
380do_malloc_test shared_err-8 -tclprep {
381  sqlite3 db2 test.db
382  execsql {
383    PRAGMA read_uncommitted = 1;
384    BEGIN;
385    CREATE TABLE t1(a, b, UNIQUE(a, b));
386  } db2
387  for {set i 0} {$i < 2} {incr i} {
388    set a [string repeat $i 10]
389    set b [string repeat $i 2000]
390    execsql {INSERT INTO t1 VALUES($a, $b)} db2
391  }
392  execsql {COMMIT} db2
393  set ::DB2 [sqlite3_connection_pointer db2]
394  set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
395  sqlite3_step $::STMT       ;# Cursor points at 0000000000
396  sqlite3_step $::STMT       ;# Cursor points at 1111111111
397} -tclbody {
398  execsql {
399    BEGIN;
400    INSERT INTO t1 VALUES(6, NULL);
401    ROLLBACK;
402  }
403} -cleanup {
404  do_test shared_malloc-8.$::n.cleanup.1 {
405    set res [catchsql {SELECT a FROM t1} db2]
406    set ans [lindex $res 1]
407    if {[lindex $res 0]} {
408       set r [expr {$ans=="disk I/O error" || $ans=="out of memory"}]
409    } else {
410       set r [expr {[lrange $ans 0 1]=="0000000000 1111111111"}]
411    }
412  } {1}
413  do_test shared_malloc-8.$::n.cleanup.2 {
414    set rc1 [sqlite3_step $::STMT]
415    set rc2 [sqlite3_finalize $::STMT]
416    if {$rc2=="SQLITE_ABORT"} {
417      incr ::aborted
418    }
419    expr {
420      ($rc1=="SQLITE_DONE" && $rc2=="SQLITE_OK") ||
421      ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_ABORT") ||
422      ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_NOMEM") ||
423      ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_IOERR")
424    }
425  } {1}
426  db2 close
427}
428do_test shared_malloc-8.X {
429  # Test that one or more queries were aborted due to the malloc() failure.
430  expr $::aborted>=1
431} {1}
432
433# This test is designed to catch a specific bug that was present during
434# development of 3.5.0. If a malloc() failed while setting the page-size,
435# a buffer (Pager.pTmpSpace) was being freed. This could cause a seg-fault
436# later if another connection tried to use the pager.
437#
438# This test will crash 3.4.2.
439#
440do_malloc_test shared_err-9 -tclprep {
441  sqlite3 db2 test.db
442} -sqlbody {
443  PRAGMA page_size = 4096;
444  PRAGMA page_size = 1024;
445} -cleanup {
446  db2 eval {
447    CREATE TABLE abc(a, b, c);
448    BEGIN;
449    INSERT INTO abc VALUES(1, 2, 3);
450    ROLLBACK;
451  }
452  db2 close
453}
454
455catch {db close}
456catch {db2 close}
457do_malloc_test shared_err-10 -tclprep {
458  sqlite3 db test.db
459  sqlite3 db2 test.db
460
461  db eval { SELECT * FROM sqlite_master }
462  db2 eval {
463    BEGIN;
464    CREATE TABLE abc(a, b, c);
465  }
466} -tclbody {
467  catch {db eval {SELECT * FROM sqlite_master}}
468  error 1
469} -cleanup {
470  execsql { SELECT * FROM sqlite_master }
471}
472
473do_malloc_test shared_err-11 -tclprep {
474  sqlite3 db test.db
475  sqlite3 db2 test.db
476
477  db eval { SELECT * FROM sqlite_master }
478  db2 eval {
479    BEGIN;
480    CREATE TABLE abc(a, b, c);
481  }
482} -tclbody {
483  catch {db eval {SELECT * FROM sqlite_master}}
484  catch {sqlite3_errmsg16 db}
485  error 1
486} -cleanup {
487  execsql { SELECT * FROM sqlite_master }
488}
489
490catch {db close}
491catch {db2 close}
492
493do_malloc_test shared_err-12 -sqlbody {
494  CREATE TABLE abc(a, b, c);
495  INSERT INTO abc VALUES(1, 2, 3);
496}
497
498catch {db close}
499catch {db2 close}
500sqlite3_enable_shared_cache $::enable_shared_cache
501finish_test
502