github.com/jdgcs/sqlite3@v1.12.1-0.20210908114423-bc5f96e4dd51/testdata/tcl/shared_err.test (about)

     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  
    18  proc skip {args} {}
    19  
    20  
    21  set testdir [file dirname $argv0]
    22  source $testdir/tester.tcl
    23  source $testdir/malloc_common.tcl
    24  db close
    25  
    26  ifcapable !shared_cache||!subquery {
    27    finish_test
    28    return
    29  }
    30  
    31  set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
    32  
    33  do_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  
    86  do_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  # 
   148  do_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  # 
   227  do_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  # 
   312  do_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  
   352  do_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  
   363  do_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  # 
   390  set ::aborted 0
   391  do_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  #
   454  do_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  #
   467  do_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  
   482  catch {db close}
   483  catch {db2 close}
   484  do_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  
   500  do_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  
   517  catch {db close}
   518  catch {db2 close}
   519  
   520  do_malloc_test shared_err-12 -sqlbody {
   521    CREATE TABLE abc(a, b, c);
   522    INSERT INTO abc VALUES(1, 2, 3);
   523  }
   524  
   525  catch {db close}
   526  catch {db2 close}
   527  sqlite3_enable_shared_cache $::enable_shared_cache
   528  finish_test