]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Clean up the implementation now that it only has to deal with the
authordrh <>
Sat, 16 Nov 2024 18:37:56 +0000 (18:37 +0000)
committerdrh <>
Sat, 16 Nov 2024 18:37:56 +0000 (18:37 +0000)
much simplier concept of COMMIT AND CONTINUE TRANSACTION.

FossilOrigin-Name: 17360660bbaf1b6009fc608f9687914789853f25ae38c1377a1ea5e5a621f34c

manifest
manifest.uuid
src/build.c
src/pager.c
src/pager.h
src/parse.y
src/vdbe.c
src/wal.c
src/wal.h

index 7be051625875e8f62e8db4a786387a0f4a18b1e4..1f03d7bdcb1567fd1c139f58ad40bfa39e3832a7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Simplify\sthe\snew\ssyntax\sto\sbe\sjust\s"COMMIT\sAND\sCONTINUE\sTRANSACTION".
-D 2024-11-16T14:40:11.304
+C Clean\sup\sthe\simplementation\snow\sthat\sit\sonly\shas\sto\sdeal\swith\sthe\nmuch\ssimplier\sconcept\sof\sCOMMIT\sAND\sCONTINUE\sTRANSACTION.
+D 2024-11-16T18:37:56.794
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
@@ -716,7 +716,7 @@ F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522
 F src/btree.c 63ca6b647342e8cef643863cd0962a542f133e1069460725ba4461dcda92b03c
 F src/btree.h 18e5e7b2124c23426a283523e5f31a4bff029131b795bb82391f9d2f3136fc50
 F src/btreeInt.h 98aadb6dcb77b012cab2574d6a728fad56b337fc946839b9898c4b4c969e30b6
-F src/build.c c219c01d3490420addfe5e9673ed136cbf89acf4c72370b548cf68a4ad5cc281
+F src/build.c 2966f47b7be312f602658ae50225bb9255264ac4d3df70332e00eea461216c98
 F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c d35723024b963edce9c0fad5b3303e8bb9266083784844baed10a6dedfe26f3b
@@ -761,9 +761,9 @@ F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d87210
 F src/os_unix.c d2edbd92b07a3f778c2defa8a2e9d75acceb6267bda56948c41e8cdda65224d6
 F src/os_win.c db4baa8f62bbfe3967c71b008cea31a8f2ff337c1667ff4d8a677e697315ff0d
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
-F src/pager.c 6d5d8ebe7e0fbaa5ad8c6b327e17271334b99e887b871df667a79b71215acfc7
-F src/pager.h 87f5995a18a11130c52d20c9556da02cdfe40ffd7daaa43ca0fcd922d83b7257
-F src/parse.y f0e72511b10d8456d456706b6e7d1ec68486622f66b5593ac00dff9ee9cd2c99
+F src/pager.c d29770208271df2adbd96bc5d353aba74f84bbd79926734e9d4d4a081556439a
+F src/pager.h 4637ae0c299215d7ed3b54e379123b518e101c0453faa2d0f7db29cb23525cee
+F src/parse.y 8e86f09a67481b842504704d2c9919dcd22bca13244461d5dade85b308a23af2
 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
 F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319
@@ -843,7 +843,7 @@ F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
 F src/utf.c 8b29d9a5956569ea2700f869669b8ef67a9662ee5e724ff77ab3c387e27094ba
 F src/util.c ceebf912f673247e305f16f97f0bb7285fca1d37413b79680714a553a9021d33
 F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40
-F src/vdbe.c d726c4fc8cca5d960d95b61573920a5f8e8ff5b34734c918680e00e3c6fbf07f
+F src/vdbe.c 1782cffa53d4bce9d9f2694debadbec6bb1e736a7e2bfd3f33a8f3d813d4cdae
 F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a
 F src/vdbeInt.h 2da01c73e8e3736a9015d5b04aa04d209bc9023d279d237d4d409205e921ea1e
 F src/vdbeapi.c 6353de05e8e78e497ccb33381ba5662ccc11c0339e5b1455faff01b6dacc3075
