SQLite

Check-in [17960165]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a problem in the in-memory journal code that could occasionally lead to a segfault when a sub-transaction that modified zero pages was committed.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 17960165f5840cab45b7a8bb02779ebfb321c68f33ec6da9ab14063ccd134fa4
User & Date: dan 2021-05-24 14:35:19
Context
2021-05-25
11:39
Enhance the shell tool ".dump PATTERN" command so that it dumps the contents of shadow tables when a virtual table is identified by the PATTERN. (check-in: b0bc5ab9 user: dan tags: trunk)
2021-05-24
14:35
Fix a problem in the in-memory journal code that could occasionally lead to a segfault when a sub-transaction that modified zero pages was committed. (check-in: 17960165 user: dan tags: trunk)
12:28
Minor comment improvements in fuzzcheck.c. (check-in: 7aca8d52 user: drh tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/memjournal.c.

253
254
255
256
257
258
259


260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
}

/*
** Truncate the in-memory file.
*/
static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
  MemJournal *p = (MemJournal *)pJfd;


  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;
    }
  }

  p->endpoint.pChunk = pIter;
  p->endpoint.iOffset = size;
  p->readpoint.pChunk = 0;
  p->readpoint.iOffset = 0;

  return SQLITE_OK;
}

/*
** Close the file.
*/
static int memjrnlClose(sqlite3_file *pJfd){







>
>
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
>







253
254
255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
}

/*
** Truncate the in-memory file.
*/
static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
  MemJournal *p = (MemJournal *)pJfd;
  assert( p->endpoint.pChunk==0 || p->endpoint.pChunk->pNext==0 );
  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;
      }
    }

    p->endpoint.pChunk = pIter;
    p->endpoint.iOffset = size;
    p->readpoint.pChunk = 0;
    p->readpoint.iOffset = 0;
  }
  return SQLITE_OK;
}

/*
** Close the file.
*/
static int memjrnlClose(sqlite3_file *pJfd){

Added test/memjournal.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
# 2021 May 24
#
# 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 memjournal


do_execsql_test 1.0 {
  PRAGMA journal_mode = memory;
  CREATE TABLE t1(a);
} {memory}

set nRow [expr 1]

do_execsql_test 1.1 {
  BEGIN;
    INSERT INTO t1 VALUES( randomblob(500) );
} {}

do_test 1.2 {
  for {set i 1} {$i <= 500} {incr i} {
    execsql {
      SAVEPOINT one;
      UPDATE t1 SET a=randomblob(500);
    }
    execsql { SAVEPOINT abc } 
    execsql { UPDATE t1 SET a=randomblob(500) WHERE rowid<=$i AND 0 }
    execsql { RELEASE abc }
  } 
} {}

do_execsql_test 1.3 {
  COMMIT;
}

finish_test