]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add a hard limit to the number of chunks a multiplexed database may consist of if...
authordan <dan@noemail.net>
Tue, 13 Dec 2011 19:03:34 +0000 (19:03 +0000)
committerdan <dan@noemail.net>
Tue, 13 Dec 2011 19:03:34 +0000 (19:03 +0000)
FossilOrigin-Name: 43a1264088c57bf598787b7a9f5d7a2536603d67

manifest
manifest.uuid
src/test_multiplex.c
test/multiplex2.test

index 3dc07e0bd54dd91cf0fa7cecf1425085ae7cc8f6..82b9fafa495158f458444b2aafb06770634a9678 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Change\sthe\sSQLITE_EXTRA_INIT\sroutine\sto\stake\sa\ssingle\sargument\swhich\sis\sa\npointer\sto\sa\sstring.\s\sCall\sSQLITE_EXTRA_INIT\swith\sa\sNULL\sargument.\nFixes\sto\smultiplexor\sto\streat\sthe\sVFS\sproperly\sin\scorner\scases.\s\sFix\sthe\ninitialization\sof\smultiplex3.test.
-D 2011-12-13T18:22:38.364
+C Add\sa\shard\slimit\sto\sthe\snumber\sof\schunks\sa\smultiplexed\sdatabase\smay\sconsist\sof\sif\sENABLE_8_3_NAMES\sis\sdefined.
+D 2011-12-13T19:03:34.498
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207
 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff
 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
 F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5
-F src/test_multiplex.c c8cfaa7fa15494454a39c7e79241760d5fbe2c0c
+F src/test_multiplex.c 10f881e4508976d970569fe0e7779bfec17907e5
 F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d
 F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e
 F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec
@@ -606,7 +606,7 @@ F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
 F test/misc7.test eafaa41b9133d7a2ded4641bbe5f340731d35a52
 F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054
 F test/multiplex.test 8bc3c71f73fe833bc8a659d454d320044a33b5da
-F test/multiplex2.test 7e507a63f3981731556224b23646d29013b98c03
+F test/multiplex2.test 896ff138d27688b68c894b8166606454ce915793
 F test/multiplex3.test e17b73e904dbd789de37192b6b94424e6f847bc3
 F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41
 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
@@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P c7de6f683d0fec62bc138b4a53b5cccc80c736c3
-R c2c58817769bc21d103f97b44c17e047
-U drh
-Z e8a8ea3bf562796b70179d1fa7b7b6fa
+P 8e65b9132530e46c62bd1352bfc2e9c29f57af5f
+R 72e3acbb02cd24af246addd5a37e5bd0
+U dan
+Z bb7ad67fc331d74f2be1df794e13fcc3
index 8aab40e31892f335472f06475e805deb808230d8..97f853f6e501ade96c3bf3992be95f060ab0bc88 100644 (file)
@@ -1 +1 @@
-8e65b9132530e46c62bd1352bfc2e9c29f57af5f
\ No newline at end of file
+43a1264088c57bf598787b7a9f5d7a2536603d67
\ No newline at end of file
index 0208d2d98df826df8eb9d8ec2f4d8a064287f074..85b63b48f4ae91aaa27e7282b7dedf84d5461c45 100644 (file)
@@ -81,6 +81,8 @@
 #define sqlite3_mutex_notheld(X)  ((void)(X),1)
 #endif /* SQLITE_THREADSAFE==0 */
 
+#define SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET 400
+
 
 /************************ Shim Definitions ******************************/
 
@@ -97,7 +99,7 @@
 #endif
 
 /* This used to be the default limit on number of chunks, but
-** it is no longer enforced.  There is currently no limit to the
+** it is no longer enforced. There is currently no limit to the
 ** number of chunks.
 **
 ** May be changed by calling the xFileControl() interface.
@@ -244,7 +246,7 @@ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){
         ** 003 and so forth.  To avoid name collisions, add 100 to the 
         ** extensions of journal files so that they are 101, 102, 103, ....
         */
-        iChunk += 100;
+        iChunk += SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET;
       }
 #endif
       sqlite3_snprintf(4,&z[n],"%03d",iChunk);
