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:
@@ -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
@@ -1 +1 @@
|
||||
3d1d13d1eb5817c22956e6e7792783116a828962
|
||||
0fb6d5a5773c282882e7283e6f8f8c009e238ff4
|
||||
+12
-24
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user