/ Check-in [255d2149]
Login

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

Overview
Comment:Change the way IO errors are handled in the xFileSize method of the multiplexor VFS. Add test file multiplex3.test.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental
Files: files | file ages | folders
SHA1:255d21499bab19ad865cd769eef49317eb9ab0ec
User & Date: dan 2011-12-13 11:15:13
References
2011-12-13
15:02
Move the multiplexor changes in the experimental branch (check-ins [255d21499b] and [199f52bced]) into the nx-devkit branch. check-in: eb95d2f7 user: drh tags: nx-devkit
Context
2011-12-13
12:10
This branch merged with nx-devkit and from there into trunk. Was: In the multiplexor, instead of generating a unique file-name when SQLite opens a temp file, allow the underlying VFS to generate a different temp file for each chunk. Given the changes to the xFileSize method, it is no longer necessary for the different chunks of a temp file to use the same base name. Closed-Leaf check-in: 199f52bc user: dan tags: experimental
11:15
Change the way IO errors are handled in the xFileSize method of the multiplexor VFS. Add test file multiplex3.test. check-in: 255d2149 user: dan tags: experimental
2011-12-12
19:48
Fix os_unix.c so that, unless 8.3 filenames are actually in use, journal and wal file permissions are assigned correctly even if SQLITE_ENABLE_8_3_NAMES is defined. check-in: 169e1229 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/test_multiplex.c.

   792    792   /* Pass xFileSize requests through to the original VFS.
   793    793   ** Aggregate the size of all the chunks before returning.
   794    794   */
   795    795   static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){
   796    796     multiplexConn *p = (multiplexConn*)pConn;
   797    797     multiplexGroup *pGroup = p->pGroup;
   798    798     int rc = SQLITE_OK;
   799         -  int rc2;
   800    799     int i;
   801    800     multiplexEnter();
   802    801     if( !pGroup->bEnabled ){
   803    802       sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL);
   804    803       if( pSubOpen==0 ){
   805    804         rc = SQLITE_IOERR_FSTAT;
   806    805       }else{
   807    806         rc = pSubOpen->pMethods->xFileSize(pSubOpen, pSize);
   808    807       }
   809    808     }else{
   810    809       sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;
   811    810       *pSize = 0;
   812         -    for(i=0; 1; i++){
          811  +    for(i=0; rc==SQLITE_OK; i++){
   813    812         sqlite3_file *pSubOpen = 0;
   814    813         int exists = 0;
   815    814         rc = multiplexSubFilename(pGroup, i);
   816         -      if( rc ) break;
   817         -      if( pGroup->flags & SQLITE_OPEN_DELETEONCLOSE ){
   818         -        exists = pGroup->nReal>=i && pGroup->aReal[i].p!=0;
   819         -        rc2 = SQLITE_OK;
          815  +      if( rc!=SQLITE_OK ) break;
          816  +      if( pGroup->nReal>i && pGroup->aReal[i].p!=0 ){
          817  +        exists = 1;
   820    818         }else{
   821         -        rc2 = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[i].z,
   822         -            SQLITE_ACCESS_EXISTS, &exists);
          819  +        const char *zReal = pGroup->aReal[i].z;
          820  +        rc = pOrigVfs->xAccess(pOrigVfs, zReal, SQLITE_ACCESS_EXISTS, &exists);
   823    821         }
   824         -      if( rc2==SQLITE_OK && exists){
   825         -        /* if it exists, open it */
   826         -        pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL);
   827         -      }else{
   828         -        /* stop at first "gap" */
          822  +      if( exists==0 ){
          823  +        /* stop at first "gap" or IO error. */
   829    824           break;
   830    825         }
   831         -      if( pSubOpen ){
   832         -        sqlite3_int64 sz;
   833         -        rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz);
   834         -        if( rc2!=SQLITE_OK ){
   835         -          rc = rc2;
   836         -        }else{
   837         -          if( sz>pGroup->szChunk ){
   838         -            rc = SQLITE_IOERR_FSTAT;
   839         -          }
   840         -          *pSize += sz;
          826  +      if( rc==SQLITE_OK ){
          827  +        pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL);
          828  +      }
          829  +      assert( pSubOpen || rc!=SQLITE_OK );
          830  +      if( rc==SQLITE_OK ){
          831  +        sqlite3_int64 sz = 0;
          832  +        rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz);
          833  +        if( rc==SQLITE_OK && sz>pGroup->szChunk ){
          834  +          rc = SQLITE_IOERR_FSTAT;
   841    835           }
   842         -      }else{
   843         -        break;
          836  +        *pSize += sz;
   844    837         }
   845    838       }
   846    839     }
   847    840     multiplexLeave();
   848    841     return rc;
   849    842   }
   850    843   

