Index: src/btree.c ================================================================== --- src/btree.c +++ src/btree.c @@ -4177,14 +4177,16 @@ rc = SQLITE_CORRUPT_BKPT; }else{ /* The current transaction allocated pages pMap->iFirst through ** nPage (inclusive) at the end of the database file. Meanwhile, ** other transactions have allocated (iFirst..nHPage). So move - ** pages (iFirst..MIN(nPage,nHPage)) to (MAX(nPage,nHPage)+1). */ + ** pages (iFirst..MIN(nPage,nHPage)) to (MAX(nPage,nHPage)+1). */ Pgno iLast = MIN(nPage, nHPage); /* Last page to move */ Pgno nCurrent; /* Current size of db */ + nCurrent = MAX(nPage, nHPage); + pBt->nPage = nCurrent; rc = btreeRelocateRange(pBt, pMap->iFirst, iLast, &nCurrent); /* There are now no collisions with the snapshot at the head of the ** database file. So at this point it would be possible to write ** the transaction out to disk. Before doing so though, attempt to @@ -6125,11 +6127,11 @@ mxPage = btreePagecount(pBt); /* EVIDENCE-OF: R-05119-02637 The 4-byte big-endian integer at offset 36 ** stores stores the total number of pages on the freelist. */ n = get4byte(&pPage1->aData[36]); testcase( n==mxPage-1 ); - if( ISCONCURRENT==0 && n>=mxPage ){ + if( n>=mxPage ){ return SQLITE_CORRUPT_BKPT; } /* Ensure page 1 is writable. This function will either change the number ** of pages in the free-list or the size of the database file. Since both ADDED test/concurrent6.test Index: test/concurrent6.test ================================================================== --- /dev/null +++ test/concurrent6.test @@ -0,0 +1,60 @@ +# 2017 May 26 +# +# 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. +# +#*********************************************************************** +# +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/lock_common.tcl +source $testdir/wal_common.tcl +set ::testprefix concurrent6 + +ifcapable !concurrent { + finish_test + return +} + +sqlite3 db2 test.db + +do_execsql_test 1.0 { + PRAGMA page_size = 1024; + PRAGMA journal_mode = wal; + CREATE TABLE t1(x); + CREATE TABLE t2(x); + CREATE TABLE t3(x); + CREATE TABLE t4(x); + + INSERT INTO t1 VALUES(zeroblob(1500)); +} {wal} + +do_execsql_test -db db2 1.1 { + BEGIN CONCURRENT; + INSERT INTO t3 VALUES(zeroblob(4000)); + DELETE FROM t1; +} + +do_execsql_test 1.2 { + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100) + INSERT INTO t2 SELECT zeroblob(1000) FROM s; + + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100) + INSERT INTO t4 SELECT zeroblob(1000) FROM s; + + DELETE FROM t4; +} + +do_execsql_test -db db2 1.3 { + COMMIT; +} + + +finish_test +