Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix an obscure problem with releasing savepoints stored in an in-memory journal that could cause subsequent savepoint rollback to fail. Problem reported by forum post d7338bf4901f1151, PoC #3. The problem appears to have been introduced at [23ca23894af352ea]. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
73c2b50211d3ae26aeb89976ec7b9fcd |
User & Date: | dan 2022-01-01 19:29:50 |
Original Comment: | Fix an obscure problem with releasing savepoints stored in an in-memory journal that could cause subsequent savepoint rollback to fail. |
Context
2022-01-02
| ||
17:24 | Fix an obscure problem with releasing savepoints stored in an in-memory journal that could cause subsequent savepoint rollback to fail. (check-in: 3c0806e4 user: drh tags: branch-3.37) | |
2022-01-01
| ||
19:55 | Attempt to fix a harmless compiler warning in FTS5. (check-in: 8e619c21 user: drh tags: trunk) | |
19:29 | Fix an obscure problem with releasing savepoints stored in an in-memory journal that could cause subsequent savepoint rollback to fail. Problem reported by forum post d7338bf4901f1151, PoC #3. The problem appears to have been introduced at [23ca23894af352ea]. (check-in: 73c2b502 user: dan tags: trunk) | |
17:21 | Remove an obsolete assert() statement that no longer does anything useful and which is not always true. Fix for PoC #1 of forum post d7338bf4901f1151. (check-in: c76a4c0b user: drh tags: trunk) | |
Changes
Changes to src/memjournal.c.
︙ | ︙ | |||
261 262 263 264 265 266 267 | if( size<p->endpoint.iOffset ){ FileChunk *pIter = 0; if( size==0 ){ memjrnlFreeChunks(p->pFirst); p->pFirst = 0; }else{ i64 iOff = p->nChunkSize; | | | 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | if( size<p->endpoint.iOffset ){ FileChunk *pIter = 0; if( size==0 ){ memjrnlFreeChunks(p->pFirst); p->pFirst = 0; }else{ i64 iOff = p->nChunkSize; for(pIter=p->pFirst; ALWAYS(pIter) && iOff<size; pIter=pIter->pNext){ iOff += p->nChunkSize; } if( ALWAYS(pIter) ){ memjrnlFreeChunks(pIter->pNext); pIter->pNext = 0; } } |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
3913 3914 3915 3916 3917 3918 3919 | ** sub-journal rolled back the content could not be restored and the ** database image would become corrupt. It is therefore fortunate that ** this circumstance cannot arise. */ #if defined(SQLITE_DEBUG) static void assertTruncateConstraintCb(PgHdr *pPg){ assert( pPg->flags&PGHDR_DIRTY ); | | | 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 | ** sub-journal rolled back the content could not be restored and the ** database image would become corrupt. It is therefore fortunate that ** this circumstance cannot arise. */ #if defined(SQLITE_DEBUG) static void assertTruncateConstraintCb(PgHdr *pPg){ assert( pPg->flags&PGHDR_DIRTY ); assert( pPg->pgno<=pPg->pPager->dbSize || !subjRequiresPage(pPg) ); } static void assertTruncateConstraint(Pager *pPager){ sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb); } #else # define assertTruncateConstraint(pPager) #endif |
︙ | ︙ |
Added test/memjournal2.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | # 2022 Jan 01 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # Tests focused on the in-memory journal. # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl set testprefix memjournal2 do_execsql_test 1.0 { PRAGMA journal_mode = memory; CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE); } {memory} set nRow [expr 2000] do_execsql_test 1.1 { BEGIN; WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<$nRow ) INSERT INTO t1 SELECT NULL, randomblob(700) FROM s; } for {set jj 200} {$jj <= 300} {incr jj} { do_execsql_test 1.2.$jj.1 { SAVEPOINT one; UPDATE t1 SET b=randomblob(700) WHERE a<=$jj; } do_execsql_test 1.2.$jj.2 { SAVEPOINT two; UPDATE t1 SET b=randomblob(700) WHERE a==1; ROLLBACK TO two; RELEASE two; } do_execsql_test 1.2.$jj.3 { SAVEPOINT two; UPDATE t1 SET b=randomblob(700) WHERE a==1; ROLLBACK TO two; RELEASE two; } do_execsql_test 1.2.$jj.4 { PRAGMA integrity_check; ROLLBACK TO one; RELEASE one; } {ok} } finish_test |