1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Test cases to improve coverage of btree.c (and minor bugfixes). (CVS 2190)

FossilOrigin-Name: 8ced491588764b1e1066787d0abf3cde8b60970b
This commit is contained in:
danielk1977
2005-01-11 10:25:06 +00:00
parent 7701e817ba
commit 2812956b18
12 changed files with 578 additions and 87 deletions

View File

@@ -1,5 +1,5 @@
C Extra\stest\scases\sto\simprove\scoverage\sof\sbtree.c\s(CVS\s2189) C Test\scases\sto\simprove\scoverage\sof\sbtree.c\s(and\sminor\sbugfixes).\s(CVS\s2190)
D 2005-01-10T12:59:52 D 2005-01-11T10:25:07
F Makefile.in ecf441ac5ca1ccfc8748a8a9537706e69893dfa4 F Makefile.in ecf441ac5ca1ccfc8748a8a9537706e69893dfa4
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1 F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
@@ -29,7 +29,7 @@ F sqlite3.def dbaeb20c153e1d366e8f421b55a573f5dfc00863
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689 F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689
F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea
F src/btree.c 241e27b4640519a45ab55d35ee3ae300a478eb23 F src/btree.c 5ec669c8839d98dd9e283cc6d4547da4adb37a81
F src/btree.h 861e40b759a195ba63819740e484390012cf81ab F src/btree.h 861e40b759a195ba63819740e484390012cf81ab
F src/build.c af1296e8a21a406b4f4c4f1e1365e075071219f3 F src/build.c af1296e8a21a406b4f4c4f1e1365e075071219f3
F src/cursor.c f883813759742068890b1f699335872bfa8fdf41 F src/cursor.c f883813759742068890b1f699335872bfa8fdf41
@@ -53,10 +53,10 @@ F src/os_unix.c 08340c864822115bf87c6c1735780a0996278b81
F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13 F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13
F src/os_win.c 3c0b0a3bc33318cf555a1cd130232ad1b9a5a711 F src/os_win.c 3c0b0a3bc33318cf555a1cd130232ad1b9a5a711
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c 4a14410a4e67173bb121a919c7f2033b93822186 F src/pager.c c6b29d55c9755f35bd9d711865aaf83e410f730f
F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862 F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862
F src/parse.y ceba179b9703657180963568f54b0e75f33e36e1 F src/parse.y ceba179b9703657180963568f54b0e75f33e36e1
F src/pragma.c 1b6f9f4caa2c441b18bf0c8793a4b4b8f3214d03 F src/pragma.c ac594f74c90ffec043c43e49358719ffeb491eec
F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357 F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
F src/select.c af6ffcf0201f8f4e2697eea25689077dc61c6109 F src/select.c af6ffcf0201f8f4e2697eea25689077dc61c6109
@@ -76,7 +76,7 @@ F src/update.c 0979397c41ac29c54fe0cc687a356d8629a633af
F src/utf.c e45ce11be6922408cd381561721f6cca7d3b992a F src/utf.c e45ce11be6922408cd381561721f6cca7d3b992a
F src/util.c 29f43c4a7b9ff29302f7899f793be6836b6cd7f9 F src/util.c 29f43c4a7b9ff29302f7899f793be6836b6cd7f9
F src/vacuum.c 1a9db113a027461daaf44724c71dd1ebbd064203 F src/vacuum.c 1a9db113a027461daaf44724c71dd1ebbd064203
F src/vdbe.c 53520958a7d63eaf138fa78f69efe225d502a9bf F src/vdbe.c c9f00cc0298e025e61b4b65555a4a23dd13325dd
F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181 F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
F src/vdbeInt.h 0f74561e629af86172de7cdf0ecaea014c51696c F src/vdbeInt.h 0f74561e629af86172de7cdf0ecaea014c51696c
F src/vdbeapi.c 0cf3bdc1072616bedc8eec7fc22e3f5a169d33fd F src/vdbeapi.c 0cf3bdc1072616bedc8eec7fc22e3f5a169d33fd
@@ -93,12 +93,14 @@ F test/auth.test 559e0816b8100740624ebb0ab7aab05f5c92831c
F test/autoinc.test c071e51ff167b8e889212273588d9cca71845b70 F test/autoinc.test c071e51ff167b8e889212273588d9cca71845b70
F test/autovacuum.test a4e8da39a6268378c4f9fc17fe2df1d5be16d631 F test/autovacuum.test a4e8da39a6268378c4f9fc17fe2df1d5be16d631
F test/autovacuum_crash.test 2dca85cbcc497098e45e8847c86407eb3554f3d4 F test/autovacuum_crash.test 2dca85cbcc497098e45e8847c86407eb3554f3d4
F test/autovacuum_ioerr.test 55ea907df34edb9be78a910a1636c2eb3c17ecc4
F test/autovacuum_ioerr2.test bf427c86e4daa8638a2eb849bbe1446c234c73d3
F test/bigfile.test d3744a8821ce9abb8697f2826a3e3d22b719e89f F test/bigfile.test d3744a8821ce9abb8697f2826a3e3d22b719e89f
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747 F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
F test/bind.test 3635ddfe0fb15ecfd158708feff6ef707e15c0a9 F test/bind.test 3635ddfe0fb15ecfd158708feff6ef707e15c0a9
F test/blob.test fc41fe95bdc10da51f0dee73ce86e75ce1d6eb9d F test/blob.test fc41fe95bdc10da51f0dee73ce86e75ce1d6eb9d
F test/btree.test ff754a2e68af75396fbbf8dfda009b4b93f086a6 F test/btree.test 8aa7424aeec844df990273fe36447e5d7e407261
F test/btree2.test aa4a6d05b1ea90b1acaf83ba89039dd302a88635 F test/btree2.test dbce930b549d5ac883a7d8905c976209ea241db3
F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4 F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4
F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2 F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2
F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027 F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027
@@ -114,6 +116,7 @@ F test/collate5.test 7999fb3122386bae38acd8ccd61e0b7c5a30e289
F test/collate6.test 6c9470d1606ee3e564675b229653e320c49ec638 F test/collate6.test 6c9470d1606ee3e564675b229653e320c49ec638
F test/conflict.test c5b849b01cfbe0a4f63a90cba6f68e2fe3a75f87 F test/conflict.test c5b849b01cfbe0a4f63a90cba6f68e2fe3a75f87
F test/corrupt.test 0080ddcece23e8ba47c44608c4fb73fd4d1d8ce2 F test/corrupt.test 0080ddcece23e8ba47c44608c4fb73fd4d1d8ce2
F test/corrupt2.test cb1f813df7559de3021e01170af0bba31507a9a5
F test/crash.test 637479504e137d065385c5b9379680d2b5372630 F test/crash.test 637479504e137d065385c5b9379680d2b5372630
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F test/cursor.test d7c65ea0fc4e321e12fbcf5c7f3e2211ef45379b F test/cursor.test d7c65ea0fc4e321e12fbcf5c7f3e2211ef45379b
@@ -134,7 +137,7 @@ F test/insert.test 56f9c20c9adc8d707490c4ffa5d4daa94826ea03
F test/insert2.test 0bb50ff999e35a21549d8ee5dc44db8ac24d31a7 F test/insert2.test 0bb50ff999e35a21549d8ee5dc44db8ac24d31a7
F test/interrupt.test 0aa230f8aedec0ad7caaf5edaced337e4cfb3820 F test/interrupt.test 0aa230f8aedec0ad7caaf5edaced337e4cfb3820
F test/intpkey.test b57cf5236fde1bd8cbc1388fa0c91908f6fd9194 F test/intpkey.test b57cf5236fde1bd8cbc1388fa0c91908f6fd9194
F test/ioerr.test fd283e768301b26bc148012ea6ebea4c2295aa20 F test/ioerr.test b37837850294c6cbafb0fd5211a4df40b10d46af
F test/join.test ea8c77b9fbc377fe553cdb5ce5f1bd72021dca5d F test/join.test ea8c77b9fbc377fe553cdb5ce5f1bd72021dca5d
F test/join2.test c97e4c5aa65dea462145529e58212a709b4722b8 F test/join2.test c97e4c5aa65dea462145529e58212a709b4722b8
F test/join3.test 67dc0d7c8dab3fff25796d0f3c3fd9c999aeded3 F test/join3.test 67dc0d7c8dab3fff25796d0f3c3fd9c999aeded3
@@ -263,7 +266,7 @@ F www/tclsqlite.tcl e73f8f8e5f20e8277619433f7970060ab01088fc
F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618 F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl c3b50d3ac31c54be2a1af9b488a89d22f1e6e746 F www/whentouse.tcl c3b50d3ac31c54be2a1af9b488a89d22f1e6e746
P 5b7a5a4d69be425163135698d889797d15f56492 P a461988661368bce799ef3d498a18e88559e14c7
R 8f87d57733bba8a8bebba0892812901d R 9631300063f5d334400b6e5706977e76
U danielk1977 U danielk1977
Z 23146f967500dcd597b4ae335d7f01e0 Z 6f3669f1f4cea6222a3e8648182fde70

