]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Replace OP_Begin, OP_Commit and OP_Rollback with OP_AutoCommit. (CVS 1500)
authordanielk1977 <danielk1977@noemail.net>
Mon, 31 May 2004 08:26:49 +0000 (08:26 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Mon, 31 May 2004 08:26:49 +0000 (08:26 +0000)
FossilOrigin-Name: b8ed812c92f2dbb4431d45aeb41646ceb53e0cbc

24 files changed:
manifest
manifest.uuid
src/btree.c
src/btree.h
src/build.c
src/main.c
src/pager.c
src/pragma.c
src/sqliteInt.h
src/test3.c
src/trigger.c
src/vacuum.c
src/vdbe.c
src/vdbeInt.h
src/vdbeapi.c
src/vdbeaux.c
test/attach.test
test/attach2.test
test/conflict.test
test/hook.test
test/lock.test
test/misc1.test
test/progress.test
test/trans.test

index 45d54fa70d77555ec2adc3e2fb0ac7b89ef36768..c61402af929864a1cd38efc9f536317eab92479e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\s3-byte\sand\s6-byte\sinteger\sserial\stypes.\s\sThis\smakes\sdatabases\ssmaller\nand\sfaster.\s\sShould\swe\sgo\sahead\sand\sadd\s5-\sand\s7-byte\sinteger\stypes\stoo?\s(CVS\s1499)
-D 2004-05-30T21:14:59
+C Replace\sOP_Begin,\sOP_Commit\sand\sOP_Rollback\swith\sOP_AutoCommit.\s(CVS\s1500)
+D 2004-05-31T08:26:49
 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 3b7ddd0dd491c265227a045b9575786c7947cf49
-F src/btree.h 512706898e248fc5ec9237b9b535cffb9b53f9cd
-F src/build.c fd36c4a603e23df35aa7f57772d965e1865e39e0
+F src/btree.c 07d0d93ba0e6f54a0f67e665d264b0bc6ab70edb
+F src/btree.h 61d670f418fa6bd88b6d2731f05fcf8b19d3ec45
+F src/build.c df54499bdf0eced593e5074fae25f6d73ebb1411
 F src/date.c 0eb922af5c5f5e2455f8dc2f98023ed3e04a857e
 F src/delete.c 72f8febf6170cda830f509c8f9dffbed3df3596c
 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
@@ -36,7 +36,7 @@ F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
 F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
 F src/insert.c 0c7966dba4cd5698e393e824f162d520e96b1978
 F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f
-F src/main.c 79f8142ee2dbf0e3b1f60251515fcf4a1339e784
+F src/main.c 4f1dd19db1a37c8617142ef053ed4398d9069daf
 F src/md5.c d2c738fedfb27f73cefcf2b0ac1f9f21894b073e
 F src/os.h ab42f4a7c4c716f26b988e759b6e12085a3bfc67
 F src/os_common.h 744286a27de55c52f1b18921e8d17abbf7fafc0f
@@ -46,39 +46,39 @@ F src/os_unix.c 585665eccd31a9bb4dc090bc6b5e29d8d42899f0
 F src/os_unix.h 426e1480f0847a7f8ba22aa9ac5115520875610b
 F src/os_win.c 92b51a38437b98d8aa3ac05b57c71e1d1092e5be
 F src/os_win.h 5d41af24caaef6c13a2d8e2399caa1c57d45c84d
-F src/pager.c 6ff6b906427d4824099140776cb8768f922f3dc5
+F src/pager.c 048872f1ccd27e4c17d77098eb6e86990a7a9b88
 F src/pager.h 78a00ac280899bcba1a89dc51585dcae6b7b3253
 F src/parse.y facaa7d07885fb9d53ec8fd676705715d3942b0f
-F src/pragma.c 84e778a73eb6a14c1a328d75f70355cb51c22803
+F src/pragma.c 7f432dee3c94460638df1e5fffeb59a560943d13
 F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53
 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
 F src/select.c 0297717eb7331604687c2e29c147d3a311359df1
 F src/shell.c ed4d237b3e52a0a42512bfcc53530e46de20c28f
 F src/sqlite.h.in edc6408c7f53c2104f781a76b926036e17018ec9
-F src/sqliteInt.h 01f9250ee3a1ab681b7ed91ad2b3748c2f230521
+F src/sqliteInt.h 576c2d7828e538873c40da7b728c912c2b5a94d1
 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
 F src/tclsqlite.c b314f12760547e4ef090e055f1298f70627450d3
 F src/test1.c 32934478366531503d634968db414df17cb38238
 F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872
-F src/test3.c 32d35d15ac821f597a58353bb7b0141085259a24
+F src/test3.c 48f14101bde4be18b351a6db977cc30b349bf1c0
 F src/test4.c 34848a9fd31aa65857b20a8bfc03aff77d8c3426
 F src/test5.c 9a1f15133f6955f067c5246e564723b5f23ff221
 F src/tokenize.c 50a87c7414de54a008427c9fed22e4e86efb6844
-F src/trigger.c 258ed8f9583c6b80e5af401cb9cce345c0c689c3
+F src/trigger.c 04b2c310d0d056b213609cab6df5fff03d5eaf88
 F src/update.c 259f06e7b22c684b2d3dda54a18185892d6e9573
 F src/utf.c f8604999a54483533ac20a63879074f01b0df384
 F src/util.c 3b647719c0bece41491300b605cff96a7a26f03a
-F src/vacuum.c 82ce1fc8ecc2e1aa284c13fe38446709f9936c63
-F src/vdbe.c 8c99c3c1e4b29b62a3e19e84b207b0fe84c45c46
+F src/vacuum.c 16d1b4ab976f19f01aa626bfdac9fee5e2cce03c
+F src/vdbe.c 3cc9b3ab6c4e5b10168d56f09b6864ccb5b50f81
 F src/vdbe.h e73f890e0f2a6c42b183d7d6937947930fe4fdeb
-F src/vdbeInt.h c2bcd6e5a6e6a3753e4c5a368629c3a625719bfc
-F src/vdbeapi.c 0c5d64c81871cb4fe5407e639604ee95738b6942
-F src/vdbeaux.c c7e66db2b52b3c816adbdec81581b5e7ad257639
+F src/vdbeInt.h 51d37798ba7bc5f2f767db0e3dbae31156ae9ff3
+F src/vdbeapi.c d43d36efeaf709bae71b743aaaee430e0b29cd1e
+F src/vdbeaux.c 9cad713e47e6e684852dfc12ef6e326fb4a2ca76
 F src/vdbemem.c 627d714c347f6af8092cc48ae1c06fd774a1ad9c
 F src/where.c 444a7c3a8b1eb7bba072e489af628555d21d92a4
 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
-F test/attach.test 0dd7cf9bf9bc915bce2da4fb616c4ea9c3da64af
-F test/attach2.test 5472d442bb2ef1ee587e0ae7472bb68b52509a38
+F test/attach.test 379d5b1c6b907c682db293811fd8210715c42721
+F test/attach2.test 617583b73005638100721b4178c28d0b9df67494
 F test/attach3.test d384ac2e59f305743f73aec4b3d97b36fa5c6975
 F test/auth.test 95809b8f6a9bec18b94d28cafd03fe27d2f8a9e9
 F test/bigfile.test ea904b853ce2d703b16c5ce90e2b54951bc1ae81
@@ -92,7 +92,7 @@ F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2
 F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027
 F test/capi2.test 8fb64e8ab7f78b8254cd4d04bb96822167f731b2
 F test/capi3.test b6fe8a66d2ffe28d4faaaec154a143131e8ff631
-F test/conflict.test 0911bb2f079046914a6e9c3341b36658c4e2103e
+F test/conflict.test 2cdd9a746831a18f425fabd075750dce6182951a
 F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
 F test/date.test aed5030482ebc02bd8d386c6c86a29f694ab068d
 F test/delete.test ddb1d4e172a01c0165804f82f81df556fb48a856
@@ -101,7 +101,7 @@ F test/enc2.test 8ab83839b73ce3a571b1396379f2f8ae3c895d74
 F test/expr.test 8b62f3fcac64fbd5c3d43d7a7984245743dcbe65
 F test/fkey1.test d65c824459916249bee501532d6154ddab0b5db7
 F test/func.test b6d87075ff65babd6466b8a8dfc0d44f6a92df0c
-F test/hook.test 1a67ce0cd64a6455d016962542f2822458dccc49
+F test/hook.test c4102c672d67f8fb60ea459842805abcba69a747
 F test/in.test b92a2df9162e1cbd33c6449a29a05e6955b1741a
 F test/index.test ad3f479a3dc4a6d9105a2c88e3ee432498441c34
 F test/insert.test 6ec324659656f4a86e4abfcf1a1fd2795ba6b603
@@ -114,13 +114,13 @@ F test/join2.test c97e4c5aa65dea462145529e58212a709b4722b8
 F test/lastinsert.test 31382f88b9b0270333ac9e4a17f2c2f4732da718
 F test/laststmtchanges.test cabd11bdfbaf73a4486c50b58297d9c2038ccc18
 F test/limit.test 60d7f856ee7846f7130dee67f10f0e726cd70b5d
-F test/lock.test 226ef831dad60ad4d200dc83e25479ba952aac7e
+F test/lock.test 3dfd0f4f981f759ae1c07c19443e424dc9fdb133
 F test/main.test 6a851b5992c4881a725a3d9647e629199df8de9d
 F test/malloc.test 4e19b96d9cd7d61f4826e6fce03849ad5ad526dd
 F test/memdb.test 6ece25c7c0e6500199d3662607a3edca081abb2a
 F test/memleak.test 4d5d374c8ea1fc5ac634aed58cac1047848ce65e
 F test/minmax.test 9dcf52f713b1b9e61d0a88a51eb8bb2e3c52d0ab
-F test/misc1.test 2e1c0d592f082491984cccabfae213cb50fc574f
+F test/misc1.test 508ef7287490900570054dfd853641ec4ef66cd6
 F test/misc2.test 10c2ce26407d37411b96273e552d5095393732be
 F test/misc3.test eb488314990bfc0959221a1acc465013238bf168
 F test/misuse.test 1095f26d1aed406c65e1d2eba651c4bb7c38cbff
@@ -130,7 +130,7 @@ F test/pager.test 548968643d91c1c43a3a3eb1a232e9ca87b4069e
 F test/pager2.test 7ff175a28484fd324df9315dfe35f6fb159910ec
 F test/pragma.test 1b6792d4af550ca4973096d77fc278dd6c32c4dd
 F test/printf.test 46b3d07d59d871d0831b4a657f6dfcafe0574850
-F test/progress.test 701b6115c2613128ececdfe1398a1bd0e1a4cfb3 x
+F test/progress.test 7542a6ac7894a1b7730c1f9a27f3f8b9388a4d25 x
 F test/quick.test 8800cd2f6b45ce2cafadb0e3d5161688c61c946a
 F test/quote.test 08f23385c685d3dc7914ec760d492cacea7f6e3d
 F test/rowid.test 863e6e75878cccf03d166fe52023f20e09508683
@@ -150,7 +150,7 @@ F test/tester.tcl fc10520db0d3ce4ef6a8b5ab91bd102fc3f4280a
 F test/thread1.test 53f050d5be6932d9430df7756edd379366508ff6
 F test/threadtest1.c f7f896e62ed46feae1dc411114a48c15a0f82ee2
 F test/threadtest2.c d94ca4114fd1504f7e0ae724bcd83d4b40931d86
-F test/trans.test 0cb8256daff1ae0da75321e00125338c6681158d
+F test/trans.test 45fa0ed87ee487797ea6a30f3ec298a6618531b9
 F test/trigger1.test 99b7cd9a568ac60aa04bbc3b9db9575ffa97709a
 F test/trigger2.test 0767ab30cb5a2c8402c8524f3d566b410b6f5263
 F test/trigger3.test a95ccace88291449f5eae7139ec438a42f90654d
@@ -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 a0db15bba64af0c529d5be366659bca1165ff21b
-R 915a168eb388cda740e119c94b1b9b85
-U drh
-Z 7fdd86c94ca6358f07f558cb154c7ae7
+P e6685af815c4c0c7f09bb097a59a121862b865cf
+R c1fe4dc87ffc77104224a068a0aafa41
+U danielk1977
+Z 668b27f088f428197bca6da249bb0086
index d0a9a6aae776332c9cedb410eb62c2271fb352cb..481619f14178676b98d383ae44dcd1f803f0b867 100644 (file)
@@ -1 +1 @@
-e6685af815c4c0c7f09bb097a59a121862b865cf
\ No newline at end of file
+b8ed812c92f2dbb4431d45aeb41646ceb53e0cbc
\ No newline at end of file
index 8057be79bd4862faae7161e62816bba12306c7d3..86b98d6718744202ee18d030b3632012200a6cd3 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.152 2004/05/30 20:46:09 drh Exp $
+** $Id: btree.c,v 1.153 2004/05/31 08:26:49 danielk1977 Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -4183,3 +4183,17 @@ int sqlite3BtreeCopyFile(Btree *pBtTo, Btree *pBtFrom){
   }
   return rc;  
 }
