]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Avoid writing frames with no checksums into the wal file if a
authordrh <>
Tue, 17 Jun 2025 19:32:23 +0000 (19:32 +0000)
committerdrh <>
Tue, 17 Jun 2025 19:32:23 +0000 (19:32 +0000)
savepoint is rolled back after dirty pages have already been
spilled into the wal file.  Also fix a corner case in the previous
check-in on this branch.

FossilOrigin-Name: c232fa2bfc1a3f2c659a1d3bb26f98f2b39f20777eebd4d08e53c21d018d3b59

manifest
manifest.uuid
src/wal.c
src/whereexpr.c
test/walcksum.test

index 2acc00dea34af225d49361453c1291d60528aa2c..fb18bba4d4e2e21086c3ff37868a867064db715c 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\san\sissue\sgoing\sback\sto\sversion\s3.39.0\swith\stransitive\sIS\sconstraints\nin\squeries\sthat\smake\suse\sof\sRIGHT\sJOIN.
-D 2025-06-16T18:04:21.872
+C Avoid\swriting\sframes\swith\sno\schecksums\sinto\sthe\swal\sfile\sif\sa\nsavepoint\sis\srolled\sback\safter\sdirty\spages\shave\salready\sbeen\nspilled\sinto\sthe\swal\sfile.\s\sAlso\sfix\sa\scorner\scase\sin\sthe\sprevious\ncheck-in\son\sthis\sbranch.
+D 2025-06-17T19:32:23.813
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -866,13 +866,13 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8
 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
 F src/vtab.c 828221bdbeaaa6d62126ee6d07fd4ec0d09dcaea846f87ad01944d8b7e548859
 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
-F src/wal.c b0f848cfba8dd057f77073493cdd542f9125b4cf87941f53e9d0db21604155c8
+F src/wal.c 20be6f0a25a80b7897cf2a5369bfd37ef198e6f0b6cdef16d83eee856056b159
 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
 F src/where.c 45a3b496248a0b36d91ce34da3278d54f8fa20e9d3fbd36d45a42051d1118137
 F src/whereInt.h ecdbfb5551cf394f04ec7f0bc7ad963146d80eee3071405ac29aa84950128b8e
 F src/wherecode.c 65670d1ef85ef54a4db3826d63be8b646c9ac280962166b645950901ed1bda29
-F src/whereexpr.c fa9bfb18c810b85e1e601282fab52d2345fd63abac7d2636b6f4b165d326d9a9
+F src/whereexpr.c 1c60db88b6e8472f4864b98014d1b2d9d16bdd42d5d181ec515acbcdeddc18db
 F src/window.c d01227141f622f24fbe36ca105fbe6ef023f9fd98f1ccd65da95f88886565db5
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test 4d7a34d328e58ca2a2d78fd76c27614a41ca7ddf4312ded9c68c04f430b3b47d
@@ -2015,7 +2015,7 @@ F test/wal_common.tcl 204d1721ac13c5e0c7fae6380315b5ab7f4e8423f580d826c5e9df1995
 F test/walbak.test 018d4e5a3d45c6298d11b99f09a8ef6876527946
 F test/walbig.test f437473a16cfb314867c6b5d1dbcd519e73e3434
 F test/walblock.test 6bb472e82730e7e4e81395e907a01d8cfc2bd9e1f01f8a9184ca572e2955a4bf
-F test/walcksum.test ba02b4fe6d22cb42e57a323003cbae62f77a740983e1355b2b520e019ae261c7
+F test/walcksum.test 50e204500eed9c691b6045e467bb2923f49aa93d8adf315e2be135fdb202c1c2
 F test/walcrash.test 21038858cc552077b0522f50b0fa87e38139306a
 F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36
 F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af
@@ -2209,9 +2209,10 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 954efdd30da169e508f27ddf2f94bc2c3b6cc3f4fd13ffa650ab53d3e35df566
-Q +9441fff52cc4e19c44df1a77ffe474f409d519b270c7166ce17f99e6ea48fc1e
-R b0145ab327b9213da050a72336e966b5
+P 6c5f4c8af90cfe2f1b06485f8cf61d7e6d4ad92f5209e84aa1c6d1a938780a64
+Q +336a59eb3afd80ce048de472368df6dfc32934ee783859d37663ed8f5cf169a5
+Q +5973f9b9aa828ec9274b02a124b95f452c58235eaafffbdda1c32b4ae2d5616d
+R 2593351e79121513b58222fea59de952
 U drh