Changes to test/multiplex.test.

     9      9   #
    10     10   #***********************************************************************
    11     11   #
    12     12   
    13     13   set testdir [file dirname $argv0]
    14     14   source $testdir/tester.tcl
    15     15   source $testdir/malloc_common.tcl
           16  +
           17  +# The tests in this file assume that SQLite is compiled without
           18  +# ENABLE_8_3_NAMES.
           19  +#
           20  +ifcapable 8_3_names {
           21  +  puts -nonewline "SQLite compiled with SQLITE_ENABLE_8_3_NAMES. "
           22  +  puts            "Skipping tests multiplex-*."
           23  +  finish_test
           24  +  return
           25  +}
    16     26   
    17     27   set g_chunk_size [ expr ($::SQLITE_MAX_PAGE_SIZE*16384) ]
    18     28   set g_max_chunks 32
    19     29   
    20     30   # This handles appending the chunk number
    21     31   # to the end of the filename.  if 
    22     32   # SQLITE_MULTIPLEX_EXT_OVWR is defined, then

Added test/multiplex3.test.

            1  +
            2  +# 2011 December 13
            3  +#
            4  +# The author disclaims copyright to this source code.  In place of
            5  +# a legal notice, here is a blessing:
            6  +#
            7  +#    May you do good and not evil.
            8  +#    May you find forgiveness for yourself and forgive others.
            9  +#    May you share freely, never taking more than you give.
           10  +#
           11  +#***********************************************************************
           12  +#
           13  +# This file contains tests for error (IO, OOM etc.) handling when using
           14  +# the multiplexor extension with 8.3 filenames.
           15  +#
           16  +
           17  +set testdir $env(SQLITE_TEST_DIR)
           18  +source $testdir/tester.tcl
           19  +source $testdir/malloc_common.tcl
           20  +set ::testprefix multiplex3
           21  +
           22  +ifcapable !8_3_names {
           23  +  puts -nonewline "SQLite compiled without SQLITE_ENABLE_8_3_NAMES. "
           24  +  puts            "Skipping tests zipvfsD-*."
           25  +  finish_test
           26  +  return
           27  +}
           28  +
           29  +db close
           30  +sqlite3_shutdown
           31  +sqlite3_config_uri 1
           32  +autoinstall_test_functions
           33  +
           34  +sqlite3_multiplex_initialize "" 1
           35  +
           36  +proc destroy_vfs_stack {} {
           37  +  generic_unregister stack
           38  +  sqlite3_multiplex_shutdown
           39  +}
           40  +
           41  +proc multiplex_delete_db {} {
           42  +  forcedelete test.db
           43  +  for {set i 1} {$i <= 1000} {incr i} {
           44  +    forcedelete test.[format %03d $i]
           45  +  }
           46  +}
           47  +
           48  +# Procs to save and restore the current muliplexed database.
           49  +#
           50  +proc multiplex_save_db {} {
           51  +  foreach f [glob -nocomplain sv_test.*] { forcedelete $f }
           52  +  foreach f [glob -nocomplain test.*]    { forcecopy $f "sv_$f" }
           53  +}
           54  +proc multiplex_restore_db {} {
           55  +  foreach f [glob -nocomplain test.*]    {forcedelete $f}
           56  +  foreach f [glob -nocomplain sv_test.*] {forcecopy $f [string range $f 3 end]} }
           57  +
           58  +
           59  +do_test 1.0 {
           60  +  multiplex_delete_db
           61  +  sqlite3 db file:test.db?8_3_names=1
           62  +  sqlite3_multiplex_control db main chunk_size [expr 256*1024]
           63  +  execsql {
           64  +    CREATE TABLE t1(a PRIMARY KEY, b);
           65  +    INSERT INTO t1 VALUES(randomblob(15), randomblob(2000));
           66  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --   2
           67  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --   4
           68  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --   8
           69  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --  16
           70  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --  32
           71  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --  64
           72  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    -- 128
           73  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    -- 256
           74  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    -- 512
           75  +  }
           76  +  set ::cksum1 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}]
           77  +  db close
           78  +  multiplex_save_db
           79  +} {}
           80  +
           81  +do_faultsim_test 1 -prep {
           82  +  multiplex_restore_db
           83  +  sqlite3 db file:test.db?8_3_names=1
           84  +  sqlite3_multiplex_control db main chunk_size [expr 256*1024]
           85  +} -body {
           86  +  execsql "UPDATE t1 SET a=randomblob(12), b=randomblob(1500) WHERE (rowid%32)=0"
           87  +} -test {
           88  +  faultsim_test_result {0 {}}
           89  +  if {$testrc!=0} {
           90  +    set cksum2 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}]
           91  +    if {$cksum2 != $::cksum1} { error "data mismatch" }
           92  +  }
           93  +}
           94  +
           95  +catch { db close }
           96  +
           97  +sqlite3_multiplex_shutdown
           98  +finish_test
           99  +