Rollback the transaction if an SQLITE_FULL error is encountered.

This is a preliminary fix for ticket #2686.  More testing and
analysis is needed before we close the ticket. (CVS 4458)

FossilOrigin-Name: 0fb6d5a5773c282882e7283e6f8f8c009e238ff4
This commit is contained in:
drh
2007-10-03 15:30:52 +00:00
parent c4f6f62900
commit 71b890a3f6
4 changed files with 67 additions and 32 deletions
+8 -7
View File
@@ -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
+1 -1
View File
@@ -1 +1 @@
3d1d13d1eb5817c22956e6e7792783116a828962
0fb6d5a5773c282882e7283e6f8f8c009e238ff4
+12 -24
View 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
+46
View File
@@ -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