View File

@@ -1 +1 @@
a461988661368bce799ef3d498a18e88559e14c7 8ced491588764b1e1066787d0abf3cde8b60970b

View File

@@ -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.229 2005/01/10 12:59:52 danielk1977 Exp $ ** $Id: btree.c,v 1.230 2005/01/11 10:25:07 danielk1977 Exp $
** **
** This file implements a external (disk-based) database using BTrees. ** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to ** For a detailed discussion of BTrees, refer to
@@ -356,7 +356,6 @@ struct BtCursor {
CellInfo info; /* A parse of the cell we are pointing at */ CellInfo info; /* A parse of the cell we are pointing at */
u8 wrFlag; /* True if writable */ u8 wrFlag; /* True if writable */
u8 isValid; /* TRUE if points to a valid entry */ u8 isValid; /* TRUE if points to a valid entry */
u8 status; /* Set to SQLITE_ABORT if cursors is invalidated */
}; };
/* /*
@@ -953,7 +952,6 @@ static int initPage(
MemPage *pParent /* The parent. Might be NULL */ MemPage *pParent /* The parent. Might be NULL */
){ ){
int pc; /* Address of a freeblock within pPage->aData[] */ int pc; /* Address of a freeblock within pPage->aData[] */
int i; /* Loop counter */
int hdr; /* Offset to beginning of page header */ int hdr; /* Offset to beginning of page header */
u8 *data; /* Equal to pPage->aData */ u8 *data; /* Equal to pPage->aData */
Btree *pBt; /* The main btree structure */ Btree *pBt; /* The main btree structure */
@@ -997,17 +995,12 @@ static int initPage(
/* Compute the total free space on the page */ /* Compute the total free space on the page */
pc = get2byte(&data[hdr+1]); pc = get2byte(&data[hdr+1]);
nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell); nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell);
i = 0;
while( pc>0 ){ while( pc>0 ){
int next, size; int next, size;
if( pc>usableSize-4 ){ if( pc>usableSize-4 ){
/* Free block is off the page */ /* Free block is off the page */
return SQLITE_CORRUPT; /* bkpt-CORRUPT */ return SQLITE_CORRUPT; /* bkpt-CORRUPT */
} }
if( i++>SQLITE_MAX_PAGE_SIZE/4 ){
/* The free block list forms an infinite loop */
return SQLITE_CORRUPT; /* bkpt-CORRUPT */
}
next = get2byte(&data[pc]); next = get2byte(&data[pc]);
size = get2byte(&data[pc+2]); size = get2byte(&data[pc+2]);
if( next>0 && next<=pc+size+3 ){ if( next>0 && next<=pc+size+3 ){
@@ -1295,6 +1288,9 @@ int sqlite3BtreeSetSafetyLevel(Btree *pBt, int level){
** of the database file used for locking (beginning at PENDING_BYTE, ** of the database file used for locking (beginning at PENDING_BYTE,
** the first byte past the 1GB boundary, 0x40000000) needs to occur ** the first byte past the 1GB boundary, 0x40000000) needs to occur
** at the beginning of a page. ** at the beginning of a page.
**
** If parameter nReserve is less than zero, then the number of reserved
** bytes per page is left unchanged.
*/ */
int sqlite3BtreeSetPageSize(Btree *pBt, int pageSize, int nReserve){ int sqlite3BtreeSetPageSize(Btree *pBt, int pageSize, int nReserve){
if( pBt->pageSizeFixed ){ if( pBt->pageSizeFixed ){
@@ -1904,6 +1900,7 @@ static void invalidateCursors(Btree *pBt){
** Print debugging information about all cursors to standard output. ** Print debugging information about all cursors to standard output.
*/ */
void sqlite3BtreeCursorList(Btree *pBt){ void sqlite3BtreeCursorList(Btree *pBt){
#ifndef SQLITE_OMIT_CURSOR
BtCursor *pCur; BtCursor *pCur;
for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
MemPage *pPage = pCur->pPage; MemPage *pPage = pCur->pPage;
@@ -1914,6 +1911,7 @@ void sqlite3BtreeCursorList(Btree *pBt){
pCur->isValid ? "" : " eof" pCur->isValid ? "" : " eof"
); );
} }
#endif
} }
#endif #endif
@@ -2117,7 +2115,6 @@ int sqlite3BtreeCursor(
pCur->pPrev = 0; pCur->pPrev = 0;
pBt->pCursor = pCur; pBt->pCursor = pCur;
pCur->isValid = 0; pCur->isValid = 0;
pCur->status = SQLITE_OK;
*ppCur = pCur; *ppCur = pCur;
return SQLITE_OK; return SQLITE_OK;
@@ -2344,9 +2341,7 @@ static int getPayload(
** the available payload. ** the available payload.
*/ */
int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
if( !pCur->isValid ){ assert( pCur->isValid );
return pCur->status;
}
assert( pCur->pPage!=0 ); assert( pCur->pPage!=0 );
assert( pCur->pPage->intKey==0 ); assert( pCur->pPage->intKey==0 );
assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell ); assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
@@ -2363,9 +2358,7 @@ int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
** the available payload. ** the available payload.
*/ */
int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
if( !pCur->isValid ){ assert( pCur->isValid );
return pCur->status ? pCur->status : SQLITE_INTERNAL;
}
assert( pCur->pPage!=0 ); assert( pCur->pPage!=0 );
assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell ); assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
return getPayload(pCur, offset, amt, pBuf, 1); return getPayload(pCur, offset, amt, pBuf, 1);
@@ -2603,9 +2596,6 @@ static int moveToRightmost(BtCursor *pCur){
*/ */
int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
int rc; int rc;
if( pCur->status ){
return pCur->status;
}
rc = moveToRoot(pCur); rc = moveToRoot(pCur);
if( rc ) return rc; if( rc ) return rc;
if( pCur->isValid==0 ){ if( pCur->isValid==0 ){
@@ -2625,9 +2615,6 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
*/ */
int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
int rc; int rc;
if( pCur->status ){
return pCur->status;
}
rc = moveToRoot(pCur); rc = moveToRoot(pCur);
if( rc ) return rc; if( rc ) return rc;
if( pCur->isValid==0 ){ if( pCur->isValid==0 ){
@@ -2670,10 +2657,6 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
*/ */
int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
int rc; int rc;
if( pCur->status ){
return pCur->status;
}
rc = moveToRoot(pCur); rc = moveToRoot(pCur);
if( rc ) return rc; if( rc ) return rc;
assert( pCur->pPage ); assert( pCur->pPage );
@@ -3274,7 +3257,7 @@ static int fillInCell(
#endif #endif
if( rc ){ if( rc ){
releasePage(pToRelease); releasePage(pToRelease);
clearCell(pPage, pCell); /* clearCell(pPage, pCell); */
return rc; return rc;
} }
put4byte(pPrior, pgnoOvfl); put4byte(pPrior, pgnoOvfl);
@@ -3873,7 +3856,8 @@ static int balance_nonroot(MemPage *pPage){
pNew = apNew[i] = apOld[i]; pNew = apNew[i] = apOld[i];
pgnoNew[i] = pgnoOld[i]; pgnoNew[i] = pgnoOld[i];
apOld[i] = 0; apOld[i] = 0;
sqlite3pager_write(pNew->aData); rc = sqlite3pager_write(pNew->aData);
if( rc ) goto balance_cleanup;
}else{ }else{
rc = allocatePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0); rc = allocatePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0);
if( rc ) goto balance_cleanup; if( rc ) goto balance_cleanup;
@@ -4236,9 +4220,6 @@ int sqlite3BtreeInsert(
unsigned char *oldCell; unsigned char *oldCell;
unsigned char *newCell = 0; unsigned char *newCell = 0;
if( pCur->status ){
return pCur->status; /* A rollback destroyed this cursor */
}
if( pBt->inTrans!=TRANS_WRITE ){ if( pBt->inTrans!=TRANS_WRITE ){
/* Must start a transaction before doing an insert */ /* Must start a transaction before doing an insert */
return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
@@ -4310,9 +4291,6 @@ int sqlite3BtreeDelete(BtCursor *pCur){
Btree *pBt = pCur->pBt; Btree *pBt = pCur->pBt;
assert( pPage->isInit ); assert( pPage->isInit );
if( pCur->status ){
return pCur->status; /* A rollback destroyed this cursor */
}
if( pBt->inTrans!=TRANS_WRITE ){ if( pBt->inTrans!=TRANS_WRITE ){
/* Must start a transaction before doing a delete */ /* Must start a transaction before doing a delete */
return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
@@ -4338,7 +4316,8 @@ int sqlite3BtreeDelete(BtCursor *pCur){
if( !pPage->leaf ){ if( !pPage->leaf ){
pgnoChild = get4byte(pCell); pgnoChild = get4byte(pCell);
} }
clearCell(pPage, pCell); rc = clearCell(pPage, pCell);
if( rc ) return rc;
if( !pPage->leaf ){ if( !pPage->leaf ){
/* /*
@@ -4410,9 +4389,7 @@ int sqlite3BtreeCreateTable(Btree *pBt, int *piTable, int flags){
/* Must start a transaction first */ /* Must start a transaction first */
return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
} }
if( pBt->readOnly ){ assert( !pBt->readOnly );
return SQLITE_READONLY;
}
/* It is illegal to create a table if any cursors are open on the /* It is illegal to create a table if any cursors are open on the
** database. This is because in auto-vacuum mode the backend may ** database. This is because in auto-vacuum mode the backend may
@@ -4771,6 +4748,7 @@ int sqlite3BtreeFlags(BtCursor *pCur){
** is used for debugging and testing only. ** is used for debugging and testing only.
*/ */
#ifdef SQLITE_TEST #ifdef SQLITE_TEST
#ifndef SQLITE_OMIT_BTREEPAGEDUMP
static int btreePageDump(Btree *pBt, int pgno, int recursive, MemPage *pParent){ static int btreePageDump(Btree *pBt, int pgno, int recursive, MemPage *pParent){
int rc; int rc;
MemPage *pPage; MemPage *pPage;
@@ -4867,8 +4845,11 @@ static int btreePageDump(Btree *pBt, int pgno, int recursive, MemPage *pParent){
fflush(stdout); fflush(stdout);
return SQLITE_OK; return SQLITE_OK;
} }
#endif
int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){ int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){
#ifndef SQLITE_OMIT_BTREEPAGEDUMP
return btreePageDump(pBt, pgno, recursive, 0); return btreePageDump(pBt, pgno, recursive, 0);
#endif
} }
#endif #endif

View File

@@ -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.180 2005/01/08 12:42:39 danielk1977 Exp $ ** @(#) $Id: pager.c,v 1.181 2005/01/11 10:25:08 danielk1977 Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "os.h" #include "os.h"
@@ -935,12 +935,14 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
rc = sqlite3OsWrite(&pPager->fd, aData, pPager->pageSize); rc = sqlite3OsWrite(&pPager->fd, aData, pPager->pageSize);
} }
if( pPg ){ if( pPg ){
/* No page should ever be rolled back that is in use, except for page /* No page should ever be explicitly rolled back that is in use, except
** 1 which is held in use in order to keep the lock on the database ** for page 1 which is held in use in order to keep the lock on the
** active. ** database active. However such a page may be rolled back as a result
** of an internal error resulting in an automatic call to
** sqlite3pager_rollback().
*/ */
void *pData; void *pData;
assert( pPg->nRef==0 || pPg->pgno==1 ); /* assert( pPg->nRef==0 || pPg->pgno==1 ); */
pData = PGHDR_TO_DATA(pPg); pData = PGHDR_TO_DATA(pPg);
memcpy(pData, aData, pPager->pageSize); memcpy(pData, aData, pPager->pageSize);
if( pPager->xDestructor ){ /*** FIX ME: Should this be xReinit? ***/ if( pPager->xDestructor ){ /*** FIX ME: Should this be xReinit? ***/

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** This file contains code used to implement the PRAGMA command. ** This file contains code used to implement the PRAGMA command.
** **
** $Id: pragma.c,v 1.82 2005/01/08 15:44:26 drh Exp $ ** $Id: pragma.c,v 1.83 2005/01/11 10:25:08 danielk1977 Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "os.h" #include "os.h"
@@ -285,7 +285,7 @@ void sqlite3Pragma(
int size = pBt ? sqlite3BtreeGetPageSize(pBt) : 0; int size = pBt ? sqlite3BtreeGetPageSize(pBt) : 0;
returnSingleInt(pParse, "page_size", size); returnSingleInt(pParse, "page_size", size);
}else{ }else{
sqlite3BtreeSetPageSize(pBt, atoi(zRight), sqlite3BtreeGetReserve(pBt)); sqlite3BtreeSetPageSize(pBt, atoi(zRight), -1);
} }
}else }else
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ #endif /* SQLITE_OMIT_PAGER_PRAGMAS */

View File

@@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing ** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code. ** commenting and indentation practices when changing or adding code.
** **
** $Id: vdbe.c,v 1.437 2005/01/10 12:59:53 danielk1977 Exp $ ** $Id: vdbe.c,v 1.438 2005/01/11 10:25:08 danielk1977 Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "os.h" #include "os.h"
@@ -2565,12 +2565,18 @@ case OP_MoveGt: {
pTos--; pTos--;
break; break;
} }
sqlite3BtreeMoveto(pC->pCursor, 0, (u64)iKey, &res); rc = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)iKey, &res);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
pC->lastRecno = pTos->i; pC->lastRecno = pTos->i;
pC->recnoIsValid = res==0; pC->recnoIsValid = res==0;
}else{ }else{
Stringify(pTos, db->enc); Stringify(pTos, db->enc);
sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res); rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
pC->recnoIsValid = 0; pC->recnoIsValid = 0;
} }
pC->deferredMoveto = 0; pC->deferredMoveto = 0;
@@ -2579,7 +2585,10 @@ case OP_MoveGt: {
sqlite3_search_count++; sqlite3_search_count++;
if( oc==OP_MoveGe || oc==OP_MoveGt ){ if( oc==OP_MoveGe || oc==OP_MoveGt ){
if( res<0 ){ if( res<0 ){
sqlite3BtreeNext(pC->pCursor, &res); rc = sqlite3BtreeNext(pC->pCursor, &res);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
pC->recnoIsValid = 0; pC->recnoIsValid = 0;
}else{ }else{
res = 0; res = 0;
@@ -2800,12 +2809,14 @@ case OP_NotExists: {
assert( pTos->flags & MEM_Int ); assert( pTos->flags & MEM_Int );
assert( p->apCsr[i]->intKey ); assert( p->apCsr[i]->intKey );
iKey = intToKey(pTos->i); iKey = intToKey(pTos->i);
rx = sqlite3BtreeMoveto(pCrsr, 0, iKey, &res); // rx = sqlite3BtreeMoveto(pCrsr, 0, iKey, &res);
rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, &res);
pC->lastRecno = pTos->i; pC->lastRecno = pTos->i;
pC->recnoIsValid = res==0; pC->recnoIsValid = res==0;
pC->nullRow = 0; pC->nullRow = 0;
pC->cacheValid = 0; pC->cacheValid = 0;
if( rx!=SQLITE_OK || res!=0 ){ // if( rx!=SQLITE_OK || res!=0 ){
if( res!=0 ){
pc = pOp->p2 - 1; pc = pOp->p2 - 1;
pC->recnoIsValid = 0; pC->recnoIsValid = 0;
} }

View File

@@ -0,0 +1,50 @@
# 2001 September 15
#
# 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.
#
#***********************************************************************
#
# This file runs the tests in the file crash.test with auto-vacuum enabled
# databases.
#
# $Id: autovacuum_ioerr.test,v 1.1 2005/01/11 10:25:07 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test2
proc finish_test {} {}
set ISQUICK 1
rename sqlite3 real_sqlite3
proc sqlite3 {args} {
set r [eval "real_sqlite3 $args"]
if { [llength $args] == 2 } {
[lindex $args 0] eval {pragma auto_vacuum = 1}
}
set r
}
rename do_test really_do_test
proc do_test {args} {
set sc [concat really_do_test "autovacuum-[lindex $args 0]" \
[lrange $args 1 end]]
eval $sc
}
source $testdir/ioerr.test
rename sqlite3 ""
rename real_sqlite3 sqlite3
rename finish_test ""
rename really_finish_test2 finish_test
rename do_test ""
rename really_do_test do_test
finish_test

189
test/autovacuum_ioerr2.test Normal file
View File

@@ -0,0 +1,189 @@
# 2001 October 12
#
# 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing for correct handling of I/O errors
# such as writes failing because the disk is full.
#
# The tests in this file use special facilities that are only
# available in the SQLite test fixture.
#
# $Id: autovacuum_ioerr2.test,v 1.1 2005/01/11 10:25:07 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
proc opendb {} {
catch {file delete -force test.db}
catch {file delete -force test.db-journal}
sqlite3 db test.db
execsql {pragma auto_vacuum = 1}
execsql {SELECT * FROM sqlite_master}
}
set ::go 1
for {set n 1} {$go} {incr n} {
do_test autovacuum-ioerr2-1.$n.1 {
set ::sqlite_io_error_pending 0
db close
opendb
execsql {
CREATE TABLE abc(a);
INSERT INTO abc VALUES(randstr(1500,1500));
}
expr [file size test.db]/1024
} {4}
do_test autovacuum-ioerr2-1.$n.2 [subst {
set ::sqlite_io_error_pending $n
}] $n
do_test autovacuum-ioerr2-1.$n.3 {
set r [catch {db eval {
CREATE TABLE abc2(a);
BEGIN;
DELETE FROM abc;
INSERT INTO abc VALUES(randstr(1500,1500));
CREATE TABLE abc3(a);
COMMIT;
}} msg]
set ::go [expr {$::sqlite_io_error_pending<=0}]
expr {$::sqlite_io_error_pending>0 || $r!=0}
} {1}
}
set ::sqlite_io_error_pending 0
set ::go 1
for {set n 1} {$go} {incr n} {
do_test autovacuum-ioerr2-2.$n.1 {
set ::sqlite_io_error_pending 0
db close
opendb
execsql {
PRAGMA cache_size = 10;
BEGIN;
CREATE TABLE abc(a);
INSERT INTO abc VALUES(randstr(1100,1100)); -- Page 4 is overflow
INSERT INTO abc VALUES(randstr(1100,1100)); -- Page 5 is overflow
}
for {set i 0} {$i<150} {incr i} {
execsql {
INSERT INTO abc VALUES(randstr(100,100));
}
}
execsql COMMIT
expr [file size test.db]/1024
} {24}
do_test autovacuum-ioerr2-2.$n.2 [subst {
set ::sqlite_io_error_pending $n
}] $n
do_test autovacuum-ioerr2-2.$n.3 {
set r [catch {db eval {
BEGIN;
DELETE FROM abc WHERE length(a)>100;
UPDATE abc SET a = randstr(90,90);
CREATE TABLE abc3(a);
COMMIT;
}} msg]
set ::go [expr {$::sqlite_io_error_pending<=0}]
expr {$::sqlite_io_error_pending>0 || $r!=0}
} {1}
}
set ::sqlite_io_error_pending 0
set ::go 1
for {set n 1} {$go} {incr n} {
do_test autovacuum-ioerr2-3.$n.1 {
set ::sqlite_io_error_pending 0
db close
opendb
execsql {
CREATE TABLE abc(a);
CREATE TABLE abc2(b);
}
} {}
do_test autovacuum-ioerr2-3.$n.2 [subst {
set ::sqlite_io_error_pending $n
}] $n
do_test autovacuum-ioerr2-3.$n.3 {
set r [catch {db eval {
BEGIN;
INSERT INTO abc2 VALUES(10);
DROP TABLE abc;
COMMIT;
DROP TABLE abc2;
}} msg]
set ::go [expr {$::sqlite_io_error_pending<=0}]
expr {$::sqlite_io_error_pending>0 || $r!=0}
} {1}
}
set ::sqlite_io_error_pending 0
do_test autovacuum-ioerr2.4.0 {
db close
opendb
execsql {
PRAGMA cache_size = 10;
BEGIN;
CREATE TABLE abc(a);
INSERT INTO abc VALUES(randstr(1100,1100)); -- Page 4 is overflow
INSERT INTO abc VALUES(randstr(1100,1100)); -- Page 5 is overflow
}
for {set i 0} {$i<2500} {incr i} {
execsql {
INSERT INTO abc VALUES(randstr(100,100));
}
}
execsql COMMIT
file copy -force test.db backup.db
} {}
proc opendb2 {} {
catch {file delete -force test.db}
catch {file delete -force test.db-journal}
file copy backup.db test.db
sqlite3 db test.db
execsql {select * from sqlite_master}
execsql {PRAGMA cache_size = 10}
return ""
}
set ::go 1
for {set n 1} {$go} {incr n} {
do_test autovacuum-ioerr2-4.$n.1 {
set ::sqlite_io_error_pending 0
db close
opendb2
} {}
do_test autovacuum-ioerr2-4.$n.2 [subst {
set ::sqlite_io_error_pending $n
}] $n
do_test autovacuum-ioerr2-4.$n.3 {
set r [catch {db eval {
BEGIN;
DELETE FROM abc WHERE oid < 3;
UPDATE abc SET a = randstr(100,100) WHERE oid > 2300;
UPDATE abc SET a = randstr(1100,1100) WHERE oid =
(select max(oid) from abc);
COMMIT;
}} msg]
set ::go [expr {$::sqlite_io_error_pending<=0}]
expr {$::sqlite_io_error_pending>0 || $r!=0}
} {1}
}
set ::sqlite_io_error_pending 0
rename opendb ""
db close
catch {file delete -force test.db}
catch {file delete -force test.db-journal}
finish_test

View File

@@ -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 script is btree database backend # focus of this script is btree database backend
# #
# $Id: btree.test,v 1.34 2005/01/10 12:59:53 danielk1977 Exp $ # $Id: btree.test,v 1.35 2005/01/11 10:25:07 danielk1977 Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
@@ -197,10 +197,13 @@ do_test btree-3.20.1 {
do_test btree-3.20.2 { do_test btree-3.20.2 {
btree_eof $::c1 btree_eof $::c1
} {1} } {1}
do_test btree-3.21 { # This test case used to test that one couldn't request data from an
set rc [catch {btree_data $::c1} res] # invalid cursor. That is now an assert()ed condition.
lappend rc $res #
} {1 SQLITE_INTERNAL} # do_test btree-3.21 {
# set rc [catch {btree_data $::c1} res]
# lappend rc $res
# } {1 SQLITE_INTERNAL}
# Commit the changes, reopen and reread the data # Commit the changes, reopen and reread the data
# #
@@ -278,10 +281,13 @@ do_test btree-3.39 {
btree_next $::c1 btree_next $::c1
btree_key $::c1 btree_key $::c1
} {0} } {0}
do_test btree-3.40 { # This test case used to test that requesting data from an invalid cursor
set rc [catch {btree_data $::c1} res] # returned SQLITE_INTERNAL. That is now an assert()ed condition.
lappend rc $res #
} {1 SQLITE_INTERNAL} # do_test btree-3.40 {
# set rc [catch {btree_data $::c1} res]
# lappend rc $res
# } {1 SQLITE_INTERNAL}
do_test btree-3.41 { do_test btree-3.41 {
lindex [btree_pager_stats $::b1] 1 lindex [btree_pager_stats $::b1] 1
} {1} } {1}
@@ -489,10 +495,13 @@ do_test btree-6.9 {
lindex [btree_pager_stats $::b1] 1 lindex [btree_pager_stats $::b1] 1
} {2} } {2}
do_test btree-6.9.1 { # This test case used to test that requesting the key from an invalid cursor
btree_move_to $::c2 {} # returned an empty string. But that is now an assert()ed condition.
btree_key $::c2 #
} {} # do_test btree-6.9.1 {
# btree_move_to $::c2 {}
# btree_key $::c2
# } {}
# If we drop table 1 it just clears the table. Table 1 always exists. # If we drop table 1 it just clears the table. Table 1 always exists.
# #
@@ -1035,8 +1044,10 @@ btree_pager_ref_dump $::b1
# Miscellaneous tests. # Miscellaneous tests.
# #
# btree-16.1 - Check that a statement cannot be started if a transaction is not # btree-16.1 - Check that a statement cannot be started if a transaction
# active. # is not active.
# btree-16.2 - Check that it is an error to request more payload from a
# btree entry than the entry contains.
do_test btree-16.1 { do_test btree-16.1 {
catch {btree_begin_statement $::b1} msg catch {btree_begin_statement $::b1} msg
set msg set msg
@@ -1058,6 +1069,89 @@ do_test btree-16.4 {
set msg set msg
} SQLITE_ERROR } SQLITE_ERROR
if {$tcl_platform(platform)=="unix"} {
do_test btree-16.5 {
btree_close $::b1
set ::origperm [file attributes test1.bt -permissions]
file attributes test1.bt -permissions o-w,g-w,a-w
set ::b1 [btree_open test1.bt 2000 0]
catch {btree_cursor $::b1 2 1} msg
file attributes test1.bt -permissions $::origperm
btree_close $::b1
set ::b1 [btree_open test1.bt 2000 0]
set msg
} {SQLITE_READONLY}
}
do_test btree-16.6 {
set ::c1 [btree_cursor $::b1 2 1]
set ::c2 [btree_cursor $::b1 2 1]
btree_begin_transaction $::b1
for {set i 0} {$i<100} {incr i} {
btree_insert $::c1 $i [string repeat helloworld 10]
}
btree_last $::c2
btree_insert $::c1 100 [string repeat helloworld 10]
} {}
do_test btree-16.7 {
btree_close_cursor $::c1
btree_close_cursor $::c2
btree_commit $::b1
set ::c1 [btree_cursor $::b1 2 1]
catch {btree_insert $::c1 101 helloworld} msg
set msg
} {SQLITE_ERROR}
do_test btree-16.8 {
btree_first $::c1
catch {btree_delete $::c1} msg
set msg
} {SQLITE_ERROR}
do_test btree-16.9 {
btree_close_cursor $::c1
btree_begin_transaction $::b1
set ::c1 [btree_cursor $::b1 2 0]
catch {btree_insert $::c1 101 helloworld} msg
set msg
} {SQLITE_PERM}
do_test btree-16.10 {
catch {btree_delete $::c1} msg
set msg
} {SQLITE_PERM}
do_test btree-16.11 {
btree_close_cursor $::c1
set ::c2 [btree_cursor $::b1 2 1]
set ::c1 [btree_cursor $::b1 2 0]
catch {btree_insert $::c2 101 helloworld} msg
set msg
} {SQLITE_LOCKED}
do_test btree-16.12 {
btree_first $::c2
catch {btree_delete $::c2} msg
set msg
} {SQLITE_LOCKED}
do_test btree-16.13 {
catch {btree_clear_table $::b1 2} msg
set msg
} {SQLITE_LOCKED}
do_test btree-16.14 {
btree_close_cursor $::c1
btree_close_cursor $::c2
btree_commit $::b1
catch {btree_clear_table $::b1 2} msg
set msg
} {SQLITE_ERROR}
do_test btree-16.15 {
catch {btree_drop_table $::b1 2} msg
set msg
} {SQLITE_ERROR}
do_test btree-16.16 {
btree_begin_transaction $::b1
set ::c1 [btree_cursor $::b1 2 0]
catch {btree_drop_table $::b1 2} msg
set msg
} {SQLITE_LOCKED}
do_test btree-99.1 { do_test btree-99.1 {
btree_close $::b1 btree_close $::b1
} {} } {}

View File

@@ -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 script is btree database backend # focus of this script is btree database backend
# #
# $Id: btree2.test,v 1.13 2004/05/10 16:18:48 drh Exp $ # $Id: btree2.test,v 1.14 2005/01/11 10:25:07 danielk1977 Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
@@ -143,10 +143,16 @@ proc check_invariants {} {
set L [btree_data $::c2] set L [btree_data $::c2]
set LM1 [expr {$L-1}] set LM1 [expr {$L-1}]
for {set i 1} {$i<=$N} {incr i} { for {set i 1} {$i<=$N} {incr i} {
set key [btree_key $::c3] set key {}
if {![btree_eof $::c3]} {
set key [btree_key $::c3]
}
if {[scan $key %d k]<1} {set k 0} if {[scan $key %d k]<1} {set k 0}
if {$k!=$i} { if {$k!=$i} {
set key [btree_key $::c4] set key {}
if {![btree_eof $::c4]} {
set key [btree_key $::c4]
}
if {[scan $key %d k]<1} {set k 0} if {[scan $key %d k]<1} {set k 0}
if {$k!=$i} { if {$k!=$i} {
return "Key $i is missing from both foreground and background" return "Key $i is missing from both foreground and background"
@@ -252,19 +258,26 @@ proc random_changes {n I K D} {
btree_delete $::c3 btree_delete $::c3
} else { } else {
if {$c<0} {btree_next $::c3} if {$c<0} {btree_next $::c3}
if {[string match $basekey* [btree_key $::c3]]} { if {![btree_eof $::c3]} {
btree_delete $::c3 if {[string match $basekey* [btree_key $::c3]]} {
btree_delete $::c3
}
} }
} }
if {[set c [btree_move_to $::c4 $basekey]]==0} { if {[set c [btree_move_to $::c4 $basekey]]==0} {
btree_delete $::c4 btree_delete $::c4
} else { } else {
if {$c<0} {btree_next $::c4} if {$c<0} {btree_next $::c4}
if {[string match $basekey* [btree_key $::c4]]} { if {![btree_eof $::c4]} {
btree_delete $::c4 if {[string match $basekey* [btree_key $::c4]]} {
btree_delete $::c4
}
} }
} }
if {[scan [btree_key $::c4] %d kx]<1} {set kx -1} set kx -1
if {![btree_eof $::c4]} {
if {[scan [btree_key $::c4] %d kx]<1} {set kx -1}
}
if {$kx==$k} { if {$kx==$k} {
btree_delete $::c4 btree_delete $::c4
} }

109
test/corrupt2.test Normal file
View File

@@ -0,0 +1,109 @@
# 2004 August 30
#
# 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to make sure SQLite does not crash or
# segfault if it sees a corrupt database file.
#
# $Id: corrupt2.test,v 1.1 2005/01/11 10:25:07 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# The following tests - corrupt2-1.* - create some databases corrupted in
# specific ways and ensure that SQLite detects them as corrupt.
#
do_test corrupt2-1.1 {
execsql {
CREATE TABLE abc(a, b, c);
}
} {}
do_test corrupt2-1.2 {
# Corrupt the 16 byte magic string at the start of the file
file delete -force corrupt.db
file delete -force corrupt.db-journal
file copy test.db corrupt.db
set f [open corrupt.db a]
seek $f 8 start
puts $f blah
close $f
sqlite3 db2 corrupt.db
catchsql {
SELECT * FROM sqlite_master;
} db2
} {1 {file is encrypted or is not a database}}
do_test corrupt2-1.3 {
db2 close
# Corrupt the page-size (bytes 16 and 17 of page 1).
file delete -force corrupt.db
file delete -force corrupt.db-journal
file copy test.db corrupt.db
set f [open corrupt.db a]
fconfigure $f -encoding binary
seek $f 16 start
puts -nonewline $f "\x00\xFF"
close $f
sqlite3 db2 corrupt.db
catchsql {
SELECT * FROM sqlite_master;
} db2
} {1 {file is encrypted or is not a database}}
do_test corrupt2-1.4 {
db2 close
# Corrupt the free-block list on page 1.
file delete -force corrupt.db
file delete -force corrupt.db-journal
file copy test.db corrupt.db
set f [open corrupt.db a]
fconfigure $f -encoding binary
seek $f 101 start
puts -nonewline $f "\xFF\xFF"
close $f
sqlite3 db2 corrupt.db
catchsql {
SELECT * FROM sqlite_master;
} db2
} {1 {database disk image is malformed}}
do_test corrupt2-1.5 {
db2 close
# Corrupt the free-block list on page 1.
file delete -force corrupt.db
file delete -force corrupt.db-journal
file copy test.db corrupt.db
set f [open corrupt.db a]
fconfigure $f -encoding binary
seek $f 101 start
puts -nonewline $f "\x00\xC8"
seek $f 200 start
puts -nonewline $f "\x00\x00"
puts -nonewline $f "\x10\x00"
close $f
sqlite3 db2 corrupt.db
catchsql {
SELECT * FROM sqlite_master;
} db2
} {1 {database disk image is malformed}}
db2 close
finish_test

View File

@@ -15,7 +15,7 @@
# The tests in this file use special facilities that are only # The tests in this file use special facilities that are only
# available in the SQLite test fixture. # available in the SQLite test fixture.
# #
# $Id: ioerr.test,v 1.8 2005/01/10 12:59:53 danielk1977 Exp $ # $Id: ioerr.test,v 1.9 2005/01/11 10:25:07 danielk1977 Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@@ -135,4 +135,43 @@ for {set n 1} {$go} {incr n} {
} }
set ::sqlite_io_error_pending 0 set ::sqlite_io_error_pending 0
set ::go 1
for {set n 1} {$go} {incr n} {
do_test ioerr-3.$n.1 {
set ::sqlite_io_error_pending 0
db close
catch {file delete -force test.db}
catch {file delete -force test.db-journal}
sqlite3 db test.db
execsql {
PRAGMA cache_size = 10;
BEGIN;
CREATE TABLE abc(a);
INSERT INTO abc VALUES(randstr(1500,1500)); -- Page 4 is overflow
}
for {set i 0} {$i<150} {incr i} {
execsql {
INSERT INTO abc VALUES(randstr(100,100));
}
}
execsql COMMIT
} {}
do_test ioerr-3.$n.2 [subst {
set ::sqlite_io_error_pending $n
}] $n
do_test ioerr-3.$n.3 {
set r [catch {db eval {
CREATE TABLE abc2(a);
BEGIN;
DELETE FROM abc WHERE length(a)>100;
UPDATE abc SET a = randstr(90,90);
COMMIT;
CREATE TABLE abc3(a);
}} msg]
set ::go [expr {$::sqlite_io_error_pending<=0}]
expr {$::sqlite_io_error_pending>0 || $r!=0}
} {1}
}
set ::sqlite_io_error_pending 0
finish_test finish_test