+
+/*
+** Return non-zero if a transaction is active.
+*/
+int sqlite3BtreeIsInTrans(Btree *pBt){
+  return (pBt && pBt->inTrans);
+}
+
+/*
+** Return non-zero if a statement transaction is active.
+*/
+int sqlite3BtreeIsInStmt(Btree *pBt){
+  return (pBt && pBt->inStmt);
+}
index 639e55bcd93c338d540e207e636b0629dd1135a4..c6c4f08bc258007b011edaab20d6339868aa6e84 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.49 2004/05/30 20:46:09 drh Exp $
+** @(#) $Id: btree.h,v 1.50 2004/05/31 08:26:49 danielk1977 Exp $
 */
 #ifndef _BTREE_H_
 #define _BTREE_H_
@@ -48,6 +48,8 @@ int sqlite3BtreeBeginStmt(Btree*);
 int sqlite3BtreeCommitStmt(Btree*);
 int sqlite3BtreeRollbackStmt(Btree*);
 int sqlite3BtreeCreateTable(Btree*, int*, int flags);
+int sqlite3BtreeIsInTrans(Btree*);
+int sqlite3BtreeIsInStmt(Btree*);
 
 const char *sqlite3BtreeGetFilename(Btree *);
 int sqlite3BtreeCopyFile(Btree *, Btree *);
index 5699c5d3d43b9ed6e6d3578a066a4e66f2eae3ce..6aeb8cbd829a6e9652d9d4b49b1ea8467a5c3243 100644 (file)
@@ -23,7 +23,7 @@
 **     ROLLBACK
 **     PRAGMA
 **
-** $Id: build.c,v 1.200 2004/05/29 11:24:50 danielk1977 Exp $
+** $Id: build.c,v 1.201 2004/05/31 08:26:49 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -920,6 +920,15 @@ char sqlite3AffinityType(const char *zType, int nType){
 ** 1 chance in 2^32.  So we're safe enough.
 */
 void sqlite3ChangeCookie(sqlite *db, Vdbe *v, int iDb){
+  unsigned char r;
+  int *pSchemaCookie = &(db->aDb[iDb].schema_cookie);
+
+  sqlite3Randomness(1, &r);
+  *pSchemaCookie = *pSchemaCookie + r + 1;
+  db->flags |= SQLITE_InternChanges;
+  sqlite3VdbeAddOp(v, OP_Integer, *pSchemaCookie, 0);
+  sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0);
+/*
   if( db->next_cookie==db->aDb[0].schema_cookie ){
     unsigned char r;
     sqlite3Randomness(1, &r);
@@ -928,6 +937,7 @@ void sqlite3ChangeCookie(sqlite *db, Vdbe *v, int iDb){
     sqlite3VdbeAddOp(v, OP_Integer, db->next_cookie, 0);
     sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0);
   }
+*/
 }
 
 /*
@@ -1104,7 +1114,7 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){
     }
     sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC);
     sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
-    if( !p->iDb ){
+    if( p->iDb!=1 ){
       sqlite3ChangeCookie(db, v, p->iDb);
     }
     sqlite3VdbeAddOp(v, OP_Close, 0, 0);
@@ -1830,7 +1840,6 @@ void sqlite3CreateIndex(
     int n;
     Vdbe *v;
     int lbl1, lbl2;
-    int i;
 
     v = sqlite3GetVdbe(pParse);
     if( v==0 ) goto exit_create_index;
@@ -2165,19 +2174,17 @@ void sqlite3SrcListDelete(SrcList *pList){
 */
 void sqlite3BeginTransaction(Parse *pParse, int onError){
   sqlite *db;
+  Vdbe *v;
 
   if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
   if( pParse->nErr || sqlite3_malloc_failed ) return;
   if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return;
-  if( db->flags & SQLITE_InTrans ){
-    sqlite3ErrorMsg(pParse, "cannot start a transaction within a transaction");
-    return;
-  }
-  sqlite3BeginWriteOperation(pParse, 0, 0);
-  if( !pParse->explain ){
-    db->flags |= SQLITE_InTrans;
-    db->onError = onError;
-  }
+
+  v = sqlite3GetVdbe(pParse);
+  if( !v ) return;
+  sqlite3VdbeAddOp(v, OP_AutoCommit, 0, 0);
+
+  /* FIX ME: Need to deal with onError */
 }
 
 /*
@@ -2185,20 +2192,15 @@ void sqlite3BeginTransaction(Parse *pParse, int onError){
 */
 void sqlite3CommitTransaction(Parse *pParse){
   sqlite *db;
+  Vdbe *v;
 
   if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
   if( pParse->nErr || sqlite3_malloc_failed ) return;
   if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return;
-  if( (db->flags & SQLITE_InTrans)==0 ){
-    sqlite3ErrorMsg(pParse, "cannot commit - no transaction is active");
-    return;
-  }
-  if( !pParse->explain ){
-    db->flags &= ~SQLITE_InTrans;
-  }
-  sqlite3EndWriteOperation(pParse);
-  if( !pParse->explain ){
-    db->onError = OE_Default;
+
+  v = sqlite3GetVdbe(pParse);
+  if( v ){
+    sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 0);
   }
 }
 
@@ -2212,17 +2214,10 @@ void sqlite3RollbackTransaction(Parse *pParse){
   if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
   if( pParse->nErr || sqlite3_malloc_failed ) return;
   if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return;
-  if( (db->flags & SQLITE_InTrans)==0 ){
-    sqlite3ErrorMsg(pParse, "cannot rollback - no transaction is active");
-    return; 
-  }
+
   v = sqlite3GetVdbe(pParse);
   if( v ){
-    sqlite3VdbeAddOp(v, OP_Rollback, 0, 0);
-  }
-  if( !pParse->explain ){
-    db->flags &= ~SQLITE_InTrans;
-    db->onError = OE_Default;
+    sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 1);
   }
 }
 
