aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordanielk1977 <danielk1977@noemail.net>2005-12-16 15:24:28 +0000
committerdanielk1977 <danielk1977@noemail.net>2005-12-16 15:24:28 +0000
commitf3f06bb30cb2d140c5ed6b79aee43bc497be4eb4 (patch)
tree191c519c11a7f311c94e977569d21efa677dd12f /src
parent71fd80bf5ca3027464eb233c36bd928f2249edc4 (diff)
downloadsqlite-f3f06bb30cb2d140c5ed6b79aee43bc497be4eb4.tar.gz
sqlite-f3f06bb30cb2d140c5ed6b79aee43bc497be4eb4.zip
Verify that the rollback-hook is invoked correctly when a malloc() failure occurs. (CVS 2824)
FossilOrigin-Name: 83c8ae5bee3b6bdb556d2e85fa260ba855742601
Diffstat (limited to 'src')
-rw-r--r--src/btree.c14
-rw-r--r--src/btree.h3
-rw-r--r--src/main.c8
-rw-r--r--src/sqlite.h.in17
-rw-r--r--src/vdbe.c19
-rw-r--r--src/vdbeaux.c32
6 files changed, 47 insertions, 46 deletions
diff --git a/src/btree.c b/src/btree.c
index 65b5594dd..052f917b7 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.274 2005/12/16 06:54:02 danielk1977 Exp $
+** $Id: btree.c,v 1.275 2005/12/16 15:24:29 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
@@ -5818,15 +5818,3 @@ int sqlite3BtreeSync(Btree *pBt, const char *zMaster){
return SQLITE_OK;
}
-#ifndef SQLITE_OMIT_GLOBALRECOVER
-/*
-** Reset the btree and underlying pager after a malloc() failure. Any
-** transaction that was active when malloc() failed is rolled back.
-*/
-int sqlite3BtreeReset(Btree *pBt){
- if( pBt->pCursor ) return SQLITE_BUSY;
- pBt->inTrans = TRANS_NONE;
- unlockBtreeIfUnused(pBt);
- return sqlite3pager_reset(pBt->pPager);
-}
-#endif
diff --git a/src/btree.h b/src/btree.h
index acc29710f..61c1cc3d5 100644
--- a/src/btree.h
+++ b/src/btree.h
@@ -13,7 +13,7 @@
** subsystem. See comments in the source code for a detailed description
** of what each interface routine does.
**
-** @(#) $Id: btree.h,v 1.64 2005/08/27 16:36:49 drh Exp $
+** @(#) $Id: btree.h,v 1.65 2005/12/16 15:24:29 danielk1977 Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_
@@ -74,7 +74,6 @@ int sqlite3BtreeCreateTable(Btree*, int*, int flags);
int sqlite3BtreeIsInTrans(Btree*);
int sqlite3BtreeIsInStmt(Btree*);
int sqlite3BtreeSync(Btree*, const char *zMaster);
-int sqlite3BtreeReset(Btree *);
const char *sqlite3BtreeGetFilename(Btree *);
const char *sqlite3BtreeGetDirname(Btree *);
diff --git a/src/main.c b/src/main.c
index ba0bb5feb..2315a6df0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.311 2005/12/16 06:54:02 danielk1977 Exp $
+** $Id: main.c,v 1.312 2005/12/16 15:24:29 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -204,8 +204,12 @@ int sqlite3_close(sqlite3 *db){
*/
void sqlite3RollbackAll(sqlite3 *db){
int i;
+ int inTrans = 0;
for(i=0; i<db->nDb; i++){
if( db->aDb[i].pBt ){
+ if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){
+ inTrans = 1;
+ }
sqlite3BtreeRollback(db->aDb[i].pBt);
db->aDb[i].inTrans = 0;
}
@@ -215,7 +219,7 @@ void sqlite3RollbackAll(sqlite3 *db){
}
/* If one has been configured, invoke the rollback-hook callback */
- if( db->xRollbackCallback ){
+ if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
db->xRollbackCallback(db->pRollbackArg);
}
}
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 966b38a20..551fddc23 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -12,7 +12,7 @@
** This header file defines the interface that the SQLite library
** presents to client programs.
**
-** @(#) $Id: sqlite.h.in,v 1.147 2005/12/16 06:54:02 danielk1977 Exp $
+** @(#) $Id: sqlite.h.in,v 1.148 2005/12/16 15:24:29 danielk1977 Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
@@ -1319,6 +1319,21 @@ void *sqlite3_update_hook(
void*
);
+/*
+** Register a callback to be invoked whenever a transaction is rolled
+** back.
+**
+** The new callback function overrides any existing rollback-hook
+** callback. If there was an existing callback, then it's pArg value
+** (the third argument to sqlite3_rollback_hook() when it was registered)
+** is returned. Otherwise, NULL is returned.
+**
+** For the purposes of this API, a transaction is said to have been
+** rolled back if an explicit "ROLLBACK" statement is executed, or
+** an error or constraint causes an implicit rollback to occur. The
+** callback is not invoked if a transaction is automatically rolled
+** back because the database connection is closed.
+*/
void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
/*
diff --git a/src/vdbe.c b/src/vdbe.c
index 95e024d20..4cedcd5c2 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.505 2005/12/15 15:22:10 danielk1977 Exp $
+** $Id: vdbe.c,v 1.506 2005/12/16 15:24:29 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -2299,16 +2299,19 @@ case OP_AutoCommit: { /* no-push */
" transaction - SQL statements in progress", 0);
rc = SQLITE_ERROR;
}else if( i!=db->autoCommit ){
- db->autoCommit = i;
if( pOp->p2 ){
assert( i==1 );
sqlite3RollbackAll(db);
- }else if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
- p->pTos = pTos;
- p->pc = pc;
- db->autoCommit = 1-i;
- p->rc = SQLITE_BUSY;
- return SQLITE_BUSY;
+ db->autoCommit = 1;
+ }else{
+ db->autoCommit = i;
+ if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
+ p->pTos = pTos;
+ p->pc = pc;
+ db->autoCommit = 1-i;
+ p->rc = SQLITE_BUSY;
+ return SQLITE_BUSY;
+ }
}
return SQLITE_DONE;
}else{
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index a99dc4643..82977e881 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -1177,12 +1177,12 @@ int sqlite3VdbeHalt(Vdbe *p){
return SQLITE_BUSY;
}else if( rc!=SQLITE_OK ){
p->rc = rc;
- xFunc = sqlite3BtreeRollback;
+ sqlite3RollbackAll(db);
}else{
sqlite3CommitInternalChanges(db);
}
}else{
- xFunc = sqlite3BtreeRollback;
+ sqlite3RollbackAll(db);
}
}else{
@@ -1227,9 +1227,9 @@ int sqlite3VdbeHalt(Vdbe *p){
}else if( p->errorAction==OE_Abort ){
xFunc = sqlite3BtreeRollbackStmt;
}else{
- xFunc = sqlite3BtreeRollback;
- db->autoCommit = 1;
abortOtherActiveVdbes(p);
+ sqlite3RollbackAll(db);
+ db->autoCommit = 1;
}
}
@@ -1240,20 +1240,14 @@ int sqlite3VdbeHalt(Vdbe *p){
*/
assert(!xFunc ||
xFunc==sqlite3BtreeCommitStmt ||
- xFunc==sqlite3BtreeRollbackStmt ||
- xFunc==sqlite3BtreeRollback
+ xFunc==sqlite3BtreeRollbackStmt
);
- if( xFunc==sqlite3BtreeRollback ){
- assert( p->rc!=SQLITE_OK );
- sqlite3RollbackAll(db);
- }else{
- for(i=0; xFunc && i<db->nDb; i++){
- int rc;
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- rc = xFunc(pBt);
- if( p->rc==SQLITE_OK ) p->rc = rc;
- }
+ for(i=0; xFunc && i<db->nDb; i++){
+ int rc;
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt ){
+ rc = xFunc(pBt);
+ if( p->rc==SQLITE_OK ) p->rc = rc;
}
}
@@ -1270,9 +1264,7 @@ int sqlite3VdbeHalt(Vdbe *p){
/* Rollback or commit any schema changes that occurred. */
if( p->rc!=SQLITE_OK && db->flags&SQLITE_InternChanges ){
sqlite3ResetInternalSchema(db, 0);
- if( xFunc!=sqlite3BtreeRollback ){
- db->flags = (db->flags | SQLITE_InternChanges);
- }
+ db->flags = (db->flags | SQLITE_InternChanges);
}
/* We have successfully halted and closed the VM. Record this fact. */