]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Rollback the transaction if an SQLITE_FULL error is encountered.
authordrh <drh@noemail.net>
Wed, 3 Oct 2007 15:30:52 +0000 (15:30 +0000)
committerdrh <drh@noemail.net>
Wed, 3 Oct 2007 15:30:52 +0000 (15:30 +0000)
This is a preliminary fix for ticket #2686.  More testing and
analysis is needed before we close the ticket. (CVS 4458)

FossilOrigin-Name: 0fb6d5a5773c282882e7283e6f8f8c009e238ff4

manifest
manifest.uuid
src/vdbeaux.c
test/tkt2686.tcl [new file with mode: 0644]

index 7bb98dc1246e12ff639b3d8d2a522bfc9e0e4172..6938377eb28a09545265b40a0ea7357cd655b1fa 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\smemory\sleak\sthat\scould\soccur\sduring\serror-state\srecovery.\s(CVS\s4457)
-D 2007-10-03T15:22:26
+C Rollback\sthe\stransaction\sif\san\sSQLITE_FULL\serror\sis\sencountered.\nThis\sis\sa\spreliminary\sfix\sfor\sticket\s#2686.\s\sMore\stesting\sand\nanalysis\sis\sneeded\sbefore\swe\sclose\sthe\sticket.\s(CVS\s4458)
+D 2007-10-03T15:30:52
 F Makefile.in cbfb898945536a8f9ea8b897e1586dd1fdbcc5db
 F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -168,7 +168,7 @@ F src/vdbe.c b6c53921512496ef4d7c4f571feb73b7a495db35
 F src/vdbe.h 03a0fa17f6753a24d6cb585d7a362944a2c115aa
 F src/vdbeInt.h 630145b9bfaa19190ab491f52658a7db550f2247
 F src/vdbeapi.c 9c2d681b75e4b90c28b9dd01a3f2e5905267f884
-F src/vdbeaux.c e35c851e3c1d18a7b90dbe35ae5e0fc9419a4ed4
+F src/vdbeaux.c 9bb437cb69ae45d7ae2acfcb83264d8bd15b39cc
 F src/vdbeblob.c 82f51cdf9b0c0af729732fde48c824e498c0a1ca
 F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
 F src/vdbemem.c 246d434fa60bde6553490eb686adfd86adcd6712
@@ -461,6 +461,7 @@ F test/tkt2409.test 20318bf6acd9b834b4420548f277b8e3a7420cd1
 F test/tkt2450.test 77ed94863f2049c1420288ddfea2d41e5e0971d6
 F test/tkt2640.test c513e7992a602a87ef3a2cc9ca1cba4146924e9b
 F test/tkt2643.test 3f3ebb743da00d4fed4fcf6daed92a0e18e57813
+F test/tkt2686.tcl 2da95620744e11807335ab07f4cc9bbfb1b08001
 F test/trace.test 75ffc1b992c780d054748a656e3e7fd674f18567
 F test/trans.test b73289992b46d38d9479ecc4fdc03d8edb2413dc
 F test/trigger1.test b361161cf20614024cc1e52ea0bdec250776b2ae