@@ -855,8 +855,8 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8
 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
 F src/vtab.c 316cd48e9320660db3047cd306cd056e4361180cebb4d0f10a39244e10c11422
 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
-F src/wal.c 75a94c7dca2018f5a0cf65022f3c59661c7d327b324de068e0e1ee1f271d9dd7
-F src/wal.h 3289ab8741f440d675f08448e067028b275774cb29548e6fb4d3ab789ab6e30e
+F src/wal.c 7a4962ae1f7cff6fe83d6f23902a2d7f19975f120c718ef4aa91b7a6a9c64c7f
+F src/wal.h a1ec57934aa26c23805e00ddbc0cd5da5760028d3608d882647345de2e330a3e
 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
 F src/where.c 4de9e7ca5f49e4a21c1d733e2b2fbbc8b62b1a157a58a562c569da84cfcb005b
 F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca
@@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 605889b02122d98011e9a8d458ba01010423680dd69446458ffe7230a1d47937
-R 14eb9d9ad1dcefff4fb094ea7a1cb27f
+P 61797109a2f0fee84bc3e0a0c021544c87e4b985e7e7b549e387e396cf1f86ec
+R 46871f34f7168e25d11ebddfd52c7c72
 U drh
-Z 7bc09c6cab911404200c67cb0830a94e
+Z 5ae0aa05318ae464a95f608ded039de8
 # Remove this line to create a well-formed Fossil manifest.