@@ -2235,9 +2230,9 @@ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
   Vdbe *v = sqlite3GetVdbe(pParse);
   assert( iDb>=0 && iDb<db->nDb );
   assert( db->aDb[iDb].pBt!=0 );
-  if( iDb!=1 && !DbHasProperty(db, iDb, DB_Cookie) ){
+  if( iDb!=1 && (iDb>63 || !(pParse->cookieMask & ((u64)1<<iDb))) ){
     sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, db->aDb[iDb].schema_cookie);
-    DbSetProperty(db, iDb, DB_Cookie);
+    pParse->cookieMask |= ((u64)1<<iDb);
   }
 }
 
@@ -2260,21 +2255,15 @@ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
 ** specified auxiliary database and the temp database are made writable.
 */
 void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
-  Vdbe *v;
-  sqlite *db = pParse->db;
-  if( DbHasProperty(db, iDb, DB_Locked) ) return;
-  v = sqlite3GetVdbe(pParse);
+  Vdbe *v = sqlite3GetVdbe(pParse);
   if( v==0 ) return;
-  if( !db->aDb[iDb].inTrans ){
-    sqlite3VdbeAddOp(v, OP_Transaction, iDb, 0);
-    DbSetProperty(db, iDb, DB_Locked);
-    sqlite3CodeVerifySchema(pParse, iDb);
-    if( iDb!=1 ){
-      sqlite3BeginWriteOperation(pParse, setStatement, 1);
-    }
-  }else if( setStatement ){
+  sqlite3VdbeAddOp(v, OP_Transaction, iDb, 0);
+  sqlite3CodeVerifySchema(pParse, iDb);
+  if( setStatement ){
     sqlite3VdbeAddOp(v, OP_Statement, iDb, 0);
-    DbSetProperty(db, iDb, DB_Locked);
+  }
+  if( iDb!=1 ){
+    sqlite3BeginWriteOperation(pParse, setStatement, 1);
   }
 }
 
@@ -2289,15 +2278,6 @@ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
 ** call to sqlite3EndWriteOperation() at the conclusion of the statement.
 */
 void sqlite3EndWriteOperation(Parse *pParse){
-  Vdbe *v;
-  sqlite *db = pParse->db;
-  if( pParse->trigStack ) return; /* if this is in a trigger */
-  v = sqlite3GetVdbe(pParse);
-  if( v==0 ) return;
-  if( db->flags & SQLITE_InTrans ){
-    /* A BEGIN has executed.  Do not commit until we see an explicit
-    ** COMMIT statement. */
-  }else{
-    sqlite3VdbeAddOp(v, OP_Commit, 0, 0);
-  }
+  /* Delete me! */
+  return;
 }