-Z d62f91dc96f20a9d25a0558704bdf5b9
+Z daec3171c23f95eb84bc08ae8a4f9cbf
 # Remove this line to create a well-formed Fossil manifest.
index 6285831f1a6218c1263df086a2ed38969602176e..6cc572dc9c87ad57b9825cc5efe99ee6632c35f0 100644 (file)
@@ -1 +1 @@
-6c5f4c8af90cfe2f1b06485f8cf61d7e6d4ad92f5209e84aa1c6d1a938780a64
+c232fa2bfc1a3f2c659a1d3bb26f98f2b39f20777eebd4d08e53c21d018d3b59
index 1fd5b201cb1ff3773b1f2d4a32a7af7d7524ee8a..41018b5845185bbef2c78a34f8298b552131040b 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -3781,6 +3781,7 @@ int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){
       if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
     }
     SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; )
+    pWal->iReCksum = 0;
   }
   return rc;
 }
@@ -3828,6 +3829,9 @@ int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){
       walCleanupHash(pWal);
     }
     SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; )
+    if( pWal->iReCksum>pWal->hdr.mxFrame ){
+      pWal->iReCksum = 0;
+    }
   }
 
   return rc;
index f089cac27a14705c4772305c3ec55fbaf3ebe09c..26bcae71c4a669c71e29e12febd09dc516c7a761 100644 (file)
@@ -946,7 +946,11 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){
   if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0;  /* (1) */
   if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0;                 /* (2) */
   if( ExprHasProperty(pExpr, EP_OuterON) ) return 0;                   /* (3) */
-  if( pExpr->op==TK_IS && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
+  assert( pSrc!=0 );
+  if( pExpr->op==TK_IS
+   && pSrc->nSrc
+   && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0
+  ){
     return 0;                                                          /* (4) */
   }
   aff1 = sqlite3ExprAffinity(pExpr->pLeft);
index 10329ba6c81431d14a15fc13cd6ae99deed7dd56..0c9a7e55c00e7bed1b74d518f6e1800317c0f4f7 100644 (file)
@@ -16,6 +16,7 @@ source $testdir/lock_common.tcl
 source $testdir/wal_common.tcl
 
 ifcapable !wal {finish_test ; return }
+set testprefix walcksum
 
 # Read and return the contents of file $filename. Treat the content as
 # binary data.
@@ -331,5 +332,152 @@ do_test walcksum-2.1 {
 catch { db close }
 catch { db2 close }
 
+#-------------------------------------------------------------------------
+# Test cases based on the bug reported at:
+# 
+#    <https://sqlite.org/forum/forumpost/b490f726db>
+#
+reset_db
+
+do_execsql_test 3.0 {
+  PRAGMA auto_vacuum = 0;
+  PRAGMA synchronous = NORMAL;
+  PRAGMA journal_mode = WAL;
+  PRAGMA cache_size = 1;
+
+  CREATE TABLE t1 (i INTEGER PRIMARY KEY, b BLOB, t TEXT);
+  PRAGMA wal_checkpoint;
+  INSERT INTO t1 VALUES(1, randomblob(2048), 'one');
+} {wal 0 2 2}
+
+do_execsql_test 3.1 {
+  BEGIN;
+    INSERT INTO t1 VALUES(2, randomblob(2048), 'two');
+    SAVEPOINT one;
+    INSERT INTO t1 VALUES(3, randomblob(2048), 'three');
+    INSERT INTO t1 VALUES(4, randomblob(2048), 'four');
+    INSERT INTO t1 VALUES(5, randomblob(2048), 'five');
+    INSERT INTO t1 VALUES(6, randomblob(2048), 'six');
+    INSERT INTO t1 VALUES(7, randomblob(2048), 'seven');
+
+    UPDATE t1 SET b=randomblob(2048) WHERE i=5;
+    UPDATE t1 SET b=randomblob(2048) WHERE i=6;
+    UPDATE t1 SET b=randomblob(2048) WHERE i=7;
+    ROLLBACK TO one;
+    INSERT INTO t1 VALUES(8, NULL, 'eight');
+  COMMIT;
+} {}
+
+do_execsql_test 3.2 {
+  SELECT i, t FROM t1
+} {1 one   2 two   8 eight}
+
+forcecopy test.db test2.db
+forcecopy test.db-wal test2.db-wal
+
+sqlite3 db2 test2.db
+do_test 1.3 {
+  execsql {
+    SELECT i, t FROM t1
+  } db2
+} {1 one   2 two   8 eight}
+
+catch { db2 close }
+
+#-------------------------------------------------------------------------
+reset_db
+
+do_execsql_test 4.0 {
+  PRAGMA auto_vacuum = 0;
+  PRAGMA synchronous = NORMAL;
+  PRAGMA journal_mode = WAL;
+  PRAGMA cache_size = 1;
+
+  CREATE TABLE t1 (i INTEGER PRIMARY KEY, b BLOB, t TEXT);
+  PRAGMA wal_checkpoint;
+  INSERT INTO t1 VALUES(1, randomblob(2048), 'one');
+} {wal 0 2 2}
+
+do_execsql_test 4.1.1 {
+  SAVEPOINT one;
+    INSERT INTO t1 VALUES(2, randomblob(2048), 'two');
+    INSERT INTO t1 VALUES(3, randomblob(2048), 'three');
+    INSERT INTO t1 VALUES(4, randomblob(2048), 'four');
+    INSERT INTO t1 VALUES(5, randomblob(2048), 'five');
+    INSERT INTO t1 VALUES(6, randomblob(2048), 'six');
+    INSERT INTO t1 VALUES(7, randomblob(2048), 'seven');
+
+    UPDATE t1 SET b=randomblob(2048) WHERE i=5;
+    UPDATE t1 SET b=randomblob(2048) WHERE i=6;
+    UPDATE t1 SET b=randomblob(2048) WHERE i=7;
+}
+
+do_execsql_test 4.1.2 {
+    ROLLBACK TO one;
+    INSERT INTO t1 VALUES(8, NULL, 'eight');
+  RELEASE one;
+} {}
+
+do_execsql_test 4.2 {
+  SELECT i, t FROM t1
+} {1 one   8 eight}
+
+forcecopy test.db test2.db
+forcecopy test.db-wal test2.db-wal
+
+sqlite3 db2 test2.db
+do_test 4.3 {
+  execsql {
+    SELECT i, t FROM t1
+  } db2
+} {1 one   8 eight}
+
+catch { db2 close }
+
+#-------------------------------------------------------------------------
+reset_db
+
+do_execsql_test 5.0 {
+  PRAGMA auto_vacuum = 0;
+  PRAGMA synchronous = NORMAL;
+  PRAGMA journal_mode = WAL;
+  PRAGMA cache_size = 1;
+
+  CREATE TABLE t1 (i INTEGER PRIMARY KEY, b BLOB, t TEXT);
+  INSERT INTO t1 VALUES(1, randomblob(2048), 'one');
+  INSERT INTO t1 VALUES(2, randomblob(2048), 'two');
+  INSERT INTO t1 VALUES(3, randomblob(2048), 'three');
+  PRAGMA wal_checkpoint;
+} {wal 0 14 14}
+
+do_execsql_test 5.1 {
+  BEGIN;
+    SELECT count(*) FROM t1;
+    SAVEPOINT one;
+    INSERT INTO t1 VALUES(4, randomblob(2048), 'four');
+    INSERT INTO t1 VALUES(5, randomblob(2048), 'five');
+    INSERT INTO t1 VALUES(6, randomblob(2048), 'six');
+    INSERT INTO t1 VALUES(7, randomblob(2048), 'seven');
+    ROLLBACK TO one;
+    INSERT INTO t1 VALUES(8, randomblob(2048), 'eight');
+    INSERT INTO t1 VALUES(9, randomblob(2048), 'nine');
+  COMMIT;
+} {3}
+
+forcecopy test.db test2.db
+forcecopy test.db-wal test2.db-wal
+
+sqlite3 db2 test2.db
+do_test 5.2 {
+  execsql {
+    SELECT i, t FROM t1
+  } db2
+} {1 one  2 two   3 three  8 eight 9 nine}
+db2 close
+
+do_execsql_test 5.3 {
+  SELECT i, t FROM t1
+} {1 one  2 two   3 three  8 eight 9 nine}
+
   
 finish_test