/ Check-in [b9170f29]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Modify the code for reading hot-journal files so that it can handle journals generated by versions 3.5.7 and earlier.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b9170f2903c480bca2bdc986e98aaeadfdb9ad2b
User & Date: dan 2010-08-19 15:11:34
Context
2010-08-19
15:12
Merge two leaves. check-in: b03091fc user: dan tags: trunk
15:11
Modify the code for reading hot-journal files so that it can handle journals generated by versions 3.5.7 and earlier. check-in: b9170f29 user: dan tags: trunk
11:05
Add new test script backcompat.test, for testing database/journal/wal file compatibility against previous versions. check-in: 8804f498 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/pager.c.

  1504   1504   
  1505   1505       /* Read the page-size and sector-size journal header fields. */
  1506   1506       if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize))
  1507   1507        || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize))
  1508   1508       ){
  1509   1509         return rc;
  1510   1510       }
         1511  +
         1512  +    /* Versions of SQLite prior to 3.5.8 set the page-size field of the
         1513  +    ** journal header to zero. In this case, assume that the Pager.pageSize
         1514  +    ** variable is already set to the correct page size.
         1515  +    */
         1516  +    if( iPageSize==0 ){
         1517  +      iPageSize = pPager->pageSize;
         1518  +    }
  1511   1519   
  1512   1520       /* Check that the values read from the page-size and sector-size fields
  1513   1521       ** are within range. To be 'in range', both values need to be a power
  1514   1522       ** of two greater than or equal to 512 or 32, and not greater than their 
  1515   1523       ** respective compile time maximum limits.
  1516   1524       */
  1517   1525       if( iPageSize<512                  || iSectorSize<32

Changes to test/backcompat.test.

    23     23   # for documentation of the available commands.
    24     24   #
    25     25   
    26     26   set testdir [file dirname $argv0]
    27     27   source $testdir/tester.tcl
    28     28   source $testdir/lock_common.tcl
    29     29   source $testdir/malloc_common.tcl
           30  +db close
    30     31   
    31     32   # Search for binaries to test against. Any executable files that match
    32     33   # our naming convention are assumed to be testfixture binaries to test
    33     34   # against.
    34     35   #
    35     36   set binaries [list]
    36         -set pattern "[file tail [info nameofexec]]?*"
           37  +set pattern "[file tail [info nameofexec]]*"
    37     38   foreach file [glob $pattern] {
    38     39     if {[file executable $file]} {lappend binaries $file}
    39     40   }
    40     41   if {[llength $binaries]==0} {
    41     42     puts "WARNING: No binaries to test against. No tests have been run."
    42     43     finish_test
    43     44     return
................................................................................
    48     49     close $chan
    49     50     set v
    50     51   }
    51     52   foreach bin $binaries {
    52     53     puts "Testing against $bin - version [get_version $bin]"
    53     54   }
    54     55   
    55         -#set binaries testfixture
           56  +proc do_backcompat_test {rv bin1 bin2 script} {
    56     57   
    57         -proc do_backcompat_test {rv binary script} {
           58  +  file delete -force test.db
           59  +
           60  +  if {$bin1 != ""} { set ::bc_chan1 [launch_testfixture $bin1] }
           61  +  set ::bc_chan2 [launch_testfixture $bin2]
    58     62   
    59     63     if { $rv } {
    60         -    proc code1 {tcl} { testfixture $::bc_chan $tcl }
    61     64       proc code2 {tcl} { uplevel #0 $tcl }
           65  +    if {$bin1 != ""} { proc code2 {tcl} { testfixture $::bc_chan1 $tcl } }
           66  +    proc code1 {tcl} { testfixture $::bc_chan2 $tcl }
    62     67     } else {
    63     68       proc code1 {tcl} { uplevel #0 $tcl }
    64         -    proc code2 {tcl} { testfixture $::bc_chan $tcl }
           69  +    if {$bin1 != ""} { proc code1 {tcl} { testfixture $::bc_chan1 $tcl } }
           70  +    proc code2 {tcl} { testfixture $::bc_chan2 $tcl }
    65     71     }
    66     72   
    67     73     proc sql1 sql { code1 [list db eval $sql] }
    68     74     proc sql2 sql { code2 [list db eval $sql] }
    69     75   
    70         -  file delete -force test.db
    71         -
    72         -  set ::bc_chan [launch_testfixture $binary]
    73     76     code1 { sqlite3 db test.db }
    74     77     code2 { sqlite3 db test.db }
    75     78   
    76     79     uplevel $script
    77     80   
    78     81     catch { code1 { db close } }
    79     82     catch { code2 { db close } }
    80         -  catch { close $::bc_chan }
           83  +  catch { close $::bc_chan2 }
           84  +  catch { close $::bc_chan1 }
    81     85   }
    82     86   
    83     87   array set ::incompatible [list]
    84     88   proc do_allbackcompat_test {script} {
    85     89   
    86     90     foreach bin $::binaries {
    87     91       set nErr [set_test_counter errors]
    88     92       foreach dir {0 1} {
    89     93   
    90         -      set ::bcname ".$dir.[string map {testfixture {}} $bin]."
           94  +      set ::bcname ".[string map {testfixture {}} $bin].$dir."
    91     95   
    92     96         rename do_test _do_test
    93     97         proc do_test {nm sql res} {
    94     98           set nm [regsub {\.} $nm $::bcname]
    95     99           uplevel [list _do_test $nm $sql $res]
    96    100         }
    97    101   
    98         -      do_backcompat_test $dir $bin $script
          102  +      do_backcompat_test $dir {} $bin $script
    99    103   
   100    104         rename do_test {}
   101    105         rename _do_test do_test
   102    106       }
   103    107       if { $nErr < [set_test_counter errors] } {
   104    108         set ::incompatible([get_version $bin]) 1
   105    109       }
................................................................................
   153    157     do_test backcompat-1.1.4 { sql1 { SELECT * FROM t1; } } {abc def ghi jkl}
   154    158     do_test backcompat-1.1.5 { sql1 { PRAGMA integrity_check } } {ok}
   155    159     do_test backcompat-1.1.6 { sql2 { PRAGMA integrity_check } } {ok}
   156    160   
   157    161     # Test that one version can roll back a hot-journal file left in the
   158    162     # file-system by the other version.
   159    163     #
          164  +  # Each test case is named "backcompat-1.X...", where X is either 0 or
          165  +  # 1. If it is 0, then the current version creates a journal file that
          166  +  # the old versions try to read. Otherwise, if X is 1, then the old version
          167  +  # creates the journal file and we try to read it with the current version.
          168  +  #
   160    169     do_test backcompat-1.2.1 { sql1 {
   161    170       PRAGMA cache_size = 10;
   162    171       BEGIN;
   163    172         INSERT INTO t1 VALUES(randomblob(400), randomblob(400));
   164    173         INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM t1;
   165    174         INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM t1;
   166    175         INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM t1;
................................................................................
   172    181     do_test backcompat-1.2.2 [list string compare $cksum1 $cksum2] 0
   173    182   
   174    183     do_test backcompat-1.2.3 { sql1 {
   175    184       BEGIN;
   176    185         UPDATE t1 SET a = randomblob(500);
   177    186     } } {}
   178    187     set data [read_file_system]
          188  +
          189  +  set f "test.db-journal[incr x]"
          190  +  file copy -force test.db-journal $f
          191  +
   179    192     do_test backcompat-1.2.4 { sql1 { COMMIT } } {}
   180    193   
   181    194     set same [expr {[sql2 {SELECT md5sum(a), md5sum(b) FROM t1}] == $cksum2}]
   182    195     do_test backcompat-1.2.5 [list set {} $same] 0
   183    196   
          197  +  code1 { db close }
          198  +  code2 { db close }
   184    199     write_file_system $data
          200  +  code1 { sqlite3 db test.db }
          201  +  code2 { sqlite3 db test.db }
          202  +
   185    203     set same [expr {[sql2 {SELECT md5sum(a), md5sum(b) FROM t1}] == $cksum2}]
   186    204     do_test backcompat-1.2.6 [list set {} $same] 1
   187    205   
   188         -  do_test backcompat-1.2.7 { sql2 { PRAGMA integrity_check } } {ok}
          206  +  do_test backcompat-1.2.7 { sql1 { PRAGMA integrity_check } } {ok}
   189    207     do_test backcompat-1.2.8 { sql2 { PRAGMA integrity_check } } {ok}
   190    208   }
   191    209   
   192    210   foreach k [lsort [array names ::incompatible]] {
   193    211     puts "ERROR: Detected incompatibility with version $k"
   194    212   }
   195    213   
   196    214   finish_test