index a50e0ef8a29f416b1b9fc3c773c7d367d32e1ca8..738a7bb0ad1497d036728b3f0717a29a6313a855 100644 (file)
@@ -1 +1 @@
-61797109a2f0fee84bc3e0a0c021544c87e4b985e7e7b549e387e396cf1f86ec
+17360660bbaf1b6009fc608f9687914789853f25ae38c1377a1ea5e5a621f34c
index 632c60f38eabc97c9629b04ec3a81b6eb3cde0d4..ef67b9b11bc6dbcd3e36dd2f9ec3332015ea81af 100644 (file)
@@ -5228,16 +5228,20 @@ void sqlite3BeginTransaction(Parse *pParse, int type){
 ** Generate VDBE code for a COMMIT or ROLLBACK statement.
 ** Code for ROLLBACK is generated if eType==TK_ROLLBACK.  Otherwise
 ** code is generated for a COMMIT.
+**
+** If bContinueTrans is true, then do the COMMIT so that past changes are
+** made permanent and visible to readers, but hold on to the write lock
+** and start a new transaction, without allowing any other database
+** connections to do a write or checkpoint.
 */
-void sqlite3EndTransaction(Parse *pParse, int eType, int eRestart){
+void sqlite3EndTransaction(Parse *pParse, int eType, int bContinueTrans){
   Vdbe *v;
   int isRollback;
 
   assert( pParse!=0 );
   assert( pParse->db!=0 );
   assert( eType==TK_COMMIT || eType==TK_END || eType==TK_ROLLBACK );
-  assert( eRestart==0 || eRestart==TK_DEFERRED || eRestart==TK_IMMEDIATE
-            || eRestart==TK_EXCLUSIVE );
+  assert( bContinueTrans==0 || bContinueTrans==1 );
   isRollback = eType==TK_ROLLBACK;
   if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION,
        isRollback ? "ROLLBACK" : "COMMIT", 0, 0) ){
@@ -5245,10 +5249,8 @@ void sqlite3EndTransaction(Parse *pParse, int eType, int eRestart){
   }
   v = sqlite3GetVdbe(pParse);
   if( v ){
-    int p3 = 0;
-    if( eRestart ) p3 = eRestart==TK_DEFERRED ? 1 : 2;
-    sqlite3VdbeAddOp3(v, OP_AutoCommit, 1, isRollback, p3);
-    if( eRestart ) sqlite3BeginTransaction(pParse, eRestart);
+    sqlite3VdbeAddOp3(v, OP_AutoCommit, 1, isRollback, bContinueTrans);
+    if( bContinueTrans ) sqlite3BeginTransaction(pParse, TK_IMMEDIATE);
   }
 }
 
index 6f98c1d6d07acfb28776d70723a8e72af033c390..d3c97e131a52b533149b9bfac2c129414a26e9d5 100644 (file)
@@ -643,7 +643,7 @@ struct Pager {
   */
   u8 eState;                  /* Pager state (OPEN, READER, WRITER_LOCKED..) */
   u8 eLock;                   /* Current lock held on database file */
-  u8 eMinLock;                /* Minimum lock */
+  u8 bHoldWrLock;             /* Do not release write locks while true */
   u8 changeCountDone;         /* Set after incrementing the change-counter */
   u8 setSuper;                /* Super-jrnl name is written into jrnl */
   u8 doNotSpill;              /* Do not spill the cache when non-zero */
@@ -1149,13 +1149,7 @@ static int pagerUnlockDb(Pager *pPager, int eLock){
   pPager->changeCountDone = pPager->tempFile; /* ticket fb3b3024ea238d5c */
   if( isOpen(pPager->fd) ){
     assert( pPager->eLock>=eLock );
-    if( pPager->eMinLock ){
-      if( eLock<SHARED_LOCK ) eLock = SHARED_LOCK;
-      if( pPager->eMinLock==2 && eLock<EXCLUSIVE_LOCK ) eLock = EXCLUSIVE_LOCK;
-      if( eLock>=pPager->eLock ){
-        return SQLITE_OK;
-      }
-    }
+    if( pPager->bHoldWrLock ) return SQLITE_OK;
     rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock);
     if( pPager->eLock!=UNKNOWN_LOCK ){
       pPager->eLock = (u8)eLock;
@@ -5373,7 +5367,7 @@ int sqlite3PagerSharedLock(Pager *pPager){
       assert( pPager->eState==PAGER_OPEN );
       assert( (pPager->eLock==SHARED_LOCK)
            || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
-           || (pPager->eMinLock>0 && pPager->eLock>=SHARED_LOCK)
+           || (pPager->bHoldWrLock && pPager->eLock>=SHARED_LOCK)
       );
     }
 
@@ -6897,20 +6891,17 @@ int sqlite3PagerIsMemdb(Pager *pPager){
 }
 
 /*
-** Set the minimum locking level on all pagers.
-**
-**    0:  No minimum
-**    1:  Read lock
-**    2:  Write lock
+** In all pagers associated with db, set or clear the bHoldWrLock
+** flag.
 */
-void sqlite3PagerMinLock(sqlite3 *db, u8 eMinLock){
+void sqlite3PagerHoldWrLock(sqlite3 *db, u8 bOnOff){
   int iDb;
   Pager *pPager;
   for(iDb=0; iDb<db->nDb; iDb++){
     if( db->aDb[iDb].pBt==0 ) continue;
     pPager = sqlite3BtreePager(db->aDb[iDb].pBt);
-    pPager->eMinLock = eMinLock;
-    if( pPager->pWal ) sqlite3WalMinLock(pPager->pWal, eMinLock);
+    pPager->bHoldWrLock = bOnOff;
+    if( pPager->pWal ) sqlite3WalHoldWrLock(pPager->pWal, bOnOff);
   }
 }
 
index 1383367059100567e520a8140b572cdf7ee9e2d4..49a3f07aeb497677fb1e66f94c34a47b0f8eb2ab 100644 (file)
@@ -218,7 +218,7 @@ void *sqlite3PagerTempSpace(Pager*);
 int sqlite3PagerIsMemdb(Pager*);
 void sqlite3PagerCacheStat(Pager *, int, int, u64*);
 void sqlite3PagerClearCache(Pager*);
-void sqlite3PagerMinLock(sqlite3*,u8);
+void sqlite3PagerHoldWrLock(sqlite3*,u8);
 int sqlite3SectorSize(sqlite3_file *);
 
 /* Functions used to truncate the database file. */
index abfd2d2b31ebfedf8d3cda40200e1ec47e5b3b51..1481f9bd4ffc6d83f65b80daeff5f635fd7e5c58 100644 (file)
@@ -172,7 +172,7 @@ transtype(A) ::= EXCLUSIVE(X). {A = @X; /*A-overwrites-X*/}
 cmd ::= ROLLBACK(X) trans_opt.            {sqlite3EndTransaction(pParse,@X,0);}
 cmd ::= COMMIT(X) trans_opt.              {sqlite3EndTransaction(pParse,@X,0);}
 cmd ::= END(X) trans_opt.                 {sqlite3EndTransaction(pParse,@X,0);}
-// See also the COMMIT AND BEGIN section below
+// See also the COMMIT AND CONTINUE TRANSACTION section below
 
 savepoint_opt ::= SAVEPOINT.
 savepoint_opt ::= .
@@ -476,13 +476,13 @@ resolvetype(A) ::= raisetype(A).
 resolvetype(A) ::= IGNORE.                   {A = OE_Ignore;}
 resolvetype(A) ::= REPLACE.                  {A = OE_Replace;}
 
-////////////////////////// COMMIT AND BEGIN ///////////////////////////////////
+////////////////////////// COMMIT AND CONTINUE TRANSACTION ////////////////////
 //
 cmd ::= COMMIT(X) AND ID(Y) TRANSACTION. {
   if( Y.n!=8  || sqlite3_strnicmp(Y.z,"continue",8)!=0 ){
     sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &Y);
   }
-  sqlite3EndTransaction(pParse, @X, TK_IMMEDIATE);
+  sqlite3EndTransaction(pParse, @X, 1);
 }
 
 ////////////////////////// The DROP TABLE /////////////////////////////////////
index 10783a8c3fb1a077ff56fb0be98d56a0b5e4aee9..893b418ef08c37b6488f3bb0676a2b7bb7c67786 100644 (file)
@@ -3937,8 +3937,8 @@ case OP_Savepoint: {
 /* Opcode: AutoCommit P1 P2 P3 * *
 **
 ** Set the database auto-commit flag to P1 (1 or 0).  The current trasaction
-** while commit when the VDBE halts if the auto-commit flag is 1.  The
-** cureent transaction will stay in effect if the auto-commit flags is 0.
+** will commit when the VDBE halts if the auto-commit flag is 1.  The
+** current transaction will stay in effect if the auto-commit flag is 0.
 ** Thus, this opcode implements COMMIT when P1 is 0 and it implements
 ** BEGIN when P1 is 1.
 **
@@ -3947,9 +3947,9 @@ case OP_Savepoint: {
 ** COMMIT fails if there are active writing VMs or active VMs that use
 ** shared cache.
 **
-** If P3 is 1 or 2 and P1 is 1, then COMMIT but also start a new transaction
-** atomically.  P3 is 1 to restart a read transaction or 2 to restart a write
-** transaction.
+** If P3 and P1 are both is 1, then COMMIT but also hang on to the write lock
+** for the transaction.  The P3 flag is used to help implement
+** COMMIT AND CONTINUE TRANSACTION.
 */
 case OP_AutoCommit: {
   int desiredAutoCommit;
@@ -3967,7 +3967,7 @@ case OP_AutoCommit: {
       assert( desiredAutoCommit==1 );
       sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
       db->autoCommit = 1;
-    }else if( desiredAutoCommit && db->nVdbeWrite>(pOp->p3==2) ){
+    }else if( desiredAutoCommit && db->nVdbeWrite>pOp->p3 ){
       /* If this instruction implements a COMMIT and other VMs are writing
       ** return an error indicating that the other VMs must complete first.
       */
@@ -3980,7 +3980,8 @@ case OP_AutoCommit: {
     }else{
       db->autoCommit = (u8)desiredAutoCommit;
     }
-    sqlite3PagerMinLock(db, pOp->p3);
+    assert( pOp->p3==0 || pOp->p3==1 );
+    sqlite3PagerHoldWrLock(db, pOp->p3);
     if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
       p->pc = (int)(pOp - aOp);
       db->autoCommit = (u8)(1-desiredAutoCommit);
@@ -3992,7 +3993,7 @@ case OP_AutoCommit: {
       if( pOp->p3 ){
         db->nVdbeActive++;
         db->nVdbeRead++;
-        if( pOp->p3==2 ) db->nVdbeWrite++;
+        db->nVdbeWrite++;
         p->eVdbeState = VDBE_RUN_STATE;
         break;
       }
@@ -9144,7 +9145,7 @@ abort_due_to_error:
     rc = SQLITE_CORRUPT_BKPT;
   }
   assert( rc );
-  sqlite3PagerMinLock(db, 0);
+  sqlite3PagerHoldWrLock(db, 0);
 #ifdef SQLITE_DEBUG
   if( db->flags & SQLITE_VdbeTrace ){
     const char *zTrace = p->zSql;
index f949073f4f38f8f700f264852b1b2b9293d2a8c6..53edcaaba06a6da013eb27081121bb8b50de7ac8 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -516,7 +516,7 @@ struct Wal {
   i16 readLock;              /* Which read lock is being held.  -1 for none */
   u8 syncFlags;              /* Flags to use to sync header writes */
   u8 exclusiveMode;          /* Non-zero if connection is in exclusive mode */
-  u8 eMinLock;               /* 0, 1, or 2, for none, read, or write */
+  u8 bHoldWrLock;            /* Do not release WAL_WRITE locks if true */
   u8 writeLock;              /* True if in a write transaction */
   u8 ckptLock;               /* True if holding a checkpoint lock */
   u8 readOnly;               /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */
@@ -2065,7 +2065,7 @@ int sqlite3WalWriteLock(Wal *pWal, int bLock){
       }
       walDisableBlocking(pWal);
     }
-  }else if( pWal->writeLock && pWal->eMinLock<2 ){
+  }else if( pWal->writeLock && !pWal->bHOldWrLock ){
     walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
     pWal->writeLock = 0;
   }
@@ -2699,7 +2699,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
             *pChanged = 1;
           }
         }
-        if( bWriteLock==0 && pWal->eMinLock<2 ){
+        if( bWriteLock==0 && !pWal->bHoldWrLock ){
           pWal->writeLock = 0;
           walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
         }
@@ -3711,7 +3711,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
 ** routine merely releases the lock.
 */
 int sqlite3WalEndWriteTransaction(Wal *pWal){
-  if( pWal->writeLock && pWal->eMinLock<2 ){
+  if( pWal->writeLock && !pWal->bHoldWrLock ){
     walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
     pWal->writeLock = 0;
     pWal->iReCksum = 0;
@@ -4462,8 +4462,8 @@ int sqlite3WalExclusiveMode(Wal *pWal, int op){
 /*
 ** Set the temporary minimum lock level for the WAL subsystem.
 */
-void sqlite3WalMinLock(Wal *pWal, int eMinLock){
-  pWal->eMinLock = eMinLock;
+void sqlite3WalHoldWrLock(Wal *pWal, int bOnOff){
+  pWal->bHoldWrLock = bOnOff;
 }
 
 /*
index 073a9529c4fb66c33f3f81615b8bebc7ede903da..36c6fb5de63696f8f46bd7e6e5bf459f9857d0d5 100644 (file)
--- a/src/wal.h
+++ b/src/wal.h
@@ -129,9 +129,10 @@ int sqlite3WalExclusiveMode(Wal *pWal, int op);
 */
 int sqlite3WalHeapMemory(Wal *pWal);
 
-/* Set the transient minimum lock level for the WAL
+/* Set or clear the transient flag that prevents the WAL_WRITE lock
+** from being released.
 */
-void sqlite3WalMinLock(Wal *pWal, int eMinLock);
+void sqlite3WalHoldWrLock(Wal *pWal, int bOnOff);
 
 #ifdef SQLITE_ENABLE_SNAPSHOT
 int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot);