Verify that the rollback-hook is invoked correctly when a malloc() failure occurs. (CVS 2824)

FossilOrigin-Name: 83c8ae5bee3b6bdb556d2e85fa260ba855742601
This commit is contained in:
danielk1977
2005-12-16 15:24:28 +00:00
parent 71fd80bf5c
commit f3f06bb30c
10 changed files with 98 additions and 66 deletions
+1 -13
View File
@@ -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
+1 -2
View File
@@ -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 *);
+6 -2
View File
@@ -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);
}
}
+16 -1
View File
@@ -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*);
/*
+11 -8
View File
@@ -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{
+12 -20
View File
@@ -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. */