@@ -580,7 +581,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 7d3f0b149bd2b9c7c12aabb93d022c0ea26f0d74
-R 758b9cd7fcc1c70228ec040144239c4a
-U danielk1977
-Z 232289e1446c6deb39d7a5dfa3b4eda2
+P 3d1d13d1eb5817c22956e6e7792783116a828962
+R 2dfb044e805a2e65c272b67cf877a8ea
+U drh
+Z fad836448ac64c67c038efdc32241a75
index 4d0adb91e5bd5c28915cfbec5993fe5d71577843..7d84e972d5d0f032d42795cd4782c80de354569c 100644 (file)
@@ -1 +1 @@
-3d1d13d1eb5817c22956e6e7792783116a828962
\ No newline at end of file
+0fb6d5a5773c282882e7283e6f8f8c009e238ff4
\ No newline at end of file
index ac347c50a599700d203be5d8161dbea4a9b98b26..bdea2a539f34e207f5e2741605d50d64b5d5201a 100644 (file)
@@ -1352,28 +1352,16 @@ int sqlite3VdbeHalt(Vdbe *p){
   ** transaction will be committed or rolled back as a result of the
   ** execution of this virtual machine. 
   **
-  ** Special errors:
+  ** If any of the following errors occur:
   **
-  **     If an SQLITE_NOMEM error has occured in a statement that writes to
-  **     the database, then either a statement or transaction must be rolled
-  **     back to ensure the tree-structures are in a consistent state. A
-  **     statement transaction is rolled back if one is open, otherwise the
-  **     entire transaction must be rolled back.
-  **
-  **     If an SQLITE_IOERR error has occured in a statement that writes to
-  **     the database, then the entire transaction must be rolled back. The
-  **     I/O error may have caused garbage to be written to the journal 
-  **     file. Were the transaction to continue and eventually be rolled 
-  **     back that garbage might end up in the database file.
-  **     
-  **     In both of the above cases, the Vdbe.errorAction variable is 
-  **     ignored. If the sqlite3.autoCommit flag is false and a transaction
-  **     is rolled back, it will be set to true.
-  **
-  ** Other errors:
-  **
-  ** No error:
+  **     SQLITE_NOMEM
+  **     SQLITE_IOERR
+  **     SQLITE_FULL
+  **     SQLITE_INTERRUPT
   **
+  ** Then the internal cache might have been left in an inconsistent
+  ** state.  We need to rollback the statement transaction, if there is
+  ** one, or the complete transaction if there is no statement transaction.
   */
 
   if( p->db->mallocFailed ){
@@ -1392,10 +1380,10 @@ int sqlite3VdbeHalt(Vdbe *p){
     /* Lock all btrees used by the statement */
     sqlite3BtreeMutexArrayEnter(&p->aMutex);
 
-    /* Check for one of the special errors - SQLITE_NOMEM or SQLITE_IOERR */
+    /* Check for one of the special errors */
     mrc = p->rc & 0xff;
-    isSpecialError = (
-        (mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR || mrc==SQLITE_INTERRUPT)?1:0);
+    isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR
+                     || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL ;
     if( isSpecialError ){
       /* This loop does static analysis of the query to see which of the
       ** following three categories it falls into:
@@ -1444,7 +1432,7 @@ int sqlite3VdbeHalt(Vdbe *p){
         if( p->rc==SQLITE_IOERR_BLOCKED && isStatement ){
           xFunc = sqlite3BtreeRollbackStmt;
           p->rc = SQLITE_BUSY;
-        } else if( p->rc==SQLITE_NOMEM && isStatement ){
+        } else if( (p->rc==SQLITE_NOMEM || p->rc==SQLITE_FULL) && isStatement ){
           xFunc = sqlite3BtreeRollbackStmt;
         }else{
           /* We are forced to roll back the active transaction. Before doing
diff --git a/test/tkt2686.tcl b/test/tkt2686.tcl
new file mode 100644 (file)
index 0000000..93ac171
--- /dev/null
@@ -0,0 +1,46 @@
+# 2007 Oct 3
+#
+# 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 is to test that ticket #2686 has been fixed.
+#
+# $Id: tkt2686.tcl,v 1.1 2007/10/03 15:30:52 drh Exp $
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+db eval {
+  PRAGMA page_size=1024;
+  PRAGMA max_page_count=50;
+  PRAGMA auto_vacuum=0;
+  CREATE TABLE filler (fill);
+}
+for {set i 1} {$i<2000} {incr i} {
+  do_test tkt2686-$i.1 {
+    db eval BEGIN
+    set rc [catch {
+      while 1 {
+        db eval {INSERT INTO filler (fill) VALUES (randstr(1000, 10000)) }
+      }
+    } msg]
+    lappend rc $msg
+  } {1 {database or disk is full}}
+  do_test tkt2686-$i.2 {
+    execsql {
+      DELETE FROM filler 
+       WHERE rowid <= (SELECT MAX(rowid) FROM filler LIMIT 20)
+    }
+  } {}
+  integrity_check tkt2686-$i.3
+  catch {db eval COMMIT}
+}
+
+finish_test