SQLite

Check-in [255d21499b]
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
Timelines: family | ancestors | descendants | both | experimental
Files: files | file ages | folders
SHA1: 255d21499bab19ad865cd769eef49317eb9ab0ec
User & Date: dan 2011-12-13 11:15:13.591
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: eb95d2f72c 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: 199f52bced 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: 255d21499b 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: 169e12295c user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/test_multiplex.c.
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830



831

832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
/* Pass xFileSize requests through to the original VFS.
** Aggregate the size of all the chunks before returning.
*/
static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){
  multiplexConn *p = (multiplexConn*)pConn;
  multiplexGroup *pGroup = p->pGroup;
  int rc = SQLITE_OK;
  int rc2;
  int i;
  multiplexEnter();
  if( !pGroup->bEnabled ){
    sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL);
    if( pSubOpen==0 ){
      rc = SQLITE_IOERR_FSTAT;
    }else{
      rc = pSubOpen->pMethods->xFileSize(pSubOpen, pSize);
    }
  }else{
    sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;
    *pSize = 0;
    for(i=0; 1; i++){
      sqlite3_file *pSubOpen = 0;
      int exists = 0;
      rc = multiplexSubFilename(pGroup, i);
      if( rc ) break;
      if( pGroup->flags & SQLITE_OPEN_DELETEONCLOSE ){
        exists = pGroup->nReal>=i && pGroup->aReal[i].p!=0;
        rc2 = SQLITE_OK;
      }else{
        rc2 = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[i].z,
            SQLITE_ACCESS_EXISTS, &exists);
      }
      if( rc2==SQLITE_OK && exists){
        /* if it exists, open it */
        pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL);
      }else{
        /* stop at first "gap" */
        break;
      }



      if( pSubOpen ){

        sqlite3_int64 sz;
        rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz);
        if( rc2!=SQLITE_OK ){
          rc = rc2;
        }else{
          if( sz>pGroup->szChunk ){
            rc = SQLITE_IOERR_FSTAT;
          }
          *pSize += sz;
        }
      }else{
        break;
      }
    }
  }
  multiplexLeave();
  return rc;
}








<












|



|
<
|
|

|
|

<
|
<
<
|


>
>
>
|
>
|
|
<
<
<
|
|
|
|
<
<
<







792
793
794
795
796
797
798

799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815

816
817
818
819
820
821

822


823
824
825
826
827
828
829
830
831
832



833
834
835
836



837
838
839
840
841
842
843
/* Pass xFileSize requests through to the original VFS.
** Aggregate the size of all the chunks before returning.
*/
static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){
  multiplexConn *p = (multiplexConn*)pConn;
  multiplexGroup *pGroup = p->pGroup;
  int rc = SQLITE_OK;

  int i;
  multiplexEnter();
  if( !pGroup->bEnabled ){
    sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL);
    if( pSubOpen==0 ){
      rc = SQLITE_IOERR_FSTAT;
    }else{
      rc = pSubOpen->pMethods->xFileSize(pSubOpen, pSize);
    }
  }else{
    sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;
    *pSize = 0;
    for(i=0; rc==SQLITE_OK; i++){
      sqlite3_file *pSubOpen = 0;
      int exists = 0;
      rc = multiplexSubFilename(pGroup, i);
      if( rc!=SQLITE_OK ) break;

      if( pGroup->nReal>i && pGroup->aReal[i].p!=0 ){
        exists = 1;
      }else{
        const char *zReal = pGroup->aReal[i].z;
        rc = pOrigVfs->xAccess(pOrigVfs, zReal, SQLITE_ACCESS_EXISTS, &exists);
      }

      if( exists==0 ){


        /* stop at first "gap" or IO error. */
        break;
      }
      if( rc==SQLITE_OK ){
        pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL);
      }
      assert( pSubOpen || rc!=SQLITE_OK );
      if( rc==SQLITE_OK ){
        sqlite3_int64 sz = 0;
        rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz);



        if( rc==SQLITE_OK && sz>pGroup->szChunk ){
          rc = SQLITE_IOERR_FSTAT;
        }
        *pSize += sz;



      }
    }
  }
  multiplexLeave();
  return rc;
}

