]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix another couple of IO or malloc() failure problems in a shared-cache context....
authordanielk1977 <danielk1977@noemail.net>
Fri, 20 Jan 2006 16:32:04 +0000 (16:32 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Fri, 20 Jan 2006 16:32:04 +0000 (16:32 +0000)
FossilOrigin-Name: 7e34163a65a5842ecc50a14a9d60601e7c9d3249

manifest
manifest.uuid
src/btree.c
src/pager.c
src/vdbeapi.c
src/vdbeaux.c
test/malloc3.test
test/shared_err.test

index 7d13cd8bd509cecc89261bcd4a6930c74f2edf8b..f4677882cce0e4c13e4afc2b625bcb15fa4b1155 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sand\stest\sthe\sprocessing\sof\ssqlite3_result_error()\swithing\saggregate\nfunctions.\s\sAllow\serrors\sto\scome\sfrom\sthe\sstep\sfunction\s(a\snew\ncapability).\s\sTicket\s#1632.\s(CVS\s2981)
-D 2006-01-20T15:45:36
+C Fix\sanother\scouple\sof\sIO\sor\smalloc()\sfailure\sproblems\sin\sa\sshared-cache\scontext.\s(CVS\s2982)
+D 2006-01-20T16:32:04
 F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967
 F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -34,7 +34,7 @@ F src/alter.c 90b779cf00489535cab6490df6dc050f40e4e874
 F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a
 F src/attach.c 0081040e9a5d13669b6712e947688c10f030bfc1
 F src/auth.c 9ae84d2d94eb96195e04515715e08e85963e96c2
-F src/btree.c e8ff8d76a412299cad1c9a2c4e1fd15ad48bae27
+F src/btree.c 8b890e64b0ad7c510635244b75d65a97ee9f26ad
 F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184
 F src/build.c 15224e2fd348ad32b9044aaa5bdc912e4067da15
 F src/callback.c 1bf497306c32229114f826707054df7ebe10abf2
@@ -59,7 +59,7 @@ F src/os_unix.c a242a9458b08f01fa11d42b23bcdb89a3fbf2a68
 F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
 F src/os_win.c 98e4e38db7d4a00647b2bb1c60d28b7ca5034c03
 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
-F src/pager.c 49fab8c32de2419cb549220d285c6399bc0d899e
+F src/pager.c 39bf1957f8531c9056c8659048a4cdd949439d66
 F src/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f
 F src/parse.y 83df51fea35f68f7e07384d75dce83d1ed30434c
 F src/pragma.c 4496cc77dc35824e1c978c3d1413b8a5a4c777d3
@@ -90,8 +90,8 @@ F src/vacuum.c 3865673cc66acd0717ecd517f6b8fdb2a5e7924b
 F src/vdbe.c 9eceb866b8197d25d07f700e16b1a50638d4bd6e
 F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
 F src/vdbeInt.h eb3f86ab08ef11635bc78eb88c3ff13f923c233b
-F src/vdbeapi.c b5a3eacce266a657cdc0fc740b60ba480fb88649
-F src/vdbeaux.c d9a757ed4e3eefc54408226cb781694059fe2b39
+F src/vdbeapi.c 75eabedc09b3b2a6f2d256f85704b8b0cc0f50fa
+F src/vdbeaux.c 9d92640082c632ab2a48fa0b1763390a78573607
 F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
 F src/vdbemem.c 2034e93b32c14bda6e306bb54e3a8e930b963027
 F src/where.c 5215507b232e718606e0014f999912d53de32a70
@@ -189,7 +189,7 @@ F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
 F test/main.test b12f01d49a5c805a33fa6c0ef168691f63056e79
 F test/malloc.test ce6d1e7e79f9db967b51e1975b50760af66db90d
 F test/malloc2.test e6e321db96d6c94cb18bf82ad7215070c41e624e
-F test/malloc3.test 1cf2376c9495973608c021efaefb25e71bd6e21f
+F test/malloc3.test 5494b3fac35a2362584c97dc5655c2c3227c798a
 F test/malloc4.test 2e29d155eb4b4808019ef47eeedfcbe9e09e0f05
 F test/malloc5.test 7425272e263325fda7d32cb55706e52b5c09e7e0
 F test/manydb.test 8de36b8d33aab5ef295b11d9e95310aeded31af8
@@ -228,7 +228,7 @@ F test/select7.test 1bf795b948c133a15a2a5e99d3270e652ec58ce6
 F test/server1.test e328b8e641ba8fe9273132cfef497383185dc1f5
 F test/shared.test 9982a65ccf3f4eee844a19f3ab0bcd7a158a76e5
 F test/shared2.test 909fc0f0277684ed29cc1b36c8e159188aec7f28
-F test/shared_err.test dea32ad1ce72c1aa88a4671b5de3900961f6c687
+F test/shared_err.test f72c9fbe1802500f0d97e768f947ae5c703c0152
 F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
 F test/subquery.test ae324ee928c5fb463a3ce08a8860d6e7f1ca5797
 F test/subselect.test 2d13fb7f450db3595adcdd24079a0dd1d2d6abc2
@@ -344,7 +344,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 97491d4eb5fc24d8f5cc7605db844359ecc6a818
-R 0ac1c3b7951d8503eabc2e4f37bf1aac
-U drh
-Z 64f4b8a9886c6294a59c365b44cd61fd
+P fd4a6bb1ac94d085dda247799c0a5c64aaeec046
+R bde9ce22812627a378f8978bb7879372
+U danielk1977
+Z c8dd5ea23e29760f9b39f58f5d5d0fb8
index 103b23698e6a5bbc15cc1c55c6ad553739e3cd9d..5e2ee2f34c83ec58dad8cd89253644678a5e52c0 100644 (file)
@@ -1 +1 @@
-fd4a6bb1ac94d085dda247799c0a5c64aaeec046
\ No newline at end of file
+7e34163a65a5842ecc50a14a9d60601e7c9d3249
\ No newline at end of file
index 9471665b3c5cb9fe248534c82dc5ab7044966a1a..cd558f7f43ea305798bd8c164dc5f38177706bca 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.303 2006/01/20 10:55:05 danielk1977 Exp $
+** $Id: btree.c,v 1.304 2006/01/20 16:32:04 danielk1977 Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -506,6 +506,8 @@ struct BtLock {
 
 #else
 
+static void releasePage(MemPage *pPage);
+
 /*
 ** Save the current cursor position in the variables BtCursor.nKey 
 ** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
@@ -540,6 +542,8 @@ static int saveCursorPosition(BtCursor *pCur){
   assert( !pCur->pPage->intKey || !pCur->pKey );
 
   /* Todo: Should we drop the reference to pCur->pPage here? */
+  releasePage(pCur->pPage);
+  pCur->pPage = 0;
 
   if( rc==SQLITE_OK ){
     pCur->eState = CURSOR_REQUIRESEEK;
@@ -2617,12 +2621,15 @@ int sqlite3BtreeCommitStmt(Btree *p){
 ** will result in an error.
 */
 int sqlite3BtreeRollbackStmt(Btree *p){
-  int rc;
+  int rc = SQLITE_OK;
   BtShared *pBt = p->pBt;
-  if( pBt->inStmt==0 || pBt->readOnly ) return SQLITE_OK;
-  rc = sqlite3pager_stmt_rollback(pBt->pPager);
-  assert( countWriteCursors(pBt)==0 );
-  pBt->inStmt = 0;
+  sqlite3MallocDisallow();
+  if( pBt->inStmt && !pBt->readOnly ){
+    rc = sqlite3pager_stmt_rollback(pBt->pPager);
+    assert( countWriteCursors(pBt)==0 );
+    pBt->inStmt = 0;
+  }
+  sqlite3MallocAllow();
   return rc;
 }
 
@@ -3174,9 +3181,8 @@ static int moveToRoot(BtCursor *pCur){
   BtShared *pBt = pCur->pBtree->pBt;
 
   restoreOrClearCursorPosition(pCur, 0);
-  assert( pCur->pPage );
   pRoot = pCur->pPage;
-  if( pRoot->pgno==pCur->pgnoRoot ){
+  if( pRoot && pRoot->pgno==pCur->pgnoRoot ){
     assert( pRoot->isInit );
   }else{
     if( 
@@ -3443,7 +3449,7 @@ int sqlite3BtreeEof(BtCursor *pCur){
 */
 int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
   int rc;
-  MemPage *pPage = pCur->pPage;
+  MemPage *pPage;
 
 #ifndef SQLITE_OMIT_SHARED_CACHE
   rc = restoreOrClearCursorPosition(pCur, 1);
@@ -3456,9 +3462,10 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
     return SQLITE_OK;
   }
   pCur->skip = 0;
-#endif
+#endif 
 
   assert( pRes!=0 );
+  pPage = pCur->pPage;
   if( CURSOR_INVALID==pCur->eState ){
     *pRes = 1;
     return SQLITE_OK;
index 9d52df3ed37737a53f346a5ed80c69b9d61ebe58..29a5dbf48c4d11bfcc7acb88ee7f06fbbe8b2c30 100644 (file)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.246 2006/01/20 10:55:05 danielk1977 Exp $
+** @(#) $Id: pager.c,v 1.247 2006/01/20 16:32:04 danielk1977 Exp $
 */
 #ifndef SQLITE_OMIT_DISKIO
 #include "sqliteInt.h"
@@ -2693,10 +2693,15 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
       CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
       if( rc!=SQLITE_OK ){
         i64 fileSize;
-        if( sqlite3OsFileSize(pPager->fd,&fileSize)!=SQLITE_OK
-               || fileSize>=pgno*pPager->pageSize ){
+        int rc2 = sqlite3OsFileSize(pPager->fd, &fileSize);
+        if( rc2!=SQLITE_OK || fileSize>=pgno*pPager->pageSize ){
+         /* An IO error occured in one of the the sqlite3OsSeek() or
+          ** sqlite3OsRead() calls above. Unreference the page and then
+          ** set it's page number to 0 (0 means "not a page").
+          */
           sqlite3pager_unref(PGHDR_TO_DATA(pPg));
-          return pager_error(pPager, rc);
+          pPg->pgno = 0;
+          return rc;
         }else{
           clear_simulated_io_error();
           memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
index 4b5c13642eea0e28b0e4f39ef579c8e79f2984bf..a8d76b26b85a3274081c8a8ee04061617ba201a8 100644 (file)
@@ -241,7 +241,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){
   }
 #endif
 
-  sqlite3Error(p->db, rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
+  sqlite3Error(p->db, rc, 0);
   p->rc = sqlite3ApiExit(p->db, p->rc);
   return rc;
 }
index 4c61e7c19240d22503995e1bbd8a340a1a4c9b7f..d9c191d54e115d3e37ddc9842e80e2ea545f0533 100644 (file)
@@ -1242,6 +1242,8 @@ int sqlite3VdbeHalt(Vdbe *p){
           /* We are forced to roll back the active transaction. Before doing
           ** so, abort any other statements this handle currently has active.
           */
+          abortOtherActiveVdbes(p);
+          sqlite3RollbackAll(db);
           db->autoCommit = 1;
         }
       }
@@ -1264,12 +1266,12 @@ int sqlite3VdbeHalt(Vdbe *p){
           return SQLITE_BUSY;
         }else if( rc!=SQLITE_OK ){
           p->rc = rc;
-          rollbackAll(db, p);
+          sqlite3RollbackAll(db);
         }else{
           sqlite3CommitInternalChanges(db);
         }
       }else{
-        rollbackAll(db, p);
+        sqlite3RollbackAll(db);
       }
     }else if( !xFunc ){
       if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
@@ -1277,7 +1279,8 @@ int sqlite3VdbeHalt(Vdbe *p){
       }else if( p->errorAction==OE_Abort ){
         xFunc = sqlite3BtreeRollbackStmt;
       }else{
-        rollbackAll(db, p);
+        abortOtherActiveVdbes(p);
+        sqlite3RollbackAll(db);
         db->autoCommit = 1;
       }
     }
@@ -1359,8 +1362,9 @@ int sqlite3VdbeReset(Vdbe *p){
   */
   if( p->pc>=0 ){
     if( p->zErrMsg ){
-      sqlite3Error(p->db, p->rc, "%s", p->zErrMsg);
-      sqliteFree(p->zErrMsg);
+      sqlite3* db = p->db;
+      sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3FreeX);
+      db->errCode = p->rc;
       p->zErrMsg = 0;
     }else if( p->rc ){
       sqlite3Error(p->db, p->rc, 0);
index bfdf3727a59a839adaf537f8110561549bcfd90b..6de89c5d40646eb3b511f1f1f4e6f5629e2d58f1 100644 (file)
@@ -13,7 +13,7 @@
 # correctly. The emphasis of these tests are the _prepare(), _step() and
 # _finalize() calls.
 #
-# $Id: malloc3.test,v 1.7 2006/01/20 10:55:05 danielk1977 Exp $
+# $Id: malloc3.test,v 1.8 2006/01/20 16:32:04 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -492,13 +492,27 @@ TEST 32 {
       sqlite3_step $::STMT32
     } {SQLITE_ROW}
   }
-puts [execsql {SELECT * FROM ghi}]
 }
-SQL {
-  BEGIN;
-  INSERT INTO ghi SELECT * FROM ghi;
-  COMMIT;
+SQL BEGIN
+TEST 33 { 
+  do_test $testid {
+    execsql {SELECT * FROM ghi}
+  } {a b c 1 2 3}
+}
+SQL -norollback { 
+  -- There is a unique index on ghi(g), so this statement may not cause
+  -- an automatic ROLLBACK. Hence the "-norollback" switch.
+  INSERT INTO ghi SELECT '2'||g, h, i FROM ghi;
+}
+TEST 34 {
+  if {[info exists ::STMT32]} {
+    do_test $testid {
+      sqlite3_finalize $::STMT32
+    } {SQLITE_OK}
+    unset ::STMT32
+  }
 }
+SQL COMMIT
 
 #
 # End of test program declaration
@@ -630,7 +644,7 @@ proc run_test {arglist {pcstart 0} {iFailStart 1}} {
 # Turn of the Tcl interface's prepared statement caching facility.
 db cache size 0
 
-run_test $::run_test_script 76 6
+run_test $::run_test_script
 # run_test [lrange $::run_test_script 0 3] 0 63
 sqlite_malloc_fail 0
 db close
index 16d629d149f8ed3997bf80cdc3083743cb6adfdf..cdbc98a21fc4d8e719c1391e20829ba76b4f87b9 100644 (file)
@@ -13,7 +13,7 @@
 # cache context. What happens to connection B if one connection A encounters
 # an IO-error whilst reading or writing the file-system?
 #
-# $Id: shared_err.test,v 1.1 2006/01/20 10:55:05 danielk1977 Exp $
+# $Id: shared_err.test,v 1.2 2006/01/20 16:32:05 danielk1977 Exp $
 
 proc skip {args} {}
 
@@ -28,7 +28,6 @@ ifcapable !shared_cache||!subquery {
 }
 set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
 
-skip \
 do_ioerr_test shared_ioerr-1 -tclprep {
   sqlite3 db2 test.db
   execsql {
@@ -52,7 +51,7 @@ do_ioerr_test shared_ioerr-1 -tclprep {
   SELECT * FROM t1;
   DELETE FROM t1 WHERE a<100;
 } -cleanup {
-  do_test shared_ioerr-$n.cleanup.1 {
+  do_test shared_ioerr-1.$n.cleanup.1 {
     set res [catchsql {
       SELECT * FROM t1;
     } db2]
@@ -131,6 +130,44 @@ do_ioerr_test shared_ioerr-2 -tclprep {
   db2 close
 }
 
+# This test is designed to provoke an IO error when a cursor position is
+# "saved" (because another cursor is going to modify the underlying table). 
+# 
+do_ioerr_test shared_ioerr-3 -tclprep {
+  sqlite3 db2 test.db
+  execsql {
+    PRAGMA read_uncommitted = 1;
+    BEGIN;
+    CREATE TABLE t1(a, b, UNIQUE(a, b));
+  } db2
+  for {set i 0} {$i < 5} {incr i} {
+    set a [string repeat $i 10]
+    set b [string repeat $i 2000]
+    execsql {INSERT INTO t1 VALUES($a, $b)} db2
+  }
+  execsql {COMMIT} db2
+  set ::DB2 [sqlite3_connection_pointer db2]
+  set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
+  sqlite3_step $::STMT       ;# Cursor points at 0000000000
+  sqlite3_step $::STMT       ;# Cursor points at 1111111111
+} -tclbody {
+  execsql {
+    INSERT INTO t1 VALUES(6, NULL);
+  }
+} -cleanup {
+  do_test shared_ioerr-3.$n.cleanup.1 {
+    sqlite3_step $::STMT
+  } {SQLITE_ROW}
+  do_test shared_ioerr-3.$n.cleanup.2 {
+    sqlite3_column_text $::STMT 0
+  } {2222222222}
+  do_test shared_ioerr-3.$n.cleanup.3 {
+    sqlite3_finalize $::STMT
+  } {SQLITE_OK}
+# db2 eval {select * from sqlite_master}
+  db2 close
+}
+
 catch {db close}
 sqlite3_enable_shared_cache $::enable_shared_cache
 finish_test