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:
27
manifest
27
manifest
@@ -1,5 +1,5 @@
|
||||
C Extra\stest\scases\sto\simprove\scoverage\sof\sbtree.c\s(CVS\s2189)
|
||||
D 2005-01-10T12:59:52
|
||||
C Test\scases\sto\simprove\scoverage\sof\sbtree.c\s(and\sminor\sbugfixes).\s(CVS\s2190)
|
||||
D 2005-01-11T10:25:07
|
||||
F Makefile.in ecf441ac5ca1ccfc8748a8a9537706e69893dfa4
|
||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
||||
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
|
||||
@@ -29,7 +29,7 @@ F sqlite3.def dbaeb20c153e1d366e8f421b55a573f5dfc00863
|
||||
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
|
||||
F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689
|
||||
F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea
|
||||
F src/btree.c 241e27b4640519a45ab55d35ee3ae300a478eb23
|
||||
F src/btree.c 5ec669c8839d98dd9e283cc6d4547da4adb37a81
|
||||
F src/btree.h 861e40b759a195ba63819740e484390012cf81ab
|
||||
F src/build.c af1296e8a21a406b4f4c4f1e1365e075071219f3
|
||||
F src/cursor.c f883813759742068890b1f699335872bfa8fdf41
|
||||
@@ -53,10 +53,10 @@ F src/os_unix.c 08340c864822115bf87c6c1735780a0996278b81
|
||||
F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13
|
||||
F src/os_win.c 3c0b0a3bc33318cf555a1cd130232ad1b9a5a711
|
||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||
F src/pager.c 4a14410a4e67173bb121a919c7f2033b93822186
|
||||
F src/pager.c c6b29d55c9755f35bd9d711865aaf83e410f730f
|
||||
F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862
|
||||
F src/parse.y ceba179b9703657180963568f54b0e75f33e36e1
|
||||
F src/pragma.c 1b6f9f4caa2c441b18bf0c8793a4b4b8f3214d03
|
||||
F src/pragma.c ac594f74c90ffec043c43e49358719ffeb491eec
|
||||
F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
|
||||
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
||||
F src/select.c af6ffcf0201f8f4e2697eea25689077dc61c6109
|
||||
@@ -76,7 +76,7 @@ F src/update.c 0979397c41ac29c54fe0cc687a356d8629a633af
|
||||
F src/utf.c e45ce11be6922408cd381561721f6cca7d3b992a
|
||||
F src/util.c 29f43c4a7b9ff29302f7899f793be6836b6cd7f9
|
||||
F src/vacuum.c 1a9db113a027461daaf44724c71dd1ebbd064203
|
||||
F src/vdbe.c 53520958a7d63eaf138fa78f69efe225d502a9bf
|
||||
F src/vdbe.c c9f00cc0298e025e61b4b65555a4a23dd13325dd
|
||||
F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
|
||||
F src/vdbeInt.h 0f74561e629af86172de7cdf0ecaea014c51696c
|
||||
F src/vdbeapi.c 0cf3bdc1072616bedc8eec7fc22e3f5a169d33fd
|
||||
@@ -93,12 +93,14 @@ F test/auth.test 559e0816b8100740624ebb0ab7aab05f5c92831c
|
||||
F test/autoinc.test c071e51ff167b8e889212273588d9cca71845b70
|
||||
F test/autovacuum.test a4e8da39a6268378c4f9fc17fe2df1d5be16d631
|
||||
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/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
|
||||
F test/bind.test 3635ddfe0fb15ecfd158708feff6ef707e15c0a9
|
||||
F test/blob.test fc41fe95bdc10da51f0dee73ce86e75ce1d6eb9d
|
||||
F test/btree.test ff754a2e68af75396fbbf8dfda009b4b93f086a6
|
||||
F test/btree2.test aa4a6d05b1ea90b1acaf83ba89039dd302a88635
|
||||
F test/btree.test 8aa7424aeec844df990273fe36447e5d7e407261
|
||||
F test/btree2.test dbce930b549d5ac883a7d8905c976209ea241db3
|
||||
F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4
|
||||
F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2
|
||||
F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027
|
||||
@@ -114,6 +116,7 @@ F test/collate5.test 7999fb3122386bae38acd8ccd61e0b7c5a30e289
|
||||
F test/collate6.test 6c9470d1606ee3e564675b229653e320c49ec638
|
||||
F test/conflict.test c5b849b01cfbe0a4f63a90cba6f68e2fe3a75f87
|
||||
F test/corrupt.test 0080ddcece23e8ba47c44608c4fb73fd4d1d8ce2
|
||||
F test/corrupt2.test cb1f813df7559de3021e01170af0bba31507a9a5
|
||||
F test/crash.test 637479504e137d065385c5b9379680d2b5372630
|
||||
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
|
||||
F test/cursor.test d7c65ea0fc4e321e12fbcf5c7f3e2211ef45379b
|
||||
@@ -134,7 +137,7 @@ F test/insert.test 56f9c20c9adc8d707490c4ffa5d4daa94826ea03
|
||||
F test/insert2.test 0bb50ff999e35a21549d8ee5dc44db8ac24d31a7
|
||||
F test/interrupt.test 0aa230f8aedec0ad7caaf5edaced337e4cfb3820
|
||||
F test/intpkey.test b57cf5236fde1bd8cbc1388fa0c91908f6fd9194
|
||||
F test/ioerr.test fd283e768301b26bc148012ea6ebea4c2295aa20
|
||||
F test/ioerr.test b37837850294c6cbafb0fd5211a4df40b10d46af
|
||||
F test/join.test ea8c77b9fbc377fe553cdb5ce5f1bd72021dca5d
|
||||
F test/join2.test c97e4c5aa65dea462145529e58212a709b4722b8
|
||||
F test/join3.test 67dc0d7c8dab3fff25796d0f3c3fd9c999aeded3
|
||||
@@ -263,7 +266,7 @@ F www/tclsqlite.tcl e73f8f8e5f20e8277619433f7970060ab01088fc
|
||||
F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
|
||||
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
||||
F www/whentouse.tcl c3b50d3ac31c54be2a1af9b488a89d22f1e6e746
|
||||
P 5b7a5a4d69be425163135698d889797d15f56492
|
||||
R 8f87d57733bba8a8bebba0892812901d
|
||||
P a461988661368bce799ef3d498a18e88559e14c7
|
||||
R 9631300063f5d334400b6e5706977e76
|
||||
U danielk1977
|
||||
Z 23146f967500dcd597b4ae335d7f01e0
|
||||
Z 6f3669f1f4cea6222a3e8648182fde70
|
||||
|
@@ -1 +1 @@
|
||||
a461988661368bce799ef3d498a18e88559e14c7
|
||||
8ced491588764b1e1066787d0abf3cde8b60970b
|
55
src/btree.c
55
src/btree.c
@@ -9,7 +9,7 @@
|
||||
** 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.
|
||||
** 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 */
|
||||
u8 wrFlag; /* True if writable */
|
||||
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 */
|
||||
){
|
||||
int pc; /* Address of a freeblock within pPage->aData[] */
|
||||
int i; /* Loop counter */
|
||||
int hdr; /* Offset to beginning of page header */
|
||||
u8 *data; /* Equal to pPage->aData */
|
||||
Btree *pBt; /* The main btree structure */
|
||||
@@ -997,17 +995,12 @@ static int initPage(
|
||||
/* Compute the total free space on the page */
|
||||
pc = get2byte(&data[hdr+1]);
|
||||
nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell);
|
||||
i = 0;
|
||||
while( pc>0 ){
|
||||
int next, size;
|
||||
if( pc>usableSize-4 ){
|
||||
/* Free block is off the page */
|
||||
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]);
|
||||
size = get2byte(&data[pc+2]);
|
||||
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,
|
||||
** the first byte past the 1GB boundary, 0x40000000) needs to occur
|
||||
** 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){
|
||||
if( pBt->pageSizeFixed ){
|
||||
@@ -1904,6 +1900,7 @@ static void invalidateCursors(Btree *pBt){
|
||||
** Print debugging information about all cursors to standard output.
|
||||
*/
|
||||
void sqlite3BtreeCursorList(Btree *pBt){
|
||||
#ifndef SQLITE_OMIT_CURSOR
|
||||
BtCursor *pCur;
|
||||
for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
|
||||
MemPage *pPage = pCur->pPage;
|
||||
@@ -1914,6 +1911,7 @@ void sqlite3BtreeCursorList(Btree *pBt){
|
||||
pCur->isValid ? "" : " eof"
|
||||
);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2117,7 +2115,6 @@ int sqlite3BtreeCursor(
|
||||
pCur->pPrev = 0;
|
||||
pBt->pCursor = pCur;
|
||||
pCur->isValid = 0;
|
||||
pCur->status = SQLITE_OK;
|
||||
*ppCur = pCur;
|
||||
return SQLITE_OK;
|
||||
|
||||
@@ -2344,9 +2341,7 @@ static int getPayload(
|
||||
** the available payload.
|
||||
*/
|
||||
int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
|
||||
if( !pCur->isValid ){
|
||||
return pCur->status;
|
||||
}
|
||||
assert( pCur->isValid );
|
||||
assert( pCur->pPage!=0 );
|
||||
assert( pCur->pPage->intKey==0 );
|
||||
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.
|
||||
*/
|
||||
int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
|
||||
if( !pCur->isValid ){
|
||||
return pCur->status ? pCur->status : SQLITE_INTERNAL;
|
||||
}
|
||||
assert( pCur->isValid );
|
||||
assert( pCur->pPage!=0 );
|
||||
assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
|
||||
return getPayload(pCur, offset, amt, pBuf, 1);
|
||||
@@ -2603,9 +2596,6 @@ static int moveToRightmost(BtCursor *pCur){
|
||||
*/
|
||||
int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
|
||||
int rc;
|
||||
if( pCur->status ){
|
||||
return pCur->status;
|
||||
}
|
||||
rc = moveToRoot(pCur);
|
||||
if( rc ) return rc;
|
||||
if( pCur->isValid==0 ){
|
||||
@@ -2625,9 +2615,6 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
|
||||
*/
|
||||
int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
|
||||
int rc;
|
||||
if( pCur->status ){
|
||||
return pCur->status;
|
||||
}
|
||||
rc = moveToRoot(pCur);
|
||||
if( rc ) return rc;
|
||||
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 rc;
|
||||
|
||||
if( pCur->status ){
|
||||
return pCur->status;
|
||||
}
|
||||
rc = moveToRoot(pCur);
|
||||
if( rc ) return rc;
|
||||
assert( pCur->pPage );
|
||||
@@ -3274,7 +3257,7 @@ static int fillInCell(
|
||||
#endif
|
||||
if( rc ){
|
||||
releasePage(pToRelease);
|
||||
clearCell(pPage, pCell);
|
||||
/* clearCell(pPage, pCell); */
|
||||
return rc;
|
||||
}
|
||||
put4byte(pPrior, pgnoOvfl);
|
||||
@@ -3873,7 +3856,8 @@ static int balance_nonroot(MemPage *pPage){
|
||||
pNew = apNew[i] = apOld[i];
|
||||
pgnoNew[i] = pgnoOld[i];
|
||||
apOld[i] = 0;
|
||||
sqlite3pager_write(pNew->aData);
|
||||
rc = sqlite3pager_write(pNew->aData);
|
||||
if( rc ) goto balance_cleanup;
|
||||
}else{
|
||||
rc = allocatePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0);
|
||||
if( rc ) goto balance_cleanup;
|
||||
@@ -4236,9 +4220,6 @@ int sqlite3BtreeInsert(
|
||||
unsigned char *oldCell;
|
||||
unsigned char *newCell = 0;
|
||||
|
||||
if( pCur->status ){
|
||||
return pCur->status; /* A rollback destroyed this cursor */
|
||||
}
|
||||
if( pBt->inTrans!=TRANS_WRITE ){
|
||||
/* Must start a transaction before doing an insert */
|
||||
return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
|
||||
@@ -4310,9 +4291,6 @@ int sqlite3BtreeDelete(BtCursor *pCur){
|
||||
Btree *pBt = pCur->pBt;
|
||||
|
||||
assert( pPage->isInit );
|
||||
if( pCur->status ){
|
||||
return pCur->status; /* A rollback destroyed this cursor */
|
||||
}
|
||||
if( pBt->inTrans!=TRANS_WRITE ){
|
||||
/* Must start a transaction before doing a delete */
|
||||
return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
|
||||
@@ -4338,7 +4316,8 @@ int sqlite3BtreeDelete(BtCursor *pCur){
|
||||
if( !pPage->leaf ){
|
||||
pgnoChild = get4byte(pCell);
|
||||
}
|
||||
clearCell(pPage, pCell);
|
||||
rc = clearCell(pPage, pCell);
|
||||
if( rc ) return rc;
|
||||
|
||||
if( !pPage->leaf ){
|
||||
/*
|
||||
@@ -4410,9 +4389,7 @@ int sqlite3BtreeCreateTable(Btree *pBt, int *piTable, int flags){
|
||||
/* Must start a transaction first */
|
||||
return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
|
||||
}
|
||||
if( pBt->readOnly ){
|
||||
return SQLITE_READONLY;
|
||||
}
|
||||
assert( !pBt->readOnly );
|
||||
|
||||
/* 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
|
||||
@@ -4771,6 +4748,7 @@ int sqlite3BtreeFlags(BtCursor *pCur){
|
||||
** is used for debugging and testing only.
|
||||
*/
|
||||
#ifdef SQLITE_TEST
|
||||
#ifndef SQLITE_OMIT_BTREEPAGEDUMP
|
||||
static int btreePageDump(Btree *pBt, int pgno, int recursive, MemPage *pParent){
|
||||
int rc;
|
||||
MemPage *pPage;
|
||||
@@ -4867,8 +4845,11 @@ static int btreePageDump(Btree *pBt, int pgno, int recursive, MemPage *pParent){
|
||||
fflush(stdout);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){
|
||||
#ifndef SQLITE_OMIT_BTREEPAGEDUMP
|
||||
return btreePageDump(pBt, pgno, recursive, 0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
12
src/pager.c
12
src/pager.c
@@ -18,7 +18,7 @@
|
||||
** file simultaneously, or one process from reading the database while
|
||||
** 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 "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);
|
||||
}
|
||||
if( pPg ){
|
||||
/* No page should ever be rolled back that is in use, except for page
|
||||
** 1 which is held in use in order to keep the lock on the database
|
||||
** active.
|
||||
/* No page should ever be explicitly rolled back that is in use, except
|
||||
** for page 1 which is held in use in order to keep the lock on the
|
||||
** 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;
|
||||
assert( pPg->nRef==0 || pPg->pgno==1 );
|
||||
/* assert( pPg->nRef==0 || pPg->pgno==1 ); */
|
||||
pData = PGHDR_TO_DATA(pPg);
|
||||
memcpy(pData, aData, pPager->pageSize);
|
||||
if( pPager->xDestructor ){ /*** FIX ME: Should this be xReinit? ***/
|
||||
|
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** 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 "os.h"
|
||||
@@ -285,7 +285,7 @@ void sqlite3Pragma(
|
||||
int size = pBt ? sqlite3BtreeGetPageSize(pBt) : 0;
|
||||
returnSingleInt(pParse, "page_size", size);
|
||||
}else{
|
||||
sqlite3BtreeSetPageSize(pBt, atoi(zRight), sqlite3BtreeGetReserve(pBt));
|
||||
sqlite3BtreeSetPageSize(pBt, atoi(zRight), -1);
|
||||
}
|
||||
}else
|
||||
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
|
||||
|
23
src/vdbe.c
23
src/vdbe.c
@@ -43,7 +43,7 @@
|
||||
** in this file for details. If in doubt, do not deviate from existing
|
||||
** 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 "os.h"
|
||||
@@ -2565,12 +2565,18 @@ case OP_MoveGt: {
|
||||
pTos--;
|
||||
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->recnoIsValid = res==0;
|
||||
}else{
|
||||
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->deferredMoveto = 0;
|
||||
@@ -2579,7 +2585,10 @@ case OP_MoveGt: {
|
||||
sqlite3_search_count++;
|
||||
if( oc==OP_MoveGe || oc==OP_MoveGt ){
|
||||
if( res<0 ){
|
||||
sqlite3BtreeNext(pC->pCursor, &res);
|
||||
rc = sqlite3BtreeNext(pC->pCursor, &res);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
pC->recnoIsValid = 0;
|
||||
}else{
|
||||
res = 0;
|
||||
@@ -2800,12 +2809,14 @@ case OP_NotExists: {
|
||||
assert( pTos->flags & MEM_Int );
|
||||
assert( p->apCsr[i]->intKey );
|
||||
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->recnoIsValid = res==0;
|
||||
pC->nullRow = 0;
|
||||
pC->cacheValid = 0;
|
||||
if( rx!=SQLITE_OK || res!=0 ){
|
||||
// if( rx!=SQLITE_OK || res!=0 ){
|
||||
if( res!=0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
pC->recnoIsValid = 0;
|
||||
}
|
||||
|
50
test/autovacuum_ioerr.test
Normal file
50
test/autovacuum_ioerr.test
Normal 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
189
test/autovacuum_ioerr2.test
Normal 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
|
||||
|
||||
|
124
test/btree.test
124
test/btree.test
@@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# 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]
|
||||
@@ -197,10 +197,13 @@ do_test btree-3.20.1 {
|
||||
do_test btree-3.20.2 {
|
||||
btree_eof $::c1
|
||||
} {1}
|
||||
do_test btree-3.21 {
|
||||
set rc [catch {btree_data $::c1} res]
|
||||
lappend rc $res
|
||||
} {1 SQLITE_INTERNAL}
|
||||
# This test case used to test that one couldn't request data from an
|
||||
# invalid cursor. That is now an assert()ed condition.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
@@ -278,10 +281,13 @@ do_test btree-3.39 {
|
||||
btree_next $::c1
|
||||
btree_key $::c1
|
||||
} {0}
|
||||
do_test btree-3.40 {
|
||||
set rc [catch {btree_data $::c1} res]
|
||||
lappend rc $res
|
||||
} {1 SQLITE_INTERNAL}
|
||||
# This test case used to test that requesting data from an invalid cursor
|
||||
# returned SQLITE_INTERNAL. That is now an assert()ed condition.
|
||||
#
|
||||
# do_test btree-3.40 {
|
||||
# set rc [catch {btree_data $::c1} res]
|
||||
# lappend rc $res
|
||||
# } {1 SQLITE_INTERNAL}
|
||||
do_test btree-3.41 {
|
||||
lindex [btree_pager_stats $::b1] 1
|
||||
} {1}
|
||||
@@ -489,10 +495,13 @@ do_test btree-6.9 {
|
||||
lindex [btree_pager_stats $::b1] 1
|
||||
} {2}
|
||||
|
||||
do_test btree-6.9.1 {
|
||||
btree_move_to $::c2 {}
|
||||
btree_key $::c2
|
||||
} {}
|
||||
# This test case used to test that requesting the key from an invalid cursor
|
||||
# returned an empty string. But that is now an assert()ed condition.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
@@ -1035,8 +1044,10 @@ btree_pager_ref_dump $::b1
|
||||
|
||||
# Miscellaneous tests.
|
||||
#
|
||||
# btree-16.1 - Check that a statement cannot be started if a transaction is not
|
||||
# active.
|
||||
# btree-16.1 - Check that a statement cannot be started if a transaction
|
||||
# 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 {
|
||||
catch {btree_begin_statement $::b1} msg
|
||||
set msg
|
||||
@@ -1058,6 +1069,89 @@ do_test btree-16.4 {
|
||||
set msg
|
||||
} 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 {
|
||||
btree_close $::b1
|
||||
} {}
|
||||
|
@@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# 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]
|
||||
@@ -143,10 +143,16 @@ proc check_invariants {} {
|
||||
set L [btree_data $::c2]
|
||||
set LM1 [expr {$L-1}]
|
||||
for {set i 1} {$i<=$N} {incr i} {
|
||||
set key {}
|
||||
if {![btree_eof $::c3]} {
|
||||
set key [btree_key $::c3]
|
||||
}
|
||||
if {[scan $key %d k]<1} {set k 0}
|
||||
if {$k!=$i} {
|
||||
set key {}
|
||||
if {![btree_eof $::c4]} {
|
||||
set key [btree_key $::c4]
|
||||
}
|
||||
if {[scan $key %d k]<1} {set k 0}
|
||||
if {$k!=$i} {
|
||||
return "Key $i is missing from both foreground and background"
|
||||
@@ -252,19 +258,26 @@ proc random_changes {n I K D} {
|
||||
btree_delete $::c3
|
||||
} else {
|
||||
if {$c<0} {btree_next $::c3}
|
||||
if {![btree_eof $::c3]} {
|
||||
if {[string match $basekey* [btree_key $::c3]]} {
|
||||
btree_delete $::c3
|
||||
}
|
||||
}
|
||||
}
|
||||
if {[set c [btree_move_to $::c4 $basekey]]==0} {
|
||||
btree_delete $::c4
|
||||
} else {
|
||||
if {$c<0} {btree_next $::c4}
|
||||
if {![btree_eof $::c4]} {
|
||||
if {[string match $basekey* [btree_key $::c4]]} {
|
||||
btree_delete $::c4
|
||||
}
|
||||
}
|
||||
}
|
||||
set kx -1
|
||||
if {![btree_eof $::c4]} {
|
||||
if {[scan [btree_key $::c4] %d kx]<1} {set kx -1}
|
||||
}
|
||||
if {$kx==$k} {
|
||||
btree_delete $::c4
|
||||
}
|
||||
|
109
test/corrupt2.test
Normal file
109
test/corrupt2.test
Normal 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
|
||||
|
@@ -15,7 +15,7 @@
|
||||
# The tests in this file use special facilities that are only
|
||||
# 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]
|
||||
source $testdir/tester.tcl
|
||||
@@ -135,4 +135,43 @@ for {set n 1} {$go} {incr n} {
|
||||
}
|
||||
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
|
||||
|
Reference in New Issue
Block a user