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