Merge the non-blocking ROLLBACK changes into trunk.
FossilOrigin-Name: 9c572d424a20b0585bfac358a5d1ee5276dd05ba
This commit is contained in:
commit
99b18401ab
40
manifest
40
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sa\sharmless\scompiler\swarning\sintroduced\sby\sthe\sprevious\scheck-in.
|
||||
D 2012-02-13T20:28:15.804
|
||||
C Merge\sthe\snon-blocking\sROLLBACK\schanges\sinto\strunk.
|
||||
D 2012-02-13T21:24:03.262
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 3f79a373e57c3b92dabf76f40b065e719d31ac34
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -122,11 +122,11 @@ F src/alter.c 149cc80d9257971b0bff34e58fb2263e01998289
|
||||
F src/analyze.c f32ff304da413851eefa562b04e61ff6cb88248b
|
||||
F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f
|
||||
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||
F src/backup.c e9538bad2d4a4fcd4308f1aed7cb18a0fbc968f9
|
||||
F src/backup.c 6be23a344d3301ae38e92fddb3a33b91c309fce4
|
||||
F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
|
||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||
F src/btree.c bb0132a725b4d5ed077924399c4f6d4b9390a721
|
||||
F src/btree.h 46e9f04672f1390255bc56865a3238b384d0f2d5
|
||||
F src/btree.c 253c3147a4ebbaee42cd329dbdc0856200bbbda7
|
||||
F src/btree.h 48a013f8964f12d944d90e4700df47b72dd6d923
|
||||
F src/btreeInt.h 26d8ca625b141927fe6620c1d2cf58eaf494ca0c
|
||||
F src/build.c c4d36e527f457f9992a6663365871dfa7c5094b8
|
||||
F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a
|
||||
@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
|
||||
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
|
||||
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
|
||||
F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d
|
||||
F src/main.c cb099cc4864b542f97938049fc74ea8ae6845ce4
|
||||
F src/main.c e936269fbc1af78cef79c27980e89209aeb20a07
|
||||
F src/malloc.c 15afac5e59b6584efe072e9933aefb4230e74f97
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c b3677415e69603d6a0e7c5410a1b3731d55beda1
|
||||
@ -182,9 +182,9 @@ F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40
|
||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||
F src/select.c 232283a2e60d91cbd9a5ddf2f6f7ecf53d590075
|
||||
F src/shell.c aa28f117033ba3e44b5eaaf2ad572222bcdfd66e
|
||||
F src/sqlite.h.in 371c30e4be94b9b0ea6400ed66663fcf8e891eb4
|
||||
F src/sqlite.h.in 4f3230be44e084a1e98f91bb031b922f33dcf3f8
|
||||
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
|
||||
F src/sqliteInt.h 736f3a7748434200db7a9e0a352b67d1b8759e0a
|
||||
F src/sqliteInt.h ea24b5f2d2e3ae7e0c1126a78c0e025ed4e98f4b
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
@ -240,11 +240,11 @@ F src/update.c d3076782c887c10e882996550345da9c4c9f9dea
|
||||
F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84
|
||||
F src/util.c 9e07bd67dfafe9c75b1da78c87ba030cebbb5388
|
||||
F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa
|
||||
F src/vdbe.c 40b14dff04692b1ee421db40c67d4921ecf17a9d
|
||||
F src/vdbe.c 21c17c43e579789959efea50f100de60efbb955c
|
||||
F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb
|
||||
F src/vdbeInt.h 6ff4180a05683566a8835d12f7ec504b22932c82
|
||||
F src/vdbeapi.c 3662b6a468a2a4605a15dfab313baa6dff81ad91
|
||||
F src/vdbeaux.c 7683d772ad638faa4567142438c4594e47f173c4
|
||||
F src/vdbeaux.c 79cf42b70e211a52d664fc4d585ee2da0a64deac
|
||||
F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb
|
||||
F src/vdbemem.c fb0ac964ccbcd94f595eb993c05bfd9c52468a4a
|
||||
F src/vdbesort.c b25814d385895544ebc8118245c8311ded7f81c9
|
||||
@ -314,9 +314,9 @@ F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b
|
||||
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
|
||||
F test/cache.test f64136b0893c293d0b910ed057b3b711249099a7
|
||||
F test/capi2.test 835d4cee9f542ea50fa8d01f3fe6de80b0627360
|
||||
F test/capi3.test 7200dff6acb17b9a4b6f9918f554eaae04968ddd
|
||||
F test/capi3.test 9c8b58b6a6aeb14e69bd8c8c7721b47d640464d1
|
||||
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
|
||||
F test/capi3c.test ccf0acf045dbacd09f6229aa4efed670aaba76a9
|
||||
F test/capi3c.test 1b5424d2ac57b7b443b5de5b9a287642c02279b6
|
||||
F test/capi3d.test 17b57ca28be3e37e14c2ba8f787d292d84b724a1
|
||||
F test/capi3e.test f7408dda65c92b9056199fdc180f893015f83dde
|
||||
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
|
||||
@ -511,7 +511,7 @@ F test/in.test a7b8a0f43da81cd08645b7a710099ffe9ad1126b
|
||||
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
|
||||
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
|
||||
F test/in4.test 64f3cc1acde1b9161ccdd8e5bde3daefdb5b2617
|
||||
F test/incrblob.test 3307c04876fe025e10256e3cc8050ab5a84aa27f
|
||||
F test/incrblob.test 26fde912a1e0aff158b3a84ef3b265f046aad3be
|
||||
F test/incrblob2.test edc3a96e557bd61fb39acc8d2edd43371fbbaa19
|
||||
F test/incrblob3.test aedbb35ea1b6450c33b98f2b6ed98e5020be8dc7
|
||||
F test/incrblob_err.test d2562d2771ebffd4b3af89ef64c140dd44371597
|
||||
@ -654,7 +654,7 @@ F test/rollback.test a1b4784b864331eae8b2a98c189efa2a8b11ff07
|
||||
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
|
||||
F test/rowid.test e58e0acef38b527ed1b0b70d3ada588f804af287
|
||||
F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798
|
||||
F test/savepoint.test 42ba63b632df4ce1bef8acdba62e4182d6505125
|
||||
F test/savepoint.test f5acd87d0c7a5f4ad6c547b47fd18c0e1aeaf048
|
||||
F test/savepoint2.test 9b8543940572a2f01a18298c3135ad0c9f4f67d7
|
||||
F test/savepoint3.test e328085853b14898d78ceea00dfe7db18bb6a9ec
|
||||
F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0
|
||||
@ -679,7 +679,7 @@ F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25
|
||||
F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977
|
||||
F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118
|
||||
F test/shared.test 34945a516532b11182c3eb26e31247eee3c9ae48
|
||||
F test/shared2.test 8f71d4eb4d5261280de92284df74172545c852cc
|
||||
F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879
|
||||
F test/shared3.test ebf77f023f4bdaa8f74f65822b559e86ce5c6257
|
||||
F test/shared4.test 72d90821e8d2fc918a08f16d32880868d8ee8e9d
|
||||
F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9
|
||||
@ -763,7 +763,7 @@ F test/tkt-d11f09d36e.test fb44f7961aa6d4b632fb7b9768239832210b5fc7
|
||||
F test/tkt-d635236375.test 9d37e988b47d87505bc9445be0ca447002df5d09
|
||||
F test/tkt-d82e3f3721.test bcc0dfba658d15bab30fd4a9320c9e35d214ce30
|
||||
F test/tkt-f3e5abed55.test 669bb076f2ac573c7398ce00f40cd0ca502043a9
|
||||
F test/tkt-f777251dc7a.test a3121f92f49af447572f7a3cde9f07806443c75d
|
||||
F test/tkt-f777251dc7a.test af6531446c64bfd268416f07b4df7be7f9c749d2
|
||||
F test/tkt-f7b4edec.test d998a08ff2b18b7f62edce8e3044317c45efe6c7
|
||||
F test/tkt-f973c7ac31.test 1da0ed15ec2c7749fb5ce2828cd69d07153ad9f4
|
||||
F test/tkt-fa7bf5ec.test 9102dfea58aa371d78969da735f9392c57e2e035
|
||||
@ -856,7 +856,7 @@ F test/trace.test 4b36a41a3e9c7842151af6da5998f5080cdad9e5
|
||||
F test/trace2.test 962175290996d5f06dc4402ca218bbfc7df4cb20
|
||||
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
|
||||
F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22
|
||||
F test/trans3.test d728abaa318ca364dc370e06576aa7e5fbed7e97
|
||||
F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732
|
||||
F test/trigger1.test de42feb7cd442787d38185ae74f5a1d7afa400cb
|
||||
F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816
|
||||
F test/trigger3.test d2c60d8be271c355d61727411e753181e877230a
|
||||
@ -989,7 +989,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
|
||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||
P 84b324606adc8437338c086404eb157f30f04130
|
||||
R d3286eff693659b9b4732d3698634dbe
|
||||
P a8a042a751557d06bf04455ed7629cb29adcd87f 549f4fd00d8325c10099b100e5202b77ee1d83ad
|
||||
R f5be37b531ffc02ec5dfb73b01bae4f2
|
||||
U drh
|
||||
Z ade107925d4b7260ea92f951a93b4e84
|
||||
Z a17a96e51ae999984897d31a6e51ca34
|
||||
|
@ -1 +1 @@
|
||||
a8a042a751557d06bf04455ed7629cb29adcd87f
|
||||
9c572d424a20b0585bfac358a5d1ee5276dd05ba
|
@ -568,7 +568,7 @@ int sqlite3_backup_finish(sqlite3_backup *p){
|
||||
}
|
||||
|
||||
/* If a transaction is still open on the Btree, roll it back. */
|
||||
sqlite3BtreeRollback(p->pDest);
|
||||
sqlite3BtreeRollback(p->pDest, SQLITE_OK);
|
||||
|
||||
/* Set the error code of the destination database handle. */
|
||||
rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
|
||||
|
24
src/btree.c
24
src/btree.c
@ -2041,7 +2041,7 @@ int sqlite3BtreeClose(Btree *p){
|
||||
** The call to sqlite3BtreeRollback() drops any table-locks held by
|
||||
** this handle.
|
||||
*/
|
||||
sqlite3BtreeRollback(p);
|
||||
sqlite3BtreeRollback(p, SQLITE_OK);
|
||||
sqlite3BtreeLeave(p);
|
||||
|
||||
/* If there are still other outstanding references to the shared-btree
|
||||
@ -3279,6 +3279,7 @@ static int countWriteCursors(BtShared *pBt){
|
||||
*/
|
||||
void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){
|
||||
BtCursor *p;
|
||||
if( pBtree==0 ) return;
|
||||
sqlite3BtreeEnter(pBtree);
|
||||
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
|
||||
int i;
|
||||
@ -3302,25 +3303,20 @@ void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){
|
||||
** This will release the write lock on the database file. If there
|
||||
** are no active cursors, it also releases the read lock.
|
||||
*/
|
||||
int sqlite3BtreeRollback(Btree *p){
|
||||
int sqlite3BtreeRollback(Btree *p, int tripCode){
|
||||
int rc;
|
||||
BtShared *pBt = p->pBt;
|
||||
MemPage *pPage1;
|
||||
|
||||
sqlite3BtreeEnter(p);
|
||||
rc = saveAllCursors(pBt, 0, 0);
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
if( rc!=SQLITE_OK ){
|
||||
/* This is a horrible situation. An IO or malloc() error occurred whilst
|
||||
** trying to save cursor positions. If this is an automatic rollback (as
|
||||
** the result of a constraint, malloc() failure or IO error) then
|
||||
** the cache may be internally inconsistent (not contain valid trees) so
|
||||
** we cannot simply return the error to the caller. Instead, abort
|
||||
** all queries that may be using any of the cursors that failed to save.
|
||||
*/
|
||||
sqlite3BtreeTripAllCursors(p, rc);
|
||||
if( tripCode==SQLITE_OK ){
|
||||
rc = tripCode = saveAllCursors(pBt, 0, 0);
|
||||
}else{
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
if( tripCode ){
|
||||
sqlite3BtreeTripAllCursors(p, tripCode);
|
||||
}
|
||||
#endif
|
||||
btreeIntegrity(p);
|
||||
|
||||
if( p->inTrans==TRANS_WRITE ){
|
||||
|
@ -77,7 +77,7 @@ int sqlite3BtreeBeginTrans(Btree*,int);
|
||||
int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
|
||||
int sqlite3BtreeCommitPhaseTwo(Btree*, int);
|
||||
int sqlite3BtreeCommit(Btree*);
|
||||
int sqlite3BtreeRollback(Btree*);
|
||||
int sqlite3BtreeRollback(Btree*,int);
|
||||
int sqlite3BtreeBeginStmt(Btree*,int);
|
||||
int sqlite3BtreeCreateTable(Btree*, int*, int flags);
|
||||
int sqlite3BtreeIsInTrans(Btree*);
|
||||
|
33
src/main.c
33
src/main.c
@ -849,19 +849,23 @@ int sqlite3_close(sqlite3 *db){
|
||||
}
|
||||
|
||||
/*
|
||||
** Rollback all database files.
|
||||
** Rollback all database files. If tripCode is not SQLITE_OK, then
|
||||
** any open cursors are invalidated ("tripped" - as in "tripping a circuit
|
||||
** breaker") and made to return tripCode if there are any further
|
||||
** attempts to use that cursor.
|
||||
*/
|
||||
void sqlite3RollbackAll(sqlite3 *db){
|
||||
void sqlite3RollbackAll(sqlite3 *db, int tripCode){
|
||||
int i;
|
||||
int inTrans = 0;
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
sqlite3BeginBenignMalloc();
|
||||
for(i=0; i<db->nDb; i++){
|
||||
if( db->aDb[i].pBt ){
|
||||
if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){
|
||||
Btree *p = db->aDb[i].pBt;
|
||||
if( p ){
|
||||
if( sqlite3BtreeIsInTrans(p) ){
|
||||
inTrans = 1;
|
||||
}
|
||||
sqlite3BtreeRollback(db->aDb[i].pBt);
|
||||
sqlite3BtreeRollback(p, tripCode);
|
||||
db->aDb[i].inTrans = 0;
|
||||
}
|
||||
}
|
||||
@ -916,12 +920,21 @@ const char *sqlite3ErrStr(int rc){
|
||||
/* SQLITE_RANGE */ "bind or column index out of range",
|
||||
/* SQLITE_NOTADB */ "file is encrypted or is not a database",
|
||||
};
|
||||
rc &= 0xff;
|
||||
if( ALWAYS(rc>=0) && rc<(int)(sizeof(aMsg)/sizeof(aMsg[0])) && aMsg[rc]!=0 ){
|
||||
return aMsg[rc];
|
||||
}else{
|
||||
return "unknown error";
|
||||
const char *zErr = "unknown error";
|
||||
switch( rc ){
|
||||
case SQLITE_ABORT_ROLLBACK: {
|
||||
zErr = "abort due to ROLLBACK";
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
rc &= 0xff;
|
||||
if( ALWAYS(rc>=0) && rc<ArraySize(aMsg) && aMsg[rc]!=0 ){
|
||||
zErr = aMsg[rc];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return zErr;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -456,6 +456,7 @@ int sqlite3_exec(
|
||||
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
|
||||
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
|
||||
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
|
||||
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flags For File Open Operations
|
||||
|
@ -2800,7 +2800,7 @@ Vdbe *sqlite3GetVdbe(Parse*);
|
||||
void sqlite3PrngSaveState(void);
|
||||
void sqlite3PrngRestoreState(void);
|
||||
void sqlite3PrngResetState(void);
|
||||
void sqlite3RollbackAll(sqlite3*);
|
||||
void sqlite3RollbackAll(sqlite3*,int);
|
||||
void sqlite3CodeVerifySchema(Parse*, int);
|
||||
void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
|
||||
void sqlite3BeginTransaction(Parse*, int);
|
||||
|
20
src/vdbe.c
20
src/vdbe.c
@ -2684,16 +2684,12 @@ case OP_Savepoint: {
|
||||
if( !pSavepoint ){
|
||||
sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName);
|
||||
rc = SQLITE_ERROR;
|
||||
}else if(
|
||||
db->writeVdbeCnt>0 || (p1==SAVEPOINT_ROLLBACK && db->activeVdbeCnt>1)
|
||||
){
|
||||
}else if( db->writeVdbeCnt>0 && p1==SAVEPOINT_RELEASE ){
|
||||
/* It is not possible to release (commit) a savepoint if there are
|
||||
** active write statements. It is not possible to rollback a savepoint
|
||||
** if there are any active statements at all.
|
||||
** active write statements.
|
||||
*/
|
||||
sqlite3SetString(&p->zErrMsg, db,
|
||||
"cannot %s savepoint - SQL statements in progress",
|
||||
(p1==SAVEPOINT_ROLLBACK ? "rollback": "release")
|
||||
"cannot release savepoint - SQL statements in progress"
|
||||
);
|
||||
rc = SQLITE_BUSY;
|
||||
}else{
|
||||
@ -2718,6 +2714,9 @@ case OP_Savepoint: {
|
||||
rc = p->rc;
|
||||
}else{
|
||||
iSavepoint = db->nSavepoint - iSavepoint - 1;
|
||||
for(ii=0; ii<db->nDb; ii++){
|
||||
sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, SQLITE_ABORT);
|
||||
}
|
||||
for(ii=0; ii<db->nDb; ii++){
|
||||
rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
|
||||
if( rc!=SQLITE_OK ){
|
||||
@ -2786,6 +2785,7 @@ case OP_AutoCommit: {
|
||||
assert( desiredAutoCommit==1 || iRollback==0 );
|
||||
assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */
|
||||
|
||||
#if 0
|
||||
if( turnOnAC && iRollback && db->activeVdbeCnt>1 ){
|
||||
/* If this instruction implements a ROLLBACK and other VMs are
|
||||
** still running, and a transaction is active, return an error indicating
|
||||
@ -2794,7 +2794,9 @@ case OP_AutoCommit: {
|
||||
sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - "
|
||||
"SQL statements in progress");
|
||||
rc = SQLITE_BUSY;
|
||||
}else if( turnOnAC && !iRollback && db->writeVdbeCnt>0 ){
|
||||
}else
|
||||
#endif
|
||||
if( turnOnAC && !iRollback && db->writeVdbeCnt>0 ){
|
||||
/* If this instruction implements a COMMIT and other VMs are writing
|
||||
** return an error indicating that the other VMs must complete first.
|
||||
*/
|
||||
@ -2804,7 +2806,7 @@ case OP_AutoCommit: {
|
||||
}else if( desiredAutoCommit!=db->autoCommit ){
|
||||
if( iRollback ){
|
||||
assert( desiredAutoCommit==1 );
|
||||
sqlite3RollbackAll(db);
|
||||
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
|
||||
db->autoCommit = 1;
|
||||
}else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
|
||||
goto vdbe_return;
|
||||
|
@ -2002,32 +2002,6 @@ static void checkActiveVdbeCnt(sqlite3 *db){
|
||||
#define checkActiveVdbeCnt(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** For every Btree that in database connection db which
|
||||
** has been modified, "trip" or invalidate each cursor in
|
||||
** that Btree might have been modified so that the cursor
|
||||
** can never be used again. This happens when a rollback
|
||||
*** occurs. We have to trip all the other cursors, even
|
||||
** cursor from other VMs in different database connections,
|
||||
** so that none of them try to use the data at which they
|
||||
** were pointing and which now may have been changed due
|
||||
** to the rollback.
|
||||
**
|
||||
** Remember that a rollback can delete tables complete and
|
||||
** reorder rootpages. So it is not sufficient just to save
|
||||
** the state of the cursor. We have to invalidate the cursor
|
||||
** so that it is never used again.
|
||||
*/
|
||||
static void invalidateCursorsOnModifiedBtrees(sqlite3 *db){
|
||||
int i;
|
||||
for(i=0; i<db->nDb; i++){
|
||||
Btree *p = db->aDb[i].pBt;
|
||||
if( p && sqlite3BtreeIsInTrans(p) ){
|
||||
sqlite3BtreeTripAllCursors(p, SQLITE_ABORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** If the Vdbe passed as the first argument opened a statement-transaction,
|
||||
** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or
|
||||
@ -2192,8 +2166,7 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
/* We are forced to roll back the active transaction. Before doing
|
||||
** so, abort any other statements this handle currently has active.
|
||||
*/
|
||||
invalidateCursorsOnModifiedBtrees(db);
|
||||
sqlite3RollbackAll(db);
|
||||
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
|
||||
sqlite3CloseSavepoints(db);
|
||||
db->autoCommit = 1;
|
||||
}
|
||||
@ -2235,13 +2208,13 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
return SQLITE_BUSY;
|
||||
}else if( rc!=SQLITE_OK ){
|
||||
p->rc = rc;
|
||||
sqlite3RollbackAll(db);
|
||||
sqlite3RollbackAll(db, SQLITE_OK);
|
||||
}else{
|
||||
db->nDeferredCons = 0;
|
||||
sqlite3CommitInternalChanges(db);
|
||||
}
|
||||
}else{
|
||||
sqlite3RollbackAll(db);
|
||||
sqlite3RollbackAll(db, SQLITE_OK);
|
||||
}
|
||||
db->nStatement = 0;
|
||||
}else if( eStatementOp==0 ){
|
||||
@ -2250,8 +2223,7 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
}else if( p->errorAction==OE_Abort ){
|
||||
eStatementOp = SAVEPOINT_ROLLBACK;
|
||||
}else{
|
||||
invalidateCursorsOnModifiedBtrees(db);
|
||||
sqlite3RollbackAll(db);
|
||||
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
|
||||
sqlite3CloseSavepoints(db);
|
||||
db->autoCommit = 1;
|
||||
}
|
||||
@ -2271,8 +2243,7 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
sqlite3DbFree(db, p->zErrMsg);
|
||||
p->zErrMsg = 0;
|
||||
}
|
||||
invalidateCursorsOnModifiedBtrees(db);
|
||||
sqlite3RollbackAll(db);
|
||||
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
|
||||
sqlite3CloseSavepoints(db);
|
||||
db->autoCommit = 1;
|
||||
}
|
||||
|
@ -894,18 +894,19 @@ do_test capi3-11.9.2 {
|
||||
catchsql {
|
||||
ROLLBACK;
|
||||
}
|
||||
} {1 {cannot rollback transaction - SQL statements in progress}}
|
||||
} {0 {}}
|
||||
do_test capi3-11.9.3 {
|
||||
sqlite3_get_autocommit $DB
|
||||
} 0
|
||||
} 1
|
||||
do_test capi3-11.10 {
|
||||
sqlite3_step $STMT
|
||||
} {SQLITE_ROW}
|
||||
} {SQLITE_ERROR}
|
||||
do_test capi3-11.11 {
|
||||
sqlite3_step $STMT
|
||||
} {SQLITE_ROW}
|
||||
do_test capi3-11.12 {
|
||||
sqlite3_step $STMT
|
||||
sqlite3_step $STMT
|
||||
} {SQLITE_DONE}
|
||||
do_test capi3-11.13 {
|
||||
sqlite3_finalize $STMT
|
||||
@ -914,15 +915,15 @@ do_test capi3-11.14 {
|
||||
execsql {
|
||||
SELECT a FROM t2;
|
||||
}
|
||||
} {1 2 3}
|
||||
} {1 2}
|
||||
do_test capi3-11.14.1 {
|
||||
sqlite3_get_autocommit $DB
|
||||
} 0
|
||||
} 1
|
||||
do_test capi3-11.15 {
|
||||
catchsql {
|
||||
ROLLBACK;
|
||||
}
|
||||
} {0 {}}
|
||||
} {1 {cannot rollback - no transaction is active}}
|
||||
do_test capi3-11.15.1 {
|
||||
sqlite3_get_autocommit $DB
|
||||
} 1
|
||||
|
@ -849,18 +849,19 @@ do_test capi3c-11.9.2 {
|
||||
catchsql {
|
||||
ROLLBACK;
|
||||
}
|
||||
} {1 {cannot rollback transaction - SQL statements in progress}}
|
||||
} {0 {}}
|
||||
do_test capi3c-11.9.3 {
|
||||
sqlite3_get_autocommit $DB
|
||||
} 0
|
||||
} 1
|
||||
do_test capi3c-11.10 {
|
||||
sqlite3_step $STMT
|
||||
} {SQLITE_ROW}
|
||||
} {SQLITE_ABORT}
|
||||
do_test capi3c-11.11 {
|
||||
sqlite3_step $STMT
|
||||
} {SQLITE_ROW}
|
||||
do_test capi3c-11.12 {
|
||||
sqlite3_step $STMT
|
||||
sqlite3_step $STMT
|
||||
} {SQLITE_DONE}
|
||||
do_test capi3c-11.13 {
|
||||
sqlite3_finalize $STMT
|
||||
@ -869,15 +870,15 @@ do_test capi3c-11.14 {
|
||||
execsql {
|
||||
SELECT a FROM t2;
|
||||
}
|
||||
} {1 2 3}
|
||||
} {1 2}
|
||||
do_test capi3c-11.14.1 {
|
||||
sqlite3_get_autocommit $DB
|
||||
} 0
|
||||
} 1
|
||||
do_test capi3c-11.15 {
|
||||
catchsql {
|
||||
ROLLBACK;
|
||||
}
|
||||
} {0 {}}
|
||||
} {1 {cannot rollback - no transaction is active}}
|
||||
do_test capi3c-11.15.1 {
|
||||
sqlite3_get_autocommit $DB
|
||||
} 1
|
||||
|
@ -473,15 +473,9 @@ if {[permutation] != "memsubsys1"} {
|
||||
flush $::blob
|
||||
} {}
|
||||
|
||||
# At this point rollback should be illegal (because
|
||||
# there is an open blob channel). But commit is also illegal because
|
||||
# the open blob is read-write.
|
||||
# At this point commit should be illegal (because
|
||||
# there is an open blob channel).
|
||||
#
|
||||
do_test incrblob-6.10 {
|
||||
catchsql {
|
||||
ROLLBACK;
|
||||
} db2
|
||||
} {1 {cannot rollback transaction - SQL statements in progress}}
|
||||
do_test incrblob-6.11 {
|
||||
catchsql {
|
||||
COMMIT;
|
||||
|
@ -303,11 +303,19 @@ ifcapable incrblob {
|
||||
execsql {SAVEPOINT abc}
|
||||
catchsql {ROLLBACK TO def}
|
||||
} {1 {no such savepoint: def}}
|
||||
do_test savepoint-5.3.2 {
|
||||
do_test savepoint-5.3.2.1 {
|
||||
execsql {SAVEPOINT def}
|
||||
set fd [db incrblob -readonly blobs x 1]
|
||||
set rc [catch {seek $fd 0;read $fd} res]
|
||||
lappend rc $res
|
||||
} {0 {hellontyeight character blob}}
|
||||
do_test savepoint-5.3.2.2 {
|
||||
catchsql {ROLLBACK TO def}
|
||||
} {1 {cannot rollback savepoint - SQL statements in progress}}
|
||||
} {0 {}}
|
||||
do_test savepoint-5.3.2.3 {
|
||||
set rc [catch {seek $fd 0; read $fd} res]
|
||||
set rc
|
||||
} {1}
|
||||
do_test savepoint-5.3.3 {
|
||||
catchsql {RELEASE def}
|
||||
} {0 {}}
|
||||
|
@ -79,48 +79,6 @@ do_test shared2-1.3 {
|
||||
list $a $count
|
||||
} {32 64}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# These tests, shared2.2.*, test the outcome when data is added to or
|
||||
# removed from a table due to a rollback while a read-uncommitted
|
||||
# cursor is scanning it.
|
||||
#
|
||||
do_test shared2-2.1 {
|
||||
execsql {
|
||||
INSERT INTO numbers VALUES(1, 'Medium length text field');
|
||||
INSERT INTO numbers VALUES(2, 'Medium length text field');
|
||||
INSERT INTO numbers VALUES(3, 'Medium length text field');
|
||||
INSERT INTO numbers VALUES(4, 'Medium length text field');
|
||||
BEGIN;
|
||||
DELETE FROM numbers WHERE (a%2)=0;
|
||||
} db1
|
||||
set res [list]
|
||||
db2 eval {
|
||||
SELECT a FROM numbers ORDER BY a;
|
||||
} {
|
||||
lappend res $a
|
||||
if {$a==3} {
|
||||
execsql {ROLLBACK} db1
|
||||
}
|
||||
}
|
||||
set res
|
||||
} {1 3 4}
|
||||
do_test shared2-2.2 {
|
||||
execsql {
|
||||
BEGIN;
|
||||
INSERT INTO numbers VALUES(5, 'Medium length text field');
|
||||
INSERT INTO numbers VALUES(6, 'Medium length text field');
|
||||
} db1
|
||||
set res [list]
|
||||
db2 eval {
|
||||
SELECT a FROM numbers ORDER BY a;
|
||||
} {
|
||||
lappend res $a
|
||||
if {$a==5} {
|
||||
execsql {ROLLBACK} db1
|
||||
}
|
||||
}
|
||||
set res
|
||||
} {1 2 3 4 5}
|
||||
|
||||
db1 close
|
||||
db2 close
|
||||
|
@ -42,7 +42,7 @@ do_test tkt-f7772-1.2 {
|
||||
BEGIN IMMEDIATE;
|
||||
SELECT x, force_rollback(), EXISTS(SELECT 1 FROM t3 WHERE w=x) FROM t2;
|
||||
}
|
||||
} {1 {callback requested query abort}}
|
||||
} {1 {abort due to ROLLBACK}}
|
||||
do_test tkt-f7772-1.3 {
|
||||
sqlite3_get_autocommit db
|
||||
} {1}
|
||||
|
@ -64,14 +64,13 @@ do_test trans3-1.5 {
|
||||
}
|
||||
} errmsg]
|
||||
lappend x $errmsg
|
||||
} {1 {cannot rollback transaction - SQL statements in progress}}
|
||||
} {1 {abort due to ROLLBACK}}
|
||||
do_test trans3-1.6 {
|
||||
set ::ecode
|
||||
} {SQLITE_BUSY}
|
||||
} {}
|
||||
do_test trans3-1.7 {
|
||||
db eval COMMIT
|
||||
db eval {SELECT * FROM t1}
|
||||
} {1 2 3 4 5}
|
||||
} {1 2 3 4}
|
||||
unset -nocomplain ecode
|
||||
|
||||
finish_test
|
||||
|
Loading…
x
Reference in New Issue
Block a user