mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Fix a couple of assert() failures that can occur in btree.c and pager.c. (CVS 6055)
FossilOrigin-Name: ae44e7482476478c8eeacfb80b282f17894530e5
This commit is contained in:
16
manifest
16
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Fix\sa\sreference\scounting\sbug\sin\srtree.\sTicket\s#3549.\s(CVS\s6054)
|
C Fix\sa\scouple\sof\sassert()\sfailures\sthat\scan\soccur\sin\sbtree.c\sand\spager.c.\s(CVS\s6055)
|
||||||
D 2008-12-22T15:04:32
|
D 2008-12-23T10:37:47
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 77635d0909c2067cee03889a1e04ce910d8fb809
|
F Makefile.in 77635d0909c2067cee03889a1e04ce910d8fb809
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -103,7 +103,7 @@ F src/attach.c 1c35f95da3c62d19de75b44cfefd12c81c1791b3
|
|||||||
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
||||||
F src/bitvec.c 4300d311b17fb3c1476623fd895a8feac02a0b08
|
F src/bitvec.c 4300d311b17fb3c1476623fd895a8feac02a0b08
|
||||||
F src/btmutex.c 63c5cc4ad5715690767ffcb741e185d7bc35ec1a
|
F src/btmutex.c 63c5cc4ad5715690767ffcb741e185d7bc35ec1a
|
||||||
F src/btree.c ad51b56b1a90e3c9ad39aabd9368325aba5a6730
|
F src/btree.c 69983b4e6567321478f2fb40cd2b0c95807927fe
|
||||||
F src/btree.h 4f141cf748d2ee7c6d7fc175f64f87a45cd44113
|
F src/btree.h 4f141cf748d2ee7c6d7fc175f64f87a45cd44113
|
||||||
F src/btreeInt.h 7ef2c872371d7508657f8d7a4efe651c741d6ee6
|
F src/btreeInt.h 7ef2c872371d7508657f8d7a4efe651c741d6ee6
|
||||||
F src/build.c f3e8377cbc0d007b01aab1e7d4fc1d5b296c422e
|
F src/build.c f3e8377cbc0d007b01aab1e7d4fc1d5b296c422e
|
||||||
@@ -142,7 +142,7 @@ F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
|
|||||||
F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5
|
F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5
|
||||||
F src/os_unix.c e6eacc7ec735ded605fefcbaf250058baa8feb12
|
F src/os_unix.c e6eacc7ec735ded605fefcbaf250058baa8feb12
|
||||||
F src/os_win.c 496e3ceb499aedc63622a89ef76f7af2dd902709
|
F src/os_win.c 496e3ceb499aedc63622a89ef76f7af2dd902709
|
||||||
F src/pager.c 59b87841ac6ea5f6e5023f2321b69572b9883a8b
|
F src/pager.c 5998dc0bfa382d43e1d8c1c498597d2600cc495b
|
||||||
F src/pager.h 7191294438881eb4d13eedade97891e8dc993905
|
F src/pager.h 7191294438881eb4d13eedade97891e8dc993905
|
||||||
F src/parse.y 4d0e33a702dc3ea7b69d8ae1914b3fbd32e46057
|
F src/parse.y 4d0e33a702dc3ea7b69d8ae1914b3fbd32e46057
|
||||||
F src/pcache.c 16dc8da6e6ba6250f8dfd9ee46036db1cbceedc6
|
F src/pcache.c 16dc8da6e6ba6250f8dfd9ee46036db1cbceedc6
|
||||||
@@ -394,7 +394,7 @@ F test/index3.test 727d55dceb9a4ec36675057bb5becfc265e28ca6
|
|||||||
F test/indexedby.test 03af52375e50d146e78f56442b6677d2932c4963
|
F test/indexedby.test 03af52375e50d146e78f56442b6677d2932c4963
|
||||||
F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908
|
F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908
|
||||||
F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435
|
F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435
|
||||||
F test/insert3.test 9a4ef3526fd3cca8b05278020ec3100448b4c677
|
F test/insert3.test 7188f1da1126eb15f1b27cf34f4c2753c7d5fd27
|
||||||
F test/insert4.test 6e382eaf7295a4463e6f29ea20fcd8e63d097eeb
|
F test/insert4.test 6e382eaf7295a4463e6f29ea20fcd8e63d097eeb
|
||||||
F test/insert5.test 1f93cbe9742110119133d7e8e3ccfe6d7c249766
|
F test/insert5.test 1f93cbe9742110119133d7e8e3ccfe6d7c249766
|
||||||
F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1
|
F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1
|
||||||
@@ -684,7 +684,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P ee0e6eae9f984472e44d7ee8f195c6e5d33f2efd
|
P bbdc0e9f2481f8d59e05ea282b615f97e09fb471
|
||||||
R 84a43cb77701b394bb942c42ab498d4d
|
R 9a4f367c203efd1d1b7375ea1b15ec85
|
||||||
U danielk1977
|
U danielk1977
|
||||||
Z a3c50f9a13d9f2d8f7a301ea5204d232
|
Z f234b11339d566d37e09d7218e4eacc3
|
||||||
|
@@ -1 +1 @@
|
|||||||
bbdc0e9f2481f8d59e05ea282b615f97e09fb471
|
ae44e7482476478c8eeacfb80b282f17894530e5
|
32
src/btree.c
32
src/btree.c
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btree.c,v 1.550 2008/12/18 15:45:07 danielk1977 Exp $
|
** $Id: btree.c,v 1.551 2008/12/23 10:37:47 danielk1977 Exp $
|
||||||
**
|
**
|
||||||
** This file implements a external (disk-based) database using BTrees.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** See the header comment on "btreeInt.h" for additional information.
|
** See the header comment on "btreeInt.h" for additional information.
|
||||||
@@ -4977,6 +4977,7 @@ static int balance_quick(BtCursor *pCur){
|
|||||||
*/
|
*/
|
||||||
pPage->isInit = 0;
|
pPage->isInit = 0;
|
||||||
sqlite3BtreeInitPage(pPage);
|
sqlite3BtreeInitPage(pPage);
|
||||||
|
assert( pPage->nOverflow==0 );
|
||||||
|
|
||||||
/* If everything else succeeded, balance the parent page, in
|
/* If everything else succeeded, balance the parent page, in
|
||||||
** case the divider cell inserted caused it to become overfull.
|
** case the divider cell inserted caused it to become overfull.
|
||||||
@@ -5025,8 +5026,8 @@ static int balance_nonroot(BtCursor *pCur){
|
|||||||
BtShared *pBt; /* The whole database */
|
BtShared *pBt; /* The whole database */
|
||||||
int nCell = 0; /* Number of cells in apCell[] */
|
int nCell = 0; /* Number of cells in apCell[] */
|
||||||
int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */
|
int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */
|
||||||
int nOld; /* Number of pages in apOld[] */
|
int nOld = 0; /* Number of pages in apOld[] */
|
||||||
int nNew; /* Number of pages in apNew[] */
|
int nNew = 0; /* Number of pages in apNew[] */
|
||||||
int nDiv; /* Number of cells in apDiv[] */
|
int nDiv; /* Number of cells in apDiv[] */
|
||||||
int i, j, k; /* Loop counters */
|
int i, j, k; /* Loop counters */
|
||||||
int idx; /* Index of pPage in pParent->aCell[] */
|
int idx; /* Index of pPage in pParent->aCell[] */
|
||||||
@@ -5069,7 +5070,7 @@ static int balance_nonroot(BtCursor *pCur){
|
|||||||
pParent = pCur->apPage[pCur->iPage-1];
|
pParent = pCur->apPage[pCur->iPage-1];
|
||||||
assert( pParent );
|
assert( pParent );
|
||||||
if( SQLITE_OK!=(rc = sqlite3PagerWrite(pParent->pDbPage)) ){
|
if( SQLITE_OK!=(rc = sqlite3PagerWrite(pParent->pDbPage)) ){
|
||||||
return rc;
|
goto balance_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
|
TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
|
||||||
@@ -5100,7 +5101,7 @@ static int balance_nonroot(BtCursor *pCur){
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( SQLITE_OK!=(rc = sqlite3PagerWrite(pPage->pDbPage)) ){
|
if( SQLITE_OK!=(rc = sqlite3PagerWrite(pPage->pDbPage)) ){
|
||||||
return rc;
|
goto balance_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -5111,12 +5112,6 @@ static int balance_nonroot(BtCursor *pCur){
|
|||||||
idx = pCur->aiIdx[pCur->iPage-1];
|
idx = pCur->aiIdx[pCur->iPage-1];
|
||||||
assertParentIndex(pParent, idx, pPage->pgno);
|
assertParentIndex(pParent, idx, pPage->pgno);
|
||||||
|
|
||||||
/*
|
|
||||||
** Initialize variables so that it will be safe to jump
|
|
||||||
** directly to balance_cleanup at any moment.
|
|
||||||
*/
|
|
||||||
nOld = nNew = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Find sibling pages to pPage and the cells in pParent that divide
|
** Find sibling pages to pPage and the cells in pParent that divide
|
||||||
** the siblings. An attempt is made to find NN siblings on either
|
** the siblings. An attempt is made to find NN siblings on either
|
||||||
@@ -5578,6 +5573,9 @@ static int balance_nonroot(BtCursor *pCur){
|
|||||||
assert( pParent->isInit );
|
assert( pParent->isInit );
|
||||||
sqlite3ScratchFree(apCell);
|
sqlite3ScratchFree(apCell);
|
||||||
apCell = 0;
|
apCell = 0;
|
||||||
|
TRACE(("BALANCE: finished with %d: old=%d new=%d cells=%d\n",
|
||||||
|
pPage->pgno, nOld, nNew, nCell));
|
||||||
|
pPage->nOverflow = 0;
|
||||||
releasePage(pPage);
|
releasePage(pPage);
|
||||||
pCur->iPage--;
|
pCur->iPage--;
|
||||||
rc = balance(pCur, 0);
|
rc = balance(pCur, 0);
|
||||||
@@ -5594,11 +5592,7 @@ balance_cleanup:
|
|||||||
for(i=0; i<nNew; i++){
|
for(i=0; i<nNew; i++){
|
||||||
releasePage(apNew[i]);
|
releasePage(apNew[i]);
|
||||||
}
|
}
|
||||||
pPage->nOverflow = 0;
|
pCur->apPage[pCur->iPage]->nOverflow = 0;
|
||||||
|
|
||||||
/* releasePage(pParent); */
|
|
||||||
TRACE(("BALANCE: finished with %d: old=%d new=%d cells=%d\n",
|
|
||||||
pPage->pgno, nOld, nNew, nCell));
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -5792,17 +5786,18 @@ static int balance(BtCursor *pCur, int isInsert){
|
|||||||
rc = sqlite3PagerWrite(pPage->pDbPage);
|
rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||||
if( rc==SQLITE_OK && pPage->nOverflow>0 ){
|
if( rc==SQLITE_OK && pPage->nOverflow>0 ){
|
||||||
rc = balance_deeper(pCur);
|
rc = balance_deeper(pCur);
|
||||||
|
assert( pCur->apPage[0]==pPage );
|
||||||
assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
|
assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
|
||||||
}
|
}
|
||||||
if( rc==SQLITE_OK && pPage->nCell==0 ){
|
if( rc==SQLITE_OK && pPage->nCell==0 ){
|
||||||
rc = balance_shallower(pCur);
|
rc = balance_shallower(pCur);
|
||||||
|
assert( pCur->apPage[0]==pPage );
|
||||||
assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
|
assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if( pPage->nOverflow>0 ||
|
if( pPage->nOverflow>0 ||
|
||||||
(!isInsert && pPage->nFree>pPage->pBt->usableSize*2/3) ){
|
(!isInsert && pPage->nFree>pPage->pBt->usableSize*2/3) ){
|
||||||
rc = balance_nonroot(pCur);
|
rc = balance_nonroot(pCur);
|
||||||
assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
@@ -5977,8 +5972,7 @@ int sqlite3BtreeInsert(
|
|||||||
|
|
||||||
/* Must make sure nOverflow is reset to zero even if the balance()
|
/* Must make sure nOverflow is reset to zero even if the balance()
|
||||||
** fails. Internal data structure corruption will result otherwise. */
|
** fails. Internal data structure corruption will result otherwise. */
|
||||||
assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
|
pCur->apPage[pCur->iPage]->nOverflow = 0;
|
||||||
pPage->nOverflow = 0;
|
|
||||||
|
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
moveToRoot(pCur);
|
moveToRoot(pCur);
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
** file simultaneously, or one process from reading the database while
|
** file simultaneously, or one process from reading the database while
|
||||||
** another is writing.
|
** another is writing.
|
||||||
**
|
**
|
||||||
** @(#) $Id: pager.c,v 1.521 2008/12/22 11:43:36 danielk1977 Exp $
|
** @(#) $Id: pager.c,v 1.522 2008/12/23 10:37:47 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_DISKIO
|
#ifndef SQLITE_OMIT_DISKIO
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
@@ -3289,6 +3289,7 @@ static int pager_write(PgHdr *pPg){
|
|||||||
*/
|
*/
|
||||||
if( !pPager->noSync ){
|
if( !pPager->noSync ){
|
||||||
pPg->flags |= PGHDR_NEED_SYNC;
|
pPg->flags |= PGHDR_NEED_SYNC;
|
||||||
|
pPager->needSync = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* An error has occured writing to the journal file. The
|
/* An error has occured writing to the journal file. The
|
||||||
@@ -3305,14 +3306,12 @@ static int pager_write(PgHdr *pPg){
|
|||||||
}else{
|
}else{
|
||||||
if( !pPager->journalStarted && !pPager->noSync ){
|
if( !pPager->journalStarted && !pPager->noSync ){
|
||||||
pPg->flags |= PGHDR_NEED_SYNC;
|
pPg->flags |= PGHDR_NEED_SYNC;
|
||||||
|
pPager->needSync = 1;
|
||||||
}
|
}
|
||||||
PAGERTRACE4("APPEND %d page %d needSync=%d\n",
|
PAGERTRACE4("APPEND %d page %d needSync=%d\n",
|
||||||
PAGERID(pPager), pPg->pgno,
|
PAGERID(pPager), pPg->pgno,
|
||||||
((pPg->flags&PGHDR_NEED_SYNC)?1:0));
|
((pPg->flags&PGHDR_NEED_SYNC)?1:0));
|
||||||
}
|
}
|
||||||
if( pPg->flags&PGHDR_NEED_SYNC ){
|
|
||||||
pPager->needSync = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the statement journal is open and the page is not in it,
|
/* If the statement journal is open and the page is not in it,
|
||||||
@@ -3409,6 +3408,7 @@ int sqlite3PagerWrite(DbPage *pDbPage){
|
|||||||
rc = pager_write(pPage);
|
rc = pager_write(pPage);
|
||||||
if( pPage->flags&PGHDR_NEED_SYNC ){
|
if( pPage->flags&PGHDR_NEED_SYNC ){
|
||||||
needSync = 1;
|
needSync = 1;
|
||||||
|
assert(pPager->needSync);
|
||||||
}
|
}
|
||||||
sqlite3PagerUnref(pPage);
|
sqlite3PagerUnref(pPage);
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is testing corner cases of the INSERT statement.
|
# focus of this file is testing corner cases of the INSERT statement.
|
||||||
#
|
#
|
||||||
# $Id: insert3.test,v 1.7 2007/09/12 17:01:45 danielk1977 Exp $
|
# $Id: insert3.test,v 1.8 2008/12/23 10:37:47 danielk1977 Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -168,4 +168,36 @@ ifcapable bloblit {
|
|||||||
}
|
}
|
||||||
db close
|
db close
|
||||||
|
|
||||||
|
file delete -force test.db
|
||||||
|
sqlite3 db test.db
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# While developing tests for a different feature (savepoint) the following
|
||||||
|
# sequence was found to cause an assert() in btree.c to fail. These
|
||||||
|
# tests are included to ensure that that bug is fixed.
|
||||||
|
#
|
||||||
|
do_test insert3-4.1 {
|
||||||
|
execsql {
|
||||||
|
CREATE TABLE t1(a, b, c);
|
||||||
|
CREATE INDEX i1 ON t1(a, b);
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t1 VALUES(randstr(10,400),randstr(10,400),randstr(10,400));
|
||||||
|
}
|
||||||
|
set r "randstr(10,400)"
|
||||||
|
for {set ii 0} {$ii < 10} {incr ii} {
|
||||||
|
execsql "INSERT INTO t1 SELECT $r, $r, $r FROM t1"
|
||||||
|
}
|
||||||
|
execsql { COMMIT }
|
||||||
|
} {}
|
||||||
|
do_test insert3-4.2 {
|
||||||
|
execsql {
|
||||||
|
PRAGMA cache_size = 10;
|
||||||
|
BEGIN;
|
||||||
|
UPDATE t1 SET a = randstr(10,10) WHERE (rowid%4)==0;
|
||||||
|
DELETE FROM t1 WHERE rowid%2;
|
||||||
|
INSERT INTO t1 SELECT randstr(10,400), randstr(10,400), c FROM t1;
|
||||||
|
COMMIT;
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
Reference in New Issue
Block a user