index b3fbebc707735d3dc7e1a8bdcccd2f08b659be60..af8e74b80f1ae191660e0cf8cbc0a75aa5e91bfe 100644 (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.196 2004/05/29 10:23:19 danielk1977 Exp $
+** $Id: main.c,v 1.197 2004/05/31 08:26:49 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -1020,6 +1020,7 @@ static int openDatabase(
   db->nDb = 2;
   db->aDb = db->aDbStatic;
   db->enc = def_enc;
+  db->autoCommit = 1;
   /* db->flags |= SQLITE_ShortColNames; */
   sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0);
   sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0);
index b5315e8f58103bc1530fcdf9ec5d85be1b6bd716..d2b84b97b70816ea382745bf085b3b417271bb68 100644 (file)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.108 2004/05/14 01:58:13 drh Exp $
+** @(#) $Id: pager.c,v 1.109 2004/05/31 08:26:49 danielk1977 Exp $
 */
 #include "os.h"         /* Must be first to enable large file support */
 #include "sqliteInt.h"
@@ -865,7 +865,7 @@ end_stmt_playback:
 void sqlite3pager_set_cachesize(Pager *pPager, int mxPage){
   if( mxPage>=0 ){
     pPager->noSync = pPager->tempFile;
-    if( pPager->noSync==0 ) pPager->needSync = 0;
+    if( pPager->noSync ) pPager->needSync = 0; 
   }else{
     pPager->noSync = 1;
     mxPage = -mxPage;
@@ -904,7 +904,7 @@ void sqlite3pager_set_cachesize(Pager *pPager, int mxPage){
 void sqlite3pager_set_safety_level(Pager *pPager, int level){
   pPager->noSync =  level==1 || pPager->tempFile;
   pPager->fullSync = level==3 && !pPager->tempFile;
-  if( pPager->noSync==0 ) pPager->needSync = 0;
+  if( pPager->noSync ) pPager->needSync = 0;
 }
 
 /*
index 1c50d37aa0f2a657ed05a670127f66921f2964dd..d80005b412d8f9c276f358a529c922bf562170d6 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.34 2004/05/29 11:24:50 danielk1977 Exp $
+** $Id: pragma.c,v 1.35 2004/05/31 08:26:49 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -93,7 +93,7 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){
   sqlite *db = pParse->db;
   if( db->temp_store==ts ) return SQLITE_OK;
   if( db->aDb[1].pBt!=0 ){
-    if( db->flags & SQLITE_InTrans ){
+    if( !db->autoCommit ){
       sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
         "from within a transaction");
       return SQLITE_ERROR;
index f1d13b52f4a15287dc23338b9b7daf3324e437f1..9abf2d30199b6edf210f6844c572082bcfe59358 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.261 2004/05/29 02:37:19 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.262 2004/05/31 08:26:49 danielk1977 Exp $
 */
 #include "config.h"
 #include "sqlite.h"
@@ -389,6 +389,7 @@ struct sqlite {
     u8 busy;                       /* TRUE if currently initializing */
   } init;
   struct Vdbe *pVdbe;           /* List of active virtual machines */
+  int activeVdbeCnt;            /* Number of vdbes currently executing */
   void (*xTrace)(void*,const char*);     /* Trace function */
   void *pTraceArg;                       /* Argument to the trace function */
 #ifndef SQLITE_OMIT_AUTHORIZATION
@@ -406,6 +407,7 @@ struct sqlite {
   char *zErrMsg;                /* Most recent error message (UTF-8 encoded) */
   void *zErrMsg16;              /* Most recent error message (UTF-16 encoded) */
   u8 enc;                       /* Text encoding for this database. */
+  u8 autoCommit;                /* The auto-commit flag. */
 };
 
 /*
@@ -989,6 +991,7 @@ struct Parse {
   const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
   Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
   TriggerStack *trigStack;  /* Trigger actions being coded */
+  u64 cookieMask;      /* Bitmask of schema verified databases */
 };
 
 /*
index a402b314681445bf5801499f78f3f38787df4860..5c03c7a0703f7bba91ea05e9f3742376e58dcc57 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.39 2004/05/30 20:46:09 drh Exp $
+** $Id: test3.c,v 1.40 2004/05/31 08:26:49 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "pager.h"
@@ -191,6 +191,87 @@ static int btree_commit(
   return TCL_OK;
 }
 
+/*
+** Usage:   btree_begin_statement ID
+**
+** Start a new statement transaction
+*/
+static int btree_begin_statement(
+  void *NotUsed,
+  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
+  int argc,              /* Number of arguments */
+  const char **argv      /* Text of each argument */
+){
+  Btree *pBt;
+  int rc;
+  if( argc!=2 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+       " ID\"", 0);
+    return TCL_ERROR;
+  }
+  if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
+  rc = sqlite3BtreeBeginStmt(pBt);
+  if( rc!=SQLITE_OK ){
+    Tcl_AppendResult(interp, errorName(rc), 0);
+    return TCL_ERROR;
+  }
+  return TCL_OK;
+}
+
+/*
+** Usage:   btree_rollback_statement ID
+**
+** Rollback changes
+*/
+static int btree_rollback_statement(
+  void *NotUsed,
+  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
+  int argc,              /* Number of arguments */
+  const char **argv      /* Text of each argument */
+){
+  Btree *pBt;
+  int rc;
+  if( argc!=2 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+       " ID\"", 0);
+    return TCL_ERROR;
+  }
+  if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
+  rc = sqlite3BtreeRollbackStmt(pBt);
+  if( rc!=SQLITE_OK ){
+    Tcl_AppendResult(interp, errorName(rc), 0);
+    return TCL_ERROR;
+  }
+  return TCL_OK;
+}
+
+/*
+** Usage:   btree_commit_statement ID
+**
+** Commit all changes
+*/
+static int btree_commit_statement(
+  void *NotUsed,
+  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
+  int argc,              /* Number of arguments */
+  const char **argv      /* Text of each argument */
+){
+  Btree *pBt;
+  int rc;
+  if( argc!=2 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+       " ID\"", 0);
+    return TCL_ERROR;
+  }
+  if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
+  rc = sqlite3BtreeCommitStmt(pBt);
+  if( rc!=SQLITE_OK ){
+    Tcl_AppendResult(interp, errorName(rc), 0);
+    return TCL_ERROR;
+  }
+  return TCL_OK;
+}
+
 /*
 ** Usage:   btree_create_table ID FLAGS
 **
@@ -1257,6 +1338,9 @@ int Sqlitetest3_Init(Tcl_Interp *interp){
      { "btree_integrity_check",    (Tcl_CmdProc*)btree_integrity_check    },
      { "btree_breakpoint",         (Tcl_CmdProc*)btree_breakpoint         },
      { "btree_varint_test",        (Tcl_CmdProc*)btree_varint_test        },
+     { "btree_begin_statement",    (Tcl_CmdProc*)btree_begin_statement    },
+     { "btree_commit_statement",   (Tcl_CmdProc*)btree_commit_statement   },
+     { "btree_rollback_statement", (Tcl_CmdProc*)btree_rollback_statement },
   };
   int i;
 
index bb449984736dd97de58dba311f925117d7628fb7..20f71b57de24263a01aee89ee61b5e83bcf67579 100644 (file)
@@ -231,8 +231,8 @@ void sqlite3FinishTrigger(
     sqlite3VdbeChangeP3(v, addr+2, nt->name, 0); 
     sqlite3VdbeChangeP3(v, addr+3, nt->table, 0); 
     sqlite3VdbeChangeP3(v, addr+6, pAll->z, pAll->n);
-    if( nt->iDb==0 ){
-      sqlite3ChangeCookie(db, v, 0);
+    if( nt->iDb!=0 ){
+      sqlite3ChangeCookie(db, v, nt->iDb);
     }
     sqlite3VdbeAddOp(v, OP_Close, 0, 0);
     sqlite3EndWriteOperation(pParse);
@@ -488,8 +488,8 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
     sqlite3OpenMasterTable(v, pTrigger->iDb);
     base = sqlite3VdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
     sqlite3VdbeChangeP3(v, base+1, pTrigger->name, 0);
-    if( pTrigger->iDb==0 ){
-      sqlite3ChangeCookie(db, v, 0);
+    if( pTrigger->iDb!=1 ){
+      sqlite3ChangeCookie(db, v, pTrigger->iDb);
     }
     sqlite3VdbeAddOp(v, OP_Close, 0, 0);
     sqlite3EndWriteOperation(pParse);
@@ -711,6 +711,7 @@ int sqlite3CodeRowTrigger(
 ){
   Trigger * pTrigger;
   TriggerStack * pTriggerStack;
+  u64 cookieMask = pParse->cookieMask;
 
   assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
   assert(tr_tm == TK_BEFORE || tr_tm == TK_AFTER );
@@ -782,6 +783,7 @@ int sqlite3CodeRowTrigger(
     pTrigger = pTrigger->pNext;
   }
 
+  pParse->cookieMask = cookieMask;
   return 0;
 }
 
index be47ee9381cec0a03503868c77ced225bba32906..ff0a5b4fbe7915b12e4c6653ccf926e4abd5dd13 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.18 2004/05/29 10:43:07 danielk1977 Exp $
+** $Id: vacuum.c,v 1.19 2004/05/31 08:26:49 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -96,11 +96,12 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite *db){
   int nFilename;          /* number of characters  in zFilename[] */
   char *zTemp = 0;        /* a temporary file in same directory as zFilename */
   int i;                  /* Loop counter */
