]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add read-transactions to the btree and vdbe. The compiler doesn't invoke
authordanielk1977 <danielk1977@noemail.net>
Mon, 31 May 2004 10:01:34 +0000 (10:01 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Mon, 31 May 2004 10:01:34 +0000 (10:01 +0000)
them yet. (CVS 1502)

FossilOrigin-Name: 6b43633a96c674a5d470578ef80ebf2227da0682

manifest
manifest.uuid
src/btree.c
src/btree.h
src/build.c
src/test3.c
src/vacuum.c
src/vdbe.c
src/vdbeaux.c

index 9dd0e5372378336dc7c928857bbfc47bf863470a..351ed714df6cd407a3eb7b42b745c17b70d91410 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\sthe\s<ON\sCONFLICT>\sclause\sfrom\sBEGIN\s(CVS\s1501)
-D 2004-05-31T08:55:34
+C Add\sread-transactions\sto\sthe\sbtree\sand\svdbe.\sThe\scompiler\sdoesn't\sinvoke\nthem\syet.\s(CVS\s1502)
+D 2004-05-31T10:01:35
 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -24,9 +24,9 @@ F sqlite.def fc4f5734786fe4743cfe2aa98eb2da4b089edb5f
 F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
 F src/attach.c c315c58cb16fd6e913b3bfa6412aedecb4567fa5
 F src/auth.c 5c2f0bea4729c98c2be3b69d6b466fc51448fe79
-F src/btree.c 07d0d93ba0e6f54a0f67e665d264b0bc6ab70edb
-F src/btree.h 61d670f418fa6bd88b6d2731f05fcf8b19d3ec45
-F src/build.c 774193e2fb0d1e6492735bcc909d525898c61204
+F src/btree.c 652efb14a17ba26759f73ca167f7d1e5d6651eb3
+F src/btree.h 1e2beb41b4b4a4fc41da67cb4692614938066f2f
+F src/build.c 8fd4c1a7df5761ff95dd0e57e82b2c08ab88bbce
 F src/date.c 0eb922af5c5f5e2455f8dc2f98023ed3e04a857e
 F src/delete.c 72f8febf6170cda830f509c8f9dffbed3df3596c
 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
@@ -60,7 +60,7 @@ F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
 F src/tclsqlite.c b314f12760547e4ef090e055f1298f70627450d3
 F src/test1.c 32934478366531503d634968db414df17cb38238
 F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872
-F src/test3.c 48f14101bde4be18b351a6db977cc30b349bf1c0
+F src/test3.c 86117b74ec7353d76f5cd85c144c7cda23a7e11b
 F src/test4.c 34848a9fd31aa65857b20a8bfc03aff77d8c3426
 F src/test5.c 9a1f15133f6955f067c5246e564723b5f23ff221
 F src/tokenize.c 50a87c7414de54a008427c9fed22e4e86efb6844
@@ -68,12 +68,12 @@ F src/trigger.c 04b2c310d0d056b213609cab6df5fff03d5eaf88
 F src/update.c 259f06e7b22c684b2d3dda54a18185892d6e9573
 F src/utf.c f8604999a54483533ac20a63879074f01b0df384
 F src/util.c 3b647719c0bece41491300b605cff96a7a26f03a
-F src/vacuum.c 16d1b4ab976f19f01aa626bfdac9fee5e2cce03c
-F src/vdbe.c 3cc9b3ab6c4e5b10168d56f09b6864ccb5b50f81
+F src/vacuum.c c91acc316127411980982938d050b299d42b81ef
+F src/vdbe.c fdb990a681d39872047fec65fffaedb7225e7420
 F src/vdbe.h e73f890e0f2a6c42b183d7d6937947930fe4fdeb
 F src/vdbeInt.h 51d37798ba7bc5f2f767db0e3dbae31156ae9ff3
 F src/vdbeapi.c d43d36efeaf709bae71b743aaaee430e0b29cd1e
-F src/vdbeaux.c 9cad713e47e6e684852dfc12ef6e326fb4a2ca76
+F src/vdbeaux.c 32ff5754d489b8e7dd4fa53762e6c02d028cb7d9
 F src/vdbemem.c 627d714c347f6af8092cc48ae1c06fd774a1ad9c
 F src/where.c 444a7c3a8b1eb7bba072e489af628555d21d92a4
 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
@@ -204,7 +204,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P b8ed812c92f2dbb4431d45aeb41646ceb53e0cbc
-R 0a7b9b75e1ce69dd86720403c073375e
+P 9029274b6129140064bd7ac34df7eaba00d28efb
+R e95c108b61d714bdf621bb4346f565fc
 U danielk1977
-Z 97096496cbbd5e8936b9c4165e249994
+Z 566da064bb78af6ca09baccb5cb6e57b
index b652e81cffa25e167441cd2901ba37472b911dbe..3ecb91cf6595513b8c7db25cafbc77af1038df2f 100644 (file)
@@ -1 +1 @@
-9029274b6129140064bd7ac34df7eaba00d28efb
\ No newline at end of file
+6b43633a96c674a5d470578ef80ebf2227da0682
\ No newline at end of file
index 86b98d6718744202ee18d030b3632012200a6cd3..ac526ef2ddf6d69c38fa4ac062c928740de485b5 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.153 2004/05/31 08:26:49 danielk1977 Exp $
+** $Id: btree.c,v 1.154 2004/05/31 10:01:35 danielk1977 Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -316,6 +316,13 @@ struct Btree {
 };
 typedef Btree Bt;
 
+/*
+** Btree.inTrans may take one of the following values.
+*/
+#define TRANS_NONE  0
+#define TRANS_READ  1
+#define TRANS_WRITE 2
+
 /*
 ** An instance of the following structure is used to hold information
 ** about a cell.  The parseCellPtr() function fills in this structure
@@ -1142,10 +1149,9 @@ page1_init_failed:
 ** If there is a transaction in progress, this routine is a no-op.
 */
 static void unlockBtreeIfUnused(Btree *pBt){
-  if( pBt->inTrans==0 && pBt->pCursor==0 && pBt->pPage1!=0 ){
+  if( pBt->inTrans==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){
     releasePage(pBt->pPage1);
     pBt->pPage1 = 0;
-    pBt->inTrans = 0;
     pBt->inStmt = 0;
   }
 }
@@ -1179,11 +1185,13 @@ static int newDatabase(Btree *pBt){
 }
 
 /*
-** Attempt to start a new transaction.
+** Attempt to start a new transaction. A write-transaction
+** is started if the second argument is true, otherwise a read-
+** transaction.
 **
-** A transaction must be started before attempting any changes
-** to the database.  None of the following routines will work
-** unless a transaction is started first:
+** A write-transaction must be started before attempting any 
+** changes to the database.  None of the following routines 
+** will work unless a transaction is started first:
 **
 **      sqlite3BtreeCreateTable()
 **      sqlite3BtreeCreateIndex()
@@ -1193,23 +1201,35 @@ static int newDatabase(Btree *pBt){
 **      sqlite3BtreeDelete()
 **      sqlite3BtreeUpdateMeta()
 */
-int sqlite3BtreeBeginTrans(Btree *pBt){
-  int rc;
-  if( pBt->inTrans ) return SQLITE_ERROR;
-  if( pBt->readOnly ) return SQLITE_READONLY;
+int sqlite3BtreeBeginTrans(Btree *pBt, int wrflag){
+  int rc = SQLITE_OK;
+
+  /* If the btree is already in a write-transaction, or it
+  ** is already in a read-transaction and a read-transaction
+  ** is requested, this is a no-op.
+  */
+  if( pBt->inTrans==TRANS_WRITE || 
+      (pBt->inTrans==TRANS_READ && !wrflag) ){
+    return SQLITE_OK;
+  }
+  if( pBt->readOnly && wrflag ){
+    return SQLITE_READONLY;
+  }
+
   if( pBt->pPage1==0 ){
     rc = lockBtree(pBt);
-    if( rc!=SQLITE_OK ){
-      return rc;
-    }
   }
-  rc = sqlite3pager_begin(pBt->pPage1->aData);
-  if( rc==SQLITE_OK ){
-    rc = newDatabase(pBt);
+
+  if( rc==SQLITE_OK && wrflag ){
+    rc = sqlite3pager_begin(pBt->pPage1->aData);
+    if( rc==SQLITE_OK ){
+      rc = newDatabase(pBt);
+    }
   }
+
   if( rc==SQLITE_OK ){
-    pBt->inTrans = 1;
-    pBt->inStmt = 0;
+    pBt->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);
+    if( wrflag ) pBt->inStmt = 0;
   }else{
     unlockBtreeIfUnused(pBt);
   }
@@ -1223,9 +1243,11 @@ int sqlite3BtreeBeginTrans(Btree *pBt){
 ** are no active cursors, it also releases the read lock.
 */
 int sqlite3BtreeCommit(Btree *pBt){
-  int rc;
-  rc = pBt->readOnly ? SQLITE_OK : sqlite3pager_commit(pBt->pPager);
-  pBt->inTrans = 0;
+  int rc = SQLITE_OK;
+  if( pBt->inTrans==TRANS_WRITE ){
+    rc = sqlite3pager_commit(pBt->pPager);
+  }
+  pBt->inTrans = TRANS_NONE;
   pBt->inStmt = 0;
   unlockBtreeIfUnused(pBt);
   return rc;
@@ -1278,12 +1300,7 @@ void sqlite3BtreeCursorList(Btree *pBt){
 int sqlite3BtreeRollback(Btree *pBt){
   int rc;
   MemPage *pPage1;
-  if( pBt->inTrans==0 ) return SQLITE_OK;
-  pBt->inTrans = 0;
-  pBt->inStmt = 0;
-  if( pBt->readOnly ){
-    rc = SQLITE_OK;
-  }else{
+  if( pBt->inTrans==TRANS_WRITE ){
     rc = sqlite3pager_rollback(pBt->pPager);
     /* The rollback may have destroyed the pPage1->aData value.  So
     ** call getPage() on page 1 again to make sure pPage1->aData is
@@ -1291,8 +1308,10 @@ int sqlite3BtreeRollback(Btree *pBt){
     if( getPage(pBt, 1, &pPage1)==SQLITE_OK ){
       releasePage(pPage1);
     }
+    invalidateCursors(pBt);
   }
-  invalidateCursors(pBt);
+  pBt->inTrans = TRANS_NONE;
+  pBt->inStmt = 0;
   unlockBtreeIfUnused(pBt);
   return rc;
 }
@@ -1314,7 +1333,7 @@ int sqlite3BtreeRollback(Btree *pBt){
 */
 int sqlite3BtreeBeginStmt(Btree *pBt){
   int rc;
-  if( !pBt->inTrans || pBt->inStmt ){
+  if( (pBt->inTrans!=TRANS_WRITE) || pBt->inStmt ){
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
   rc = pBt->readOnly ? SQLITE_OK : sqlite3pager_stmt_begin(pBt->pPager);
@@ -3360,7 +3379,7 @@ int sqlite3BtreeInsert(
   if( pCur->status ){
     return pCur->status;  /* A rollback destroyed this cursor */
   }
-  if( !pBt->inTrans ){
+  if( pBt->inTrans!=TRANS_WRITE ){
     /* Must start a transaction before doing an insert */
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
@@ -3427,7 +3446,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
   if( pCur->status ){
     return pCur->status;  /* A rollback destroyed this cursor */
   }
-  if( !pBt->inTrans ){
+  if( pBt->inTrans!=TRANS_WRITE ){
     /* Must start a transaction before doing a delete */
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
@@ -3508,7 +3527,7 @@ int sqlite3BtreeCreateTable(Btree *pBt, int *piTable, int flags){
   MemPage *pRoot;
   Pgno pgnoRoot;
   int rc;
-  if( !pBt->inTrans ){
+  if( pBt->inTrans!=TRANS_WRITE ){
     /* Must start a transaction first */
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
@@ -3577,7 +3596,7 @@ static int clearDatabasePage(
 int sqlite3BtreeClearTable(Btree *pBt, int iTable){
   int rc;
   BtCursor *pCur;
-  if( !pBt->inTrans ){
+  if( pBt->inTrans!=TRANS_WRITE ){
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
   for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
@@ -3605,7 +3624,7 @@ int sqlite3BtreeDropTable(Btree *pBt, int iTable){
   int rc;
   MemPage *pPage;
   BtCursor *pCur;
-  if( !pBt->inTrans ){
+  if( pBt->inTrans!=TRANS_WRITE ){
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
   for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
@@ -3657,7 +3676,7 @@ int sqlite3BtreeUpdateMeta(Btree *pBt, int idx, u32 iMeta){
   unsigned char *pP1;
   int rc;
   assert( idx>=1 && idx<=15 );
-  if( !pBt->inTrans ){
+  if( pBt->inTrans!=TRANS_WRITE ){
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
   assert( pBt->pPage1!=0 );
@@ -4153,7 +4172,9 @@ int sqlite3BtreeCopyFile(Btree *pBtTo, Btree *pBtFrom){
   int rc = SQLITE_OK;
   Pgno i, nPage, nToPage;
 
-  if( !pBtTo->inTrans || !pBtFrom->inTrans ) return SQLITE_ERROR;
+  if( pBtTo->inTrans!=TRANS_WRITE || pBtFrom->inTrans!=TRANS_WRITE ){
+    return SQLITE_ERROR;
+  }
   if( pBtTo->pCursor ) return SQLITE_BUSY;
   memcpy(pBtTo->pPage1->aData, pBtFrom->pPage1->aData, pBtFrom->usableSize);
   rc = sqlite3pager_overwrite(pBtTo->pPager, 1, pBtFrom->pPage1->aData);
@@ -4188,7 +4209,7 @@ int sqlite3BtreeCopyFile(Btree *pBtTo, Btree *pBtFrom){
 ** Return non-zero if a transaction is active.
 */
 int sqlite3BtreeIsInTrans(Btree *pBt){
-  return (pBt && pBt->inTrans);
+  return (pBt && (pBt->inTrans==TRANS_WRITE));
 }
 
 /*
index c6c4f08bc258007b011edaab20d6339868aa6e84..931cca990ce42109c219fb07c546b3f62cd1c9d5 100644 (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.50 2004/05/31 08:26:49 danielk1977 Exp $
+** @(#) $Id: btree.h,v 1.51 2004/05/31 10:01:35 danielk1977 Exp $
 */
 #ifndef _BTREE_H_
 #define _BTREE_H_
@@ -41,7 +41,7 @@ int sqlite3BtreeOpen(const char *zFilename, Btree **, int nCache, int flags);
 int sqlite3BtreeClose(Btree*);
 int sqlite3BtreeSetCacheSize(Btree*,int);
 int sqlite3BtreeSetSafetyLevel(Btree*,int);
-int sqlite3BtreeBeginTrans(Btree*);
+int sqlite3BtreeBeginTrans(Btree*,int);
 int sqlite3BtreeCommit(Btree*);
 int sqlite3BtreeRollback(Btree*);
 int sqlite3BtreeBeginStmt(Btree*);
index 52e7827774c18f4a3b246b2c28132bf71461b818..c2ce6a7aab5cb4ebe3e831f319b988f4c588ad49 100644 (file)
@@ -23,7 +23,7 @@
 **     ROLLBACK
 **     PRAGMA
 **
-** $Id: build.c,v 1.202 2004/05/31 08:55:34 danielk1977 Exp $
+** $Id: build.c,v 1.203 2004/05/31 10:01:35 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -555,8 +555,8 @@ void sqlite3StartTable(
       pParse->nErr++;
       return;
     }
-    if( db->flags & SQLITE_InTrans ){
-      rc = sqlite3BtreeBeginTrans(db->aDb[1].pBt);
+    if( db->flags & !db->autoCommit ){
+      rc = sqlite3BtreeBeginTrans(db->aDb[1].pBt, 1);
       if( rc!=SQLITE_OK ){
         sqlite3ErrorMsg(pParse, "unable to get a write lock on "
           "the temporary database file");
@@ -2255,7 +2255,7 @@ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
 void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
   Vdbe *v = sqlite3GetVdbe(pParse);
   if( v==0 ) return;
-  sqlite3VdbeAddOp(v, OP_Transaction, iDb, 0);
+  sqlite3VdbeAddOp(v, OP_Transaction, iDb, 1);
   sqlite3CodeVerifySchema(pParse, iDb);
   if( setStatement ){
     sqlite3VdbeAddOp(v, OP_Statement, iDb, 0);
index 5c03c7a0703f7bba91ea05e9f3742376e58dcc57..da90cfaaca3919906626c7ba089bbab85f7150c5 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test3.c,v 1.40 2004/05/31 08:26:49 danielk1977 Exp $
+** $Id: test3.c,v 1.41 2004/05/31 10:01:35 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "pager.h"
@@ -129,7 +129,7 @@ static int btree_begin_transaction(
     return TCL_ERROR;
   }
   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
-  rc = sqlite3BtreeBeginTrans(pBt);
+  rc = sqlite3BtreeBeginTrans(pBt, 1);
   if( rc!=SQLITE_OK ){
     Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
index ff0a5b4fbe7915b12e4c6653ccf926e4abd5dd13..d0fca6ea4986c6656c8426969c65d2ad8244c14e 100644 (file)
@@ -14,7 +14,7 @@
 ** Most of the code in this file may be omitted by defining the
 ** SQLITE_OMIT_VACUUM macro.
 **
-** $Id: vacuum.c,v 1.19 2004/05/31 08:26:49 danielk1977 Exp $
+** $Id: vacuum.c,v 1.20 2004/05/31 10:01:35 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -196,7 +196,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite *db){
     u32 meta;
 
     assert( 0==sqlite3BtreeIsInTrans(pMain) );
-    rc = sqlite3BtreeBeginTrans(db->aDb[0].pBt);
+    rc = sqlite3BtreeBeginTrans(db->aDb[0].pBt, 1);
     if( rc!=SQLITE_OK ) goto end_of_vacuum;
 
     /* Copy Btree meta values 3 and 4. These correspond to SQL layer meta 
index 787b0eeffec7039bfbd57e657ede5069ac2c057d..390924b5d6432cf3094b101a8dcd1d4e26146cf7 100644 (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.351 2004/05/31 08:26:49 danielk1977 Exp $
+** $Id: vdbe.c,v 1.352 2004/05/31 10:01:35 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -2234,7 +2234,7 @@ case OP_AutoCommit: {
   break;
 }
 
-/* Opcode: Transaction P1 * *
+/* Opcode: Transaction P1 P2 *
 **
 ** Begin a transaction.  The transaction ends when a Commit or Rollback
 ** opcode is encountered.  Depending on the ON CONFLICT setting, the
@@ -2244,11 +2244,14 @@ case OP_AutoCommit: {
 ** started.  Index 0 is the main database file and index 1 is the
 ** file used for temporary tables.
 **
-** A write lock is obtained on the database file when a transaction is
-** started.  No other process can read or write the file while the
-** transaction is underway.  Starting a transaction also creates a
-** rollback journal.  A transaction must be started before any changes
-** can be made to the database.
+** If P2 is non-zero, then a write-transaction is started.  A write lock is
+** obtained on the database file when a write-transaction is started.  No
+** other process can read or write the file while the transaction is
+** underway.  Starting a transaction also creates a rollback journal.  A
+** transaction must be started before any changes can be made to the
+** database.
+**
+** If P2 is zero, then a read-lock is obtained on the database file.
 */
 case OP_Transaction: {
   int busy = 1;
@@ -2258,9 +2261,8 @@ case OP_Transaction: {
   assert( i>=0 && i<db->nDb );
   pBt = db->aDb[i].pBt;
 
-  if( sqlite3BtreeIsInTrans(pBt) ) break;
-  while( pBt && busy /* && !sqlite3BtreeIsInTrans(pBt) */ ){
-    rc = sqlite3BtreeBeginTrans(db->aDb[i].pBt);
+  while( pBt && busy ){
+    rc = sqlite3BtreeBeginTrans(db->aDb[i].pBt, pOp->p2);
     switch( rc ){
       case SQLITE_BUSY: {
         if( db->xBusyCallback==0 ){
@@ -2526,7 +2528,7 @@ case OP_OpenTemp: {
   rc = sqlite3BtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
 
   if( rc==SQLITE_OK ){
-    rc = sqlite3BtreeBeginTrans(pCx->pBt);
+    rc = sqlite3BtreeBeginTrans(pCx->pBt, 1);
   }
   if( rc==SQLITE_OK ){
     /* If a transient index is required, create it by calling
index 60e785361a9f72660b06612b4f8401018b495d42..adf9b29de5a8409164368c8c7b7d2a61cf678514 100644 (file)
@@ -979,9 +979,9 @@ int sqlite3VdbeReset(Vdbe *p, char **pzErrMsg){
   }
 
   for(i=0; xFunc && i<db->nDb; i++){
+    int rc;
     Btree *pBt = db->aDb[i].pBt;
     if( sqlite3BtreeIsInTrans(pBt) ){
-      int rc;
       if( db->xCommitCallback && needXcommit ){
         if( db->xCommitCallback(db->pCommitArg)!=0 ){
           p->rc = SQLITE_CONSTRAINT;
@@ -990,9 +990,9 @@ int sqlite3VdbeReset(Vdbe *p, char **pzErrMsg){
         }
         needXcommit = 0;
       }
-      rc = xFunc(pBt);
-      if( p->rc==SQLITE_OK ) p->rc = rc;
     }
+    rc = xFunc(pBt);
+    if( p->rc==SQLITE_OK ) p->rc = rc;
   }