/ Check-in [9c572d42]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge the non-blocking ROLLBACK changes into trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 9c572d424a20b0585bfac358a5d1ee5276dd05ba
User & Date: drh 2012-02-13 21:24:03
References
2012-03-31
17:15 Ticket [27ca74af] Nested SAVEPOINT release causes pending query abort status still Open with 3 other changes artifact: d44befae user: drh
Context
2012-02-14
15:34
Enhance the fuzzer virtual table to support multiple rule sets. check-in: a8293873 user: drh tags: trunk
2012-02-13
21:24
Merge the non-blocking ROLLBACK changes into trunk. check-in: 9c572d42 user: drh tags: trunk
20:28
Fix a harmless compiler warning introduced by the previous check-in. check-in: a8a042a7 user: drh tags: trunk
17:01
Add the new SQLITE_ABORT_ROLLBACK extended error code to be returned for statements that are cancelled due to a rollback. Closed-Leaf check-in: 549f4fd0 user: drh tags: nonblocking-rollback
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/backup.c.

   564    564       while( *pp!=p ){
   565    565         pp = &(*pp)->pNext;
   566    566       }
   567    567       *pp = p->pNext;
   568    568     }
   569    569   
   570    570     /* If a transaction is still open on the Btree, roll it back. */
   571         -  sqlite3BtreeRollback(p->pDest);
          571  +  sqlite3BtreeRollback(p->pDest, SQLITE_OK);
   572    572   
   573    573     /* Set the error code of the destination database handle. */
   574    574     rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
   575    575     sqlite3Error(p->pDestDb, rc, 0);
   576    576   
   577    577     /* Exit the mutexes and free the backup context structure. */
   578    578     if( p->pDestDb ){

Changes to src/btree.c.

  2037   2037       }
  2038   2038     }
  2039   2039   
  2040   2040     /* Rollback any active transaction and free the handle structure.
  2041   2041     ** The call to sqlite3BtreeRollback() drops any table-locks held by
  2042   2042     ** this handle.
  2043   2043     */
  2044         -  sqlite3BtreeRollback(p);
         2044  +  sqlite3BtreeRollback(p, SQLITE_OK);
  2045   2045     sqlite3BtreeLeave(p);
  2046   2046   
  2047   2047     /* If there are still other outstanding references to the shared-btree
  2048   2048     ** structure, return now. The remainder of this procedure cleans 
  2049   2049     ** up the shared-btree.
  2050   2050     */
  2051   2051     assert( p->wantToLock==0 && p->locked==0 );