@@ -264,6 +266,18 @@ static sqlite3_file *multiplexSubOpen(
 ){
   sqlite3_file *pSubOpen = 0;
   sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;        /* Real VFS */
+
+#ifdef SQLITE_ENABLE_8_3_NAMES
+  /* If JOURNAL_8_3_OFFSET is set to (say) 500, then any overflow files are 
+  ** part of a database journal are named db.501, db.502, and so on. A 
+  ** database may therefore not grow to larger than 500 chunks. Attempting
+  ** to open chunk 501 indicates the database is full. */
+  if( iChunk>=SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET ){
+    *rc = SQLITE_FULL;
+    return 0;
+  }
+#endif
+
   *rc = multiplexSubFilename(pGroup, iChunk);
   if( (*rc)==SQLITE_OK && (pSubOpen = pGroup->aReal[iChunk].p)==0 ){
     pSubOpen = sqlite3_malloc( pOrigVfs->szOsFile );
@@ -633,7 +647,7 @@ static int multiplexWrite(
       rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst);
     }
   }else{
-    while( iAmt > 0 ){
+    while( rc==SQLITE_OK && iAmt>0 ){
       int i = (int)(iOfst / pGroup->szChunk);
       sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL);
       if( pSubOpen ){
@@ -643,13 +657,9 @@ static int multiplexWrite(
         iAmt -= extra;
         rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt,
                                         iOfst % pGroup->szChunk);
-        if( rc!=SQLITE_OK ) break;
         pBuf = (char *)pBuf + iAmt;
         iOfst += iAmt;
         iAmt = extra;
-      }else{
-        rc = SQLITE_IOERR_WRITE;
-        break;
       }
     }
   }
index b3a1656b02172b6ca6f2e721a2e8c59948caf295..bf5791fe88d53b79b68166d98619fd87dc197a92 100644 (file)
@@ -14,6 +14,7 @@ set testdir [file dirname $argv0]
 source $testdir/tester.tcl
 source $testdir/malloc_common.tcl
 source $testdir/lock_common.tcl
+set testprefix multiplex2
 db close
 
 do_multiclient_test tn {
@@ -46,10 +47,10 @@ do_multiclient_test tn {
     SELECT count(*) FROM t1;
   } 
 
-  do_test multiplex-1.$tn.1 { sql1 { SELECT count(*) FROM t1 } } 512
-  do_test multiplex-1.$tn.2 { sql2 { SELECT count(*) FROM t1 } } 512
+  do_test 1.$tn.1 { sql1 { SELECT count(*) FROM t1 } } 512
+  do_test 1.$tn.2 { sql2 { SELECT count(*) FROM t1 } } 512
   sql2 { DELETE FROM t1 ; VACUUM }
-  do_test multiplex-1.$tn.3 { sql1 { SELECT count(*) FROM t1 } } 0
+  do_test 1.$tn.3 { sql1 { SELECT count(*) FROM t1 } } 0
 
   sql1 {
     INSERT INTO t1 VALUES(randomblob(10), randomblob(4000));          --    1
@@ -65,8 +66,54 @@ do_multiclient_test tn {
     SELECT count(*) FROM t1;
   }
 
-  do_test multiplex-1.$tn.4 { sql2 { SELECT count(*) FROM t1 } } 512
+  do_test 1.$tn.4 { sql2 { SELECT count(*) FROM t1 } } 512
 }
 
+catch {db close}
+foreach f [glob -nocomplain test.*] { forcedelete $f }
+
+ifcapable 8_3_names {
+  sqlite3 db test.db -vfs multiplex
+  sqlite3_multiplex_control db main chunk_size [expr 256*1024]
+
+  # Insert 512 * 256K (128MB) of data. If each row is around 4K, this means
+  # we need 32768 rows.
+  do_catchsql_test 2.1 {
+    CREATE TABLE t1(a, b);
+    INSERT INTO t1 VALUES(randomblob(10), randomblob(4000));          --    1
+    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --    2
+    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --    4
+    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --    8
+    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   16
+    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   32
+    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   64
+    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  128
+    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  256
+    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  512
+
+    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   1K
+    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   2K
+    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   4K
+    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   8K
+    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  16K
+    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  32K
+  
+  } {1 {database or disk is full}}
+
+  do_execsql_test 2.2 {
+    UPDATE t1 SET a=randomblob(9), b=randomblob(3900);
+    PRAGMA integrity_check;
+  } ok
+
+  db close
+  sqlite3 db test.db -vfs multiplex
+  sqlite3_multiplex_control db main chunk_size [expr 256*1024]
+
+  do_execsql_test 2.3 {
+    PRAGMA integrity_check;
+  } ok
+}
+
+catch { db close }
 catch { sqlite3_multiplex_shutdown }
 finish_test