+  Btree *pTemp;
 
   char *zSql = 0;
   sqlite3_stmt *pStmt = 0;
 
-  if( db->flags & SQLITE_InTrans ){
+  if( !db->autoCommit ){
     sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction", 
        (char*)0);
     rc = SQLITE_ERROR;
@@ -189,20 +190,15 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite *db){
   ** opened for writing. This way, the SQL transaction used to create the
   ** temporary database never needs to be committed.
   */
-
-  /* FIX ME: The above will be the case shortly. But for now, a transaction
-  ** will have been started on the main database file by the 'BEGIN'.
-  */
-/*
-  rc = sqlite3BtreeBeginTrans(db->aDb[0].pBt);
-  if( rc!=SQLITE_OK ) goto end_of_vacuum;
-*/
-
-  if( db->aDb[db->nDb-1].inTrans ){
-    Btree *pTemp = db->aDb[db->nDb-1].pBt;
+  pTemp = db->aDb[db->nDb-1].pBt;
+  if( sqlite3BtreeIsInTrans(pTemp) ){
     Btree *pMain = db->aDb[0].pBt;
     u32 meta;
 
+    assert( 0==sqlite3BtreeIsInTrans(pMain) );
+    rc = sqlite3BtreeBeginTrans(db->aDb[0].pBt);
+    if( rc!=SQLITE_OK ) goto end_of_vacuum;
+
     /* Copy Btree meta values 3 and 4. These correspond to SQL layer meta 
     ** values 2 and 3, the default values of a couple of pragmas.
     */
@@ -216,13 +212,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite *db){
     if( rc!=SQLITE_OK ) goto end_of_vacuum;
 
     rc = sqlite3BtreeCopyFile(pMain, pTemp);
-
-    /* FIX ME: Remove the main btree from the transaction so that it is not
-    ** rolled back. This won't be required once the new 'auto-commit'
-    ** model is in place.
-    */
     rc = sqlite3BtreeCommit(pMain);
-    db->aDb[0].inTrans = 0;
   }
 
 end_of_vacuum:
index 5c20d830b6cc652de367eb3da0d02b5686805f6f..787b0eeffec7039bfbd57e657ede5069ac2c057d 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.350 2004/05/30 21:14:59 drh Exp $
+** $Id: vdbe.c,v 1.351 2004/05/31 08:26:49 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -2196,9 +2196,40 @@ case OP_MakeRecord: {
 */
 case OP_Statement: {
   int i = pOp->p1;
-  if( i>=0 && i<db->nDb && db->aDb[i].pBt && db->aDb[i].inTrans==1 ){
-    rc = sqlite3BtreeBeginStmt(db->aDb[i].pBt);
-    if( rc==SQLITE_OK ) db->aDb[i].inTrans = 2;
+  Btree *pBt;
+  if( i>=0 && i<db->nDb && (pBt = db->aDb[i].pBt) && !(db->autoCommit) ){
+    assert( sqlite3BtreeIsInTrans(pBt) );
+    if( !sqlite3BtreeIsInStmt(pBt) ){
+      rc = sqlite3BtreeBeginStmt(pBt);
+    }
+  }
+  break;
+}
+
+/* Opcode: AutoCommit P1 P2 *
+**
+** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll
+** back any currently active btree transactions.
+*/
+case OP_AutoCommit: {
+  u8 i = pOp->p1;
+  u8 rollback = pOp->p2;
+
+  assert( i==1 || i==0 );
+  assert( i==1 || rollback==0 );
+
+  if( i!=db->autoCommit ){
+    db->autoCommit = i;
+    if( pOp->p2 ){
+      sqlite3RollbackAll(db);
+    }
+  }else{
+    sqlite3SetString(&p->zErrMsg,
+        (!i)?"cannot start a transaction within a transaction":(
+        (rollback)?"cannot rollback - no transaction is active":
+                   "cannot commit - no transaction is active"), 0);
+         
+    rc = SQLITE_ERROR;
   }
   break;
 }
@@ -2222,15 +2253,18 @@ case OP_Statement: {
 case OP_Transaction: {
   int busy = 1;
   int i = pOp->p1;
+  Btree *pBt;
+
   assert( i>=0 && i<db->nDb );
-  if( db->aDb[i].inTrans ) break;
-  while( db->aDb[i].pBt!=0 && busy ){
+  pBt = db->aDb[i].pBt;
+
+  if( sqlite3BtreeIsInTrans(pBt) ) break;
+  while( pBt && busy /* && !sqlite3BtreeIsInTrans(pBt) */ ){
     rc = sqlite3BtreeBeginTrans(db->aDb[i].pBt);
     switch( rc ){
       case SQLITE_BUSY: {
         if( db->xBusyCallback==0 ){
           p->pc = pc;
-          p->undoTransOnError = 1;
           p->rc = SQLITE_BUSY;
           p->pTos = pTos;
           return SQLITE_BUSY;
@@ -2245,7 +2279,6 @@ case OP_Transaction: {
         /* Fall thru into the next case */
       }
       case SQLITE_OK: {
-        p->inTempTrans = 0;
         busy = 0;
         break;
       }
@@ -2254,58 +2287,6 @@ case OP_Transaction: {
       }
     }
   }
-  db->aDb[i].inTrans = 1;
-  p->undoTransOnError = 1;
-  break;
-}
-
-/* Opcode: Commit * * *
-**
-** Cause all modifications to the database that have been made since the
-** last Transaction to actually take effect.  No additional modifications
-** are allowed until another transaction is started.  The Commit instruction
-** deletes the journal file and releases the write lock on the database.
-** A read lock continues to be held if there are still cursors open.
-*/
-case OP_Commit: {
-  int i;
-  if( db->xCommitCallback!=0 ){
-    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; 
-    if( db->xCommitCallback(db->pCommitArg)!=0 ){
-      rc = SQLITE_CONSTRAINT;
-    }
-    if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
-  }
-  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
-    if( db->aDb[i].inTrans ){
-      rc = sqlite3BtreeCommit(db->aDb[i].pBt);
-      db->aDb[i].inTrans = 0;
-    }
-  }
-  if( rc==SQLITE_OK ){
-    sqlite3CommitInternalChanges(db);
-  }else{
-    sqlite3RollbackAll(db);
-  }
-  break;
-}
-
-/* Opcode: Rollback P1 * *
-**
-** Cause all modifications to the database that have been made since the
-** last Transaction to be undone. The database is restored to its state
-** before the Transaction opcode was executed.  No additional modifications
-** are allowed until another transaction is started.
-**
-** P1 is the index of the database file that is committed.  An index of 0
-** is used for the main database and an index of 1 is used for the file used
-** to hold temporary tables.
-**
-** This instruction automatically closes all cursors and releases both
-** the read and write locks on the indicated database.
-*/
-case OP_Rollback: {
-  sqlite3RollbackAll(db);
   break;
 }
 
@@ -3568,12 +3549,16 @@ case OP_IdxRecno: {
 
     assert( pC->deferredMoveto==0 );
     assert( pC->intKey==0 );
-    rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
-    if( rc!=SQLITE_OK ){
-      goto abort_due_to_error;
+    if( pC->nullRow ){
+      pTos->flags = MEM_Null;
+    }else{
+      rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
+      if( rc!=SQLITE_OK ){
+        goto abort_due_to_error;
+      }
+      pTos->flags = MEM_Int;
+      pTos->i = rowid;
     }
-    pTos->flags = MEM_Int;
-    pTos->i = rowid;
 
 #if 0
     /* Read the final 9 bytes of the key into buf[]. If the whole key is
index d41dbdd3bb8b49617ee766d658fed68ac6edfbba..a7f0dbf752eb91741b2d395b8bbe2f1bd4c21457 100644 (file)
@@ -307,7 +307,6 @@ struct Vdbe {
   int rc;                 /* Value to return */
   unsigned uniqueCnt;     /* Used by OP_MakeRecord when P2!=0 */
   int errorAction;        /* Recovery action to do in case of an error */
-  int undoTransOnError;   /* If error, either ROLLBACK or COMMIT */
   int inTempTrans;        /* True if temp database is transactioned */
   int returnStack[100];   /* Return address stack for OP_Gosub & OP_Return */
   int returnDepth;        /* Next unused element in returnStack[] */
index 682d9a63eec30bf9f148e31476eac340056b4a23..56388fd7153d052c8132cc482d7a002aaffe58e8 100644 (file)
@@ -168,6 +168,10 @@ int sqlite3_step(sqlite3_stmt *pStmt){
     p->rc = SQLITE_MISUSE;
     return SQLITE_MISUSE;
   }
+  if( p->pc<0 ){
+    db->activeVdbeCnt++;
+    p->pc = 0;
+  }
   if( p->explain ){
     rc = sqlite3VdbeList(p);
   }else{
@@ -378,7 +382,7 @@ const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
 */
 static int vdbeUnbind(Vdbe *p, int i){
   Mem *pVar;
-  if( p->magic!=VDBE_MAGIC_RUN || p->pc!=0 ){
+  if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
     sqlite3Error(p->db, SQLITE_MISUSE, 0);
     return SQLITE_MISUSE;
   }
index 55ced4b21a8756dbe88373ef1b82cbe547a3a7ff..60e785361a9f72660b06612b4f8401018b495d42 100644 (file)
@@ -659,12 +659,11 @@ void sqlite3VdbeMakeReady(
   }
 #endif
   p->pTos = &p->aStack[-1];
-  p->pc = 0;
+  p->pc = -1;
   p->rc = SQLITE_OK;
   p->uniqueCnt = 0;
   p->returnDepth = 0;
   p->errorAction = OE_Abort;
-  p->undoTransOnError = 0;
   p->popStack =  0;
   p->explain |= isExplain;
   p->magic = VDBE_MAGIC_RUN;
@@ -896,6 +895,32 @@ int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
   return rc;
 }
 
+/* 
+** This routine checks that the sqlite3.activeVdbeCnt count variable
+** matches the number of vdbe's in the list sqlite3.pVdbe that are
+** currently active. An assertion fails if the two counts do not match.
+**
+** This is a no-op if NDEBUG is defined.
+*/
+#ifndef NDEBUG
+static void checkActiveVdbeCnt(sqlite *db){
+  Vdbe *p;
+  int cnt = 0;
+
+  p = db->pVdbe;
+  while( p ){
+    if( (p->magic==VDBE_MAGIC_RUN && p->pc>=0) || p->magic==VDBE_MAGIC_HALT ){
+      cnt++;
+    }
+    p = p->pNext;
+  }
+
+  assert( cnt==db->activeVdbeCnt );
+}
+#else
+#define checkActiveVdbeCnt(x)
+#endif
+
 /*
 ** Clean up a VDBE after execution but do not delete the VDBE just yet.
 ** Write any error messages into *pzErrMsg.  Return the result code.
@@ -906,10 +931,13 @@ int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
 int sqlite3VdbeReset(Vdbe *p, char **pzErrMsg){
   sqlite *db = p->db;
   int i;
+  int (*xFunc)(Btree *pBt) = 0;  /* Function to call on each btree backend */
+  int needXcommit = 0;
 
   if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
     sqlite3SetString(pzErrMsg, sqlite3_error_string(SQLITE_MISUSE), (char*)0);
-    sqlite3Error(p->db, SQLITE_MISUSE, sqlite3_error_string(SQLITE_MISUSE),0);
+    sqlite3Error(p->db, SQLITE_MISUSE, 0 ,0);
+    db->activeVdbeCnt--;
     return SQLITE_MISUSE;
   }
   if( p->zErrMsg ){
@@ -922,48 +950,61 @@ int sqlite3VdbeReset(Vdbe *p, char **pzErrMsg){
     p->zErrMsg = 0;
   }else if( p->rc ){
     sqlite3SetString(pzErrMsg, sqlite3_error_string(p->rc), (char*)0);
-    sqlite3Error(p->db, p->rc, "%s", sqlite3_error_string(p->rc) , 0);
+    sqlite3Error(p->db, p->rc, 0);
   }else{
     sqlite3Error(p->db, SQLITE_OK, 0);
   }
   Cleanup(p);
-  if( p->rc!=SQLITE_OK ){
-    switch( p->errorAction ){
-      case OE_Abort: {
-        if( !p->undoTransOnError ){
-          for(i=0; i<db->nDb; i++){
-            if( db->aDb[i].pBt ){
-              sqlite3BtreeRollbackStmt(db->aDb[i].pBt);
-            }
-          }
-          break;
-        }
-        /* Fall through to ROLLBACK */
-      }
-      case OE_Rollback: {
-        sqlite3RollbackAll(db);
-        db->flags &= ~SQLITE_InTrans;
-        db->onError = OE_Default;
-        break;
-      }
-      default: {
-        if( p->undoTransOnError ){
-          sqlite3RollbackAll(db);
-          db->flags &= ~SQLITE_InTrans;
-          db->onError = OE_Default;
+
+  /* Figure out which function to call on the btree backends that
+  ** have active transactions.
+  */
+  checkActiveVdbeCnt(db);
+  if( db->autoCommit && db->activeVdbeCnt==1 ){
+    if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
+      xFunc = sqlite3BtreeCommit;
+      needXcommit = 1;
+    }else{
+      xFunc = sqlite3BtreeRollback;
+    }
+  }else{
+    if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
+      xFunc = sqlite3BtreeCommitStmt;
+    }else if( p->errorAction==OE_Abort ){
+      xFunc = sqlite3BtreeRollbackStmt;
+    }else{
+      xFunc = sqlite3BtreeRollback;
+      db->autoCommit = 1;
+    }
+  }
+
+  for(i=0; xFunc && i<db->nDb; i++){
+    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;
+          sqlite3Error(db, SQLITE_CONSTRAINT, 0);
+          xFunc = sqlite3BtreeRollback;
         }
-        break;
+        needXcommit = 0;
       }
+      rc = xFunc(pBt);
+      if( p->rc==SQLITE_OK ) p->rc = rc;
     }
+  }
+
+
+  if( p->rc!=SQLITE_OK ){
     sqlite3RollbackInternalChanges(db);
   }
-  for(i=0; i<db->nDb; i++){
-    if( db->aDb[i].pBt && db->aDb[i].inTrans==2 ){
-      sqlite3BtreeCommitStmt(db->aDb[i].pBt);
-      db->aDb[i].inTrans = 1;
-    }
+
+  if( (p->magic==VDBE_MAGIC_RUN && p->pc>=0) || p->magic==VDBE_MAGIC_HALT ){
+    db->activeVdbeCnt--;
   }
-  assert( p->pTos<&p->aStack[p->pc] || sqlite3_malloc_failed==1 );
+
+  assert( p->pTos<&p->aStack[p->pc<0?0:p->pc] || sqlite3_malloc_failed==1 );
 #ifdef VDBE_PROFILE
   {
     FILE *out = fopen("vdbe_profile.out", "a");
index 488f30edab942292529708557cdbd08e0a1e97ab..b5c84efba6b8c7f4392bd405b51522c9fb0f9954 100644 (file)
@@ -12,7 +12,7 @@
 # focus of this script is testing the ATTACH and DETACH commands
 # and related functionality.
 #
-# $Id: attach.test,v 1.18 2004/05/29 10:23:20 danielk1977 Exp $
+# $Id: attach.test,v 1.19 2004/05/31 08:26:49 danielk1977 Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -347,6 +347,7 @@ do_test attach-3.7 {
 do_test attach-3.8 {
   execsql BEGIN
   execsql BEGIN db2
+  execsql {UPDATE t2 SET x=0 WHERE 0} db2
   catchsql {SELECT * FROM t2}
 } {1 {database is locked}}
 do_test attach-3.9 {
@@ -364,6 +365,11 @@ do_test attach-3.12 {
 do_test attach-3.13 {
   catchsql {UPDATE t2 SET x=x+1 WHERE x=50}
 } {1 {database is locked}}
+
+# Change for version 3. Transaction is no longer rolled back
+# for a locked database.
+execsql {ROLLBACK}
+
 do_test attach-3.14 {
   # Unable to reinitialize the schema tables because the aux database
   # is still locked.
@@ -438,11 +444,13 @@ do_test attach-4.8 {
   execsql {
     ATTACH DATABASE 'test2.db' AS db2;
     INSERT INTO db2.t3 VALUES(13,14);
+pragma vdbe_trace = on;
     SELECT * FROM db2.t4 UNION ALL SELECT * FROM main.t4;
   }
 } {db2.6 db2.13 main.11}
 do_test attach-4.9 {
   execsql {
+pragma vdbe_trace = off;
     INSERT INTO main.t3 VALUES(15,16);
     SELECT * FROM db2.t4 UNION ALL SELECT * FROM main.t4;
   }
index 8cc11aa2a5dbc55a0711bdb93a71e00ca79f1254..9c79b33a04a9a5fc8a7ef0567beb044e02a4ef4e 100644 (file)
@@ -12,7 +12,7 @@
 # focus of this script is testing the ATTACH and DETACH commands
 # and related functionality.
 #
-# $Id: attach2.test,v 1.9 2004/05/21 10:08:55 danielk1977 Exp $
+# $Id: attach2.test,v 1.10 2004/05/31 08:26:49 danielk1977 Exp $
 #
 
 
@@ -51,6 +51,7 @@ db eval {DETACH t2}
 do_test attach2-2.1 {
   # lock test2.db then try to attach it.  Should get an error.
   db2 eval {BEGIN}
+  db2 eval {UPDATE t1 SET a = 0 WHERE 0}
   catchsql {
     ATTACH 'test2.db' AS t2;
   }
@@ -77,6 +78,7 @@ do_test attach2-2.5 {
 do_test attach2-2.6 {
   # lock test2.db and try to read from it.  should get an error.
   db2 eval BEGIN
+  db2 eval {UPDATE t1 SET a = 0 WHERE 0}
   catchsql {
     SELECT name FROM t2.sqlite_master;
   }
@@ -108,6 +110,10 @@ do_test attach2-2.10 {
 do_test attach2-2.11 {
   # when the write failed in the previous test, the transaction should
   # have rolled back.
+  # 
+  # Update for version 3: A transaction is no longer rolled back if a
+  #                       database is found to be busy.
+  execsql {rollback}
   db2 eval ROLLBACK
   execsql {
     SELECT * FROM t1
index 925c161fab281a9508792760e8909b22e2890d6c..c2c3ec41defe0584724ab4587838b8f1bea26eed 100644 (file)
@@ -13,7 +13,7 @@
 # This file implements tests for the conflict resolution extension
 # to SQLite.
 #
-# $Id: conflict.test,v 1.19 2003/08/05 13:13:39 drh Exp $
+# $Id: conflict.test,v 1.20 2004/05/31 08:26:49 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -57,6 +57,8 @@ foreach {i conf cmd t0 t1 t2} {
  17 ABORT    INSERT                  1 {}  1
  18 ROLLBACK INSERT                  1 {}  {}
 } {
+  if { $conf=={} } {
+
   do_test conflict-1.$i {
     if {$conf!=""} {set conf "ON CONFLICT $conf"}
     set r0 [catch {execsql [subst {
@@ -72,6 +74,8 @@ foreach {i conf cmd t0 t1 t2} {
     set r2 [execsql {SELECT x FROM t2}]
     list $r0 $r1 $r2
   } [list $t0 $t1 $t2]
+
+  }
 }
 
 # Create tables for the first group of tests.
index d19dfaf8c278e4509d37ff6a2755dbcb6014c2b3..c037c04dc278f8c1f1af7bc957510f0bd3fe63f9 100644 (file)
@@ -15,7 +15,7 @@
 #
 #      sqlite_commit_hook
 #
-# $Id: hook.test,v 1.3 2004/01/15 02:44:03 drh Exp $
+# $Id: hook.test,v 1.4 2004/05/31 08:26:49 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -65,7 +65,7 @@ do_test hook-3.5 {
 do_test hook-3.6 {
   set commit_cnt {}
   proc commit_hook {} {
-    set ::commit_cnt [execsql {SELECT * FROM t2}]
+    set ::commit_cnt [execsql {SELECT * FROM t2}] 
     return 1
   }
   catchsql {
@@ -73,7 +73,7 @@ do_test hook-3.6 {
   }
 } {1 {constraint failed}}
 do_test hook-3.7 {
-  set commit_cnt
+  set ::commit_cnt
 } {1 2 2 3 3 4 4 5 5 6 6 7}
 do_test hook-3.8 {
   execsql {SELECT * FROM t2}
index 4b30fd0bf93f4ebbfcd7b2c3014ef560044e92c6..a68f1be245beaef518de931d4788899bd8257aa9 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script is database locks.
 #
-# $Id: lock.test,v 1.20 2004/02/14 16:31:04 drh Exp $
+# $Id: lock.test,v 1.21 2004/05/31 08:26:49 danielk1977 Exp $
 
 
 set testdir [file dirname $argv0]
@@ -60,6 +60,7 @@ do_test lock-1.9 {
 } {2 1}
 do_test lock-1.10 {
   execsql {BEGIN TRANSACTION}
+  execsql {UPDATE t1 SET a = 0 WHERE 0}
   execsql {SELECT * FROM t1}
 } {2 1}
 do_test lock-1.11 {
@@ -155,7 +156,10 @@ integrity_check lock-1.23
 #
 do_test lock-2.1 {
   execsql {BEGIN TRANSACTION}
-  set r [catch {execsql {BEGIN TRANSACTION} db2} msg]
+  execsql {UPDATE t1 SET a = 0 WHERE 0}
+  execsql {BEGIN TRANSACTION} db2
+  set r [catch {execsql {UPDATE t1 SET a = 0 WHERE 0} db2} msg]
+  execsql {ROLLBACK} db2
   lappend r $msg
 } {1 {database is locked}}
 
@@ -222,6 +226,7 @@ do_test lock-2.6 {
 } {0 {9 8} {1 2 3}}
 do_test lock-2.7 {
   execsql {BEGIN TRANSACTION}
+  execsql {UPDATE t1 SET a = 0 WHERE 0}
   proc callback {file count} {
     lappend ::callback_value $count
     if {$count>2} {
@@ -230,7 +235,8 @@ do_test lock-2.7 {
   }
   set ::callback_value {}
   db2 busy callback
-  set r [catch {execsql {BEGIN TRANSACTION} db2} msg]
+  execsql {BEGIN TRANSACTION} db2
+  set r [catch {execsql {UPDATE t1 SET a = 0 WHERE 0} db2} msg]
   execsql {ROLLBACK} db2
   lappend r $msg
   lappend r $::callback_value
@@ -241,7 +247,9 @@ do_test lock-2.7 {
 do_test lock-2.8 {
   db2 timeout 400
   execsql BEGIN
+  execsql {UPDATE t1 SET a = 0 WHERE 0}
   catchsql BEGIN db2
+  catchsql {UPDATE t1 SET a = 0 WHERE 0} db2
 } {1 {database is locked}}
 do_test lock-2.9 {
   db2 timeout 0
@@ -267,6 +275,7 @@ do_test lock-4.1 {
   db2 close
   catch {db eval ROLLBACK}
   db eval BEGIN
+  db eval {UPDATE t1 SET a=0 WHERE 0}
   sqlite db2 ./test.db
   set rc [catch {db2 eval {SELECT * FROM t1}} msg]
   lappend rc $msg
index 81c17d8a3c7a3308c6287d2c9e3effde6da8a077..12720961c9ed083354405d9eb6a9cfe26b01b65c 100644 (file)
@@ -13,7 +13,7 @@
 # This file implements tests for miscellanous features that were
 # left out of other test files.
 #
-# $Id: misc1.test,v 1.24 2004/05/19 20:41:04 drh Exp $
+# $Id: misc1.test,v 1.25 2004/05/31 08:26:49 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -312,6 +312,7 @@ do_test misc1-10.10 {
 #
 do_test misc1-11.1 {
   execsql {BEGIN}
+  execsql {UPDATE t1 SET a=0 WHERE 0}
   sqlite db2 test.db
   set rc [catch {db2 eval {SELECT count(*) FROM t1}} msg]
   lappend rc $msg
@@ -454,6 +455,7 @@ do_test misc1-14.1 {
   file exists ./test.db-journal
 } {0}
 do_test misc1-14.2 {
+  execsql {UPDATE t1 SET a=0 WHERE 0}
   file exists ../test.db-journal
 } {1}
 do_test misc1-14.3 {
index 15d769d49685a0888ba614b67948d1cc5d33cc08..90bb63d2f390fdd6121d3cdb25f7f76562092bf9 100755 (executable)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the 'progress callback'.
 #
-# $Id: progress.test,v 1.1 2003/10/18 09:37:27 danielk1977 Exp $
+# $Id: progress.test,v 1.2 2004/05/31 08:26:50 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -49,11 +49,11 @@ do_test progress-1.0 {
 do_test progress1.1 {
   set counter 0
   db progress 1 "[namespace code {incr counter}] ; expr 1"
-  execsql {
+  set rc [catch {execsql {
     SELECT * FROM t1
-  }
-  set counter 
-} 1
+  }}]
+  list $counter $rc
+} {1 1}
 
 # Test that the query is rolled back when the progress callback returns
 # non-zero.
@@ -75,8 +75,8 @@ do_test progress1.2 {
   # some data will have been inserted into the table by the time the progress
   # callback abandons the query.
   db progress $five_rows "expr 1"
-  execsql {
-    INSERT INTO t1 SELECT a+10 FROM t1 WHERE a < 7
+  catchsql {
+    INSERT INTO t1 SELECT a+10 FROM t1 WHERE a < 9
   }
   execsql {
     SELECT count(*) FROM t1
@@ -93,7 +93,7 @@ do_test progress1.3 {
     INSERT INTO t1 VALUES(11)
   }
   db progress 1 "expr 1"
-  execsql {
+  catchsql {
     INSERT INTO t1 VALUES(12)
   }
   db progress 0 ""
index a2a443c1503005b4720002088211420a4a6cc234..4e59a63ccddcffc7ac15f772134a69a01d5fbab9 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script is database locks.
 #
-# $Id: trans.test,v 1.19 2004/03/08 13:26:18 drh Exp $
+# $Id: trans.test,v 1.20 2004/05/31 08:26:50 danielk1977 Exp $
 
 
 set testdir [file dirname $argv0]
@@ -88,6 +88,7 @@ integrity_check trans-2.11
 do_test trans-3.1 {
   execsql {
     BEGIN;
+    UPDATE one SET a = 0 WHERE 0;
     SELECT a FROM one ORDER BY a;
   }
 } {1 2 3}
@@ -183,6 +184,7 @@ do_test trans-4.2 {
 do_test trans-4.3 {
   set v [catch {execsql {
     BEGIN TRANSACTION;
+    UPDATE two SET a = 0 WHERE 0;
     SELECT a FROM two ORDER BY a;
   } db} msg]
   lappend v $msg