................................................................................
  3275   3275   ** the rollback.  The rollback may have deleted tables
  3276   3276   ** or moved root pages, so it is not sufficient to
  3277   3277   ** save the state of the cursor.  The cursor must be
  3278   3278   ** invalidated.
  3279   3279   */
  3280   3280   void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){
  3281   3281     BtCursor *p;
         3282  +  if( pBtree==0 ) return;
  3282   3283     sqlite3BtreeEnter(pBtree);
  3283   3284     for(p=pBtree->pBt->pCursor; p; p=p->pNext){
  3284   3285       int i;
  3285   3286       sqlite3BtreeClearCursor(p);
  3286   3287       p->eState = CURSOR_FAULT;
  3287   3288       p->skipNext = errCode;
  3288   3289       for(i=0; i<=p->iPage; i++){
................................................................................
  3298   3299   ** invalided by this operation.  Any attempt to use a cursor
  3299   3300   ** that was open at the beginning of this operation will result
  3300   3301   ** in an error.
  3301   3302   **
  3302   3303   ** This will release the write lock on the database file.  If there
  3303   3304   ** are no active cursors, it also releases the read lock.
  3304   3305   */
  3305         -int sqlite3BtreeRollback(Btree *p){
         3306  +int sqlite3BtreeRollback(Btree *p, int tripCode){
  3306   3307     int rc;
  3307   3308     BtShared *pBt = p->pBt;
  3308   3309     MemPage *pPage1;
  3309   3310   
  3310   3311     sqlite3BtreeEnter(p);
  3311         -  rc = saveAllCursors(pBt, 0, 0);
  3312         -#ifndef SQLITE_OMIT_SHARED_CACHE
  3313         -  if( rc!=SQLITE_OK ){
  3314         -    /* This is a horrible situation. An IO or malloc() error occurred whilst
  3315         -    ** trying to save cursor positions. If this is an automatic rollback (as
  3316         -    ** the result of a constraint, malloc() failure or IO error) then 
  3317         -    ** the cache may be internally inconsistent (not contain valid trees) so
  3318         -    ** we cannot simply return the error to the caller. Instead, abort 
  3319         -    ** all queries that may be using any of the cursors that failed to save.
  3320         -    */
  3321         -    sqlite3BtreeTripAllCursors(p, rc);
         3312  +  if( tripCode==SQLITE_OK ){
         3313  +    rc = tripCode = saveAllCursors(pBt, 0, 0);
         3314  +  }else{
         3315  +    rc = SQLITE_OK;
  3322   3316     }
  3323         -#endif
         3317  +  if( tripCode ){
         3318  +    sqlite3BtreeTripAllCursors(p, tripCode);
         3319  +  }
  3324   3320     btreeIntegrity(p);
  3325   3321   
  3326   3322     if( p->inTrans==TRANS_WRITE ){
  3327   3323       int rc2;
  3328   3324   
  3329   3325       assert( TRANS_WRITE==pBt->inTransaction );
  3330   3326       rc2 = sqlite3PagerRollback(pBt->pPager);

Changes to src/btree.h.

    73     73   int sqlite3BtreeGetReserve(Btree*);
    74     74   int sqlite3BtreeSetAutoVacuum(Btree *, int);
    75     75   int sqlite3BtreeGetAutoVacuum(Btree *);
    76     76   int sqlite3BtreeBeginTrans(Btree*,int);
    77     77   int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
    78     78   int sqlite3BtreeCommitPhaseTwo(Btree*, int);
    79     79   int sqlite3BtreeCommit(Btree*);
    80         -int sqlite3BtreeRollback(Btree*);
           80  +int sqlite3BtreeRollback(Btree*,int);
    81     81   int sqlite3BtreeBeginStmt(Btree*,int);
    82     82   int sqlite3BtreeCreateTable(Btree*, int*, int flags);
    83     83   int sqlite3BtreeIsInTrans(Btree*);
    84     84   int sqlite3BtreeIsInReadTrans(Btree*);
    85     85   int sqlite3BtreeIsInBackup(Btree*);
    86     86   void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
    87     87   int sqlite3BtreeSchemaLocked(Btree *pBtree);

Changes to src/main.c.

   845    845       sqlite3_free(db->lookaside.pStart);
   846    846     }
   847    847     sqlite3_free(db);
   848    848     return SQLITE_OK;
   849    849   }
   850    850   
   851    851   /*
   852         -** Rollback all database files.
          852  +** Rollback all database files.  If tripCode is not SQLITE_OK, then
          853  +** any open cursors are invalidated ("tripped" - as in "tripping a circuit
          854  +** breaker") and made to return tripCode if there are any further
          855  +** attempts to use that cursor.
   853    856   */
   854         -void sqlite3RollbackAll(sqlite3 *db){
          857  +void sqlite3RollbackAll(sqlite3 *db, int tripCode){
   855    858     int i;
   856    859     int inTrans = 0;
   857    860     assert( sqlite3_mutex_held(db->mutex) );
   858    861     sqlite3BeginBenignMalloc();
   859    862     for(i=0; i<db->nDb; i++){
   860         -    if( db->aDb[i].pBt ){
   861         -      if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){
          863  +    Btree *p = db->aDb[i].pBt;
          864  +    if( p ){
          865  +      if( sqlite3BtreeIsInTrans(p) ){
   862    866           inTrans = 1;
   863    867         }
   864         -      sqlite3BtreeRollback(db->aDb[i].pBt);
          868  +      sqlite3BtreeRollback(p, tripCode);
   865    869         db->aDb[i].inTrans = 0;
   866    870       }
   867    871     }
   868    872     sqlite3VtabRollback(db);
   869    873     sqlite3EndBenignMalloc();
   870    874   
   871    875     if( db->flags&SQLITE_InternChanges ){
................................................................................
   912    916       /* SQLITE_MISUSE      */ "library routine called out of sequence",
   913    917       /* SQLITE_NOLFS       */ "large file support is disabled",
   914    918       /* SQLITE_AUTH        */ "authorization denied",
   915    919       /* SQLITE_FORMAT      */ "auxiliary database format error",
   916    920       /* SQLITE_RANGE       */ "bind or column index out of range",
   917    921       /* SQLITE_NOTADB      */ "file is encrypted or is not a database",
   918    922     };
   919         -  rc &= 0xff;
   920         -  if( ALWAYS(rc>=0) && rc<(int)(sizeof(aMsg)/sizeof(aMsg[0])) && aMsg[rc]!=0 ){
   921         -    return aMsg[rc];
   922         -  }else{
   923         -    return "unknown error";
          923  +  const char *zErr = "unknown error";
          924  +  switch( rc ){
          925  +    case SQLITE_ABORT_ROLLBACK: {
          926  +      zErr = "abort due to ROLLBACK";
          927  +      break;
          928  +    }
          929  +    default: {
          930  +      rc &= 0xff;
          931  +      if( ALWAYS(rc>=0) && rc<ArraySize(aMsg) && aMsg[rc]!=0 ){
          932  +        zErr = aMsg[rc];
          933  +      }
          934  +      break;
          935  +    }
   924    936     }
          937  +  return zErr;
   925    938   }
   926    939   
   927    940   /*
   928    941   ** This routine implements a busy callback that sleeps and tries
   929    942   ** again until a timeout value is reached.  The timeout value is
   930    943   ** an integer number of milliseconds passed in as the first
   931    944   ** argument.

Changes to src/sqlite.h.in.

   452    452   #define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
   453    453   #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
   454    454   #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
   455    455   #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
   456    456   #define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
   457    457   #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
   458    458   #define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
          459  +#define SQLITE_ABORT_ROLLBACK          (SQLITE_ABORT | (2<<8))
   459    460   
   460    461   /*
   461    462   ** CAPI3REF: Flags For File Open Operations
   462    463   **
   463    464   ** These bit values are intended for use in the
   464    465   ** 3rd parameter to the [sqlite3_open_v2()] interface and
   465    466   ** in the 4th parameter to the [sqlite3_vfs.xOpen] method.

Changes to src/sqliteInt.h.

  2796   2796   int sqlite3ExprListCompare(ExprList*, ExprList*);
  2797   2797   void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
  2798   2798   void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
  2799   2799   Vdbe *sqlite3GetVdbe(Parse*);
  2800   2800   void sqlite3PrngSaveState(void);
  2801   2801   void sqlite3PrngRestoreState(void);
  2802   2802   void sqlite3PrngResetState(void);
  2803         -void sqlite3RollbackAll(sqlite3*);
         2803  +void sqlite3RollbackAll(sqlite3*,int);
  2804   2804   void sqlite3CodeVerifySchema(Parse*, int);
  2805   2805   void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
  2806   2806   void sqlite3BeginTransaction(Parse*, int);
  2807   2807   void sqlite3CommitTransaction(Parse*);
  2808   2808   void sqlite3RollbackTransaction(Parse*);
  2809   2809   void sqlite3Savepoint(Parse*, int, Token*);
  2810   2810   void sqlite3CloseSavepoints(sqlite3 *);

Changes to src/vdbe.c.

  2680   2680         pSavepoint = pSavepoint->pNext
  2681   2681       ){
  2682   2682         iSavepoint++;
  2683   2683       }
  2684   2684       if( !pSavepoint ){
  2685   2685         sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName);
  2686   2686         rc = SQLITE_ERROR;
  2687         -    }else if( 
  2688         -        db->writeVdbeCnt>0 || (p1==SAVEPOINT_ROLLBACK && db->activeVdbeCnt>1) 
  2689         -    ){
         2687  +    }else if( db->writeVdbeCnt>0 && p1==SAVEPOINT_RELEASE ){
  2690   2688         /* It is not possible to release (commit) a savepoint if there are 
  2691         -      ** active write statements. It is not possible to rollback a savepoint
  2692         -      ** if there are any active statements at all.
         2689  +      ** active write statements.
  2693   2690         */
  2694   2691         sqlite3SetString(&p->zErrMsg, db, 
  2695         -        "cannot %s savepoint - SQL statements in progress",
  2696         -        (p1==SAVEPOINT_ROLLBACK ? "rollback": "release")
         2692  +        "cannot release savepoint - SQL statements in progress"
  2697   2693         );
  2698   2694         rc = SQLITE_BUSY;
  2699   2695       }else{
  2700   2696   
  2701   2697         /* Determine whether or not this is a transaction savepoint. If so,
  2702   2698         ** and this is a RELEASE command, then the current transaction 
  2703   2699         ** is committed. 
................................................................................
  2714   2710             p->rc = rc = SQLITE_BUSY;
  2715   2711             goto vdbe_return;
  2716   2712           }
  2717   2713           db->isTransactionSavepoint = 0;
  2718   2714           rc = p->rc;
  2719   2715         }else{
  2720   2716           iSavepoint = db->nSavepoint - iSavepoint - 1;
         2717  +        for(ii=0; ii<db->nDb; ii++){
         2718  +          sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, SQLITE_ABORT);
         2719  +        }
  2721   2720           for(ii=0; ii<db->nDb; ii++){
  2722   2721             rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
  2723   2722             if( rc!=SQLITE_OK ){
  2724   2723               goto abort_due_to_error;
  2725   2724             }
  2726   2725           }
  2727   2726           if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
................................................................................
  2782   2781     desiredAutoCommit = pOp->p1;
  2783   2782     iRollback = pOp->p2;
  2784   2783     turnOnAC = desiredAutoCommit && !db->autoCommit;
  2785   2784     assert( desiredAutoCommit==1 || desiredAutoCommit==0 );
  2786   2785     assert( desiredAutoCommit==1 || iRollback==0 );
  2787   2786     assert( db->activeVdbeCnt>0 );  /* At least this one VM is active */
  2788   2787   
         2788  +#if 0
  2789   2789     if( turnOnAC && iRollback && db->activeVdbeCnt>1 ){
  2790   2790       /* If this instruction implements a ROLLBACK and other VMs are
  2791   2791       ** still running, and a transaction is active, return an error indicating
  2792   2792       ** that the other VMs must complete first. 
  2793   2793       */
  2794   2794       sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - "
  2795   2795           "SQL statements in progress");
  2796   2796       rc = SQLITE_BUSY;
  2797         -  }else if( turnOnAC && !iRollback && db->writeVdbeCnt>0 ){
         2797  +  }else
         2798  +#endif
         2799  +  if( turnOnAC && !iRollback && db->writeVdbeCnt>0 ){
  2798   2800       /* If this instruction implements a COMMIT and other VMs are writing
  2799   2801       ** return an error indicating that the other VMs must complete first. 
  2800   2802       */
  2801   2803       sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
  2802   2804           "SQL statements in progress");
  2803   2805       rc = SQLITE_BUSY;
  2804   2806     }else if( desiredAutoCommit!=db->autoCommit ){
  2805   2807       if( iRollback ){
  2806   2808         assert( desiredAutoCommit==1 );
  2807         -      sqlite3RollbackAll(db);
         2809  +      sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
  2808   2810         db->autoCommit = 1;
  2809   2811       }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
  2810   2812         goto vdbe_return;
  2811   2813       }else{
  2812   2814         db->autoCommit = (u8)desiredAutoCommit;
  2813   2815         if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
  2814   2816           p->pc = pc;

Changes to src/vdbeaux.c.

  1998   1998     assert( cnt==db->activeVdbeCnt );
  1999   1999     assert( nWrite==db->writeVdbeCnt );
  2000   2000   }
  2001   2001   #else
  2002   2002   #define checkActiveVdbeCnt(x)
  2003   2003   #endif
  2004   2004   
  2005         -/*
  2006         -** For every Btree that in database connection db which 
  2007         -** has been modified, "trip" or invalidate each cursor in
  2008         -** that Btree might have been modified so that the cursor
  2009         -** can never be used again.  This happens when a rollback
  2010         -*** occurs.  We have to trip all the other cursors, even
  2011         -** cursor from other VMs in different database connections,
  2012         -** so that none of them try to use the data at which they
  2013         -** were pointing and which now may have been changed due
  2014         -** to the rollback.
  2015         -**
  2016         -** Remember that a rollback can delete tables complete and
  2017         -** reorder rootpages.  So it is not sufficient just to save
  2018         -** the state of the cursor.  We have to invalidate the cursor
  2019         -** so that it is never used again.
  2020         -*/
  2021         -static void invalidateCursorsOnModifiedBtrees(sqlite3 *db){
  2022         -  int i;
  2023         -  for(i=0; i<db->nDb; i++){
  2024         -    Btree *p = db->aDb[i].pBt;
  2025         -    if( p && sqlite3BtreeIsInTrans(p) ){
  2026         -      sqlite3BtreeTripAllCursors(p, SQLITE_ABORT);
  2027         -    }
  2028         -  }
  2029         -}
  2030         -
  2031   2005   /*
  2032   2006   ** If the Vdbe passed as the first argument opened a statement-transaction,
  2033   2007   ** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or
  2034   2008   ** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement
  2035   2009   ** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the 
  2036   2010   ** statement transaction is commtted.
  2037   2011   **
................................................................................
  2188   2162         if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){
  2189   2163           if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && p->usesStmtJournal ){
  2190   2164             eStatementOp = SAVEPOINT_ROLLBACK;
  2191   2165           }else{
  2192   2166             /* We are forced to roll back the active transaction. Before doing
  2193   2167             ** so, abort any other statements this handle currently has active.
  2194   2168             */
  2195         -          invalidateCursorsOnModifiedBtrees(db);
  2196         -          sqlite3RollbackAll(db);
         2169  +          sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
  2197   2170             sqlite3CloseSavepoints(db);
  2198   2171             db->autoCommit = 1;
  2199   2172           }
  2200   2173         }
  2201   2174       }
  2202   2175   
  2203   2176       /* Check for immediate foreign key violations. */
................................................................................
  2231   2204             rc = vdbeCommit(db, p);
  2232   2205           }
  2233   2206           if( rc==SQLITE_BUSY && p->readOnly ){
  2234   2207             sqlite3VdbeLeave(p);
  2235   2208             return SQLITE_BUSY;
  2236   2209           }else if( rc!=SQLITE_OK ){
  2237   2210             p->rc = rc;
  2238         -          sqlite3RollbackAll(db);
         2211  +          sqlite3RollbackAll(db, SQLITE_OK);
  2239   2212           }else{
  2240   2213             db->nDeferredCons = 0;
  2241   2214             sqlite3CommitInternalChanges(db);
  2242   2215           }
  2243   2216         }else{
  2244         -        sqlite3RollbackAll(db);
         2217  +        sqlite3RollbackAll(db, SQLITE_OK);
  2245   2218         }
  2246   2219         db->nStatement = 0;
  2247   2220       }else if( eStatementOp==0 ){
  2248   2221         if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
  2249   2222           eStatementOp = SAVEPOINT_RELEASE;
  2250   2223         }else if( p->errorAction==OE_Abort ){
  2251   2224           eStatementOp = SAVEPOINT_ROLLBACK;
  2252   2225         }else{
  2253         -        invalidateCursorsOnModifiedBtrees(db);
  2254         -        sqlite3RollbackAll(db);
         2226  +        sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
  2255   2227           sqlite3CloseSavepoints(db);
  2256   2228           db->autoCommit = 1;
  2257   2229         }
  2258   2230       }
  2259   2231     
  2260   2232       /* If eStatementOp is non-zero, then a statement transaction needs to
  2261   2233       ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to
................................................................................
  2267   2239         rc = sqlite3VdbeCloseStatement(p, eStatementOp);
  2268   2240         if( rc ){
  2269   2241           if( p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ){
  2270   2242             p->rc = rc;
  2271   2243             sqlite3DbFree(db, p->zErrMsg);
  2272   2244             p->zErrMsg = 0;
  2273   2245           }
  2274         -        invalidateCursorsOnModifiedBtrees(db);
  2275         -        sqlite3RollbackAll(db);
         2246  +        sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
  2276   2247           sqlite3CloseSavepoints(db);
  2277   2248           db->autoCommit = 1;
  2278   2249         }
  2279   2250       }
  2280   2251     
  2281   2252       /* If this was an INSERT, UPDATE or DELETE and no statement transaction
  2282   2253       ** has been rolled back, update the database connection change-counter. 

Changes to test/capi3.test.

   890    890   do_test capi3-11.9.1 {
   891    891     sqlite3_get_autocommit $DB
   892    892   } 0
   893    893   do_test capi3-11.9.2 {
   894    894     catchsql {
   895    895       ROLLBACK;
   896    896     }
   897         -} {1 {cannot rollback transaction - SQL statements in progress}}
          897  +} {0 {}}
   898    898   do_test capi3-11.9.3 {
   899    899     sqlite3_get_autocommit $DB
   900         -} 0
          900  +} 1
   901    901   do_test capi3-11.10 {
   902    902     sqlite3_step $STMT
   903         -} {SQLITE_ROW}
          903  +} {SQLITE_ERROR}
   904    904   do_test capi3-11.11 {
   905    905     sqlite3_step $STMT
   906    906   } {SQLITE_ROW}
   907    907   do_test capi3-11.12 {
          908  +  sqlite3_step $STMT
   908    909     sqlite3_step $STMT
   909    910   } {SQLITE_DONE}
   910    911   do_test capi3-11.13 {
   911    912     sqlite3_finalize $STMT
   912    913   } {SQLITE_OK}
   913    914   do_test capi3-11.14 {
   914    915     execsql {
   915    916       SELECT a FROM t2;
   916    917     }
   917         -} {1 2 3}
          918  +} {1 2}
   918    919   do_test capi3-11.14.1 {
   919    920     sqlite3_get_autocommit $DB
   920         -} 0
          921  +} 1
   921    922   do_test capi3-11.15 {
   922    923     catchsql {
   923    924       ROLLBACK;
   924    925     }
   925         -} {0 {}}
          926  +} {1 {cannot rollback - no transaction is active}}
   926    927   do_test capi3-11.15.1 {
   927    928     sqlite3_get_autocommit $DB
   928    929   } 1
   929    930   do_test capi3-11.16 {
   930    931     execsql {
   931    932       SELECT a FROM t2;
   932    933     }

Changes to test/capi3c.test.

   845    845   do_test capi3c-11.9.1 {
   846    846     sqlite3_get_autocommit $DB
   847    847   } 0
   848    848   do_test capi3c-11.9.2 {
   849    849     catchsql {
   850    850       ROLLBACK;
   851    851     }
   852         -} {1 {cannot rollback transaction - SQL statements in progress}}
          852  +} {0 {}}
   853    853   do_test capi3c-11.9.3 {
   854    854     sqlite3_get_autocommit $DB
   855         -} 0
          855  +} 1
   856    856   do_test capi3c-11.10 {
   857    857     sqlite3_step $STMT
   858         -} {SQLITE_ROW}
          858  +} {SQLITE_ABORT}
   859    859   do_test capi3c-11.11 {
   860    860     sqlite3_step $STMT
   861    861   } {SQLITE_ROW}
   862    862   do_test capi3c-11.12 {
          863  +  sqlite3_step $STMT
   863    864     sqlite3_step $STMT
   864    865   } {SQLITE_DONE}
   865    866   do_test capi3c-11.13 {
   866    867     sqlite3_finalize $STMT
   867    868   } {SQLITE_OK}
   868    869   do_test capi3c-11.14 {
   869    870     execsql {
   870    871       SELECT a FROM t2;
   871    872     }
   872         -} {1 2 3}
          873  +} {1 2}
   873    874   do_test capi3c-11.14.1 {
   874    875     sqlite3_get_autocommit $DB
   875         -} 0
          876  +} 1
   876    877   do_test capi3c-11.15 {
   877    878     catchsql {
   878    879       ROLLBACK;
   879    880     }
   880         -} {0 {}}
          881  +} {1 {cannot rollback - no transaction is active}}
   881    882   do_test capi3c-11.15.1 {
   882    883     sqlite3_get_autocommit $DB
   883    884   } 1
   884    885   do_test capi3c-11.16 {
   885    886     execsql {
   886    887       SELECT a FROM t2;
   887    888     }

Changes to test/incrblob.test.

   469    469     } {10}
   470    470     do_test incrblob-6.9 {
   471    471       seek $::blob 0
   472    472       puts -nonewline $::blob "invocation"
   473    473       flush $::blob
   474    474     } {}
   475    475     
   476         -  # At this point rollback should be illegal (because 
   477         -  # there is an open blob channel).  But commit is also illegal because
   478         -  # the open blob is read-write.
          476  +  # At this point commit should be illegal (because 
          477  +  # there is an open blob channel).
   479    478     #
   480         -  do_test incrblob-6.10 {
   481         -    catchsql {
   482         -      ROLLBACK;
   483         -    } db2
   484         -  } {1 {cannot rollback transaction - SQL statements in progress}}
   485    479     do_test incrblob-6.11 {
   486    480       catchsql {
   487    481         COMMIT;
   488    482       } db2
   489    483     } {1 {cannot commit transaction - SQL statements in progress}}
   490    484     
   491    485     do_test incrblob-6.12 {

Changes to test/savepoint.test.

   299    299       catchsql {RELEASE abc}
   300    300     } {1 {no such savepoint: abc}}
   301    301     
   302    302     do_test savepoint-5.3.1 {
   303    303       execsql  {SAVEPOINT abc}
   304    304       catchsql {ROLLBACK TO def}
   305    305     } {1 {no such savepoint: def}}
   306         -  do_test savepoint-5.3.2 {
          306  +  do_test savepoint-5.3.2.1 {
   307    307       execsql  {SAVEPOINT def}
   308    308       set fd [db incrblob -readonly blobs x 1]
          309  +    set rc [catch {seek $fd 0;read $fd} res]
          310  +    lappend rc $res
          311  +  } {0 {hellontyeight character blob}}
          312  +  do_test savepoint-5.3.2.2 {
   309    313       catchsql {ROLLBACK TO def}
   310         -  } {1 {cannot rollback savepoint - SQL statements in progress}}
          314  +  } {0 {}}
          315  +  do_test savepoint-5.3.2.3 {
          316  +    set rc [catch {seek $fd 0; read $fd} res]
          317  +    set rc
          318  +  } {1}
   311    319     do_test savepoint-5.3.3 {
   312    320       catchsql  {RELEASE def}
   313    321     } {0 {}}
   314    322     do_test savepoint-5.3.4 {
   315    323       close $fd
   316    324       execsql  {savepoint def}
   317    325       set fd [db incrblob blobs x 1]

Changes to test/shared2.test.

    75     75           DELETE FROM numbers;
    76     76         } db1
    77     77       }
    78     78     }
    79     79     list $a $count
    80     80   } {32 64}
    81     81   
    82         -#---------------------------------------------------------------------------
    83         -# These tests, shared2.2.*, test the outcome when data is added to or 
    84         -# removed from a table due to a rollback while a read-uncommitted 
    85         -# cursor is scanning it.
    86         -#
    87         -do_test shared2-2.1 {
    88         -  execsql {
    89         -    INSERT INTO numbers VALUES(1, 'Medium length text field');
    90         -    INSERT INTO numbers VALUES(2, 'Medium length text field');
    91         -    INSERT INTO numbers VALUES(3, 'Medium length text field');
    92         -    INSERT INTO numbers VALUES(4, 'Medium length text field');
    93         -    BEGIN;
    94         -    DELETE FROM numbers WHERE (a%2)=0;
    95         -  } db1
    96         -  set res [list]
    97         -  db2 eval {
    98         -    SELECT a FROM numbers ORDER BY a;
    99         -  } {
   100         -    lappend res $a
   101         -    if {$a==3} {
   102         -      execsql {ROLLBACK} db1
   103         -    }
   104         -  }
   105         -  set res
   106         -} {1 3 4}
   107         -do_test shared2-2.2 {
   108         -  execsql {
   109         -    BEGIN;
   110         -    INSERT INTO numbers VALUES(5, 'Medium length text field');
   111         -    INSERT INTO numbers VALUES(6, 'Medium length text field');
   112         -  } db1
   113         -  set res [list]
   114         -  db2 eval {
   115         -    SELECT a FROM numbers ORDER BY a;
   116         -  } {
   117         -    lappend res $a
   118         -    if {$a==5} {
   119         -      execsql {ROLLBACK} db1
   120         -    }
   121         -  }
   122         -  set res
   123         -} {1 2 3 4 5}
   124     82   
   125     83   db1 close
   126     84   db2 close
   127     85   
   128     86   do_test shared2-3.2 {
   129     87     sqlite3_enable_shared_cache 1
   130     88   } {1}

Changes to test/tkt-f777251dc7a.test.

    38     38   db function force_rollback force_rollback
    39     39   
    40     40   do_test tkt-f7772-1.2 {
    41     41     catchsql {
    42     42       BEGIN IMMEDIATE;
    43     43       SELECT x, force_rollback(), EXISTS(SELECT 1 FROM t3 WHERE w=x) FROM t2;
    44     44     }
    45         -} {1 {callback requested query abort}}
           45  +} {1 {abort due to ROLLBACK}}
    46     46   do_test tkt-f7772-1.3 {
    47     47     sqlite3_get_autocommit db
    48     48   } {1}
    49     49   
    50     50   do_test tkt-f7772-2.1 {
    51     51     execsql {
    52     52        DROP TABLE IF EXISTS t1;

Changes to test/trans3.test.

    60     60           if {[catch {db eval ROLLBACK} errmsg]} {
    61     61              set ::ecode [sqlite3_extended_errcode db]
    62     62              error $errmsg
    63     63           }
    64     64        }
    65     65     } errmsg]
    66     66     lappend x $errmsg
    67         -} {1 {cannot rollback transaction - SQL statements in progress}}
           67  +} {1 {abort due to ROLLBACK}}
    68     68   do_test trans3-1.6 {
    69     69     set ::ecode
    70         -} {SQLITE_BUSY}
           70  +} {}
    71     71   do_test trans3-1.7 {
    72         -  db eval COMMIT
    73     72     db eval {SELECT * FROM t1}
    74         -} {1 2 3 4 5}
           73  +} {1 2 3 4}
    75     74   unset -nocomplain ecode
    76     75   
    77     76   finish_test