Changes to test/multiplex.test.
9
10
11
12
13
14
15










16
17
18
19
20
21
22
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl











set g_chunk_size [ expr ($::SQLITE_MAX_PAGE_SIZE*16384) ]
set g_max_chunks 32

# This handles appending the chunk number
# to the end of the filename.  if 
# SQLITE_MULTIPLEX_EXT_OVWR is defined, then







>
>
>
>
>
>
>
>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl

# The tests in this file assume that SQLite is compiled without
# ENABLE_8_3_NAMES.
#
ifcapable 8_3_names {
  puts -nonewline "SQLite compiled with SQLITE_ENABLE_8_3_NAMES. "
  puts            "Skipping tests multiplex-*."
  finish_test
  return
}

set g_chunk_size [ expr ($::SQLITE_MAX_PAGE_SIZE*16384) ]
set g_max_chunks 32

# This handles appending the chunk number
# to the end of the filename.  if 
# SQLITE_MULTIPLEX_EXT_OVWR is defined, then
Added test/multiplex3.test.






































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

# 2011 December 13
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests for error (IO, OOM etc.) handling when using
# the multiplexor extension with 8.3 filenames.
#

set testdir $env(SQLITE_TEST_DIR)
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
set ::testprefix multiplex3

ifcapable !8_3_names {
  puts -nonewline "SQLite compiled without SQLITE_ENABLE_8_3_NAMES. "
  puts            "Skipping tests zipvfsD-*."
  finish_test
  return
}

db close
sqlite3_shutdown
sqlite3_config_uri 1
autoinstall_test_functions

sqlite3_multiplex_initialize "" 1

proc destroy_vfs_stack {} {
  generic_unregister stack
  sqlite3_multiplex_shutdown
}

proc multiplex_delete_db {} {
  forcedelete test.db
  for {set i 1} {$i <= 1000} {incr i} {
    forcedelete test.[format %03d $i]
  }
}

# Procs to save and restore the current muliplexed database.
#
proc multiplex_save_db {} {
  foreach f [glob -nocomplain sv_test.*] { forcedelete $f }
  foreach f [glob -nocomplain test.*]    { forcecopy $f "sv_$f" }
}
proc multiplex_restore_db {} {
  foreach f [glob -nocomplain test.*]    {forcedelete $f}
  foreach f [glob -nocomplain sv_test.*] {forcecopy $f [string range $f 3 end]} }


do_test 1.0 {
  multiplex_delete_db
  sqlite3 db file:test.db?8_3_names=1
  sqlite3_multiplex_control db main chunk_size [expr 256*1024]
  execsql {
    CREATE TABLE t1(a PRIMARY KEY, b);
    INSERT INTO t1 VALUES(randomblob(15), randomblob(2000));
    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --   2
    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --   4
    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --   8
    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --  16
    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --  32
    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --  64
    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    -- 128
    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    -- 256
    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    -- 512
  }
  set ::cksum1 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}]
  db close
  multiplex_save_db
} {}

do_faultsim_test 1 -prep {
  multiplex_restore_db
  sqlite3 db file:test.db?8_3_names=1
  sqlite3_multiplex_control db main chunk_size [expr 256*1024]
} -body {
  execsql "UPDATE t1 SET a=randomblob(12), b=randomblob(1500) WHERE (rowid%32)=0"
} -test {
  faultsim_test_result {0 {}}
  if {$testrc!=0} {
    set cksum2 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}]
    if {$cksum2 != $::cksum1} { error "data mismatch" }
  }
}

catch { db close }

sqlite3_multiplex_shutdown
finish_test